From cae8fa8120c70195f34a2456f18c4c848a2d3e0c Mon Sep 17 00:00:00 2001 From: obrien Date: Sat, 16 Oct 1999 06:09:09 +0000 Subject: Virgin import of the GCC 2.95.1 compilers --- contrib/gcc/BUGS | 10 +- contrib/gcc/ChangeLog | 23788 +++++++++++++++----------- contrib/gcc/FSFChangeLog | 2154 +++ contrib/gcc/LANGUAGES | 12 + contrib/gcc/Makefile.in | 1003 +- contrib/gcc/NEWS | 8 + contrib/gcc/README | 8 +- contrib/gcc/acconfig.h | 56 +- contrib/gcc/aclocal.m4 | 448 +- contrib/gcc/alias.c | 579 +- contrib/gcc/basic-block.h | 178 +- contrib/gcc/bitmap.c | 6 +- contrib/gcc/bitmap.h | 6 +- contrib/gcc/c-aux-info.c | 244 +- contrib/gcc/c-common.c | 408 +- contrib/gcc/c-convert.c | 2 +- contrib/gcc/c-decl.c | 438 +- contrib/gcc/c-iterate.c | 6 +- contrib/gcc/c-lang.c | 21 +- contrib/gcc/c-lex.c | 705 +- contrib/gcc/c-lex.h | 6 +- contrib/gcc/c-parse.gperf | 8 +- contrib/gcc/c-parse.in | 90 +- contrib/gcc/c-pragma.c | 465 +- contrib/gcc/c-pragma.h | 69 +- contrib/gcc/c-tree.h | 65 +- contrib/gcc/c-typeck.c | 557 +- contrib/gcc/caller-save.c | 738 +- contrib/gcc/calls.c | 2623 +-- contrib/gcc/cccp.c | 1445 +- contrib/gcc/cexp.y | 376 +- contrib/gcc/collect2.c | 567 +- contrib/gcc/collect2.h | 36 + contrib/gcc/combine.c | 330 +- contrib/gcc/config.in | 178 +- contrib/gcc/config/alpha/alpha-interix.h | 252 + contrib/gcc/config/alpha/alpha.c | 1462 +- contrib/gcc/config/alpha/alpha.h | 325 +- contrib/gcc/config/alpha/alpha.md | 1037 +- contrib/gcc/config/alpha/alpha32.h | 104 + contrib/gcc/config/alpha/crtbegin.asm | 89 +- contrib/gcc/config/alpha/crtend.asm | 3 + contrib/gcc/config/alpha/elf.h | 62 +- contrib/gcc/config/alpha/lib1funcs.asm | 325 + contrib/gcc/config/alpha/linux-ecoff.h | 7 +- contrib/gcc/config/alpha/linux-elf.h | 3 +- contrib/gcc/config/alpha/linux.h | 6 +- contrib/gcc/config/alpha/netbsd-elf.h | 3 +- contrib/gcc/config/alpha/netbsd.h | 3 +- contrib/gcc/config/alpha/osf.h | 12 +- contrib/gcc/config/alpha/t-ieee | 6 + contrib/gcc/config/alpha/t-interix | 16 + contrib/gcc/config/alpha/vms.h | 4 - contrib/gcc/config/alpha/vxworks.h | 6 +- contrib/gcc/config/alpha/xm-alpha-interix.h | 45 + contrib/gcc/config/alpha/xm-alpha.h | 2 +- contrib/gcc/config/dbxcoff.h | 4 +- contrib/gcc/config/dbxelf.h | 109 + contrib/gcc/config/elfos.h | 704 + contrib/gcc/config/float-sh.h | 2 +- contrib/gcc/config/fp-bit.c | 15 +- contrib/gcc/config/i386/aix386ng.h | 6 +- contrib/gcc/config/i386/bsd.h | 4 +- contrib/gcc/config/i386/crtdll.h | 6 +- contrib/gcc/config/i386/cygwin.asm | 32 + contrib/gcc/config/i386/cygwin.h | 525 + contrib/gcc/config/i386/dgux.c | 4 +- contrib/gcc/config/i386/dgux.h | 37 +- contrib/gcc/config/i386/djgpp-rtems.h | 41 + contrib/gcc/config/i386/djgpp.h | 161 + contrib/gcc/config/i386/freebsd-elf.h | 122 +- contrib/gcc/config/i386/gas.h | 7 +- contrib/gcc/config/i386/gnu.h | 27 +- contrib/gcc/config/i386/i386-coff.h | 8 +- contrib/gcc/config/i386/i386-interix.h | 575 + contrib/gcc/config/i386/i386.c | 1831 +- contrib/gcc/config/i386/i386.h | 407 +- contrib/gcc/config/i386/i386.md | 3437 ++-- contrib/gcc/config/i386/interix.c | 110 + contrib/gcc/config/i386/isc.h | 33 +- contrib/gcc/config/i386/isccoff.h | 4 +- contrib/gcc/config/i386/linux.h | 14 +- contrib/gcc/config/i386/mingw32.h | 23 +- contrib/gcc/config/i386/moss.h | 3 +- contrib/gcc/config/i386/netbsd.h | 8 +- contrib/gcc/config/i386/next.h | 4 +- contrib/gcc/config/i386/openbsd.h | 8 +- contrib/gcc/config/i386/osf1elf.h | 4 +- contrib/gcc/config/i386/osfrose.h | 34 +- contrib/gcc/config/i386/sco.h | 4 +- contrib/gcc/config/i386/sco5.h | 43 +- contrib/gcc/config/i386/scodbx.h | 4 +- contrib/gcc/config/i386/sequent.h | 7 +- contrib/gcc/config/i386/sol2.h | 3 + contrib/gcc/config/i386/sun386.h | 8 +- contrib/gcc/config/i386/sysv5.h | 35 + contrib/gcc/config/i386/t-cygwin | 16 + contrib/gcc/config/i386/t-dgux | 6 +- contrib/gcc/config/i386/t-djgpp | 2 + contrib/gcc/config/i386/t-interix | 16 + contrib/gcc/config/i386/t-udk | 2 + contrib/gcc/config/i386/t-uwin | 5 + contrib/gcc/config/i386/udk.h | 30 + contrib/gcc/config/i386/unix.h | 9 +- contrib/gcc/config/i386/uwin.asm | 32 + contrib/gcc/config/i386/uwin.h | 93 + contrib/gcc/config/i386/vxi386.h | 39 + contrib/gcc/config/i386/win-nt.h | 4 +- contrib/gcc/config/i386/win32.h | 280 + contrib/gcc/config/i386/winnt.c | 36 +- contrib/gcc/config/i386/x-cygwin | 4 + contrib/gcc/config/i386/x-djgpp | 24 + contrib/gcc/config/i386/xm-cygwin.h | 58 + contrib/gcc/config/i386/xm-djgpp.h | 44 + contrib/gcc/config/i386/xm-dos.h | 24 + contrib/gcc/config/i386/xm-i386-interix.h | 34 + contrib/gcc/config/i386/xm-mingw32.h | 8 +- contrib/gcc/config/i386/xm-os2.h | 8 +- contrib/gcc/config/i386/xm-uwin.h | 39 + contrib/gcc/config/interix.h | 107 + contrib/gcc/config/nextstep.c | 13 +- contrib/gcc/config/nextstep.h | 17 +- contrib/gcc/config/openbsd.h | 6 + contrib/gcc/config/ptx4.h | 7 +- contrib/gcc/config/sparc/elf.h | 16 + contrib/gcc/config/sparc/gmon-sol2.c | 24 +- contrib/gcc/config/sparc/hal.h | 33 + contrib/gcc/config/sparc/linux.h | 2 +- contrib/gcc/config/sparc/linux64.h | 157 +- contrib/gcc/config/sparc/pbd.h | 30 +- contrib/gcc/config/sparc/sol2-c1.asm | 42 +- contrib/gcc/config/sparc/sol2-ci.asm | 8 + contrib/gcc/config/sparc/sol2-cn.asm | 2 +- contrib/gcc/config/sparc/sol2-sld-64.h | 363 + contrib/gcc/config/sparc/sol2.h | 12 +- contrib/gcc/config/sparc/sp64-elf.h | 9 +- contrib/gcc/config/sparc/sparc.c | 5452 +++--- contrib/gcc/config/sparc/sparc.h | 970 +- contrib/gcc/config/sparc/sparc.md | 5512 +++--- contrib/gcc/config/sparc/splet.h | 28 +- contrib/gcc/config/sparc/sun4o3.h | 8 +- contrib/gcc/config/sparc/sysv4.h | 35 +- contrib/gcc/config/sparc/t-halos | 2 + contrib/gcc/config/sparc/t-linux64 | 21 + contrib/gcc/config/sparc/t-sol2 | 22 +- contrib/gcc/config/sparc/t-sol2-64 | 8 + contrib/gcc/config/sparc/t-splet | 5 +- contrib/gcc/config/sparc/xm-sp64.h | 2 + contrib/gcc/config/sparc/xm-sysv4-64.h | 27 + contrib/gcc/config/svr4.h | 96 +- contrib/gcc/config/t-freebsd | 1 - contrib/gcc/config/t-gnu | 7 +- contrib/gcc/config/t-openbsd | 2 - contrib/gcc/config/t-rtems | 7 + contrib/gcc/config/tm-dwarf2.h | 4 + contrib/gcc/config/x-interix | 24 + contrib/gcc/config/xm-interix.h | 77 + contrib/gcc/configure | 4480 ++++- contrib/gcc/configure.in | 1861 +- contrib/gcc/convert.c | 8 + contrib/gcc/cp/ChangeLog | 6346 ++++++- contrib/gcc/cp/Make-lang.in | 91 +- contrib/gcc/cp/Makefile.in | 89 +- contrib/gcc/cp/NEWS | 36 + contrib/gcc/cp/call.c | 787 +- contrib/gcc/cp/class.c | 3008 ++-- contrib/gcc/cp/config-lang.in | 2 +- contrib/gcc/cp/cp-tree.def | 42 +- contrib/gcc/cp/cp-tree.h | 1241 +- contrib/gcc/cp/cvt.c | 233 +- contrib/gcc/cp/decl.c | 4773 ++++-- contrib/gcc/cp/decl.h | 5 - contrib/gcc/cp/decl2.c | 2530 +-- contrib/gcc/cp/errfn.c | 166 +- contrib/gcc/cp/error.c | 529 +- contrib/gcc/cp/except.c | 204 +- contrib/gcc/cp/exception.cc | 35 +- contrib/gcc/cp/expr.c | 83 +- contrib/gcc/cp/friend.c | 294 +- contrib/gcc/cp/g++spec.c | 19 +- contrib/gcc/cp/gxx.gperf | 9 +- contrib/gcc/cp/gxxint.texi | 150 +- contrib/gcc/cp/inc/exception | 6 +- contrib/gcc/cp/inc/new | 6 +- contrib/gcc/cp/inc/new.h | 2 - contrib/gcc/cp/inc/typeinfo | 8 +- contrib/gcc/cp/init.c | 1000 +- contrib/gcc/cp/input.c | 8 +- contrib/gcc/cp/lang-options.h | 43 +- contrib/gcc/cp/lang-specs.h | 31 +- contrib/gcc/cp/lex.c | 1182 +- contrib/gcc/cp/lex.h | 4 +- contrib/gcc/cp/method.c | 604 +- contrib/gcc/cp/new.cc | 2 +- contrib/gcc/cp/new1.cc | 2 +- contrib/gcc/cp/new2.cc | 2 +- contrib/gcc/cp/parse.y | 842 +- contrib/gcc/cp/pt.c | 7691 ++++++--- contrib/gcc/cp/ptree.c | 16 +- contrib/gcc/cp/repo.c | 22 +- contrib/gcc/cp/rtti.c | 167 +- contrib/gcc/cp/search.c | 3841 ++--- contrib/gcc/cp/semantics.c | 461 +- contrib/gcc/cp/sig.c | 161 +- contrib/gcc/cp/spew.c | 24 +- contrib/gcc/cp/tinfo.cc | 6 +- contrib/gcc/cp/tinfo.h | 4 +- contrib/gcc/cp/tinfo2.cc | 2 +- contrib/gcc/cp/tree.c | 1067 +- contrib/gcc/cp/typeck.c | 2268 +-- contrib/gcc/cp/typeck2.c | 417 +- contrib/gcc/cp/xref.c | 69 +- contrib/gcc/cpp.texi | 164 +- contrib/gcc/cppalloc.c | 45 +- contrib/gcc/cpperror.c | 105 +- contrib/gcc/cppexp.c | 593 +- contrib/gcc/cppfiles.c | 1605 ++ contrib/gcc/cpphash.c | 1613 +- contrib/gcc/cpphash.h | 47 +- contrib/gcc/cppinit.c | 1778 ++ contrib/gcc/cpplib.c | 7795 ++------- contrib/gcc/cpplib.h | 313 +- contrib/gcc/cppmain.c | 57 +- contrib/gcc/cppspec.c | 234 + contrib/gcc/cppulp.c | 26 + contrib/gcc/cross-make | 11 - contrib/gcc/crtstuff.c | 107 +- contrib/gcc/cse.c | 636 +- contrib/gcc/dbxout.c | 24 +- contrib/gcc/doprint.c | 27 +- contrib/gcc/dwarf2.h | 31 +- contrib/gcc/dwarf2out.c | 899 +- contrib/gcc/dwarfout.c | 199 +- contrib/gcc/dwarfout.h | 2 + contrib/gcc/dyn-string.c | 33 +- contrib/gcc/dyn-string.h | 29 +- contrib/gcc/eh-common.h | 25 +- contrib/gcc/emit-rtl.c | 408 +- contrib/gcc/except.c | 559 +- contrib/gcc/except.h | 50 +- contrib/gcc/exgettext | 118 + contrib/gcc/explow.c | 75 +- contrib/gcc/expmed.c | 297 +- contrib/gcc/expr.c | 1075 +- contrib/gcc/expr.h | 82 +- contrib/gcc/extend.texi | 297 +- contrib/gcc/f/BUGS | 114 +- contrib/gcc/f/ChangeLog | 5326 +----- contrib/gcc/f/INSTALL | 352 + contrib/gcc/f/Make-lang.in | 115 +- contrib/gcc/f/Makefile.in | 21 +- contrib/gcc/f/NEWS | 1651 +- contrib/gcc/f/RELEASE-PREP | 5 + contrib/gcc/f/ansify.c | 4 +- contrib/gcc/f/assert.j | 2 +- contrib/gcc/f/bad.c | 26 +- contrib/gcc/f/bad.def | 6 +- contrib/gcc/f/bad.h | 6 +- contrib/gcc/f/bit.c | 2 +- contrib/gcc/f/bit.h | 2 +- contrib/gcc/f/bld-op.def | 2 +- contrib/gcc/f/bld.c | 15 +- contrib/gcc/f/bld.h | 23 +- contrib/gcc/f/bugs.texi | 204 +- contrib/gcc/f/bugs0.texi | 14 +- contrib/gcc/f/com-rt.def | 7 +- contrib/gcc/f/com.c | 7589 ++++---- contrib/gcc/f/com.h | 37 +- contrib/gcc/f/config.j | 2 +- contrib/gcc/f/convert.j | 2 +- contrib/gcc/f/data.c | 6 +- contrib/gcc/f/data.h | 2 +- contrib/gcc/f/equiv.c | 2 +- contrib/gcc/f/equiv.h | 2 +- contrib/gcc/f/expr.c | 189 +- contrib/gcc/f/expr.h | 2 +- contrib/gcc/f/ffe.texi | 2024 +++ contrib/gcc/f/fini.c | 39 +- contrib/gcc/f/flags.j | 2 +- contrib/gcc/f/g77.1 | 14 +- contrib/gcc/f/g77.texi | 2848 +-- contrib/gcc/f/g77spec.c | 18 +- contrib/gcc/f/glimits.j | 2 +- contrib/gcc/f/global.c | 165 +- contrib/gcc/f/global.h | 6 +- contrib/gcc/f/hconfig.j | 2 +- contrib/gcc/f/implic.c | 10 +- contrib/gcc/f/implic.h | 4 +- contrib/gcc/f/info-b.def | 2 +- contrib/gcc/f/info-k.def | 2 +- contrib/gcc/f/info-w.def | 2 +- contrib/gcc/f/info.c | 22 +- contrib/gcc/f/info.h | 12 +- contrib/gcc/f/input.j | 2 +- contrib/gcc/f/intdoc.c | 101 +- contrib/gcc/f/intdoc.in | 229 +- contrib/gcc/f/intdoc.texi | 289 +- contrib/gcc/f/intrin.c | 84 +- contrib/gcc/f/intrin.def | 22 +- contrib/gcc/f/intrin.h | 17 +- contrib/gcc/f/lab.c | 2 +- contrib/gcc/f/lab.h | 2 +- contrib/gcc/f/lang-options.h | 253 +- contrib/gcc/f/lang-specs.h | 30 +- contrib/gcc/f/lex.c | 84 +- contrib/gcc/f/lex.h | 10 +- contrib/gcc/f/malloc.c | 16 +- contrib/gcc/f/malloc.h | 8 +- contrib/gcc/f/name.c | 6 +- contrib/gcc/f/name.h | 6 +- contrib/gcc/f/news.texi | 933 +- contrib/gcc/f/news0.texi | 17 +- contrib/gcc/f/output.j | 3 +- contrib/gcc/f/parse.c | 2 +- contrib/gcc/f/proj.c | 2 +- contrib/gcc/f/proj.h | 2 +- contrib/gcc/f/root.texi | 40 + contrib/gcc/f/rtl.j | 2 +- contrib/gcc/f/src.c | 2 +- contrib/gcc/f/src.h | 2 +- contrib/gcc/f/st.c | 2 +- contrib/gcc/f/st.h | 2 +- contrib/gcc/f/sta.c | 8 +- contrib/gcc/f/sta.h | 8 +- contrib/gcc/f/stb.c | 122 +- contrib/gcc/f/stb.h | 16 +- contrib/gcc/f/stc.c | 50 +- contrib/gcc/f/stc.h | 2 +- contrib/gcc/f/std.c | 129 +- contrib/gcc/f/std.h | 2 +- contrib/gcc/f/ste.c | 3020 ++-- contrib/gcc/f/ste.h | 14 +- contrib/gcc/f/storag.c | 2 +- contrib/gcc/f/storag.h | 2 +- contrib/gcc/f/stp.c | 2 +- contrib/gcc/f/stp.h | 2 +- contrib/gcc/f/str-1t.fin | 2 +- contrib/gcc/f/str-2t.fin | 2 +- contrib/gcc/f/str-fo.fin | 2 +- contrib/gcc/f/str-io.fin | 2 +- contrib/gcc/f/str-nq.fin | 2 +- contrib/gcc/f/str-op.fin | 2 +- contrib/gcc/f/str-ot.fin | 2 +- contrib/gcc/f/str.c | 2 +- contrib/gcc/f/str.h | 2 +- contrib/gcc/f/sts.c | 14 +- contrib/gcc/f/sts.h | 16 +- contrib/gcc/f/stt.c | 8 +- contrib/gcc/f/stt.h | 8 +- contrib/gcc/f/stu.c | 8 +- contrib/gcc/f/stu.h | 2 +- contrib/gcc/f/stv.c | 2 +- contrib/gcc/f/stv.h | 2 +- contrib/gcc/f/stw.c | 8 +- contrib/gcc/f/stw.h | 11 +- contrib/gcc/f/symbol.c | 15 +- contrib/gcc/f/symbol.def | 2 +- contrib/gcc/f/symbol.h | 13 +- contrib/gcc/f/system.j | 2 +- contrib/gcc/f/target.c | 4 +- contrib/gcc/f/target.h | 30 +- contrib/gcc/f/tconfig.j | 2 +- contrib/gcc/f/tm.j | 2 +- contrib/gcc/f/top.c | 37 +- contrib/gcc/f/top.h | 11 +- contrib/gcc/f/toplev.j | 2 +- contrib/gcc/f/tree.j | 2 +- contrib/gcc/f/type.c | 2 +- contrib/gcc/f/type.h | 2 +- contrib/gcc/f/version.c | 2 +- contrib/gcc/f/version.h | 2 +- contrib/gcc/f/where.c | 4 +- contrib/gcc/f/where.h | 2 +- contrib/gcc/final.c | 230 +- contrib/gcc/fix-header.c | 140 +- contrib/gcc/fixincludes | 155 +- contrib/gcc/fixproto | 27 +- contrib/gcc/flags.h | 59 +- contrib/gcc/floatlib.c | 627 +- contrib/gcc/flow.c | 7322 ++++---- contrib/gcc/fold-const.c | 714 +- contrib/gcc/frame.c | 53 +- contrib/gcc/frame.h | 24 +- contrib/gcc/function.c | 1212 +- contrib/gcc/function.h | 36 +- contrib/gcc/gansidecl.h | 86 +- contrib/gcc/gcc.1 | 4 +- contrib/gcc/gcc.c | 1048 +- contrib/gcc/gcc.texi | 699 +- contrib/gcc/gccspec.c | 43 + contrib/gcc/gcov-io.h | 12 +- contrib/gcc/gcov.c | 120 +- contrib/gcc/gcse.c | 1607 +- contrib/gcc/gen-protos.c | 46 +- contrib/gcc/genattr.c | 49 +- contrib/gcc/genattrtab.c | 378 +- contrib/gcc/gencheck.c | 18 +- contrib/gcc/gencodes.c | 49 +- contrib/gcc/genconfig.c | 49 +- contrib/gcc/genemit.c | 63 +- contrib/gcc/genextract.c | 108 +- contrib/gcc/genflags.c | 49 +- contrib/gcc/gengenrtl.c | 66 +- contrib/gcc/genopinit.c | 61 +- contrib/gcc/genoutput.c | 254 +- contrib/gcc/genpeep.c | 51 +- contrib/gcc/genrecog.c | 206 +- contrib/gcc/getpwd.c | 9 +- contrib/gcc/glimits.h | 2 +- contrib/gcc/global.c | 389 +- contrib/gcc/gmon.c | 2 +- contrib/gcc/graph.c | 475 + contrib/gcc/gthr-vxworks.h | 18 +- contrib/gcc/gthr.h | 8 +- contrib/gcc/haifa-sched.c | 600 +- contrib/gcc/halfpic.c | 10 +- contrib/gcc/halfpic.h | 6 +- contrib/gcc/hash.c | 137 +- contrib/gcc/hash.h | 85 +- contrib/gcc/hwint.h | 96 + contrib/gcc/input.h | 2 +- contrib/gcc/integrate.c | 585 +- contrib/gcc/integrate.h | 46 +- contrib/gcc/intl.c | 6 + contrib/gcc/intl.h | 52 + contrib/gcc/invoke.texi | 1505 +- contrib/gcc/jump.c | 1046 +- contrib/gcc/lcm.c | 799 + contrib/gcc/libgcc2.c | 538 +- contrib/gcc/local-alloc.c | 461 +- contrib/gcc/longlong.h | 10 +- contrib/gcc/loop.c | 4510 +++-- contrib/gcc/loop.h | 100 +- contrib/gcc/machmode.h | 118 +- contrib/gcc/mbchar.c | 290 + contrib/gcc/mbchar.h | 41 + contrib/gcc/md.texi | 86 +- contrib/gcc/mips-tdump.c | 112 +- contrib/gcc/mips-tfile.c | 246 +- contrib/gcc/objc/Make-lang.in | 161 +- contrib/gcc/objc/Makefile.in | 48 +- contrib/gcc/objc/config-lang.in | 2 - contrib/gcc/objc/lang-specs.h | 96 + contrib/gcc/objc/objc-act.c | 165 +- contrib/gcc/objc/objc-tree.def | 2 +- contrib/gcc/optabs.c | 705 +- contrib/gcc/output.h | 67 +- contrib/gcc/prefix.c | 120 +- contrib/gcc/prefix.h | 28 + contrib/gcc/print-rtl.c | 150 +- contrib/gcc/print-tree.c | 12 +- contrib/gcc/profile.c | 15 +- contrib/gcc/protoize.c | 533 +- contrib/gcc/pself4.c | 2 + contrib/gcc/pself5.c | 5 + contrib/gcc/real.c | 569 +- contrib/gcc/real.h | 18 +- contrib/gcc/recog.c | 817 +- contrib/gcc/recog.h | 105 +- contrib/gcc/reg-stack.c | 787 +- contrib/gcc/regclass.c | 685 +- contrib/gcc/regmove.c | 555 +- contrib/gcc/regs.h | 21 +- contrib/gcc/reload.c | 1229 +- contrib/gcc/reload.h | 106 +- contrib/gcc/reload1.c | 8929 +++++----- contrib/gcc/reorg.c | 1428 +- contrib/gcc/resource.c | 1289 ++ contrib/gcc/resource.h | 46 + contrib/gcc/rtl.c | 86 +- contrib/gcc/rtl.def | 30 +- contrib/gcc/rtl.h | 302 +- contrib/gcc/rtl.texi | 229 +- contrib/gcc/rtlanal.c | 334 +- contrib/gcc/sbitmap.c | 470 + contrib/gcc/sbitmap.h | 122 + contrib/gcc/scan-decls.c | 11 +- contrib/gcc/scan.c | 2 +- contrib/gcc/scan.h | 12 +- contrib/gcc/sched.c | 270 +- contrib/gcc/sdbout.c | 89 +- contrib/gcc/stab.def | 2 +- contrib/gcc/stmt.c | 1098 +- contrib/gcc/stor-layout.c | 98 +- contrib/gcc/stupid.c | 223 +- contrib/gcc/system.h | 249 +- contrib/gcc/tlink.c | 183 +- contrib/gcc/tm.texi | 371 +- contrib/gcc/toplev.c | 2208 ++- contrib/gcc/toplev.h | 121 +- contrib/gcc/tree.c | 277 +- contrib/gcc/tree.def | 76 +- contrib/gcc/tree.h | 190 +- contrib/gcc/unroll.c | 1253 +- contrib/gcc/varasm.c | 267 +- contrib/gcc/varray.h | 43 +- contrib/gcc/version.c | 2 +- contrib/gcc/xcoffout.c | 4 +- contrib/gcc/xcoffout.h | 21 +- 499 files changed, 130583 insertions(+), 81623 deletions(-) create mode 100644 contrib/gcc/FSFChangeLog create mode 100644 contrib/gcc/collect2.h create mode 100644 contrib/gcc/config/alpha/alpha-interix.h create mode 100644 contrib/gcc/config/alpha/alpha32.h create mode 100644 contrib/gcc/config/alpha/lib1funcs.asm create mode 100644 contrib/gcc/config/alpha/t-ieee create mode 100644 contrib/gcc/config/alpha/t-interix create mode 100644 contrib/gcc/config/alpha/xm-alpha-interix.h create mode 100644 contrib/gcc/config/dbxelf.h create mode 100644 contrib/gcc/config/elfos.h create mode 100644 contrib/gcc/config/i386/cygwin.asm create mode 100644 contrib/gcc/config/i386/cygwin.h create mode 100644 contrib/gcc/config/i386/djgpp-rtems.h create mode 100644 contrib/gcc/config/i386/djgpp.h create mode 100644 contrib/gcc/config/i386/i386-interix.h create mode 100644 contrib/gcc/config/i386/interix.c create mode 100644 contrib/gcc/config/i386/sysv5.h create mode 100644 contrib/gcc/config/i386/t-cygwin create mode 100644 contrib/gcc/config/i386/t-djgpp create mode 100644 contrib/gcc/config/i386/t-interix create mode 100644 contrib/gcc/config/i386/t-udk create mode 100644 contrib/gcc/config/i386/t-uwin create mode 100644 contrib/gcc/config/i386/udk.h create mode 100644 contrib/gcc/config/i386/uwin.asm create mode 100644 contrib/gcc/config/i386/uwin.h create mode 100644 contrib/gcc/config/i386/win32.h create mode 100644 contrib/gcc/config/i386/x-cygwin create mode 100644 contrib/gcc/config/i386/x-djgpp create mode 100644 contrib/gcc/config/i386/xm-cygwin.h create mode 100644 contrib/gcc/config/i386/xm-djgpp.h create mode 100644 contrib/gcc/config/i386/xm-i386-interix.h create mode 100644 contrib/gcc/config/i386/xm-uwin.h create mode 100644 contrib/gcc/config/interix.h create mode 100644 contrib/gcc/config/sparc/hal.h create mode 100644 contrib/gcc/config/sparc/sol2-sld-64.h create mode 100644 contrib/gcc/config/sparc/t-halos create mode 100644 contrib/gcc/config/sparc/t-linux64 create mode 100644 contrib/gcc/config/sparc/t-sol2-64 create mode 100644 contrib/gcc/config/sparc/xm-sysv4-64.h create mode 100644 contrib/gcc/config/tm-dwarf2.h create mode 100644 contrib/gcc/config/x-interix create mode 100644 contrib/gcc/config/xm-interix.h create mode 100644 contrib/gcc/cppfiles.c create mode 100644 contrib/gcc/cppinit.c create mode 100644 contrib/gcc/cppspec.c create mode 100644 contrib/gcc/cppulp.c create mode 100755 contrib/gcc/exgettext create mode 100644 contrib/gcc/f/INSTALL create mode 100644 contrib/gcc/f/RELEASE-PREP create mode 100644 contrib/gcc/f/ffe.texi create mode 100644 contrib/gcc/f/root.texi create mode 100644 contrib/gcc/gccspec.c create mode 100644 contrib/gcc/graph.c create mode 100644 contrib/gcc/hwint.h create mode 100644 contrib/gcc/intl.c create mode 100644 contrib/gcc/intl.h create mode 100644 contrib/gcc/lcm.c create mode 100644 contrib/gcc/mbchar.c create mode 100644 contrib/gcc/mbchar.h create mode 100644 contrib/gcc/objc/lang-specs.h create mode 100644 contrib/gcc/prefix.h create mode 100644 contrib/gcc/pself4.c create mode 100644 contrib/gcc/pself5.c create mode 100644 contrib/gcc/resource.c create mode 100644 contrib/gcc/resource.h create mode 100644 contrib/gcc/sbitmap.c create mode 100644 contrib/gcc/sbitmap.h (limited to 'contrib') diff --git a/contrib/gcc/BUGS b/contrib/gcc/BUGS index 33c9386..2d875a0 100644 --- a/contrib/gcc/BUGS +++ b/contrib/gcc/BUGS @@ -1,9 +1,9 @@ -If you think you may have found a bug in GNU CC, please +If you think you may have found a bug in GCC, please read the Bugs section of the GCC manual for advice on (1) how to tell when to report a bug, (2) where to send your bug report, and -(2) how to write a useful bug report and what information +(3) how to write a useful bug report and what information it needs to have. There are three ways to read the Bugs section. @@ -20,4 +20,8 @@ to get to the section on bugs. Or use standalone Info in a like manner. (Standalone Info is part of the Texinfo distribution.) (3) By hand. Search for the chapter "Reporting Bugs" in gcc.texi, or - cat /usr/local/info/gcc* | more "+/^File: emacs, Node: Bugs," + cat /usr/local/info/gcc* | more "+/^File: gcc.info, Node: Bugs," + +You may also want to take a look at the GCC FAQ, in which there are +additional instructions for submitting bug reports: + http://www.gnu.org/software/gcc/faq.html#bugreport diff --git a/contrib/gcc/ChangeLog b/contrib/gcc/ChangeLog index f1be44e..446c775 100644 --- a/contrib/gcc/ChangeLog +++ b/contrib/gcc/ChangeLog @@ -1,14110 +1,17060 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. -Sun Mar 14 03:23:47 1999 Jeffrey A Law (law@cygnus.com) +1999-08-13 Michael Meissner - * README, gcc.1, gcc.texi, version.c: Update for egcs-1.1.2 release. + * Makefile.in (GCC_FOR_TARGET): Move -B./ after the tooldir -B. -Thu Mar 11 14:00:58 1999 Richard Henderson +Fri Aug 13 01:42:24 1999 Jeffrey A Law (law@cygnus.com) - * alpha.h (HARD_REGNO_MODE_OK): Disallow QI/HImode in fp regs. - (MODES_TIEABLE_P): Update. + Tue Aug 3 00:03:41 1999 Kaveh R. Ghazi + * fixincludes: Fix the return type of bsearch, char* -> void*. + * fixinc/inclhack.def: Likewise. -Thu Mar 11 00:20:52 1999 Alexandre Oliva +Fri Aug 13 01:29:57 1999 Alexandre Oliva - * gcc.texi: Update bug reporting instructions to match - current ezmlm list reality. + * dwarfout.c (fundamental_type_code): Return FT_boolean for + INTEGER_TYPE with precision==1, it's __java_boolean. -Mon Mar 8 01:19:23 1999 Jeffrey A Law (law@cygnus.com) +1999-08-11 Richard Earnshaw (rearnsha@arm.com) - * version.c: Bump for prerelease. + * emit-rtl.c (mark_reg_pointer): Don't increase the alignment of + a register that is already known to be a pointer. -Mon Mar 8 01:16:30 1999 Manfred Hollstein - Jeff Law +1999-08-11 Bruce Korb - * configure.in (cpp_install_dir): Initialize from $enable_cpp - if that's looking like a pathname. - * configure: Rebuilt. + * fixinc/inclhack.tpl: Only install assert.h conditionally. + * fixinc/inclhack.sh: Regenerated. + * fixinc/fixincl.sh: Regenerated. - * Makefile.in (install-cpp, uninstall-cpp): cpp_install_dir is an - absolute pathname, not a $prefix relative pathname. +Wed Aug 11 00:34:22 1999 Joe Buck -Fri Mar 5 01:19:22 1999 Jeffrey A Law (law@cygnus.com) + * invoke.texi: s/GNU CC/GCC/ for consistency with gcc.texi. + Fix documentation of -ansi flag to describe its C++ behavior. + Remove bogus reference to GCC 2.9. - Thu Dec 17 18:21:49 1998 Rainer Orth - * fixincludes (c_asm.h): Wrap Digital UNIX V4.0B DEC C specific - asm() etc. function declarations in __DECC. +Tue Aug 10 22:40:36 1999 Jeffrey A Law (law@cygnus.com) -Wed Mar 3 23:55:14 1999 Zack Weinberg + Thu Aug 5 22:27:15 1999 J"orn Rennecke + * config/sh/lib1funcs.asm (___movstrSI0): Change or r0,r0,r0 to nop. + (___mulsi3): Use '!' comment character. - * cpp.in: New. Better cpp shell script. - * cpp.sh: Delete. - * Makefile.in (cpp.sh): Build from cpp.in +Sat Aug 7 00:06:30 1999 Jeffrey A Law (law@cygnus.com) -Tue Mar 2 01:27:52 1999 H.J. Lu (hjl@gnu.org) + * gcc.texi: Update bug reporting text. - * Makefile.in (cpp_install_dir, INSTALL_CPP, UNINSTALL_CPP): New - variables. - (install-cpp, uninstall-cpp): New targets. - (install-normal): Depend on $(INSTALL_CPP). - (uninstall): Depend on $(UNINSTALL_CPP). - * configure.in (cpp_install_dir): New, substitute. - (tmake_file): Added t-install-cpp for --enable-cpp. - * configure: Rebuilt. - * cpp.sh: New cpp script. - * config/t-install-cpp: New target fragment. + Tue Jul 20 17:07:54 1999 Richard Henderson + * rs6000.h (struct rs6000_args): Add sysv_gregno. + * rs6000.c (init_cumulative_args): Init sysv_gregno. + (function_arg_boundary): Align DFmode. + (function_arg_advance): Restructure for ABI_V4; use sysv_gregno + to get fp reg and stack overflow correct. + (function_arg): Likewise. + (function_arg_pass_by_reference): True for TFmode for ABI_V4. + (setup_incoming_varargs): Restructure for ABI_V4; use + function_arg_advance to skip final named argument. + (expand_builtin_saveregs): Properly unskip the last integer arg + when doing varargs. Adjust overflow location calculation. + * ginclude/va-ppc.h (struct __va_list_tag): Make gpr and fpr + explicitly unsigned. + (__VA_FP_REGSAVE): Use new OFS argument instead of AP->fpr directly. + (__VA_GP_REGSAVE): Similarly. + (__va_longlong_p): Delete. + (__va_arg_type_violation): New declaration. + (va_arg): Restructure. Flag promotion errors. Align double. + TFmode passed by reference. + * rs6000.md (movdi_32+1): Use GEN_INT after arithmetic + in the HOST_BITS_PER_WIDE_INT > 32 case. -Mon Mar 1 23:38:20 1999 Jeffrey A Law (law@cygnus.com) +1999-08-6 Herman A.J. ten Brugge - Tue Feb 2 23:38:35 1999 David O'Brien - * i386/freebsd*.h now allows '$' in label names and does not use the - PCC struct return method. + * reg-stack.c (change_stack) Fixed problem with negative array index. - Wed Dec 30 23:00:28 1998 David O'Brien - * configure.in (FreeBSD ELF): Needs special crt files. - * configure: Rebuilt. +Fri Aug 6 20:41:08 1999 Jeffrey A Law (law@cygnus.com) -Sun Feb 28 14:47:53 1999 Arturo Montes + Mon Jul 19 15:09:29 1999 David Edelsohn + * rs6000.md (arithmetic, logical, and shift Rc combiner patterns): + Disable patterns performing SImode comparisons with SImode values + if TARGET_POWERPC64 and instruction does not sign-extend or does + not mask to narrower than SImode, i.e. where bit 31 and bit 63 may + differ for signed quantities. + (indirect_jump): Add expander to choose RTL based on TARGET_64BIT. + (tablejump): Patterns contingent on TARGET_64BIT not TARGET_POWERPC64. + (decrement_and_branch_on_count): Add 64-bit variant. - * config/i386/t-sco5gas (crti.o): New target. +Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com) -Sun Feb 28 00:50:28 1999 Franz Sirl - Jeffrey A Law (law@cygnus.com) + * gcc.c: Update URLs and mail addresses. + * gcc.texi: Likewise. - * cse.c (fold_rtx): Update comments for (const (minus (label) (label))) - case. - (cse_insn): Avoid creating a bogus REG_EQUAL note for - (const (minus (label) (label))) - (record_jump_cond): Fix mismatched paren in comment. - -Sat Feb 27 22:48:38 1999 H.J. Lu (hjl@gnu.org) - Jeffrey A Law (law@cygnus.com) +Thu Aug 5 01:14:13 1999 Daniel Jacobowitz - * frame.h: Update some comments. - * crtstuff.c (TARGET_ATTRIBUTE_WEAK): Define. - (__register_frame_info, __deregister_frame_info): Declare using - TARGET_WEAK_ATTRIBUTE. - (__do_global_dtors_aux): Check if __deregister_frame_info is - zero before calling it. - (__do_global_dtors): Likewise. - (frame_dummy): Check if __register_frame_info is zero before - calling it. - (__frame_dummy): Likewise. - -Sat Feb 27 19:47:39 1999 Marc Espie + * rs6000.c (current_file_function_operand): Return zero for + weak functions. + (rs6000_encode_section_info): Do not set SYMBOL_REF_FLAG for + weak symbols. + * rs6000.h (ENCODE_SECTION_NIFO): Do not set SYMBOL_REF_FLAG + for weak symbols. - * config/t-openbsd (T_CFLAGS): Add -Dmkstemps=my_mkstemps. +Thu Aug 5 00:56:30 1999 Geoffrey Keating -Sat Feb 27 19:37:04 1999 Arturo Montes + * rs6000.c (rs6000_stack_info): For ABI_V4/ABI_SOLARIS -fpic, always + allocate space in the stack frame for the PIC register. - * i386/t-sco5 (crti.o): New target. - * i386/sco5.h (STARTFILE_SPEC): Include crti.o when - linking -shared. - * configure.in (i[34567]86-*-sco3.2v5*): Add crti.o. - * configure: Rebuilt. +Thu Aug 5 00:20:47 1999 Jeffrey A Law (law@cygnus.com) -Sat Feb 27 19:29:46 1999 Toon Moene - Mark Mitchell - Jeffrey A Law (law@cygnus.com) + * m68k.md (xordi3, anddi3): These patterns are not available on + the coldfire. - * alias.c (true_dependence): Only apply MEM_IN_STRUCT_P tests - when flag_structure_noalias is set. - * toplev.c (flag_structure_noalias): New variable. - (f_options): Add -fstructure-noalias. - * flags.h (flag_structure_noalias): Declare. - * invoke.texi: Update documentation. +Wed Aug 4 23:39:20 1999 Mark Mitchell -Sat Feb 27 19:19:36 1999 Jeffrey A Law (law@cygnus.com) + * real.c (GET_REAL): Don't violate ANSI/ISO aliasing rules. + (PUT_REAL): Likewise. - * SERVICE: Update from the FSF. +Wed Aug 4 02:15:32 1999 Richard Henderson -Fri Feb 26 19:31:25 1999 Dave Love + * jump.c (delete_insn): Delete the addr_vec when deleting a tablejump. - * md.texi, invoke.texi: Fix unterminated @xrefs. +Wed Aug 4 01:08:44 1999 Jeffrey A Law (law@cygnus.com) -Fri Feb 26 01:47:46 1999 Jeffrey A Law (law@cygnus.com) + * flow.c (delete_unreachable_blocks): Do not call merge_blocks + or tidy_fallthru_edge if the last insn in the block is not + an unconditional jump or a simple conditional jump. - Sun Jan 17 03:20:47 1999 H.J. Lu (hjl@gnu.org) - * reg-stack.c (subst_stack_regs_pat): Abort if the destination - of a FP conditional move is not on the FP register stack. +Tue Aug 3 03:51:20 1999 Jeffrey A Law (law@cygnus.com) - * Makefile.in (compare, gnucompare): We do not care about - comparison failures for objc/linking.o either. + * cse.c (cse_insn): Fix dumb thinko in last change. -Wed Feb 24 23:17:41 1999 Jeffrey A Law (law@cygnus.com) +Mon Aug 2 23:45:45 1999 Hans-Peter Nilsson - Thu Feb 18 19:59:37 1999 Marc Espie - * configure.in :Handle OpenBSD platforms. + * dwarf2out.c (add_location_or_const_value_attribute): Correct + test for sizes of passed and declared parameter types. + +Mon Aug 2 12:45:09 1999 Richard Henderson + + * alpha.c (override_options): Don't force ALPHA_TP_PROG for ev6. + +Mon Aug 2 01:34:22 1999 Jeffrey A Law (law@cygnus.com) + + * fix-header.c (main): When testing for CONTINUED, use string + equality, not pointer equality. + +Mon Aug 2 01:27:24 1999 Dan Nicolaescu + + * sparc.c (sparc_block_profiler): Use the %g2 register, not %o0. + +Sun Aug 1 22:46:42 1999 Jeffrey A Law (law@cygnus.com) + + * cse.c (cse_insn): Fix loop which deletes insns after a jump + that has become an unconditional jump. + + * m68k.c (output_function_prologue): Fix typo in CPU32 case. + (output_function_epilogue): Similarly. + + Tue Jul 20 12:37:30 1999 Hans-Peter Nilsson + * dwarf2out.c (output_abbrev_section): Terminate with a zero. + + Thu Jul 15 15:40:09 1999 Jim Wilson + * tree.c (build_type_attribute_variant): Move current_obstack restore + after build_qualified_type call. + + Fri Jun 4 03:20:40 1999 J"orn Rennecke + * sh.c (fixup_addr_diff_vecs): Emit braf reference label. + (braf_label_ref_operand): Delete. + * sh.h (PREDICATE_CODES): Remove braf_label_ref_operand. + * sh.md (casesi_jump_2): Operand1 is now the inside of a + label_ref, and has no predicate. + The patten has a predicate to guard against invalid substitutions. + (dummy_jump): Delete. + (casesi): Update use of casesi_jump_2. + +Thu Jul 31 12:34:45 1999 Joe Buck + + * gcc.texi: Use terms "GNU Compiler Collection" and "GCC". + Also update copyright. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + + * verison.c: No longer a prerelease. + +Wed Jul 28 13:49:03 1999 Jeffrey A Law (law@cygnus.com) + + * README: Update. + +Sun Jul 25 21:40:33 1999 Jeffrey A Law (law@cygnus.com) + + * gcc.texi: More changes related to list conversion. + * invoke.texi: Likewise. + +Sat Jul 17 23:58:24 1999 David Edelsohn + + * rs6000.md (insv, extzv): Remove SImode dependence in named + patterns. Explicitly generate DImode RTL if PowerPC64 and + operand is DImode. + (insvdi): Reverse start and size in instruction template. + +1999-07-17 Alexandre Oliva + + * gcc.texi: Update e-mail addresses and URLs to gcc.gnu.org. + Removed paragraph about compression of files and size limitation, + duplicated in the FAQ. Use gcc-patches for posting patches. + * gcc.c (main): Updated URL with bug reporting instructions to + gcc.gnu.org. Removed e-mail address. + * system.h (abort): Likewise. + +1999-07-17 Kaveh R. Ghazi + + * Makefile.in (stmp-multilib-sub): Make the files extracted + from $(LIBGCC1) writable. + +Fri Jul 16 01:39:57 1999 Jeffrey A Law (law@cygnus.com) + + * m68k.c (output_function_prologue): Fix computation of save mask + when generating PIC code. + +1999-07-12 Joseph S. Myers + + * invoke.texi: Typo fixes. + +Wed Jul 14 23:28:06 1999 Jeffrey A Law (law@cygnus.com) + + * emit-rtl.c (gen_realpart): Issue an error for cases GCC can not + handle at this time instead of silently generating incorrect code. + (gen_imagpart): Likewise. + + * reload.c (find_reloads): Emit a USE for a pseudo register without + a hard register if we could not create an optional reload for the + pseudo. + +Wed Jul 14 01:57:39 1999 Richard Henderson + + * regclass.c (scan_one_insn): Notice subregs that change the + size of their operand. + (record_reg_classes): Use that to obey CLASS_CANNOT_CHANGE_SIZE. + +Wed Jul 14 01:37:06 1999 Jeffrey A Law (law@cygnus.com) + + * configure.in (alpha*-*-*): Include alpha/t-ieee. * configure: Rebuilt. - * config/openbsd.h: New file. - * config/xm-openbsd.h: New file. - * config/t-openbsd: New file. - * config/t-openbsd-thread: New file. + * alpha/t-ieee: New file. - Thu Feb 18 13:15:56 1999 Marc Espie - * alpha/openbsd.h: New file. - * alpha/xm-openbsd.h: New file. - * sparc/openbsd.h: New file. - * sparc/xm-openbsd.h: New file. - * m68k/openbsd.h: New file. - * m68k/xm-openbsd.h: New file. - * i386/openbsd.h: New file, originally from netbsd. - * i386/xm-openbsd.h: New file. +Tue Jul 13 10:44:14 1999 Jeffrey A Law (law@cygnus.com) + + Wed Jun 16 20:29:00 1999 J"orn Rennecke + * cse.c (cse_insn): Don't put hard register source into tables for + the last insn of a libcall. + + * rs6000.c (find_addr_reg): Do not select r0 as an address + register. + +Tue Jul 13 00:46:18 1999 Philippe De Muyter + + * m68k/x-mot3300 (XCFLAGS): List of big files now includes `cse.o'. + +Mon Jul 12 23:39:08 1999 Jeffrey A Law (law@cygnus.com) + + * rs6000.md (movsf): Do not force easy FP constants into memory. + +Sun Jul 11 11:21:24 1999 Jason Merrill + + * toplev.c (main): Don't complain about saying -gdwarf. + +Fri Jul 9 03:51:52 1999 Jeffrey A Law (law@cygnus.com) + + * version.c: Drop "gcc-" prefix from version #. + +Thu Jul 8 19:15:51 1999 Jim Wilson + + * unroll.c (unroll_loops): Don't delete named CODE_LABEL or + NOTE_INSN_DELETED_LABEL note. + +Thu Jul 8 14:18:46 1999 Richard Henderson + + * m68k.c (output_function_prologue): Add pic register to mask + if live and flag_pic. + (output_function_epilogue): Likewise. + +Thu Jul 8 10:28:25 1999 Craig Burley + + * invoke.texi (DEC Alpha Options): Put @end table at + beginning of line, to avoid confusing texi2html. + +Wed Jul 7 02:00:04 1999 Franz Sirl + + * reload1.c (gen_reload): When synthesizing a 3 operand add + sequence, improve test for when to reload OP1 into the reload + register instead of OP0. + +Wed Jul 7 01:38:03 1999 Jim Wilson + + * unroll.c (unroll_loop): Don't delete NOTE_INSN_DELETED_LABEL notes. + +1999-07-07 Manfred Hollstein + + * m88k/dguxbcs.h (CPP_SPEC): Add missing \ in multi-line + string literal. + +Wed Jul 7 01:16:43 1999 Richard Henderson + + * ginclude/varargs.h (__builtin_va_alist_t): New typedef. + (va_dcl): Use __builtin_va_alist_t. + +Wed Jul 7 01:13:31 1999 Jason Merrill + + * dwarf2out.c (gen_struct_or_union_type_die): Only remember types + on the permanent_obstack. + * dwarfout.c (output_type): Likewise. + +Fri Jul 2 03:05:13 1999 Jeffrey A Law (law@cygnus.com) + + * dwarfout.c (field_byte_offset): Correctly compute the object's + byte offset for the first bit of a field which crosses an alignment + boundary on a !BYTES_BIG_ENDIAN target. + +Fri Jul 2 01:36:36 1999 Robert Lipe + + * fixinc.svr4: Fix by deleting protos for htons and + ntohs. + +Fri Jul 2 00:46:47 1999 Richard Henderson + Jeff Law + + * ginclude/varargs.h (va_dcl): Use word_mode for type of + __builtin_va_list. + + * except.c: Include intl.h. + (expand_eh_return): Set current_function_cannot_inline. + (save_eh_status, restore_eh_status): Twiddle eh_return_stub_label. + * function.h (struct function): Add eh_return_stub_label. + * flow.c (delete_unreachable_blocks): Don't merge across EH edges. + * Makefile.in (except.o): Depend on intl.h. + +Fri Jul 2 00:04:23 1999 David Edelsohn + + * rs6000.md (movdf_hardfloat32): Handle PRE_INC and PRE_DEC the + same as offsettable in cases 1 and 2. + +1999-07-01 Mark Kettenis + + * config/i386/gnu.h (CPP_SPEC): Define __PIC__ and __pic__ if + -fPIC or -fpic is specified. + +Wed Jun 30 23:56:01 1999 Jeffrey A Law (law@cygnus.com) + + * expr.c (emit_block_move): Use copy_to_mode_reg for + !TARGET_MEM_FUNCTIONS case too. + +Tue Jun 29 01:37:53 1999 Jeffrey A Law (law@cygnus.com) + + * mips.md (leasi, leadi): New patterns. + + * expr.c (emit_block_move): Properly handle case where one of the + block move arguments has a queued increment or decrement. + (clear_storage): Similarly. Fix formatting goof. + +Mon Jun 28 05:32:09 1999 Jeffrey A Law (law@cygnus.com) - Wed Nov 19 12:56:54 1997 Andreas Schwab - * configure.in: Fix check for . + * m68k.h (CONDITIONAL_REGISTER_USAGE): Define for !SUN_FPA + case. Also make the PIC register call_used. + + * m68k.h (FINALIZE_PIC): Delete. + * m68k.c (finalize_pic): Delete. + + * m68k.h (CONDITIONAL_REGISTER_USAGE): Make the PIC register fixed + when -fpic/-fPIC. + +Mon Jun 28 05:16:35 1999 Richard Henderson + + * m68k.h (PREFERRED_RELOAD_CLASS): Don't force any FP const_doubles + to memory. + +Mon Jun 28 04:07:27 1999 David Edelsohn + + * rs6000.c (output_toc): Always use hex values for floating-point + constants. Store single-precision values in upper-half of TOC + entry in 64-bit mode. + * rs6000.md (floatsidf2, floatunssidf2): Add !TARGET_POWERPC64 + to final constraints. + (fix_truncdfsi2 splitter): Change pattern matching fctiwz. + (fctiwz): Improve accuracy of RTL for pattern. + + * rs6000.c (print_operand, case 'L'): Use plus_constant_for_output. + + * expmed.c (expand_divmod): Ensure unsigned value fits in reg_note. + +Fri Jun 25 06:06:37 1999 Richard Henderson + + * alpha.h (MASK_SUPPORT_ARCH, MASK_CPU_EV5, MASK_CPU_EV6): Define + such that MASK_SUPPORT_ARCH is not negative. + +Fri Jun 25 05:35:44 1999 Jeffrey A Law (law@cygnus.com) + + * loop.c (verify_dominator): Properly handle ADDR_VEC and + ADDR_DIFF_VEC insns that appear inside loops. + +Thu Jun 24 22:54:05 1999 David Edelsohn + Jeff Law + + * rs6000.md (movdf_hardfloat32): Revert previous patch. + Handle LO_SUM the same as offsettable in cases 1 and 2. + * rs6000.c (find_addr_reg): Revert previous patch. + +Thu Jun 24 22:43:12 1999 Philippe De Muyter + + * system.h (strstr): New external function declaration. + * acconfig.h (NEED_DECLARATION_STRSTR): New define slot. + * configure.in (GCC_NEED_DECLARATIONS): Check for strstr. + * config.in, configure: Rebuilt. + +1999-06-24 Tom Tromey + + * gcc.c (main): Read user-specified specs files after computing + additional startfile_prefixes. + +1999-06-24 Bruce Korb + + *fixinc/inclhack.def(end_else_label): combined else_label + and endif_label and fixed the sed expression. + *fixinc/{fixincl.x|inclhack.sh}: regen + +Tue Jun 22 01:58:18 1999 Jeffrey A Law (law@cygnus.com) + + * rs6000.md (movdf_hardfloat32): Use %X instead of always emitting + 'x' when handling non-offsettable addresses + +Tue Jun 22 00:20:05 1999 Richard Earnshaw (rearnsha@arm.com) + + * final.c (shorten_branches): Don't try to split an insn that has + been deleted. + +Mon Jun 21 23:32:17 1999 Jeffrey A Law (law@cygnus.com) + + Thu Jun 17 15:07 1999 Bruce Korb + * fixincludes: ISCNTL patch + +Mon Jun 21 22:15:50 1999 Jeffrey A Law (law@cygnus.com) + + * rs6000.c (find_addr_reg): Handle LO_SUM addresses. + +Mon Jun 21 22:14:05 1999 David Edelsohn + + * rs6000.md (movdf_hardfloat32): Fix typo. + +Mon Jun 21 20:10:42 1999 Richard Henderson + + * collect2.c (main): Log frame table count. + (GCC_OK_SYMBOL) [ECOFF]: Accept stGlobal. + (scan_prog_file) [COFF]: Handle frame tables. + + * alpha/alpha.h (UNALIGNED_SHORT_ASM_OP): Define. + (UNALIGNED_INT_ASM_OP, UNALIGNED_DOUBLE_INT_ASM_OP): Define. + * alpha/elf.h: Undef them again. + * alpha/vms.h: Remove their definitions. + +1999-06-21 Jakub Jelinek + + * real.c (ereal_from_double): Fix for 64-bit big endian hosts. + * emit-rtl.c (gen_lowpart_common): Add case for hosts where double + fits in HOST_WIDE_INT and one uses union to access a long constant + as double. + +Mon Jun 21 17:18:25 1999 Richard Henderson + + * sparc.c (sparc_override_options): Don't allow profiling for + code models other than medlow. + (sparc_function_profiler): New function from old FUNCTION_PROFILER + macro. Use ASM_GENERATE_INTERNAL_LABEL and MCOUNT_FUNCTION. + (sparc_function_block_profiler): Likewise. Use user_label_prefix. + (sparc_block_profiler): Likewise. + (sparc_function_block_profiler_exit): Likewise. + * sparc.h (FUNCTION_PROFILER): Call new sparc.c function. + (FUNCTION_BLOCK_PROFILER): Likewise. + (BLOCK_PROFILER): Likewise. + (FUNCTION_BLOCK_PROFILER_EXIT): Likewise. + (MCOUNT_FUNCTION): New. + * sparc/pbd.h (FUNCTION_PROFILER): Delete. + (FUNCTION_BLOCK_PROFILER, BLOCK_PROFILER): Delete. + * sparc/sun4o3.h (FUNCTION_PROFILER): Delete. + (MCOUNT_FUNCTION): New. + * sparc/sysv4.h (FUNCTION_BLOCK_PROFILER): Delete. + (BLOCK_PROFILER): Delete. + (MCOUNT_FUNCTION): New. + +Mon Jun 21 06:22:21 1999 Mark Elbrecht + + * i386/djgpp.h (LIB_SPEC): New. + (STARTFILE_SPEC): New. + + * i386/xm-djgpp.h (NO_SYS_SIGLIST): Deleted. Now obsolete. + +Mon Jun 21 06:19:33 1999 Philippe De Muyter + + * fixinc/Makefile.in (gnu-regex.o): Do not define STDC_HEADERS in + compiler flags. + + * system.h (WSTOPSIG): New macro. + +Mon Jun 21 05:33:15 1999 Mumit Khan + + * c-pragma.c (push_alignment): Don't ignore alignments greater than + 4 bytes. + (insert_pack_attributes): Take into account member natural + alignment. + + * i386/winnt.c (exports_head): New static variable. + (i386_pe_record_exported_symbol): New function. + (i386_pe_asm_file_end): Use. + * i386/cygwin.h (ASM_OUTPUT_COMMON): Record the exported + symbols to be emitted at end of assembly. + (ASM_DECLARE_OBJECT_NAME): Likewise. + (ASM_DECLARE_FUNCTION_NAME): Likewise. + + * i386/uwin.h (CPP_SPEC): Use -idirafter instead -iprefix and + -iwithprefix. + +Mon Jun 21 05:17:00 1999 David Edelsohn + + * rs6000.md (movdf_hardfloat32): Use worst case insn length + attributes for cases 1 and 2. + + * rs6000.c (find_addr_reg): New function. + * rs6000.h (find_addr_reg): Declare. + (offsettable_addr_operand): Delete. + * rs6000.md (movdf_hardfloat32): Handle non-offsettable loads + from and stores to GPRs. + +Mon Jun 21 04:44:31 1999 Jeffrey A Law (law@cygnus.com) + + * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Fix paren error introduced + in last change. + +Sun Jun 20 17:24:35 1999 Richard Henderson + + * haifa-sched.c (sched_analyze): Don't clear reg_last_uses on calls. + +Sat Jun 19 22:52:55 1999 Richard Henderson + + * haifa-sched.c (sched_analyze): Mark call-user regs as clobbered + instead of set. + +Sat Jun 19 05:40:07 1999 Philip Blundell + + * arm.c (arm_reload_in_hi): Invert sense of test on BYTES_BIG_ENDIAN. + +Sat Jun 19 05:25:05 1999 Richard Earnshaw (rearnsha@arm.com) + + * arm.h (CONDITIONAL_REGISTER_USAGE): If flag_pic, never use + PIC_OFFSET_TABLE_REGNUM for general alloaction. + (INITIAL_ELIMINATION_OFFSET): Count the fact that the PIC register + must be stacked if it is used for PIC accesses. + * arm.c (use_return_insn): Handle PIC register specially. + (output_return_instruction): Likewise. + (output_func_{prologue,epilogue}): Likewise. + (output_expand_prologue): Likewise. + + * arm.c (arm_override_options): Remove warning about PIC code + not being supported. + +Fri Jun 18 15:44:18 1999 Richard Henderson + + * alpha.c (alpha_expand_block_move): Use get_insns rather than + gen_sequence as argument to emit_no_conflict_block. + +Fri Jun 18 06:48:30 1999 Kaveh R. Ghazi + + * fixinc/inclhack.def (ioctl_fix_ctrl): Fix the definition of _*ISCTRL(). + * fixinc/{fixincl.x,inclhack.sh}: regen + +Thu Jun 17 13:28:30 1999 David O'Brien + + * i386/freebsd-elf.h (LINK_SPEC): Fix typo. + + * i386/freebsd-elf.h (FUNCTION_PROFILER): labels are not needed and + the reference to `mcount' was not correct for the ELF on FreeBSD. + +Thu Jun 17 02:54:30 1999 Jeffrey A Law (law@cygnus.com) + + * invoke.texi (ia32 options): Fix typo. + + * emit-rtl.c (operand_subword): Tighten checks for when it is safe + to safe to extract a subword out of a REG. + +Wed Jun 16 10:33:02 1999 Jason Merrill + + * dwarfout.c (add_incomplete_type): New fn. + (output_type): Call it. + (retry_incomplete_types): New fn. + (dwarfout_finish): Call it. + + From Eric Raskin : + (output_type): Output types for bases. + +Tue Jun 15 01:55:20 1999 David O'Brien + + * i386/freebsd-elf.h (LINK_SPEC): clean up the linking library + specifications and make it realistic. + (LIB_SPEC): Likewise. + +Mon Jun 14 03:55:40 1999 Jeffrey A Law (law@cygnus.com) + + * configure.in (rs6000-ibm-aix4.3*, powerpc-ibm-aix4.3*): Do not + require a sub-version #. * configure: Rebuilt. - * varasm.c (declare_weak): If HANDLE_PRAGMA_WEAK, call - handle_pragma_weak. - -Wed Feb 24 03:17:56 1999 Jeffrey A Law (law@cygnus.com) +1999-06-14 Robert Lipe (robertlipe@usa.net) - * version.c: Bump for prerelease. + * svr4.h (DWARF2_DEBUGGING_INFO): Check for redefinition. - * Makefile.in (compare, gnucompare): Ignore comparison failures - for some objects in the ObjC runtime. +1999-06-14 Andreas Jaeger -Wed Feb 24 02:39:08 1999 Jeffrey A Law (law@cygnus.com) + * gcc.texi: Mention gcc 2.95 instead of egcs 1.00. - Mon Dec 7 16:15:51 1998 J"orn Rennecke - * sh.c (output_far_jump): Emit braf only for TARGET_SH2. +Sun Jun 13 01:08:02 1999 Mark Mitchell - Mon Nov 23 16:46:46 1998 J"orn Rennecke - * va-sh.h (__va_arg_sh1): Use __asm instead of asm. + * invoke.texi (node Option Summary): Add -fpermissive flag. -Tue Feb 23 00:38:17 1999 Jeffrey A Law (law@cygnus.com) +Sat Jun 12 03:40:42 1999 Jeffrey A Law (law@cygnus.com) - Thu Sep 3 00:23:21 1998 Richard Henderson - * ginclude/va-alpha.h: Protect entire second portion of the - file against double inclusion. + * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Do nothing with operands + that require PIC code sequences. - Mon Aug 31 13:57:55 1998 Richard Henderson - * alpha/va_list.h: New file. - * alpha/x-alpha (EXTRA_HEADERS): New. Add va_list.h. +Fri Jun 11 03:17:51 1999 Jeffrey A Law (law@cygnus.com) - Sat Aug 1 17:59:30 1998 Richard Henderson - * ginclude/va-alpha.h (va_list): Use a typedef, not a define. + * Makefile.in (libgcc2): Pass MAYBE_USE_COLLECT2 as an argument. + * libgcc2.c (__CTOR_LIST, __DTOR_LIST); Do not provide + initializers is some circumstances. -Sun Feb 21 20:35:10 1999 Jeffrey A Law (law@cygnus.com) + * fixinc/inclhack.def (endif_label): Add additional selector for + more bogus stuff after #endif statements. + * fixinc/inclhack.sh, fixinc/fixincl.x: Rebuilt. - Wed Oct 28 22:58:35 1998 Jason Merrill - * tree.c (append_random_chars): New fn. - (get_file_function_name_long): Use it. +Thu Jun 10 20:45:27 1999 Mumit Khan - Thu Aug 13 17:08:11 1998 Jason Merrill - * tree.c (get_file_function_name_long): Split out... - (get_file_function_name): ...from here. + * i386/cygwin.h (SET_ASM_OP): Define. - * config/aoutos.h (ASM_OUTPUT_CONSTRUCTOR): Delete. - (ASM_OUTPUT_DESTRUCTOR, ASM_OUTPUT_GC_ENTRY): Likewise. - * tm.texi: Update docs for constructors and destructors. +Thu Jun 10 20:37:57 1999 Mumit Khan -Tue Feb 16 21:02:07 1999 Anton Hartl + * reg-stack.c (stack_reg_life_analysis): Find all the RETURN insns. - * rs6000.md (call_value): Fix typo. +Thu Jun 10 14:47:59 1999 Bruce Korb -Tue Feb 16 01:37:33 1999 Charles G Waldman + * fixinc/inclhack.def(sun_auth_proto): We do not know how to + test for the presence of valid prototypes. Delete bypass expr. + (ioctl_fix_ctrl): Correct the selection expression. - * c-common.c (shorten_compare): Get the min/max value from the - underlying type of an enumeration, not the enumerated type itself. + * fixinc/inclhack.def(no_double_slash): fixed quoting rules + * fixinc/inclhack.sh: regen + * fixinc/fixincl.x: regen -Mon Feb 15 11:33:51 1999 Jeffrey A Law (law@cygnus.com) +Thu Jun 10 01:22:59 1999 Jeffrey A Law (law@cygnus.com) - Sat Jan 16 21:48:17 1999 Marc Espie (Marc.Espie@openbsd.org) - * gcc.c: (do_spec_1): Fix obvious typo. + * loop.c (strength_reduce): Disable biv->giv translations and + giv recombination. For the release branch only. - * jump.c: Include insn-attr.h. - (delete_computation): If reload has completed and insn scheduling - after reload is enabled, then do not depend on REG_DEAD notes. - * Makefile.in (jump.o): Depend on insn-attr.h. +Wed Jun 9 15:57:57 1999 Franz Sirl - * sparc.c (output_scc_insn): Add missing argument to output_cbranch. + * rs6000.md (movsi_got_internal_mem): Delete. + * rs6000.h (CONDITIONAL_REGISTER_USAGE): Mark PIC_OFFSET_TABLE_REGNUM. + (GOT_TOC_REGNUM): Delete. + (PIC_OFFSET_TABLE_REGNUM): Define. + (FINALIZE_PIC): Disable. + * rs6000.c (rs6000_got_register): New code for fixed pic register. + (rs6000_replace_regno): Delete. + (rs6000_finalize_pic): Likewise. + (output_prolog): Handle PIC_OFFSET_TABLE_REGNUM. - * loop.c (mark_loop_jump): Handle LO_SUM. If we encounter something - we do not understand, mark the loop and containing loops as invalid. +Wed Jun 9 19:44:26 1999 J"orn Rennecke -Sun Feb 14 23:05:34 1999 Jeffrey A Law (law@cygnus.com) + * loop.c (loop_insn_first_p): Don't compare LUIDs when P + is a note; use <= for the compare; advance P while it is + a NOTE. - Tue Feb 9 21:14:03 1999 J"orn Rennecke - * alias.c (init_alias_analysis): Avoid self-referential value - when setting reg_known_value from REG_EQUAL notes. +Wed Jun 9 13:12:24 1999 Jeffrey A Law (law@cygnus.com) + + * fixinc/inclhack.def (no_double_slash): Fix quoting for test. + * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh; Rebuilt. + + * varasm.c (remove_from_pending_weak_list): Verify t->name + is non-NULL before passing it to strcmp. + +Wed Jun 9 23:01:17 1999 Michael Hayes + + * invoke.texi: Add C4x invocation docs. + +Wed Jun 9 22:42:49 1999 Michael Hayes + + * config/c4x/c4x.h (TARGET_EXPOSE_LDP, LEGITIMIZE_RELOAD_ADDRESS): + Define new macros. + * config/c4x/c4x.c (c4x_emit_move_sequence, src_operand): Use + TARGET_EXPOSE_LDP. + (c4x_legitimize_reload_address): New function. + * config/c4x/c4x.md: Update docs. + +Wed Jun 9 06:50 1999 Bruce Korb + + * fixinc/inclhack.def(sun_auth_proto): bypass the patch if + the typed arguments are not part of a comment + (ioctl_fix_ctrl): Added a purpose comment + * fixinc/fixincl.x: regenerate + * fixinc/inclhack.sh: regenerate + +Wed Jun 9 04:14:48 1999 Jeffrey A Law (law@cygnus.com) + + * fixincludes: Avoid removing '.'. + * fixinc/fixinc.svr4: Likewise. + * fixinc/fixinc.winnt: Likewise. + * fixinc/inclhack.tpl: Likewise. + * fixinc/fixincl.sh, fixinc/inclhack.sh: Rebuilt. + +Wed Jun 9 03:55:34 1999 Jim Wilson + + * configure.in (rs6000-ibm-aix4.[12]*): Change rx6000 to rs6000. + * configure: Regenerate. + + * configure.in (rs6000-ibm-aix4.[12]*): Delete use of aix41-gld.h. + Add use of x-aix41-gld. + +1999-06-09 Kaveh R. Ghazi + + * fixinc/inclhack.def (sun_catmacro): Escape parens in the select + pattern. + * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. + +Wed Jun 9 03:10:34 1999 Mumit Khan + + * c-pragma.c (handle_pragma_token): Handle `#pragma pack()' + correctly. + +Tue Jun 8 05:47:48 1999 Richard Earnshaw (rearnsha@arm.com) + + * optabs.c (expand_cmplxdiv_wide): Use expand_abs to get the absolute + values. + +Mon Jun 7 22:30:37 1999 Jeffrey A Law (law@cygnus.com) + + * fixinc/inclhack.def (bad_lval): Remove bogus selector. + * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh; Rebuilt. + + * fixinc/inclhack.def (avoid_bool): Also catch + "typedef [unsigned] int bool". + * fixinc/inclhack.sh, fixinc/fixincl.x, fixinc/fixincl.sh: Rebuilt. + + * m68k/x-hp3bsd44: Delete obsolete and incorrect file. + * configure.in (m68k-hp-bsd4.4): No longer use x-hp3bsd44. + * configure: Rebuilt. + +Mon Jun 7 22:05:03 1999 Mark Kettenis + + * config/i386/gnu.h: Include right after , + such that we can override its definitions if necessary. + (CPP_SPEC): New define. Support processor specific predefines via + %(cpp_cpu). + (CC1_SPEC): New define. Support processor specific compiler + options via %(cc1_cpu). + (STARTFILE_SPEC): New define. Use crt0.o instead of crt1.o for + -static. + +1999-06-07 Kaveh R. Ghazi + + * fixinc/inclhack.def (math_gcc_ifndefs): Insert whitespace + between sed's -e flag, and the open-quote following it. + * fixinc/fixincl.x, fixinc/fixincl.sh: Rebuilt. + +Mon Jun 7 20:34:20 1999 Robert Lipe + Jeffrey A Law (law@cygnus.com) + + * varasm.c (assemble_start_function): Remove the function + from the pending weak decls list when we define a function. + (assemble_variable): Similarly for variables. + (weak_finish): Ignore items on the list with a NULL name. + (remove_from_ending_weak_list); New function to "remove" an item + from the pending weak declarations list. + +Mon Jun 7 19:27:07 1999 Jerry Quinn + + * pa.md (fmpyfadd, fmpynfadd, fnegabs): New patterns. + +Sun Jun 6 11:58:34 1999 Jakub Jelinek + + * sparc.md (abstf2): This should be an expand. + (split after abstf2_notv9): Fix mode. + (abstf2_hq_v9): New pattern. + (abstf2_v9): Only use when no hard quad. + (absdf2_v9): Fix if target is not the same as source. + (ashrsi3_extend, ashrsi3_extend2, lshrsi3_extend, lshrsi3_extend2): + Add correct output constraints. + +Sat Jun 5 17:04:16 1999 Craig Burley + + From Dave Love to egcs-patches on 20 May 1999 17:38:38 +0100: + * invoke.texi: Clarify text vis-a-vis Intel CPUs. - Mon Aug 17 02:03:55 1998 Richard Henderson - * regclass.c (allocate_reg_info): Respect MIN when clearing data. +Fri Jun 4 13:30:27 1999 Rainer Orth - * loop.c (scan_loop): Fix typo in last change. + * alpha/osf.h (CPP_SUBTARGET_SPEC): Handle -threads. + (LIB_SPEC): Likewise. + Link with -lprof1_r for -g/-pg. -Sat Feb 13 11:53:12 1999 Jeffrey A Law (law@cygnus.com) +1999-06-04 Andreas Schwab - 1999-02-05 Michael Meissner - J"orn Rennecke - * loop.c (check_dbra_loop): A store using an address giv for which - we have no life information is not reversible. - * loop.c (first_loop_store_insn): New file-scope variable. - (prescan_loop): Set it. - (check_dbra_loop): Check if a store depends on a register - that is set after the store. + * loop.c (check_dbra_loop): Fix change of Jan 19. - Sun Jan 31 13:22:02 1999 John Wehle (john@feith.com) - * i386.md (movsicc, movhicc, movsfcc, movdfcc, - movxfcc, movdicc): Delete unconstrained alternatives. - * i386.c (output_fp_conditional_move, - output_int_conditional_move): Delete unused case. +Fri Jun 4 00:12:40 1999 Marc Espie - Tue Aug 18 10:33:30 1998 Jeffrey A Law (law@cygnus.com) - * expr.c (emit_block_move): Do not call memcpy as a libcall - instead build up a CALL_EXPR and call it like any other - function. - (clear_storage): Similarly for memset. + * freebsd-elf.h (SWITCH_TAKES_ARG): Redefine, not define. + (STARTFILE_SPEC): Define, override the svr4.h version. + (ENDFILE_SPEC): Likewise. - Sun Sep 20 20:57:02 1998 Robert Lipe - * configure.in (i*86-*-sysv5*): Use fixinc.svr4 to patch byteorder - problems. - * configure: Regenerate. +Thu Jun 3 23:58:55 1999 Jeffrey A Law (law@cygnus.com) -Fri Feb 12 23:20:54 1999 Michael P. Hayes + * fixinc/inclhack.def (limits_ifndefs): Also apply to sys/limits.h + * fixinc/fixincl.x: Regenerated. + * fixinc/inclhack.sh: Regenerated. - * loop.c (scan_loop): Call reg_in_basic_block_p before - loop_reg_used_before_p. +Thu Jun 3 07:48 1999 Bruce Korb -Thu Feb 11 01:53:10 1999 Jeffrey A Law (law@cygnus.com) + * fixinc/inclhack.def(Io_Def_Quotes): corrected sed expression + * fixinc/fixincl.x: regenerate + * fixinc/inclhack.sh: regenerate - Wed Nov 18 22:13:00 1998 J"orn Rennecke - * expr.c (store_expr): Don't generate load-store pair - if TEMP is identical (according to ==) with TARGET. +Thu Jun 3 22:27:50 1999 Robert Lipe -Thu Feb 11 01:06:49 1999 Nathan Sidwell + * i386/udk.h (LINK_SPEC): Correct linker search path for + system libraries. - * fold-const.c (range_binop): Take account of the bounded nature - of fixed length arithmetic when comparing unbounded ranges. +Thu Jun 3 02:15:07 1999 Jason Merrill -Wed Feb 10 11:03:22 1999 Richard Henderson + * dwarf2out.c (add_incomplete_type): New fn. + (gen_struct_or_union_type_die): Call it. + (retry_incomplete_types): New fn. + (dwarf2out_finish): Call it. - * configure.in (alphaev6*): Fix typo in target_cpu_default2. +Thu Jun 3 01:19:03 1999 Jeffrey A Law (law@cygnus.com) -Tue Feb 9 00:00:14 1999 Mark Kettenis + * gcse.c (insert_insn_end_bb): Correct placement of insns when the + current block starts with a CODE_LABEL and ends with a CALL and + we can not find all the argument setup instructions for the CALL. - * configure.in (i[34567]86-*gnu*): Set float_format to i386. - * configure: Rebuilt. +Wed Jun 2 12:25:55 1999 Richard Henderson -Sat Feb 6 16:03:36 1999 Jeffrey A Law (law@cygnus.com) + * alpha.c (override_options): Thinko in last patch. - * invoke.texi, expr.c: Update email addresses. + * alpha/osf.h (CPP_SUBTARGET_SPEC): Define. + (LIB_SPEC): Recognize -pthread. - * gcc.c, gcc.texi: Update email addresses. +Wed Jun 2 07:07 1999 Bruce Korb -Sat Jan 30 05:27:25 1999 Jeffrey A Law (law@cygnus.com) + * fixinc/fixincl.c(global def): Add FD_SHELL_SCRIPT to mark + fixes that need "file=xxx\n" prepended before invocation + (start_fixer - new): starting the fixer process is complex enough + to warrent its own routine. It prepends the "file=xxx\n" stuff. + (process): uses the new routine; omit usage of putenv() + * fixinc/fixincl.tpl: mark shell scripts with FD_SHELL_SCRIPT + * fixinc/fixincl.x: regenerate - Thu Jan 21 01:59:30 1999 Richard Henderson - * explow.c (allocate_dynamic_stack_space): Use register_operand - instead of arith_operand, which does not exist. +Wed Jun 2 06:36:14 1999 Richard Earnshaw (rearnsha@arm.com) -Thu Jan 28 09:44:04 1999 Jeffrey A Law (law@cygnus.com) + * arm.md (zero_extendqidi2): Don't allow operand1 to be a memory + reference. Temporary work-around for problems with constant + pool handling. - * configure.in (hppa1.0-hp-hpux10*): Use t-pa. - * configure: Rebuilt. +Wed Jun 2 02:40:43 1999 Jeffrey A Law (law@cygnus.com) -Thu Jan 21 23:27:06 1999 Jeffrey A Law (law@cygnus.com) + * README, configure.in, gcc.1, gcc.texi: Update name (egcs -> gcc) + and version #s (1.1 -> 2.95) as needed. + * README.g77: Kill way out of date file in the toplevel directory. - * m68k.md (ashldi_const): Disable for !TARGET_5200. Fix indention. - (ashldi3 expander): Similarly. Update comments. - (ashrdi_const, lshrdi_const): Fix indention. - (ashrdi3, lshrdi3): FIx indention. Update comments. +Wed Jun 2 00:52:34 1999 David O'Brien -Thu Jan 21 20:33:31 1999 Richard Henderson + * configure.in (i[34567]86-*-freebsdelf): Don't include linux.h, + i386/freebsd-elf.h no longer requires it. Instead include svr4.h. + * configure: Rebuilt. + * i386/freebsd-elf.h (DEFAULT_VTABLE_THUNKS): Define. + (ASM_COMMENT_START, ASM_APP_ON, ASM_APP_OFF, SET_ASM_OP): Likewise. + (PREFERRED_DEBUGGING_TYPE, WCHAR_UNSIGNED): Likewise. + (SWITCH_TAKES_ARG): Likewise. + * i386/freebsd.h: Remove FREEBSD_NATIVE support. + * config/t-freebsd: Moved from config/i386/ so it can used for all + FreeBSD targets. + +Mon May 31 02:22:55 1999 Philippe De Muyter - * rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Recognize and accept - transformations that we have performed earlier. - * alpha.h (LEGITIMIZE_RELOAD_ADDRESS): Likewise. + * m68k/x-mot3300 (XCFLAGS): Fixed to match stb.o, not f/stb.o. -Sun Jan 17 20:39:20 1999 Richard Henderson +Wed Jun 2 00:08:34 1999 Robert Lipe - * jump.c (rtx_renumbered_equal_p): Special case CODE_LABEL. + * configure.in (i[34567]86-*-udk*): Install headers with cpio. + * configure: Rebuilt. -Sun Jan 17 19:01:47 1999 Jeffrey A Law (law@cygnus.com) +Wed Jun 2 00:49:00 EDT 1999 John Wehle (john@feith.com) - * i386.md (integer conditional moves): Add missing earlyclobbers. + * flow.c (mark_regs_live_at_end, insn_dead_p, + mark_set_1, mark_used_regs): Only give FRAME_POINTER_REGNUM + and HARD_FRAME_POINTER_REGNUM special treatment if reload + hasn't run or the frame pointer is needed. + * haifa-sched.c (attach_deaths): Likewise. + * sched.c (attach_deaths): Likewise. - * regmove.c (optimize_reg_copy_1): Undo Aug 18 change. Update - REG_N_CALLS_CROSSED and REG_LIVE_LENGH if and only if we change - where a register is live. +Thu May 27 22:06:52 1999 Mark Mitchell -Fri Jan 15 01:19:42 1999 Jeffrey A Law (law@cygnus.com) + * cccp.c (handle_directive): Handle backslash-newlines in quoted + strings correctly. - * unroll.c (find_splittable_givs): For a DEST_ADDR giv, do not share - a register with another DEST_ADDR giv if the address is not valid. +Mon May 31 22:42:02 1999 Jeffrey A Law (law@cygnus.com) - * h8300.h (ASM_OUTPUT_LABELREF): Use asm_fprintf, not fprintf. + * Remove this patch (from the branch only) + Wed May 26 09:53:05 1999 Mark Mitchell + * fold-const.c (fold): STRIP_NOPS when deciding whether or not + something is a candidate for optimize_bit_field_compare. -Mon Jan 11 20:23:34 1999 Richard Henderson +Mon May 31 15:23:23 1999 Richard Henderson - * sparc.c (legitimize_pic_address): Treat labels like symbols. - (emit_move_sequence): Likewise. - * sparc.h (PRINT_OPERAND_ADDRESS): Likewise. - (ASM_OUTPUT_ADDR_VEC_ELT): Don't special case CM_MEDLOW. - (ASM_OUTPUT_ADDR_DIFF_ELT): Likewise. Don't reference magic `1b'. - * sparc.md (move_pic_label_si): Kill. - (move_label_di): Kill. - (pic_tablejump_32, pic_tablejump_64): Kill. - (tablejump): Expose pic arithmetic to the compiler. + * alpha.md (reload_*_help): New patterns and splitters. + (reload_*): Use them. + (mov[qh]i): Likewise. -Thu Jan 7 00:33:33 1999 Bernd Schmidt +Mon May 31 09:36:11 1999 Cort Dougan - * combine.c (num_sign_bit_copies): In NEG, MULT, DIV and MOD cases, - when a test can't be performed due to limited width of - HOST_BITS_PER_WIDE_INT, use the more conservative approximation. - Fix UDIV case for cases where the first operand has the highest bit - set. + * rs6000/linux.h (LINK_SPEC): Use emulation elf32ppclinux. -Wed Jan 6 23:37:47 1999 Jeffrey A Law (law@cygnus.com) +Sat May 29 19:08:10 1999 Philip Blundell - * h8300.h (ASM_OUTPUT_LABELREF): Define. + * config/arm/aout.h (ASM_OUTPUT_ALIGN): Only define if not already + defined. + * config/arm/elf.h (ASM_OUTPUT_ALIGN): Define. + (MAX_OFILE_ALIGNMENT): Likewise. -Wed Jan 6 02:23:36 1999 "Charles M. Hannum" +Mon May 31 00:45:14 1999 Jeffrey A Law (law@cygnus.com) - * expr.c (store_expr): If the lhs is a memory location pointed - to be a postincremented (or postdecremented) pointer, always - force the rhs to be evaluated into a pseudo. + * jump.c (jump_optimize_1): Only set CAN_REACH_END if + calculate_can_reach_end returns nonzero. -Fri Jan 1 11:48:20 1999 Jeffrey A Law (law@cygnus.com) + * Makefile.in (CFLAGS): Remove warning flags. + (WARN_CFLAGS): Disable. - * i386.md (doubleword shifts): Fix dumb mistakes in previous change. + * configure.in (native gas tests): Search for an assembler in the + same manner that the installed compiler will. + * configure: Rebuilt. + * tm.texi (MD_EXEC_PREFIX): Note need to update configure.in too. -Wed Dec 30 23:44:11 1998 Jeffrey A Law (law@cygnus.com) + * alias.c (find_base_term): Improve handling of addresses + constructed from binary operations. - * m68k.md (adddi_dilshr32): Allow all operands to be registers too. - (adddi_dishl32): Similarly. +Sun May 30 14:43:37 1999 Robert Lipe - * cse.c (invalidate_skipped_block): Call invalidate_from_clobbers - for each insn in the skipped block. + * fixincl.c: Replace local include scheme with #includes of + gansidecl.h and system.h. + * procopen.c: Likewise. + * server.c: Likewise. - * i386.md (doubleword shifts): Avoid namespace pollution. +Sun May 30 14:18:40 1999 Jeffrey A Law (law@cygnus.com) -Mon Dec 28 10:44:40 1998 Richard Henderson + * function.h (cleanup_label, frame_offset): Declare. + (tail_recursion_label, tail_recursion_reentry): Likewise. + (arg_pointer_save_area, rtl_expr_chain): Likewise. + * stmt.c (cleanup_label, frame_offset): Delete extern declarations. + (tail_recursion_label, tail_recursion_reentry): Likewise. + (arg_pointer_save_area, rtl_expr_chain): Likewise. - * combine.c (subst): Process the inputs to a parallel asm_operands - only once. +Fri May 28 03:47:03 1999 Eric Raskin (ehr@listworks.com) -Sun Dec 13 00:09:47 1998 Jeffrey A Law (law@cygnus.com) + * i386/t-dgux (EXTRA_PARTS): Add crti.o. + (crti.o): Add build rule and dependencies. - * i386/next.h (ASM_OUTPUT_ALIGN): Use 0x90 for fill character. +Fri May 28 03:07:10 1999 Franz Sirl - * h8300.c (h8300_encode_label): Use '&' for tiny data items. - * h8300.h (TINY_DATA_NAME_P): Likewise. - (STRIP_NAME_ENCODING): Handle '&'. + * rs6000/sysv4.h (CC1_SPEC): Add support for -profile + (LIB_LINUX_SPEC): Likewise. + (LIB_LINUX_SPEC): Add support for -pthread + (CPP_OS_LINUX_SPEC): Likewise. + (CPP_SYSV_SPEC): Avoid redefinitions if both -fpic and -fPIC are + specified -Wed Dec 2 01:44:58 1998 Jeffrey A Law (law@cygnus.com) + * rs6000.c (output_mi_thunk): Enable full support again. - * egcs-1.1.1 released. +Thu May 27 13:04:52 1999 H.J. Lu (hjl@gnu.org) -Mon Nov 23 20:28:02 1998 Mike Stump + * i386.c (output_fp_cc0_set): Don't check the JUMP_INSN code for + conditional move. + (notice_update_cc, output_float_compare): Enable TARGET_CMOVE support. + (output_float_compare, output_fp_cc0_set): Fix the FLOAT comparison + for IEEE math and CC_FCOMI. + (put_jump_code): No IEEE if CC_FCOMI is set. - * libgcc2.c (top_elt): Remove top_elt, it isn't thread safe. - The strategy we now use is to pre allocate the top_elt along - with the EH context so that each thread has its own top_elt. - This is necessary as the dynmanic cleanup chain is used on the - top element of the stack and each thread MUST have its own. - (new_eh_context): Likewise. - (__sjthrow): Likewise. +1999-05-27 Andreas Schwab -Mon Nov 23 09:53:44 1998 Richard Henderson + * fold-const.c (fold_truthop): Make the field reference unsigned + when converting a single bit compare. - * local-alloc.c (local_alloc): Use malloc not alloca for - reg_qty, reg_offset, ref_next_in_qty. +Thu May 27 03:07:13 1999 Philip Blundell -Mon Nov 23 09:49:49 1998 Andrew MacLeod + Based on patch by Scott Bambrough and Pat Beirne: + * config/arm/arm.c (making_const_table): New variable. + * config/arm/arm.h (making_const_table): Declare. + (OUTPUT_INT_ADDR_CONST): Mark symbols as position independent if + appropriate. + * config/arm/arm.md (consttable_4, consttable_8, consttable_end): + Keep track of when we are building the constant table. - * cplus-dem.c (demangle_prefix): Use the last "__" - in the mangled name when looking for the signature. This allows - template names to begin with "__". +Thu May 27 02:52:55 1999 Jeffrey A Law (law@cygnus.com) -Mon Nov 23 09:40:41 1998 David Edelsohn + * varasm.c (STRIP_NAME_ENCODING): Remove default definition. + * output.h (STRIP_NAME_ENCODING): Strip '*' like the old varasm + version did. - * rs6000.h (LEGITIMIZE_ADDRESS): Add missing "goto WIN". +Thu May 27 02:40:48 1999 J"orn Rennecke -Mon Nov 9 23:29:39 1998 David Edelsohn + * loop.c (strength_reduce): Don't do biv->giv conversion on constants. - * rs6000.md (floatunssidf2_internal splitter): Use base register - operand, not hard-coded SP. +Thu May 27 02:09:27 1999 Jeffrey A Law (law@cygnus.com) -Mon Nov 9 23:05:51 1998 Richard Earnshaw (rearnsha@arm.com) + * reload.c (push_reload): Do not call remove_address_replacements + when presented with identical optional reloads. - Restore ABI compatibility for NetBSD. - * arm/netbsd.h (DEFAULT_PCC_STRUCT_RETURN): Override setting in - arm.h - (RETURN_IN_MEMORY): Likewise. +Wed May 26 14:18:05 1999 Richard Henderson - * arm.c (add_constant): When taking the address of an item in the - pool, get the mode of the item addressed. + * alpha.h (MASK_FIX, TARGET_FIX): New. + (MASK_*): Reorganize constants. + (CPP_AM_FIX_SPEC): New. + (TARGET_SWITCHES): Add FIX. + (EXTRA_SPECS): Likewise. + (CPP_CPU_EV6_SPEC): Use FIX, not CIX. + (SECONDARY_MEMORY_NEEDED): Likewise. + (REGISTER_MOVE_COST): Likewise. + * alpha.c (override_options): Add FIX support. Always use + ALPHA_TP_PROG for ev6. + * alpha.md (sqrt and mov[sd]i patterns): Use FIX, not CIX. + * alpha/elf.h (ASM_FILE_START): Look at FIX too. + * configure.in (target_cpu_default2) [ev6]: Use FIX, not CIX. - * arm.c (final_prescan_insn, case INSN): If an insn doesn't - contain a SET or a PARALLEL, don't consider it for conditional - execution. +Wed May 26 09:53:05 1999 Mark Mitchell -Mon Nov 9 22:43:57 1998 Jean-Pierre Radley + * fold-const.c (fold): STRIP_NOPS when deciding whether or not + something is a candidate for optimize_bit_field_compare. - * fixinc.sco: Paramaterize #include_next values. - * fixinc/fixinc.sco: Likewise. +Wed May 26 03:54:33 1999 Melissa O'Neill -Mon Nov 9 22:43:57 1998 Robert Lipe + * fixinc/fixincl.c: (WIFSIGNALED): Define if not already defined. + (WTERMSIG, WIFEXITED, WEXITSTATUS, WIFSTOPPED, WSTOPSIG): Likewise. + (S_IRUSR, S_IWUSR, S_IXUSR, S_IRGRP, S_IWGRP, S_IXGRP): Likewise. + (S_IROTH, S_IWOTH, S_IXOTH, S_IRWXU, S_IRWXG, S_IRWXO): Likewise. - * fixinc.sco: Borrow code to wrap 'bool' typedefs from tinfo.h - and term.h from fixinc.wrap. +Wed May 26 02:19:31 1999 Philip Blundell -Thu Nov 5 07:57:45 EST 1998 Andrew MacLeod + * arm.h (NEED_PLT_GOT): Fix mistake in last change. + (GOT_PCREL): New macro. Define to 1 if not already defined. + * arm/elf.h (GOT_PCREL): Define to 0. + * arm.c (arm_finalize_pic): Take into account the setting of + GOT_PCREL. - * except.c (expand_fixup_region_end): Make sure outer context labels - are not issued in an inner context during cleanups. +Tue May 25 14:06:06 1999 Jeffrey A Law (law@cygnus.com) -Sun Nov 1 11:04:32 1998 Jeffrey A Law (law@cygnus.com) + * output.h (STRIP_NAME_ENCODING): Provide default definition. + * dwarf2out.c (ASM_NAME_TO_STRING): Use STRIP_NAME_ENCODING. - * i386/linux.h (CPP_PREDEFINES): Bring back -Di386 for the last time. + * flow.c (mark_set_1): Do not record BLKmode stores as dead + store elimination candidates. - * From Christian Gafton: - * i386/linux.h (CPP_PREDEFINES): Add -D__i386__. - * sparc/linux.h (CPP_PREDEFINES): Add -D__sparc__. - * sparc/linux64.h (CPP_PREDEFIENS): Add -D__sparc__. +Mon May 24 14:34:31 1999 Jeffrey A Law (law@cygnus.com) -Sat Oct 31 00:40:05 1998 Jeffrey A Law (law@cygnus.com) + * loop.c (strength_reduce): Do not clear NOT_EVERY_ITERATION at the + last CODE_LABEL in a loop if we have previously passed a jump + to the top of the loop. - * jump.c (jump_optimize): Initialize mappings from INSN_UID to - EH region if exceptions are enabled and we're performing cross - jump optimizations. - (find_cross_jump): Exit loop if the insns are in different EH regions. +Mon May 24 01:02:58 1999 Mark Mitchell -Fri Oct 30 00:54:25 1998 Peter Jakubek + * stmt.c (expand_end_bindings): Ignore any elements of VARS that + are not VAR_DECLs. - * m68k.h (INDIRECTABLE_1_ADDRESS_P): Fix thinko. +Sun May 23 20:31:16 1999 Jeffrey A Law (law@cygnus.com) -Thu Oct 29 12:14:58 1998 Jason Merrill + * loop.c (strength_reduce): Grow reg_single_usage as needed. - * alpha/linux.h (CPP_PREDEFINES): Add missing space. +Sun May 23 10:13:20 1999 David O'Brien -Tue Oct 27 16:11:43 1998 David Edelsohn + * i386/freebsd-elf.h (LINK_SPEC): Change -static to -Bstatic. + Also remove a useless comment. - * collect2.c (aix64_flag): New variable. - (main, case 'b'): Parse it. - (GCC_CHECK_HDR): object magic number must match mode. - (scan_prog_file): Only check for shared object if valid header. - Print debugging if header/mode mismatch. - * README.RS6000: Update. +Sun May 23 10:05:23 1999 Jerry Quinn -Sun Oct 25 23:36:52 1998 Jason Merrill + * pa.md (negdf2,negsf2): Use fneg instead of fsub on pa 2.0. - * stmt.c (expand_fixup): Set fixup->before_jump to a - NOTE_INSN_DELETED instead of a NOTE_INSN_BLOCK_BEG. +Sat May 22 01:27:49 1999 Mark Mitchell -Sun Oct 25 18:35:06 1998 David Edelsohn + * expr.h (lang_expand_constant): Guard with #ifdef TREE_CODE. - * ginclude/va-ppc.h (va_arg): longlong types in overflow area are - not doubleword aligned. +Thu May 20 10:00:42 1999 Stephen L Moshier -Sun Oct 25 12:07:00 1998 Mumit Khan + * Makefile.in (GCC_FOR_TARGET): Add -I$(build_tooldir)/include. + +Thu May 20 09:58:57 1999 Jan Hubicka - * i386/crtdll.h (CPP_PREDEFINES): Fix typo. - * i386/mingw32.h (CPP_PREDEFINES): Likewise. + * function.c (assign_stack_local): Align stack slot propertly. + (assign_outer_stack_local): Likewise. + +Thu May 20 10:38:43 1999 Mark Mitchell -Fri Oct 23 22:41:40 1998 David Edelsohn + * expr.h (lang_expand_constant): Declare. + * toplev.c (lang_expand_constant): Define it. + * varasm.c (output_constant): Use it. - * rs6000.md (movsf): Disable explicit secondary-reload-like - functionality if TARGET_POWERPC64. - (movdf): Remove TARGET_POWERPC64 explicit secondary-reload-like - functionality. +Thu May 20 11:28:53 1999 Kaveh R. Ghazi -Fri Oct 23 22:38:57 1998 Jeffrey A Law (law@cygnus.com) + * optabs.c (expand_cmplxdiv_straight, expand_cmplxdiv_wide): + Change function definitions to K&R style. - * m68k.md (5200 movqi): Do not allow byte sized memory references - using address regs. - * m68k.c (output_move_qimode): Do not use byte sized operations on - address registers. +Thu May 20 08:15:00 1999 Bruce Korb -Fri Oct 23 00:56:11 1998 Jason Merrill + * fixinc/fixincl.c(main): we must not ignore SIGCLD now. - * expr.c (pending_chain): Move up. - (save_expr_status): Do save pending_chain. - (restore_expr_status): And restore it. - * function.h (struct function): Add pending_chain. +Thu May 20 07:06:39 1999 Alexandre Oliva -Mon Oct 19 13:22:13 1998 Geoff Keating + * fixinc/Makefile.in(gnu-regex.o): add $(INCLUDES) to compile options + * fixinc/fixincl.c(wait_for_pid): K&R-ify arguments + (several places): omit static initialization + (process): use single fd, since only the read fd is used + * fixinc/gnu-regex.c: define 'const' away, if not supported + * fixinc/procopen.c(several places): omit static initialization + * fixinc/server.c: define 'volitile' away, if not supported - * loop.c (scan_loop): Be more selective about what invariants are - moved out of a loop. +1999-05-20 Andreas Schwab -Wed Oct 14 23:27:08 1998 Didier FORT (didier.fort@fedex.com) + * config/dbxcoff.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Use + asm_fprintf and %L to generate the label name. + * config/dbxelf.h (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Likewise. + (ASM_OUTPUT_SOURCE_LINE): Correct generation of internal labels. - * fixincludes: Fix up rpc/{clnt,svr,xdr}.h for SunOS. +Thu May 20 01:40:55 1999 Jeffrey A Law (law@cygnus.com) -Wed Oct 14 22:13:28 1998 Joel Sherrill (joel@OARcorp.com) + * jump.c (can_reverse_comparison_p): Do not abort if the comparison + insn for a conditional jump can not be found. - * Makefile.in (stmp-fixinc): Do not install assert.h if not desired. - * config/t-rtems: Do not install assert.h -- use newlib's. +Wed May 19 23:58:58 1999 Jeffrey A Law (law@cygnus.com) -Sat Oct 3 19:01:03 1998 Richard Henderson + * mips.h (ENCODE_SECTION_INFO): Do not perform GP optimizations + on variables in specific sections other than .sbss and .sdata. - * alpha/linux.h (CPP_PREDEFINES): Define __alpha__ for imake. +Tue May 18 11:20:48 1999 Mark Mitchell -Fri Oct 2 01:33:30 1998 Jim Wilson + * stmt.c (expand_return): Call start_cleanup_deferral and + end_cleanup_deferral around conditional code. - * i386/winnt.c (i386_pe_asm_file_end): Check - TREE_SYMBOL_REFERENCED. +Wed May 19 03:10:08 1999 Bruce Korb -Fri Oct 2 01:31:54 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/fixincl.tpl: Avoid depending on ANSI C features for + filename lists. Utilizes new AutoGen function "krstr". + * fixinc/fixincl.x: Rebuilt. - * regclass.c (reg_scan_mark_refs): Return immediately if passed a - NULL_RTX as an argument. +Wed May 19 02:47:11 1999 Jan Hubicka (hubicka@freesoft.cz) - * gcc.texi: Fix version # that somehow slipped through. + * i386.c (output_float_compare): Avoid GNU-C extensions. -Fri Oct 2 01:24:19 1998 Geoff Keating +Wed May 19 00:50:24 1999 Jeffrey A Law (law@cygnus.com) - * gcse.c: New definition NEVER_SET for reg_first_set, reg_last_set, - mem_first_set, mem_last_set; because 0 can be a CUID. - (oprs_unchanged_p): Use new definition. - (record_last_reg_set_info): Likewise. - (record_last_mem_set_info): Likewise. - (compute_hash_table): Likewise. + * version.c: Bump version to gcc-2.95 prerelease. -Fri Oct 2 01:20:04 1998 Richard Earnshaw (rearnsha@arm.com) +Tue May 18 03:53:37 1999 Craig Burley - * arm.c (add_constant): New parameter address_only, change caller. - Set it non-zero if taking the address of an item in the pool. - (arm_reorg): Handle cases where we need the address of an item in - the pool. + Improve open-coding of complex divide: + * flags.h: Declare new front-end-malleable flag. + * toplev.c: Define new flag. + * optabs.c (expand_cmplxdiv_straight): New function to do original + open-coding. + (expand_cmplxdiv_wide): New function to do new open-coding, + from Toon Moene, with changes (call to emit_barrier, dropping + of spurious `ok = 1;', plus the obvious `break;' -> `return 0;'). + (expand_binop): A bit of spacing fixing, while at it. + Use new functions instead of inlining the open-coding code. - * arm.c (bad_signed_byte_operand): Check both arms of a sum in - a memory address. - * arm.md (splits for *extendqihi_insn and *extendqisi_insn): Handle - memory addresses that are not in standard canonical form. +Tue May 18 00:51:46 1999 Krister Walfridsson -Fri Oct 2 01:16:02 1998 Jeffrey A Law (law@cygnus.com) + * configure.in (arm*-*-netbsd*): Use collect2. + (i[34567]86-*-netbsd*): Likewise. + (m68k*-*-netbsd*): Likewise. + (ns32k-*-netbsd*): Likewise. + (sparc-*-netbsd*): Likewise. + (vax-*-netbsd*): Likewise. + * configure: Rebuilt. - * reg-stack.c (straighten_stack): Do nothing if the virtual stack is - empty or has a single entry. +Tue May 18 00:21:34 1999 Zack Weinberg -Sat Sep 5 23:29:39 1998 Mumit Khan + * cppspec.c: Insert -no-gcc into command line unless -gcc was + given by user. + * gcc.c (default_compilers): Define __GNUC__ and + __GNUC_MINOR__ only if -no-gcc was not given. + * objc/lang-specs.h: Likewise. + * cpp.texi: Document -x and -std options; explain that -lang + is no longer supported. Minor related corrections. - * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't check for - for exact section attributions. +Mon May 17 23:56:39 1999 Alexandre Oliva - * i386/mingw32.h (CPP_PREDEFINES): Add __MSVCRT__ for msvc - runtime. - * i386/crtdll.h (CPP_PREDEFINES): Define. + * Makefile.in (stmp-fixproto): Pass location of mkinstalldirs to + fixproto. + * fixproto: Avoid unportable constructs such as `basename' and + `mkdir -p'. Use mkinstalldirs from the environment if `mkdir -p' + fails. -Sat Sep 5 21:46:47 1998 Richard Henderson + * fixinc/fixincl.c: Remove #error, it is not portable. - * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, - not whatever we're generating now. +Mon May 17 23:50:41 1999 Marc Espie -Sat Sep 5 14:23:31 1998 Torbjorn Granlund + * collect2.c (main): Fix typo in COLLECT2_HOST_INITIALIZATION. - * m68k.md (zero_extendsidi2): Fix typo. +Mon May 17 19:45:41 1999 Rainer Orth -Tue Sep 1 01:58:38 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/fixincl.c (process): Wait for children from chain_open() + to avoid creating zombies. - * egcs-1.1 released. - * version.c: Update for egcs-1.1 release. + * fixinc/inclhack.tpl: Removed no-op pipe. -Mon Aug 31 14:55:02 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/inclhack.sh fixinc/fixincl.sh: regenerate - * NEWS: Add SCO Openserver and Unixware 7 notes. +Mon May 17 07:23:34 1999 Mark Mitchell - * NEWS: Fix typos. + * tree.def (TYPE_NONCOPIED_PARTS): Revise documentation to match + reality. + * expr.c (init_noncopied_parts): Don't generate initializers for + parts that don't need them. -Sat Aug 29 14:52:28 1998 David S. Miller +Mon May 17 02:56:35 PDT 1999 Jeff Law (law@cygnus.com) - * config/sparc/sparc.md (movdf_insn, movtf_insn): Fix type and - length attributes to match May 3rd changes made here. - * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Fix and make - call-used %l7 when generating pic code. + * version.c: Bump for snapshot. -Sat Aug 29 14:59:32 1998 Mumit Khan +Sat Oct 31 05:08:34 CET 1998 Jan Hubicka (hubicka@freesoft.cz) - * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't emit - .linkonce directive after the first time. + * reg-stack.c: Do not emit pop insns after cc0 setter. + (emit_pop_insn): Do not emit insn in case WHEN is NULL. + (compare_for_stack_reg): Update REG_DEAD note and + do not emit push insn. -Sat Aug 29 14:48:12 1998 Jeffrey A Law (law@cygnus.com) + * i386.c: (output_float_compare): Handle new REG_DEAD notes. - * m68k.md (beq0_di): Generate correct (and more efficient) code when - the clobbered operand overlaps with an input. - (bne0_di): Similarly. +Mon May 17 01:57:37 1999 David Daney -Sat Aug 29 12:38:54 1998 Jeffrey A Law (law@cygnus.com) + * i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker + if -mimpure-text. - * NEWS: Various updates. +1999-05-17 Andreas Schwab -Tue Aug 25 19:35:24 1998 Jim Wilson + * m68k.c (standard_68881_constant_p): Don't accept -0.0 as valid + 68881 constant. - * configure.in (powerpc-ibm-aix4.[12]*): Change from 4.[12].*. - (rs6000-ibm-aix4.[12]*): Likewise. - * configure: Regnerate. + * fold-const.c (fold_truthop): When converting a one-bit + comparison don't sign extend the constant. -Thu Aug 27 23:44:49 1998 Jeffrey A Law (law@cygnus.com) + * cse.c (cse_insn): Copy SRC_CONST before putting it in the + REG_EQUAL note. - * reload1.c (forget_old_reloads_1): Keep track of the largest mode - found while stripping SUBREGS and invalidate reloads for all the hard - regs specified by that largest mode. egcs-1.1 only hack. The - mainline tree will get a better fix. +1999-05-17 Mike Stump -Tue Aug 25 19:43:11 1998 Jeffrey A Law (law@cygnus.com) + * rs6000/vxppc.h (CPP_SPEC): Fix support for vararg functions. - * From Alexandre: - * configure.in: Do not set thread_file to "irix" since no such - support exists yet. +Sat May 15 14:22:40 1999 Jeffrey A Law (law@cygnus.com) - * reorg.c (fill_simple_delay_slots): Do not abort if we encounter - an insn on the unfilled_slots_list that has no delay slots. - (fill_eager_delay_slots): Similarly. + * fixinc/hackshell.tpl: Fix mis-applied patch. + * fixinc/inclhack.sh: Regenerated. -Mon Aug 24 15:20:19 1998 David Edelsohn +Thu May 13 21:05:55 1999 Mark Kettenis - * rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Use TARGET_POWERPC64 - when testing LEGITIMATE_INDEXED_ADDRESS_P DFmode and DImode. - (LEGITIMIZE_ADDRESS): Use TARGET_POWERPC64 for INDEXED fixup. - * rs6000.c (print_operand, case 'L'): Add UNITS_PER_WORD, not 4. - (print_operand, cases 'O' and 'T'): Fix typos in lossage strings. - * rs6000.md (fix_truncdfsi2_store): Remove %w from non-CONST_INT - operand. - (movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64): Change - 'o' to 'm' for GPR variant constraints. + * fixinc/mkfixinc.sh: Add the Hurd (*-*-gnu*) to the list of + targets that do not need any fixes. - * rs6000.md (movqi, movhi): Add CONSTANT_P_RTX. +Sat May 15 14:12:38 1999 Michael Hayes -Mon Aug 24 01:21:38 PDT 1998 Jeff Law (law@cygnus.com) + * config/c4x/c4x.md (set_lo_sum+2): New splitter to load large + const_ints. - * version.c: Bump for snapshot. +Sat May 15 14:09:08 1999 Michael Hayes -Sun Aug 23 00:47:52 1998 Jeffrey A Law (law@cygnus.com) + * config/c4x/c4x.md (decrement_and_branch_on_count): Disabled. + (doloop_begin, doloop_end): New patterns. + (*rptb_init): Added extra operands. - * regmove.c (optimize_reg_copy_3): Disable for egcs-1.1. +Fri May 14 21:31:36 1999 Michael Hayes -Thu Aug 20 13:56:53 1998 Michael Meissner + * config/c4x/c4x.md (*umulqi3_highpart_clobber): Fix operand 2 + constraints order. - * config/i386/winnt.c: Include system.h, not stdio.h to get - sys/param.h pulled in before rtl.h in case the system defines MIN - and MAX. +1999-05-14 Ulrich Drepper -Wed Aug 19 21:33:19 1998 David Edelsohn + * fixinc/fixinc.x86-linux-gnu (FD_ZERO): Fix operand numbers in + asm input operands. - * rs6000.c (rs6000_output_load_toc_table): Use ld for 64-bit. - (output_toc): Use single TOC slot or llong minimal-toc for DFmode - and DImode 64-bit. Use llong for minimal-toc SFmode and - SYMBOL_REF / LABEL_REF 64-bit. - (output_function_profiler): Use llong for profiler label and ld to - load 64-bit label address. +Thu May 13 15:34:18 1999 David Edelsohn -Tue Aug 18 23:48:30 1998 Richard Henderson + * rs6000.c (mask_constant): Delete. + (mask_operand): Move mask_constant() body to here. + * rs6000.h (mask_constant): Delete declaration. + * rs6000.md (nabsdi2): Reverse subtraction in splitter. - * c-common.c (decl_attributes): Issue an error if the argument - to alias is not a string. +Thu May 13 02:25:01 1999 Jeffrey A Law (law@cygnus.com) -Tue Aug 18 13:05:59 BST 1998 Richard Earnshaw (rearnsha@arm.com) + * cpp.texi: Fix some typos. - * arm.c (arm_override_options): Remove lie about ignoring PIC flag. +Thu May 13 01:49:55 1999 Graham Stott -Tue Aug 18 10:32:11 1998 Jeffrey A Law (law@cygnus.com) + * loop.c (maybe_eliminate_biv): Check regno against + max_reg_before_loop. - * haifa-sched.c (sched_analyze): Put all JUMP_INSNs on the last - pending memory flush list. + * i386.c (memory_address_info): Correct the scale + factor test. - * regmove.c (fixup_match_2): Do not call reg_overlap_mentioned_p - on notes. +Thu May 13 01:31:19 1999 Nick Burrett - * regmove.c (optimize_reg_copy_1): Update REG_N_CALLS_CROSSED - and REG_LIVE_LENGTH as successful substitutions are made. + * arm.md (nop): Backout Apr 27 change. Ensure REGISTER_PREFIX is + applied to each register. + * aof.h (ASM_FILE_START): Define register `r0'. -Mon Aug 17 21:07:19 1998 Jeffrey A Law (law@cygnus.com) +1999-05-12 20:22 -0400 Zack Weinberg - * From Graham - * tree.c (build_index_type): Copy TYPE_SIZE_UNIT from sizetype - to itype. - * c-decl.c (finish_enum): Copy TYPE_SIZ_UNIT from enumtype to tem. + * configure.in: Make --enable-cpp and --with-cpp-install-dir + documented options. Enable the cpp driver by default. + * configure: Rebuilt. - * rs6000.c (secondary_reload_class): For TARGET_ELF, indicate that - a BASE_REGS register is needed as an intermediate when copying - a symbolic value into any register class other than BASE_REGS. +Wed May 12 18:08:48 1999 David Edelsohn + Richard Henderson -Mon Aug 17 11:25:52 1998 Richard Earnshaw + * rs6000.c (print_operand) [w]: Calculate signed constant more clearly. + (rs6000_allocate_stack_space): Print as hexadecimal value. + * rs6000.h (CONST_OK_FOR_LETTER_P): 'L' checks for a signed, + 16-bit shifted constant. Fix typo for 'P'. + (EXTRA_CONSTARINT): 'T' checks for a 32-bit mask operand. + * rs6000.md (movsi, addsi3_internal1, movdi, adddi3_internal1): + Use 'L' for shifted constant. + (anddi3_internal3): Fix typo. + (32-bit mask patterns): Use 'T'. - * arm.h (SECONDARY_INPUT_RELOAD_CLASS): Return NO_REGS if compiling - for architecture v4. +Wed May 12 07:30:31 1999 Bruce Korb -Sun Aug 16 00:57:48 PDT 1998 Jeff Law (law@cygnus.com) + * fixinc/fixincl.c(quoted_file_exists): new procedure to ensure that + a file exists before trying to copy it into the destination + (extract_quoted_files): use that routine. - * version.c: Bump for snapshot. +Wed May 12 07:27:31 1999 Craig Burley -Sun Aug 16 01:53:21 1998 Richard Henderson + Allow front end (like g77's) to override maintenance of errno: + * expr.c (expand_builtin): Bother with errno only if + flag_errno_math. + * flags.h: Declare flag_errno_math. + * toplev.c: Define flag_errno_math. - * reload.c (find_equiv_reg): Reject equivalences separated - by a volatile instruction. +Tue May 11 23:55:49 1999 Jeffrey A Law (law@cygnus.com) -Sun Aug 16 00:21:44 1998 Franz Sirl + * fixproto: Change "mkdir" calls to "mkdir -p" - * rs6000/linux.h (CPP_OS_DEFAULT_SPEC): Define. + * fixinc/inclhack.def (io_def_quotes): Consistently allow multiple + whitespace characters between the "define" and the name of the macro. + * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. -Sat Aug 15 20:22:33 1998 H.J. Lu (hjl@gnu.org) +Tue May 11 20:46:37 1999 Richard Henderson - * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Handle aggregated - return type. - * config/alpha/win-nt.h (ASM_OUTPUT_MI_THUNK): Likewise. + * alpha.c (alpha_expand_block_move): Handle TImode registers + used with ADDRESSOF. + (alpha_expand_block_clear): Handle ADDRESSOF specially. -Fri Aug 14 21:07:03 1998 Jeffrey A Law (law@cygnus.com) +1999-05-11 Ulrich Drepper - From Joern: - * expr.c (store_expr): Don't optimize away load-store pair - when either source or destination have a side effect. + * fixinc/fixinc.x86-linux-gnu (FD_ZERO): Remove unneccessary + memory output operand which irritates gcc. - * loop.c (add_label_notes): Do not ignore references to labels - before dispatch tables. Mirrors Apr 8 change to mark_jump_label. - * gcse.c (add_label_notes): Similarly. +Tue May 11 11:45:16 1999 Dave Brolley - * pa.h (ASM_OUTPUT_MI_THUNK): Strip name encoding. + * toplev.c (documented_lang_options): Add -MD, -MMD, -M and -MM for + cpplib-enabled compilers. - * m68k.md (adddi_dilshr32): One of the operands must be a register. - (adddi_dishl32): Similarly. +Tue May 11 11:34:56 1999 Vladimir Makarov -Fri Aug 14 01:45:06 1998 Mumit Khan + * config/sparc/sparc.h (GO_IF_LEGITIMATE_ADDRESS): Add parentheses + around &&. - * i386/cygwin32.h (DEFAULT_PCC_STRUCT_RETURN): Define. +Mon May 10 13:51:24 1999 Nick Clifton -Fri Aug 14 01:40:21 1998 Geoffrey Keating + * tm.texi (FUNCTION_ARG): Stack element of PARALLEL must come + first. - * rs6000/linux.h (LINK_SPEC): Pass -G args to the linker. +Tue May 11 01:32:01 1999 Jeffrey A Law (law@cygnus.com) -Fri Aug 14 01:23:23 1998 Richard Earnshaw (rearnsha@arm.com) + * fixinc/inclhack.def (sun_auth_proto): Apply to all targets. + (sysz_stdlib_for_sun): Similarly. + * fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. - * arm/netbsd.h (TARGET_DEFAULT): Default includes software floating - point. - (CPP_FLOAT_DEFAULT_SPEC): Re-define accordingly. +Mon May 10 20:34:10 1999 Jim Wilson -Fri Aug 14 01:23:23 1998 Jeffrey A Law (law@cygnus.com) + * config/mips/elf.h (UNIQUE_SECTION_P): Undef. + * config/mips/elf64.h (UNIQUE_SECTION_P): Undef. + * config/mips/mips.h (UNIQUE_SECTION_P): Define to 0. - * README.RS6000: Bring over dje's changes from the mainline - source tree. +1999-05-10 18:21 -0400 Zack Weinberg -Fri Aug 14 01:19:08 1998 Robert Lipe + * cppfiles.c (initialize_input_buffer): New function. + (finclude): Call it, if pfile->input_buffer is NULL. Accept + any character device as an input file. + (read_and_prescan): Use pfile->input_buffer and + pfile->input_speccase. + * cppinit.c (cpp_cleanup): Free pfile->input_buffer and + pfile->input_speccase. + * cpplib.h (cpp_reader): Add input_buffer, input_speccase, and + input_buffer_len members. Use memcpy in CPP_PUTS_Q. - * install.texi: Various SCO OpenServer tweaks. + * cppmain.c: Buffer output in the token_buffer; throttle + number of calls to fwrite; check for errors from fwrite. -Thu Aug 13 19:55:05 1998 Jim Wilson +1999-05-10 18:21 -0400 Zack Weinberg - * reload1.c (eliminate_regs_in_insn): Handle another case when - eliminating the frame pointer to the hard frame pointer. Add - missing ep->to_rtx check to one existing case. + * cppspec.c: Treat two non-option arguments as input and + output file. Three or more non-option args is an error. + Clean up. + * gcc.c (default_compilers): Pass -$ to the preprocessor. + * objc/lang-specs.h: Likewise. -Tue Aug 11 17:45:39 1998 Dave Love +Mon May 10 12:59:20 1999 Jeffrey A Law (law@cygnus.com) - * README.g77: Update from Craig. + * optabs.c (emit_cmp_and_jump_insns): Handle the case where both + operands to the comparison are constants. -Sat Aug 8 19:20:22 1998 Gary Thomas (gdt@linuxppc.org) +Mon May 10 07:28:10 1999 Bruce Korb - * rs6000.c (rs6000_allocate_stack_space) Fix typo which - caused bad assembly code to be generated. + * fixinc/inclhack.def(arm_norcroft_hint): check before fixing + (no_double_slash): portability + (math_exception): added reminder comment -Sat Aug 8 18:52:51 1998 Jeffrey A Law (law@cygnus.com) +Mon May 10 01:28:10 1999 Craig Burley - * netbsd.h: Fix typo. + From Fri May 7 9:31:41 1999 Donn Terry (donn@interix.com): + * varasm.c (mark_constant_pool): Add some transitive closure. -Mon Aug 3 23:43:55 PDT 1998 Jeff Law (law@cygnus.com) +Sun May 9 22:51:04 1999 Craig Burley - * version.c: Bump for snapshot. + Fix gcc.dg/990506-0.c: + * c-typeck.c (require_complete_type): Handle ERROR_MARK input. -Sun Aug 2 00:42:50 1998 Jeffrey A Law (law@cygnus.com) +Sun May 9 13:19:12 1999 Jeffrey A Law (law@cygnus.com) - * i386/netbsd.h: Undo previous change to DWARF2_UNWIND_INFO. - * m68k/netbsd.h: Likewise. - * ns32k/netbsd.h: Likewise. - * sparc/netbsd.h: Likewise. + * gcse.c (cprop_insn): Do not try to simplify a simple jump. + +Sun May 9 11:12:19 1999 Philip Blundell -Fri Jul 31 17:08:59 1998 Jeffrey A Law (law@cygnus.com) + * config/arm/arm.h (ASM_OUTPUT_MI_THUNK): Add (PLT) to branch if + necessary. Reported by jim@federated.com. - * configure.in (mingw configuration): Fix typo. - * configure: Rebuilt. +Sat May 8 23:05:35 1999 Jeffrey A Law (law@cygnus.com) -Fri Jul 31 20:22:02 1998 Michael Meissner + * pa.h (PRINT_OPERAND_ADDRESS): Output "%r0", not "r0" for the + base register in an absolute memory address. + * pa.md (conditional moves): Avoid using immediate zero for + register zero. - * rs6000.c (rs6000_override_options): If big endian and -Os, use - load/store multiple instructions unless user overrides. +Sat May 8 06:23:21 1999 Philip Blundell -Fri Jul 31 17:08:59 1998 Jeffrey A Law (law@cygnus.com) + Based on patch by Scott Bambrough: + * config/arm/arm.h (NEED_PLT_GOT): New macro. Set to 0 if not + already defined. + * config/arm/elf.h (NEED_PLT_GOT): Define to flag_pic. + * config/arm/arm.md (call_symbol, call_value_symbol et al.): If + NEED_PLT_GOT is true, add explicit "(PLT)" to generated branches. + * config/arm/arm.c (output_func_epilogue, + output_return_instruction): Likewise for calls to abort. - * ns32k/netbsd.h: Fix typo. +Sat May 8 01:57:58 1999 Donn Terry (donn@interix.com) -Thu Jul 30 19:50:15 1998 David Edelsohn + * calls.c (rtx_for_function_call): Extend function pointer being + passed to chkr_check_exec_libfunc, if needed. - * rs6000/x-aix43 (AR_FOR_TARGET_FLAGS): Delete. - (AR_FOR_TARGET): Define. +Sat May 8 01:51:50 1999 David Edelsohn -Thu Jul 30 19:11:30 1998 Richard Henderson + * ginclude/stdarg.h (__va_rounded_size): Use long type for + rounding on AIX. + * ginclude/varargs.h: Likewise. - * alpha.md (fp cmp): Replicate patterns for ALPHA_TP_INSN. - (fcmov): Remove ALPHA_TP_INSN patterns -- fcmov doesn't trap. +Sat May 8 01:47:20 1999 Andreas Schwab -Thu Jul 30 12:51:09 1998 Mark Mitchell + * invoke.texi: Remove duplicates in the description of -d + letters. Fix use of @item vs. @itemx. - * dyn-string.h: New file. - * dyn-string.c: Likewise. - * Makefile.in (OBJS): Add dyn-string.o. - (dwarf2out.o): Add dyn-string.h dependency. - (dyn-string.o): List dependencies. - * dwarf2out.c: Include dyn-string.h. - (ASM_NAME_TO_STRING): Use dyn_string_append, rather than strcpy. - (addr_const_to_string): Take a dyn_string_t, not a char* as a - prototype. Use dyn_string_append rather than strcat, throughout. - (addr_to_string): Use dyn_string_t. +Sat May 8 01:43:02 1999 Franz Sirl -Thu Jul 30 00:58:34 1998 Jeffrey A Law (law@cygnus.com) + * rs6000.h (RS6000_VARARGS_OFFSET): Die die die. + (CUMULATIVE_ARGS): Remove varargs_offset; update commentary. + * rs6000.c (setup_incoming_varargs): Fix typo last change. + (init_cumulative_args): Remove varargs_offset references. - * i386.md (movqi): When optimizing a load of (const_int 1) into a - NON_QI_REG_P, pretend the register is SImode. + * rs6000/linux.h (NO_IMPLICIT_EXTERN_C): Define. + (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Undefine. -Wed Jul 29 23:49:23 1998 Todd Vierling +Sat May 8 01:34:19 1999 Andreas Schwab - * configure.in: Use xm-netbsd.h as the NetBSD xm file (not xm-siglist). - Accept arm32 as arm, m68k4k as m68k, mipsle as mips-dec, and any - manufacturer id for ns32k. - * configure: Regenerated. - * config/netbsd.h: When using ASM_WEAKEN_LABEL, make it global too. - * config/t-netbsd: Don't compile libgcc1-test as the fns are in libc. - * config/i386/netbsd.h: Undefine DWARF2_UNWIND_INFO, not define as 0. - * config/m68k/netbsd.h: Same. - * config/ns32k/netbsd.h: Same. - * config/sparc/netbsd.h: Same. + * reload1.c (gen_mode_int): New function. + (reload_cse_move2add): Use it to generate the new constants. -Wed Jul 29 22:39:21 1998 Jeffrey A Law (law@cygnus.com) +Sat May 8 01:25:09 1999 Andreas Schwab - * unroll.c (unroll_loop): Do not abort for an UNROLL_MODULO - or UNROLL_COMPLETELY loop that starts with a jump to its - exit code. + * varasm.c (output_constant): Do nothing if -fsyntax-only. -Wed Jul 29 22:18:14 1998 David Edelsohn +Fri May 7 19:10:15 1999 Vladimir Makarov - * rs6000/rs6000.md (absdi2 define_split): Swap operands of MINUS. - * rs6000/rs6000.c (mask64_operand): Use HOST_BITS_PER_WIDE_INT. - (print_operand, case 'B'): Don't fall through. - (print_operand, case 'S'): Correct mask begin/end computation. - Use HOST_BITS_PER_WIDE_INT. - * rs6000/rs6000.h (CPP_PREDEFINES): Define _LONG_LONG. - (CONDITIONAL_REGISTER_USAGE): GPR13 fixed if TARGET_64BIT. - * rs6000/aix41.h (CPP_PREDEFINES): Same. - * rs6000/aix43.h (CPP_PREDEFINES): Same. + * sparc.h (GO_IF_LEGITIMATE_ADDRESS): Prohibit REG+REG addressing + for TFmode when there are no instructions which accept REG+REG + instructions. -Tue Jul 28 23:29:04 1998 Jason Merrill +Fri May 7 12:38:54 1999 Jim Wilson - * configure.in: Fix --without/--disable cases for local-prefix, - gxx-include-dir and checking. + * mips/elf64.h (MAKE_DECL_ONE_ONLY, UNIQUE_SECTION_P): Define. + * mips/mips.c (mips_select_rtx_section): When TARGET_MIPS16, use + function_section instead of text_section. + * mips/mips.h (ENCODE_SECTION_INFO): Add check for UNIQUE_SECTION_P + in TARGET_MIPS16 STRING_CST handling. -Tue Jul 28 22:10:43 1998 David S. Miller +Fri May 7 09:54:11 1999 Nick Clifton - * configure.in (enable_haifa): Set by default for sparc64 too. - configure: Rebuilt. + Patch from: Nick Burrett -Tue Jul 28 23:29:04 1998 Jason Merrill + * arm.c (arm_poke_function_name): New function to implement + -mpoke-function-name. + * aof.h (ASM_DECLARE_FUNCTION_NAME): Call it. + * aout.h (ASM_DECLARE_FUNCTION_NAME): Likewise. + * elf.h (ASM_DECLARE_FUNCTION_NAME): Likewise. + * arm.h: Prototype it. + (TARGET_SWITCHES): Add `no-poke-function-name'. - * i386/cygwin32.h (VALID_MACHINE_TYPE_ATTRIBUTE): New macro. - * i386/winnt.c (associated_type): New fn. - (i386_pe_valid_type_attribute_p): New fn. - (i386_pe_check_vtable_importexport): Remove. - (i386_pe_dllexport_p): Use associated_type. - (i386_pe_dllimport_p): Likewise. +Fri May 7 14:19:31 1999 Rainer Orth - From Antonio M. O. Neto : - * i386.c (i386_valid_type_attribute_p): Also accept - attributes for METHOD_TYPEs. + * fixinc/server.c (load_data): Cast text_size to long, adapt + format. + * fixinc/server.c (read_pipe_timeout): Declare volatile, modified + in signal handler. + (sig_handler): Add debug code. + * fixinc/server.c (run_shell): Don't \-escape cd, it breaks the + Ultrix V4.3 /bin/sh. + * fixinc/server.c (def_args): Use static instead of STATIC to + avoid redefinition error from linker iff DEBUG. -Tue Jul 28 23:17:39 1998 Peter Gerwinski + * fixinc/hackshell.tpl: Don't strip trailing directory from + DESTDIR - that is already done - * tree.c (build_range_type): Copy TYPE_SIZE_UNIT. + * fixinc/fixincl.c (run_compiles): fix memory leak -Tue Jul 28 22:31:12 1998 Craig Burley +Thu May 6 20:34:00 1999 Mark Mitchell - * gcc.c: Fix commentary describing %g, %u, %U, and %O. + * resource.c (mark_referenced_resources): Make volatil + monotonically increasing. + (mark_set_resources): Likewise. - * gcc.c (do_spec_1): Fix handling of %g%O and %U%O to prevent - them from generating a new base name for each occurence of - a specific suffix. +Thu May 6 20:02:33 1999 Fred Fish -1998-07-28 Vladimir N. Makarov + * rs6000/xm-beos.h (HAVE_VPRINTF): Don't redefine if already defined. + (HAVE_PUTENV, HAVE_ATEXIT, HAVE_RENAME): Likewise. - * cse.c (cse_insn): Enable subsitution inside libcall only for REG, - SUBREG, MEM. - * rtlanal.c (replace_rtx): Prohibit replaces in CONST_DOUBLE. +Wed May 5 20:28:32 1999 Jason Merrill -Mon Jul 27 00:54:41 1998 Jason Merrill + * install.texi (Header Dirs): s/GPLUS/GPLUSPLUS/. - * tree.c (simple_cst_equal, case CONSTRUCTOR): OK if the elts are - identical. +Wed May 5 23:44:15 1999 J"orn Rennecke -Mon Jul 27 22:20:02 1998 Jeffrey A Law (law@cygnus.com) + * unroll.c (copy_loop_body): Don't copy VTOP notes from copy_notes_from. - * pa.c (move_operand): Accept CONSTANT_P_RTX. +Wed May 5 16:26:13 1999 Vladimir Makarov -Mon Jul 27 00:46:56 PDT 1998 Jeff Law (law@cygnus.com) + * function.c (purge_addressof_replacements): Rename into + purge_bitfield_addressof_replacements. + (purge_addressof_replacements): New variable. + (purge_addressof_1): Add code for changing addressof in notes for + field values which are extracted by usage MEM with narrower mode. + (purge_addressof): Initialize purge_bitfield_addressof_replacements. - * version.c: Bump for snapshot. +Wed May 5 07:40:02 1999 Nick Clifton -Sun Jul 26 01:11:12 1998 H.J. Lu (hjl@gnu.org) + Patch from: Nick Burrett + * config/arm/arm.h (ARM_MCOUNT_NAME): Define. + (FUNCTION_PROFILER): Remove assembler dialect dependency and use + ARM_MCOUNT_NAME. + (TRAMPOLINE_TEMPLATE): Remove assembler dialect dependency. - * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Return 0 when eliminating - the frame pointer and compiling PIC code and reload has not completed. + * config/arm/aof.h (ARM_MCOUNT_NAME): Define. - * i386.c (output_to_reg): Add code to emulate non-popping DImode - case. +1999-05-05 09:58 -0400 Zack Weinberg -Sun Jul 26 01:02:54 1998 Jeffrey A Law (law@cygnus.com) + * gcc.c (default_compilers): Fix brace nesting bug. + * objc/lang-specs.h: Use %i, not %g.mi, for the input file + when processing an .mi file. - * regmove.c (regmove_optimize): Fix typo initializing regmove_bb_head. +Tue May 4 13:17:55 1999 Mark Mitchell -Sat Jul 25 23:29:23 1998 Gerald Pfeifer + * resource.c (mark_set_resources): Handle UNSPEC_VOLATILE, + ASM_INPUT, TRAP_IF, and ASM_OPERANDS just like in + mark_referenced_resources. - * Makefile.in (install-info): Only try to update the info - directory file if it exists in the first place. +Mon May 3 22:38:41 1999 David Edelsohn -Fri Jul 24 18:58:37 1998 Klaus Espenlaub + * rs6000/aix43.h (SUBTARGET_OVERRIDE_OPTIONS): Change non-PowerPC + and AIX64 combination to warning. Add warning for disabling + PowerPC64 support when using 64-bit mode. + (LIB_SPEC): Do not link with libg.a in 64-bit mode. + (LINK_SPEC): Do not export libg.exp symbols in 64-bit mode. + * rs6000/rs6000.h (MY_ISCOFF): Treat import/export files as valid + XCOFF files. + (read_only_data_section, private_data_section, + read_only_private_data_section): Always align CSECTs to doubleword + boundary regardless of mode. + (TEXT_SECTION_ASM_OP): Align text CSECT on doubleword boundary in + 64-bit mode. + (DATA_SECTION_ASM_OP): Always align CSECT to doubleword boundary. + (ASM_OUTPUT_LOCAL): Use rounded size in 64-bit mode to + maintain doublword alignment. - * rs6000.h (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Delete. +Mon May 3 14:45:23 1999 Jeffrey A Law (law@cygnus.com) -Thu Jul 23 18:53:20 1998 Jim Wilson + * mn10200.md (btst insns): btst does not leave cc0 in a useable + state for redundant tst eliminatino. + * mn10300.md (btst insns): Likewise. - * dbxout.c (dbxout_range_type): Only call dbxout_type_index for - already defined type. +Mon May 3 16:14:32 1999 Kaveh R. Ghazi -Wed Jul 22 14:08:54 1998 David S. Miller + * mips.h (Pmode): Revert Oct 14th change which added a cast. - * profile.c (branch_prob): Call allocate_reg_info after outputting - profile rtl in instrument_arcs. +Sun May 2 14:02:21 1999 Mark Mitchell -Tue Jul 21 22:40:09 PDT 1998 Jeff Law (law@cygnus.com) + * tree.h (struct tree_decl): Add comdat_flag. + (DECL_COMDAT): Define it. + * toplev.c (wrapup_global_declarations): Don't output a + DECL_COMDAT function just because it's public. - * version.c: Bump for snapshot. +Sun May 2 15:16:42 1999 Joseph S. Myers -Tue Jul 21 23:28:35 1998 Klaus Kaempf + * pdp11.h (TARGET_SWITCHES): Fix error in previous change. + (ASSEMBLER_DIALECT): Define. + (CONDITIONAL_REGISTER_USAGE): Rename floating point registers if + required for the UNIX assembler. + (ASM_OUTPUT_INT): Remove. The compiler will synthesise it. + (ASM_OUTPUT_ADDR_VEC_PROLOGUE): Remove. + (ASM_OPEN_PAREN, ASM_CLOSE_PAREN): Change to "[" and "]". + (TRAMPOLINE_TEMPLATE): Use ASM_OUTPUT_SHORT. + * pdp11.c (output_addr_const_pdp11): Copy of output_addr_const + adapted to output constants in octal. + * pdp11.c, pdp11.h, pdp11.md: Use output_addr_const_pdp11 instead + of output_addr_const. Output constants in octal. Use assembler + dialect alternatives where DEC and UNIX assemblers use different + instruction names. - * cccp.c (do_include): Fix vax c style include handling. +Sun May 2 01:15:06 PDT 1999 Jeff Law (law@cygnus.com) -Tue Jul 21 15:49:31 1998 David Edelsohn + * version.c: Bump for snapshot. - * rs6000.h (PREDICATE_CODES): Add CONSTANT_P_RTX. - * rs6000.md (movsi, movdi): Add CONSTANT_P_RTX. - * rs6000.c (short_cint_operand): Add CONSTANT_P_RTX. - (u_short_cint_operand): Same. - (reg_or_cint_operand): Same. - (logical_operand): Same. - (input_operand): Same. - (reg_or_short_operand): Use u_short_cint_operand. +Fri Apr 30 13:55:43 1999 Richard Henderson -Tue Jul 21 03:59:08 1998 David S. Miller + * va-ppc.h (__va_start_common): Let __builtin_saveregs do the work. + * rs6000.c (expand_builtin_saveregs): For V4, initialize a private + va_list struct, and return a pointer to it. + (setup_incoming_varargs): V4 save area based off virtual_stack_vars + instead of frame_pointer. - * jump.c (jump_optimize): When simplifying noop moves and - PUSH_ROUNDING, fix thinko so we use same criterion for identifying - the PUSHes to rewrite in second loop as we did in the first. +Thu Apr 29 23:02:22 1999 Mark Mitchell -Tue Jul 21 00:31:01 1998 Jeffrey A Law (law@cygnus.com) + * emit-rtl.c (start_sequence): Expand comments. + (start_sequence_for_rtl_expr): Likewise. + (push_to_sequence): Likewise. + (end_sequence): Likewise. + * expr.c (inhibit_defer_pop): Likewise. + * expr.h (inhibit_defer_pop): Likewise. + (NO_DEFER_POP): Likewise. + (OK_DEFER_POP): Likewise. - * gcc.c (do_spec): Call "error" not "warning". +Thu Apr 29 22:13:46 1999 Robert Lipe - * configure.in: Fix minor problems with gas feature detection code. - * configure: Rebuilt. + * configure.in (i?86-UnixWare7*-sysv): Set thread_file to 'posix' + --enable-threads[={yes,pthreads,posix}] is passed as a command + line parameter to configure. + * config/i386/sysv5.h (LIB_SPEC): Add support for '-pthread'. + (CPP_SPEC): Likewise. - * gcc.c (do_spec): Issue a warning for '%[]' usage. +Thu Apr 29 17:23:59 1999 Richard Henderson - * Undo this change. - * gcc.c: Delete %[spec] support. - (do_spec_1, case '('): Likewise. - (do_spec_1, case '['): Call error. + * emit-rtl.c (operand_subword): Religiously mask and sign-extend + from 32-bits to HOST_WIDE_INT. -Mon Jul 20 22:34:17 1998 Richard Henderson +Thu Apr 29 15:58:52 1999 Robert Lipe - * alpha.h (CPP_SPEC): Tidy. Hook to cpp_cpu and cpp_subtarget. - (CPP_SUBTARGET_SPEC): Default to empty string. - (CPP_AM_*, CPP_IM_*, CPP_CPU_*, CPP_CPU_SPEC): New. - (EXTRA_SPECS, SUBTARGET_EXTRA_SPECS): New. - * alpha/elf.h (LD_SPEC): Use %(elf_dynamic_linker). - * alpha/linux-elf.h (SUBTARGET_EXTRA_SPECS): New. - (LIB_SPEC): Tidy. - * alpha/linux.h (CPP_PREDEFINES): Tidy. - * alpha/netbsd-elf.h (SUBTARGET_EXTRA_SPECS): New. - * alpha/netbsd.h (CPP_PREDEFINES): Tidy. - * alpha/osf.h (CPP_PREDEFINES): Remove bits subsumed by CPP_CPU_SPEC. - * alpha/win-nt.h (CPP_PREDEFINES): Likewise. - * alpha/vsf.h (CPP_PREDEFINES): Likewise. - (CPP_SUBTARGET_SPEC): New. Do this instead of overriding CPP_SPEC. - * alpha/vxworks.h: Likewise. + * fixinc/regex.c, fixinc/regex.h: Removed. Replace with... + * fixinc/gnu-regex.c, fixinc/gnu-regex.h: Imported from GDB 4.18. + * fixinc/Makefile.in (OBJ, HDR): Handle name changes from above. + (gnu-regex.o): Define REGEX_MALLOC to avoid memory leak. + * fixinc/fixincl.c: new regex.h header name + * Makefile.in: new regex.[ch] file names -Mon Jul 20 22:51:57 1998 Ken Raeburn +Thu Apr 29 12:53:33 1999 Richard Henderson - * mips.md (reload_outsi): Added missing REGNO call. - (smulsi3_highpart, umulsi3_highpart): Provide prototype for - function pointer. - (mul_acc_di, mul_acc_64bit_di): Don't use match_op_dup, use - another match_operator and compare the codes. + * calls.c (emit_call_1): Pass rounded_stack_size to emit_call + instead of the unrounded size. - * mips.h (MASK_DEBUG_E, MASK_DEBUG_I): Set to zero. +1999-04-28 14:40 Bruce Korb - * MIPS multiply pattern fixes: - * mips.h (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): - Add union classes for HI, LO, or HILO plus general registers. - (GENERATE_MADD): Deleted. - * mips.md (mulsi3_mult3): Don't disparage output-LO alternative. - Add TARGET_MAD to condition. - (mulsi3): Test HAVE_mulsi3_mult3, not specific flags. - (mul_acc_si): Expand GENERATE_MADD here; it's the only use. Use - "*d" for accumulator, to give preference to LO initially but not - during reload. + * fixinc/mkfixinc.sh: Makesure the result shell script is writable -Mon Jul 20 01:13:19 1998 Jim Wilson +Wed Apr 28 10:36:39 1999 Andreas Schwab - * function.c (fixup_var_refs_insns): Handle CLOBBER of a CONCAT. + * config/m68k/m68k.md (cmpsi+1): Use cmp.w when comparing a 16 bit + constant with an address register. -Sat Jul 18 15:20:19 1998 Mark Mitchell +Wed Apr 28 00:14:41 PDT 1999 Jeff Law (law@cygnus.com) - * loop.c (maybe_eliminate_biv_1): Avoid signed/unsigned comparison - confusion when setting cc0. + * version.c: Bump for snapshot. -Fri Jul 17 03:26:12 1998 Rihcard Earnshaw (rearnsha@arm.com) +Tue Apr 27 19:50:25 EDT 1999 Andrew MacLeod + + * rtl.h (REG_EH_REGION): Update comment to indicate a value of -1 + indicates no throw and no nonlocal gotos. + * optabs.c (emit_libcall_block): Emit REG_EH_REGION with a value + of -1 instead of 0 to indicate a nonlocal goto won't happen either. + * flow.c (count_basic_blocks, find_basic_blocks_1): Ignore libcall + blocks, look for REG_EH_REGION note exclusively. + (make_edges): Check for REG_EH_REGION > 0 for specified handlers. - * tree.c (valid_machine_attribute): Only create a new type variant if - there is a decl to use it. +Tue Apr 27 15:33:42 1999 David Edelsohn + + * rs6000.h (read_only_data_section, private_data_section, + read_only_private_data_section, toc_section): Align CSECT on + doubleword boundary for 64-bit target. + (DATA_SECTION_ASM_OP): Likewise. + * rs6000.c (rs6000_stack_info): Leaf procedure stack limit is 288. + +Tue Apr 27 20:19:47 1999 J"orn Rennecke + + * sh.md (insv): Use copy_addr_to_reg. + + * final.c (insn_lengths_max_uid): New variable. + (init_insn_lengths, shorten_branches): Set it. + (get_attr_lengths): Test insn uid against insn_lengths_max_uid. + +1999-04-27 08:32 -0400 Zack Weinberg + + * expr.c (emit_move_insn_1): Abort if MODE argument is invalid. + (compare): Punt if TREE_OPERAND (exp, 0) is an ERROR_MARK. + +Tue Apr 27 01:33:43 1999 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (ORDINARY_FLAGS_TO_PASS): Renmaed from FLAGS_TO_PASS. + Remove "CC". + (FLAGS_TO_PASS): New variable. + +Tue Apr 27 00:36:44 1999 Nick Burrett + + * arm.md (nop): Output instruction using output_asm_insn to fix + assembler dialect problems. -Fri Jul 17 02:01:00 1998 Jeffrey A Law (law@cygnus.com) +Mon Apr 26 23:55:50 1999 Robert Lipe - * Makefile.in (WARN_CFLAGS): Disable -W -Wall for the release - branch. + * Makefile.in (fixinc.sh): Fix dependencies. -Thu Jul 16 14:48:04 1998 Nick Clifton + * fixinc/inclhack.def (avoid_bool): Enable match if typedefs are + prepended by spaces. + (sco5_stat_wrappers): New fix. Make sys/stat.h C++ safe. + * fixinc/fixincl.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. - * gcc.c (do_spec_1): Cope with %g/%u/%U options which do not have - a suffix. +Mon Apr 26 23:28:54 1999 Mumit Khan + Donn Terry -Thu Jul 16 17:07:24 1998 Kaveh R. Ghazi + * function.c (put_var_into_stack): Change ptr_mode to Pmode + in setup for chkr_set_right_libfunc calls. + (assign_params): Likewise. + * expr.c (emit_push_insn): Change ptr_mode to Pmode in + setup for chkr_copy_bitmap_libfunc and chkr_set_right_libfunc calls. + (expand_assignment): Change ptr_mode to Pmode in + setup for chkr_add_libfunc and chkr_copy_bitmap_libfunc. + (store_expr): Change ptr_mode to Pmode in + setup for chkr_add_libfunc and chkr_copy_bitmap_libfunc. + (expand_expr): Change ptr_mode to Pmode in + setup for chkr_check_addr_libfunc. + (expand_builtin): Change ptr_mode to Pmode in + setup for chkr_check_str_libfunc, chkr_copy_bitmap_libfunc and + chkr_check_addr_libfunc. + * calls.c (rtx_for_function_call): Change ptr_mode to Pmode in + setup for chkr_check_exec_libfunc. + (expand_call): Change ptr_mode to Pmode in + setup for chkr_set_right_libfunc. + (expand_call): Change ptr_mode to Pmode in + setup for chkr_set_right_libfunc. + (store_one_arg): Change ptr_mode to Pmode in + setup for chkr_set_right_libfunc. - * cplus-dem.c (demangle_nested_args): Make function definition - static to match the prototype. + * c-parse.in (absdcl1): Allow attributes in explicit typespecs. + (%expect): Update. + * c-parse.y: Regenerate. + * c-parse.c: Likewise. + * objc/objc-parse.c: Likewise. + * objc/objc-parse.y: Likewise. -Thu Jul 16 01:17:44 1998 Richard Henderson +Mon Apr 26 21:17:41 1999 Jason Merrill - * loop.c (emit_iv_add_mult): Scan the entire insn list generated - for the sequence, recording base values. + * c-pragma.c (push_alignment): Don't ignore alignments greater than + 4 bytes. + (handle_pragma_token): Likewise. -Wed Jul 15 00:52:54 PDT 1998 Jeff Law (law@cygnus.com) + * c-pragma.c: Support for #pragma pack (push, , ). + (struct align_stack): Add id field. + (push_alignment, pop_alignment): Take id parameter. + (handle_pragma_token): Add necessary states. + * c-pragma.h (enum pragma_state): Add necessary states. - * version.c: Bump for snapshot. +Tue Apr 27 13:58:23 1999 Michael Hayes -Wed Jul 15 00:52:20 PDT 1998 Jeff Law (law@cygnus.com) + * config/c4x/c4x.md (*cmpqf, *cmpqf_noov, *cmpqi_test, + *cmpqi_test_noov): Remove ? modifier from constraints list. + (*smulqi3_highpart_clobber, *umulqi3_highpart_clobber): Swap + output strings to match new constraint ordering. - * version.c: Bump for snapshot. +1999-04-26 19:16 -0400 Zack Weinberg -Tue Jul 14 14:15:30 1998 Nick Clifton + * cpphash.c (dump_definition): New function. + * cpphash.h: Prototype it. - * gcc.c: Remove ANSI-C ism from --help code. + * cpplib.c (handle_directive): Don't output anything here. + Streamline. + (pass_thru_directive): Take a length, not a pointer to the + end. All callers changed. + (do_define): Handle -dD, -dN, -g3 entirely here. Streamline. + (do_include): Handle -dI here. + (do_ident): Correct to match cccp. + (do_pragma): Copy the pragma through here. + (do_assert, do_unassert): Tidy. - * toplev.c: Support --help with USE_CPPLIB. + * cppinit.c (cpp_finish): If -dM was specified, walk the macro + hash table and call dump_definition on all the entries. + * cppmain.c: cpp_finish may produce output. -Tue Jul 14 02:20:38 1998 Jeffrey A Law (law@cygnus.com) +Mon Apr 26 15:27:33 1999 Mark Mitchell - * configure.in: Rework gas feature code to work with symlink based - source trees. + * toplev.c (compile_file): Move call to check_global_declarations + after output_exception_table to restore behavior as it was before + 1999-04-22 change. - * version.c: Bump to avoid problems with old spec files during - bootstrap. +1999-04-26 10:50 -0700 Bruce Korb + + * fixinc/fixincl.c: Improve the handling of child process exits + * fixinc/server.[ch]: Export the interface for shutting down + the server process + * fixinc/inclhack.tpl: Remove unnecessary character quote + * fixinc/fixincl.sh, fixinc/inclhack.sh: Regenerate + +Mon Apr 26 10:41:42 EDT 1999 Andrew MacLeod + + * alpha.md (builtin_setjmp_receiver): Use a label_ref instead of + a code label. + +1999-04-26 09:47 -0400 Zack Weinberg + + * rtl.texi: Document the rtl classes and their relation to + formats. + +Mon Apr 26 01:02:38 1999 Richard Henderson + + * alpha.md (fix_trunc patterns): Use reg_no_subreg_operand on op0 + for less work in reload. + (movsf and movdf patterns): Put fp reg alternatives first. + +Mon Apr 26 01:55:56 1999 Marc Espie + + * configure.in (openbsd): Factorize xmake_file. + (ix86 openbsd): Trim obsolete comment. + (vax openbsd): Fix typo. + * configure: Rebuilt. -Mon Jul 13 23:11:44 1998 David S. Miller +Mon Apr 26 01:30:59 1999 Donn Terry - * config/sparc/sparc.c (output_scc_insn): Enclose || conditions in - parens while walking over notes. - * config/sparc/sparc.md (reg movdi split): Clean up matching - conditions. - (all DI arithop splits on 32-bit): Handle immediate arguments - correctly when they are CONST_INTs. + * expr.c (expand_assignment): Improve test for pointer type. -Mon Jul 13 23:57:21 1998 Kamil Iskra +Mon Apr 26 00:26:18 1999 Richard Henderson - * m68k/m68k.h (TARGET_SWITCHES): Clear MASK_68040_ONLY for - -m68020-40, -m68020-60 and -m5200. + * alpha.c (print_operand_address): Account for the subreg word. -Mon Jul 13 23:52:05 1998 Weiwen Liu +Mon Apr 26 01:08:36 1999 Toshiyasu Morita (tm@netcom.com) - * gcc.c (do_spec_1): Fix %O handling for secure temporary file - creation. + * fold-const.c (make_range): Always initialize arg0 and arg1. + (fold): Similarly for alt0 and alt1. + * function.c (fixup_var_refs_insns): Initialize insn_list. + (instantiate_virtual_regs_1): Initialize offset. + * optabs.c (expand_binop): Initialize carry_in, carry_out, op0_xhigh + and op1_xhigh. + * stmt.c (expand_end_case): Initialize minval and maxval. -Mon Jul 13 23:42:36 1998 Ralf Corsepius +Mon Apr 26 01:02:34 1999 Nathan Sidwell - * sh/elf.h (MAX_OFILE_ALIGNMENT): Undefine before including svr4.h. + * toplev.c (report_error_function): Reorder file stack and + function name printing. Ignore FILE parameter. -Mon Jul 13 23:36:08 1998 Jim Wilson +Mon Apr 26 00:58:54 1999 Jerry Quinn - * i386/i386.h (CPP_486_SPEC, CPP_586_SPEC, CPP_686_SPEC): New specs. - (CPP_CPU_DEFAULT_SPEC, CPP_CPU_SPEC): Use them. - (EXTRA_SPECS): Support them. - * gcc.c: Delete %[spec] support. - (do_spec_1, case '('): Likewise. - (do_spec_1, case '['): Call error. - * i386/aix386ng.h, cygwin32.h, freebsd-elf.h, gas.h, isc.h, - linux-aout.h, linux-oldld.h, linux.h, osfelf.h, osfrose.h, sco.h, - sco4.h, sco4dbx.h, sco5.h, sol2.h, sysv3.h (CPP_SPEC): Delete - %[cpp_cpu]. + * pa.h (architecture_type): New enum. + (pa_arch_string, pa_arch): Declare. + (MASK_PA_10, MASK_PA_20): New flags. + (TARGET_SWITCHES): Add pa-risc-2-0. Update docs for PA1.0 codegen. + (TARGET_OPTIONS): Add -march= option. + * pa.c (pa_arch, pa_arch_string): Define. + (override_options): Set them. + * pa/pa-hpux10.h (ASM_FILE_START): Output LEVEL 2.0 asm directive for + 2.0 architecture. + * invoke.texi (Option Summary, HPPA Options): Document new + architecture flags. -Mon Jul 13 23:31:04 1998 Andreas Schwab + * pa/pa-hpux.h, pa/pa-hpux10.h, pa/pa-hpux9.h, pa/pa-osf.h, pa.h, + pa.c, pa.md, configure.in, configure: Replace TARGET_SNAKE by + TARGET_PA_11 and MASK_SNAKE by MASK_PA_11. - * m68k.c (output_scc_di): Use cmpw #0 only for address registers. +Mon Apr 26 00:28:25 1999 Theodore Papadopoulo -Mon Jul 13 23:26:43 1998 Jeffrey A Law (law@cygnus.com) + * flags.h (inline_max_insns): Declare. + * integrate.c (inline_max_insns): New variable. + (function_cannot_inline_p): Use it. + * toplev.c (main): Add the flag -finline-limit-n. + (display_help): Document -finline-limit-n. + * invoke.texi: Document -finline-limit-n - * tree.h (tree_common): Note front-end dependencies on layout of - this structure. +Sun Apr 25 23:03:32 1999 Richard Henderson -Mon Jul 13 23:18:39 1998 Craig Burley + * stmt.c (expand_asm_operands): Reload in-out reg-only memory operands. - * stmt.c (expand_expr_stmt): If not assigning fresh - value to last_expr_value, zero it, so old garbage - doesn't get dereferenced. +Sun Apr 25 13:06:13 1999 Richard Henderson -Mon Jul 13 23:06:55 1998 Henning.Petersen@t-online.de (Henning Petersen) + * function.c (assign_parms/STACK_BYTES): Revert last change, + and that of 19 Nov. - * gcse.c (hash_scan_insn): Add missing argument declaration. +Sun Apr 25 12:30:50 1999 Richard Henderson -Mon Jul 13 18:59:13 1998 Jim Wilson + * calls.c (emit_call_1): New arg rounded_stack_size; update callers. + Update pending_stack_adjust based on this value. + (compute_argument_block_size): Include pending_stack_adjust in + PREFERRED_STACK_BOUNDARY alignment. + * function.c (assign_parms): Don't round to PREFERRED_STACK_BOUNDARY. - * configure.in (mips-sgi-irix5cross64, mips-sgi-irix5*): Remove - HAVE_INTTYPES_H from xm_defines. Define xm_file to mips/xm-iris5.h. - * mips/xm-iris5.h (USG): Delete. +Sun Apr 25 14:38:10 EDT 1999 John Wehle (john@feith.com) -Mon Jul 13 17:18:47 1998 Nick Clifton + * stupid.c (stupid_mark_refs): Generate a REG_UNUSED note + for a register which is clobbered even if the register + was used by an earlier instruction. - * cccp.c (main): Add support for parsing --help. - (display_help): New function: display command line switches. + * i386.md (fix_truncsfdi2, fix_truncdfdi2, + fix_truncxfdi2): Don't bother with the gen_reg_RTX. + (fix_truncsfsi2, fix_truncsfdi2, fix_truncdfsi2, + fix_truncdfdi2, fix_truncxfsi2, fix_truncxfdi2): Update + operand constraints and modes. + * i386.c (output_fix_trunc): Use HImode register to avoid + memory stalls. Call output_move_double instead of output_to_reg. + (output_to_reg): Remove. + * i386.h: Likewise. - * cpplib.c (cpp_handle_option): Add support for parsing --help. - (display_help): New function: display command line switches. + * i386.md (negsf2, negdf2, negxf2): Set the type + attribute to fpop. - * gcc.c (main): Add support for parsing --help, and passing it on - to the sub-processes invoked by gcc. - (display_help): New function: display comman line switches. +Sat Apr 24 23:15:57 1999 Donn Terry (donn@interix.com) - * tm.texi (TARGET_SWITCHES and TARGET_OPTIONS): Document - 'description' field added to structure. + * alpha.md (call_value_nt): Correct subscripts. - * toplev.c: Add support for parsing --help. - Add documentation strings to command line option tables. - (display_help): New function: display comman line switches. +Sat Apr 24 20:49:20 1999 Richard Henderson -Mon Jul 13 16:15:10 1998 John Carr + * alpha.h (PRINT_OPERAND_ADDRESS): Break out to ... + * alpha.c (print_operand_address): here. Handle subregs. - * sparc.c, sparc.h, sparc.md: New trampoline code. - Allow integer operand 1 to V8+ DImode shift instructions. - Fix bugs in V8+ wide multiply patterns. - In 32 bit mode, split DImode register moves and logical instructions. - Write V9 branch prediction flag. - Use V9 conditional move more often for scc. +Fri Apr 23 22:35:41 EDT 1999 John Wehle (john@feith.com) -Mon Jul 13 15:10:09 1998 Philippe De Muyter + * acconfig.h (HAVE_GAS_FILDS_FISTS): Add. + * configure.in: Check assembler instructions. + * configure: Rebuild. + * config.in: Likewise. + * i386.md (floathisf2, floathidf2, floathixf2): New patterns. + * i386.c (print_operand): Use the proper suffix for a 387 HImode + operand. Abort if a 387 operand has an unsupported size. - * invoke.texi(-fno-builtin): Explain that the names of built-in - functions begin with `__builtin_', not `__'. +Fri Apr 23 16:57:40 1999 Richard Henderson -Mon Jul 13 19:01:52 1998 J"orn Rennecke + * alpha.c (alpha_write_verstamp): Mark `file' unused. + * alpha.h (FUNCTION_VALUE): Use gen_rtx_REG not gen_rtx. + (LIBCALL_VALUE): Likewise. + (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Handle normal subregs. - * reload1.c (reload_reg_free_before_p): Abort for RELOAD_FOR_OUTPUT. +Fri Apr 23 14:57:33 1999 Donn Terry -Mon Jul 13 10:50:17 1998 Mark Mitchell + * alpha32.h (INITIALIZE_TRAMPOLINE): Get offsets right. - * cplus-dem.c (SCOPE_STRING): Remove DMGL_JAVA stuff. - (cplus_demangle_opname): Initialize work. - (demangle_template): Remove is_java_array. - (do_type): Remove DMGL_JAVA stuff. - (long_options): Remove "java". - (main): Remove 'j' option. + * alpha.c (alpha_initialize_trampoline): Add covert_memory_address + calls as needed. -Mon Jul 13 10:19:00 1998 Jeffrey A Law (law@cygnus.com) +Fri Apr 23 14:36:47 1999 Richard Henderson - * mn10300.h (REG_CLASS_FROM_LETTER): Map 'y' to SP_REGS. - Handle 'x' as NO_REGS for this cpu. - (REGNO_OK_FOR_BIT_BASE_P): Define. - (REG_OK_FOR_BIT_BASE_P): Define. - (GO_IF_LEGITIMATE_ADDRESS): Use them. - (REG_OK_FOR_INDEX_P): Tweak. - * mn13000.c (REG_SAVE_BYTES): Define. - (expand_epilogue, initial_offset): Use it. - (secondary_reload_class): Slightly reformat. - (output_tst): Tweak comments. - * mn10300.md: Change 'x' to 'y' for SP_REGS. Then add 'x' to many - patterns. - (addsi3): Turn into a define_expand/define_insn pair. Rework code for - three operand addition case to be more efficient. - (subsi3): Turn into a define_expand/define_insn pair. + * alpha.c (alpha_expand_prologue): Don't negate frame size + for use with subq. - * expr.c (expand_expr): Only set MEM_IN_STRUCT_P if the memory address - is not varying for REFERENCE_TYPE or when we think we might have found - an optimized access to the first element in an array. +Fri Apr 23 09:43:18 1999 Nick Clifton -Mon Jul 13 02:24:08 1998 David S. Miller + * print-rtl.c (print_rtx): Display LABEL_NUSES for labels. - * regclass.c (reg_scan_mark_refs): New arg min_regno. Only update - regscan information for REGs with numbers greater than or equal to - this. All callers changed. - (reg_scan_update): New function to efficiently update regscan - information on the fly. - * rtl.h: Add prototype. - * jump.c (jump_optimize): Call it when we make a transformation - which generates new pseudo-REGs. +Thu Apr 22 23:08:37 1999 Mark Mitchell -Sun Jul 12 13:08:14 1998 Jeffrey A Law (law@cygnus.com) + * toplev.h (wrapup_global_declarations): Declare. + (check_global_declarations): Likewise. + * toplev.c (wrapup_global_declarations): New function, split out + from ... + (check_global_declarations): Likewise... + (compile_file): Here. - * collect2.c (main): Use "-x c" instead of "-lang-c" for force the - compiler into C mode. +Thu Apr 22 22:34:41 1999 Richard Henderson -Sun Jul 12 01:27:05 1998 Jason Merrill + * c-parse.in (expr_no_commas): Verify we've an expr before + calling C_SET_EXP_ORIGINAL_CODE. - * cplus-dem.c (demangle_nested_args): Return a value. - - * tree.h (TYPE_P): New macro. - -Sat Jul 11 16:19:48 1998 Mark Mitchell - - * cplus-dem.c (string): Move definition before work_stuff. - (work_stuff): Add volatile_type, forgetting_types, - previous_argument, and nrepeats fields. - (SCOPE_STRING): New macro. - (demangle_template): Add `remember' parameter. Add comment. - Register the `B' code type here, if remembering. Tidy. Fix crash - on NULL tmpl_argvec. Be consistent with use of tname/trawname. - (demangle_nested_args): New function. - (internal_cplus_demangle): Handle volatile-qualified member - functions. - (mop_up): Delete the previous_argument string if present. - (demangle_signature): Tidy. Handle volatile-qualified member - functions. Handle back-references using the `B' code. Use extra - parameter to demangle_template and SCOPE_STRING where appropriate. - (demangle_template_value_parm): Fix thinko; 'B' is not an integral - code. - (demangle_class): Use SCOPE_STRING. - (gnu_special): Pass additional argument to demangle_template. - Use SCOPE_STRING. - (demangle_qualified): Save qualified types for later - back-references. Handle constructors and destructors for template - types correctly. - (do_type): Tidy. Use SCOPE_STRING. Pass extra argument to - demangle_template. Use demangled_nested_args. Don't remember - qualified types here; that's now done in demangle_qualified. - Similarly for templates. - (do_arg): Improve commment. Handle 'n' repeat code. - (remember_type): Check forgetting_types. - (demangle_args): Deal with 'n' repeat codes. Tidy. - -Sat Jul 11 02:59:08 1998 Richard Earnshaw +Thu Apr 22 22:22:15 EDT 1999 John Wehle (john@feith.com) - * arm.md (extendhisi2_mem, movhi, movhi_bytes): Propagate the volatile - and structure attribute flags to MEMs generated. - (splits for sign-extended HI & QI mode from memory): Also propagate - the volatile flag. + * toplev.c (rest_of_compilation): Always set + current_function_uses_only_leaf_regs appropriately. - * configure.in (thumb-*-coff*): Don't cause fixincludes to be run. +Thu Apr 22 14:39:43 1999 Mumit Khan + + * i386/xm-cygwin.h (HAVE_BCOPY): Delete unneeded macro. + (HAVE_BZERO): Likewise. + (HAVE_BCMP): Likewise. + (HAVE_RINDEX): Likewise. + (HAVE_INDEX): Likewise. + (DIR_SEPARATOR_2): Define. + (GET_ENV_PATH_LIST): Turn path lists into POSIX. + (PATH_SEPARATOR): Use ':'. -Fri Jul 10 19:06:59 1998 Michael Meissner +1999-04-22 Bruce Korb - * varray.h: Include system.h if it hasn't already been included - before to get size_t declared. + * configure.in: enable disabling of fast fixincludes + * configure: regenerate -Fri Jul 10 12:53:58 1998 David S. Miller +1999-04-21 14:55 -0400 Zack Weinberg - * jump.c (jump_optimize): If after_regscan and our transformations - generate new REGs, rerun reg_scan. + * gen-protos.c: #undef abort after including system.h. + Delete defns of fancy_abort and fatal. + * fix-header.c: Delete defn of fancy_abort. -Fri Jul 10 11:50:43 EDT 1998 Andrew MacLeod +Wed Apr 21 12:09:38 1999 Mumit Khan - * config/i960/i960.c (i960_address_cost): MEMA operands with - positive offsets < 4096 are free. + * cccp.c (simplify_filename): Always preserve leading double slash. -Fri Jul 10 12:34:37 1998 Andreas Schwab +Wed Apr 21 18:15:55 1999 Michael Hayes - * config/m68k/m68k.c (const_uint32_operand): Recognize - CONSTANT_P_RTX. - (const_sint32_operand): Likewise. + * config/c4x/c4x.md: Add new peepholes to remove redundant loads. -Thu Jul 9 22:58:59 1998 Jeffrey A Law (law@cygnus.com) +Wed Apr 21 17:41:29 1999 Michael Hayes - * Makefile.in (alias.o): Depend on $(EXPR_H). + * config/c4x/c4x.md (binary patterns): Reorder alternatives + so that two operand instructions are chosen before three operand + instructions. -Thu Jul 9 18:24:56 1998 J"orn Rennecke +Tue Apr 20 23:38:58 1999 Nathan Sidwell - * reload1.c (choose_reload_regs): If using an equivalence from - find_equiv_reg and reg_reloaded_valid is not set for this register, - clear the associated spill_reg_store. + * objc/Make-lang.in (objc-parse.c): Put BISON parameters in correct + order. -Thu Jul 9 18:12:49 1998 J"orn Rennecke + * Makefile.in (c-parse.c): Put BISON parameters in correct + order. - * reload1.c (emit_reload_insns): If an output reload copies only - to a secondary reload register, indicate that the secondary reload - does the actual store. +Tue Apr 20 16:38:11 1999 Richard Henderson -Thu Jul 9 18:01:05 1998 J"orn Rennecke + * alpha.md (nt_lda): New pattern. + * alpha.c (alpha_expand_prologue): Use it for large frames + under windows nt. - * reload.c (find_equiv_reg): If need_stable_sp is set, - check if stack pointer is changed directly in a PARALLEL. +Tue Apr 20 17:57:14 1999 Catherine Moore -Thu Jul 9 10:38:14 1998 Jeffrey A Law (law@cygnus.com) + * config/arm/arm.md (movhi): Add check for odd offset. - * jump.c (duplicate_loop_exit_test): Fix thinko. +Tue Apr 20 13:14:58 EDT 1999 John Wehle (john@feith.com) -Thu Jul 9 01:30:37 1998 Joel Sherrill - Ralf Corsepius + * i386.c (output_move_double): Abort if a non-offsettable + memory operand is encountered. Delete unused code. + (find_addr_reg): Remove. - * config/i386/rtemself.h: Updated to keep in sync with - config/i386/linux.h. +Mon Apr 19 21:13:02 1999 Craig Burley - * configure.in: Added sh-rtemself. - * configure: Rebuilt. - * config/sh/rtems.h: Removed -D__ELF__ since it is now COFF. - * config/sh/rtemself.h: New file. + * tree.def (BLOCK): Fix typo in comment. - * config/rs6000/rtems.h: Defined STARTFILE_DEFAULT_SPEC. +1999-04-19 14:51 -0400 Zack Weinberg -Wed Jul 8 21:43:14 1998 Jeffrey A Law (law@cygnus.com) + * cpplib.c (output_line_command): Drop CONDITIONAL argument. + We can omit unnecessary line commands if file_change == + same_file and pfile->lineno != 0. All callers changed. + (cpp_get_token [case '\n']): Don't bump pfile->lineno if + CPP_OPTIONS (pfile)->no_line_commands is set. + * cpplib.h: Fix prototype of output_line_command. - * configure.in: Check if the assembler supports ".balign" and - ".p2align" and define HAVE_GAS_BALIGN_AND_P2ALIGN appropriately. - * acconfig.h (HAVE_GAS_BALIGN_AND_P2ALIGN): New tag. - * i386/gas.h (ASM_OUTPUT_ALIGN): If the assembler has support for - ".balign" then use it. +1999-04-18 17:46 -0400 Zack Weinberg - * print-rtl.c (print_rtx): Revert previous patch. + * cppfiles.c (find_position, read_and_prescan): Use `unsigned + long' variables consistently to count line and column numbers. - * jump.c (duplicate_loop_exit_test): Do not duplicate the loop exit - test if the exit code has an insn with ASM_OPERANDS. +Sun Apr 18 15:50:33 EDT 1999 John Wehle (john@feith.com) - * i386/cygwin32.h (STDIO_PROTO): Fix typo. - * m32r.h (STDIO_PROTO): Fix typo. + * output.h (current_function_is_leaf, + current_function_uses_only_leaf_regs): Declare. + * function.c (current_function_is_leaf, + current_function_uses_only_leaf_regs): Define. + (init_function_start): Initialize current_function_is_leaf + and current_function_uses_only_leaf_regs. + * final.c (leaf_function): Don't define. + (final_start_function): Replace uses of leaf_function with + current_function_uses_only_leaf_regs. + * toplev.c (rest_of_compilation): Set current_function_is_leaf + prior to invoking local register allocation. + (rest_of_compilation): Replace uses of leaf_function with + current_function_uses_only_leaf_regs. + * dbxout.c (dbxout_symbol, dbxout_parms): Likewise. + * dwarf2out.c (add_location_or_const_vaule_attribute): Likewise. + * dwarfout.c (add_location_or_const_value_attribute): Likewise. + * sdbout.c (sdbout_symbol): Likewise. + * sparc.h (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Likewise. + * sparc.c (eligible_for_epilogue_delay, output_return, + sparc_return_peephole_ok): Likewise. + * sparc.md (leaf_function attribute, untyped_return): Likewise. + * i386.c (ix86_compute_frame_size): Don't align the stack + for leaf functions which don't allocate any stack slots. + * tm.texi: Update documentation. - * pa.h (LEGITIMIZE_RELOAD_ADDRESS): Handle addresses created by - LEGITIMIZE_RELOAD_ADDRESS. - * tm.texi (LEGITIMIZE_RELOAD_ADDRESS): Note that this macro must be - able to handle addresses created by previous invocations of the macro. +Sun Apr 18 02:15:09 PDT 1999 Jeff Law (law@cygnus.com) - * flow.c (find_auto_inc): Remove most recent change. Real bug was - elsewhere. + * version.c: Bump for snapshot. - * cse.c (count_reg_usage): Count registers used in addresses of - CLOBBERs. +Sun Apr 18 00:08:45 1999 Richard Henderson -Wed Jul 8 15:08:29 1998 Jim Wilson + * alpha.h (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Correct last change -- + make sure FP_BASE_P registers are only used with an integer. - * Makefile.in (STAGESTUFF): Readd line lost during June 9 FSF merge. +Sat Apr 17 22:54:17 1999 Richard Henderson - * configure.in (mips64orion-*-rtems*): Use elf64.h not elfl64.h. + * alpha.h (REG_OK_FP_BASE_P): New macro. + (GO_IF_LEGITIMATE_SIMPLE_ADDRESS): Use it. + * alpha.md (adddi3+1): New insn to handle large constants off + the soft frame pointer. + (adddi3+2): Don't split soft frame pointer or arg pointer additions. -1998-07-08 Vladimir N. Makarov +Sun Apr 18 17:24:10 1999 Michael Hayes - * config/fp-bit.c (__gexf2, __fixxfsi, __floatsixf): Add function - stubs. + * config/c4x/c4x.c (legitimize_operands): Use rtx_cost + to determine if it is worthwhile forcing a constant into a register. + * config/c4x/c4x.h (CONST_COSTS): An integer value of 255 or 65535 + used with a logical and or an integer value of 16 or 24 used with + a right shift has zero cost on the C40. - * toplev.c (lang_options): Add -Wlong-long, -Wno-long-long - options. - * c-decl.c (warn_long_long): Define. - (c_decode_option): Parse -Wlong-long, -Wno-long-long options. - (grokdeclarator): Add flag `warn_long_long' as guard for - warning "ANSI C does not support `long long'". - * invoke.texi: Add description of options -Wlong-long, - -Wno-long-long. - * gcc.1: The same as above. - -Wed Jul 8 02:43:34 1998 Jeffrey A Law (law@cygnus.com) +Sat Apr 17 21:30:11 1999 Bernd Schmidt - * rtlanal.c (reg_overlap_mentioned_p): Handle STRICT_LOW_PART. If - either argument is CONSTANT_P, then return zero. - * reload.c (reg_overlap_mentioned_for_reload_p): Similarly. + * gcse.c (compute_local_properties): If setp is nonzero, clear + TRANSP instead of setting it to all ones. - * configure.in: Also look at $srcdir/gas/configure to find a - gas version #. +Sat Apr 17 21:10:10 1999 Jan Hubicka -Wed Jul 8 00:28:22 1998 Carlo Wood + * i386.c (i386_preferred_stack_boundary_string): New global variable. + (i386_preferred_stack_boundary): New global variable. + (override_functions): Set it. Tidy option setting code. + * i386.h (TARGET_OPTIONS): New command line option. + (i386_preferred_stack_boundary_string): Declare it. + (i386_preferred_stack_boundary): Likewise. + (PREFERRED_STACK_BOUNDARY): Use i386_preferred_stack_boundary. - * dsp16xx.h : Clean up of macro OPTIMIZATION_OPTIONS +Sat Apr 17 19:22:38 1999 Jan Hubicka -Tue Jul 7 21:18:14 1998 Mumit Khan + * i386.c (k6_cost): Take into account the decoding time. - * i386/cygwin32.h (ASM_DECLARE_FUNCTION_NAME): Merge duplicate - definitions from last two patches. +Sat Apr 17 19:13:22 1999 Donn Terry -Tue Jul 7 23:03:34 1998 J"orn Rennecke + * i386.h (PRINT_OPERAND_PUNCT_VALID_P): Allow _. + * i386.c (print_operand): New %_ operator. + (load_pic_register): Proper number of leading _ in GOT literal. + * i386.md (prologue_get_pc_and_set_got): Likewise. + * i386/unix.h (ASM_OUTPUT_MI_THUNK): Likewise. - * reload1.c (choose_reload_regs): Don't set reload_override_in - if EQUIV is clobbered in INSN and the reload is done after INSN. +Sat Apr 17 19:13:07 1999 Richard Henderson -Tue Jul 7 21:23:36 1998 J"orn Rennecke + * alpha.c (alpha_expand_prologue): Use gen_adddi3 instead of + emit_move_insn+plus_constant. For NT, don't use the stack probe + loop pointer to allocate stack space. + * alpha.md (adddi3): Always use lda to set the stack pointer. - * expr.c (emit_queue): If emitting a SEQUENCE, set QUEUED_INSN - to the first insn of the sequence. +1999-04-17 20:11 -0400 Zack Weinberg -Tue Jul 7 21:05:25 1998 J"orn Rennecke + * c-aux-info.c, emit-rtl.c, explow.c, expmed.c, gcse.c, + haifa-sched.c, optabs.c, reorg.c, resource.c, sched.c: Include + toplev.h for real declaration of trim_filename. + * Makefile.in: Update dependencies. - * cse.c (cse_insn): Don't make change without validation. +Sat Apr 17 14:36:19 1999 Craig Burley -Tue Jul 7 11:40:05 1998 Jeffrey A Law (law@cygnus.com) + * tree.c (chainon): Check for circularity only if + ENABLE_CHECKING is defined. - * mn10200.md (various zero/sign extension patterns): zero and sign - extensions which use "sub" clobber cc0. +1999-04-17 10:15 -0400 Zack Weinberg -Tue Jul 7 09:12:08 PDT 1998 Jeff Law (law@cygnus.com) + * cccp.c: Make fatal non-static. - * version.c: Bump for snapshot. +Sat Apr 17 23:47:24 1999 Michael Hayes -Tue Jul 7 10:07:20 1998 Jeffrey A Law (law@cygnus.com) + * config/c4x/c4x.md (*andqi3_255_clobber,*andqi3_65535_clobber): + New logical and patterns using C40 bit-field insert instructions. + (*lshrqi3_24_clobber,*ashrqi3_24_clobber,*lshrqi3_16_clobber, + *ashrqi3_16_clobber): New shift patterns using C40 bit-field insert + instructions. - * print-rtl.c (print_rtx): Use REAL_VALUE_TYPE instead of "double". +1999-04-16 22:44 -0400 Zack Weinberg -Tue Jul 7 08:41:27 1998 Richard Henderson (rth@cygnus.com) + * system.h: Always prototype abort. Prototype fatal. Define + abort to call fatal, not fprintf/exit. Define a stub macro + for trim_filename. + * toplev.c: Define DIR_SEPARATOR. (trim_filename): New + function. + * toplev.h: Prototype trim_filename, and #undef system.h's stub. - * print-rtl.c (print_rtx): Only print fp values when REAL_VALUE_TYPE - is a double. + * gcc.c, genattr.c, genattrtab.c, gencodes.c, genconfig.c, + genemit.c, genextract.c, genflags.c, genopinit.c, genoutput.c, + genpeep.c, genrecog.c: Make fatal non-static. + * gcov.c, gengenrtl.c, protoize.c: #undef abort after + including system.h. -Tue Jul 7 00:31:58 PDT 1998 Jeff Law (law@cygnus.com) + * config/i386/dgux.h, config/m68k/xm-amix.h: Remove stale code + relating to abort. - * version.c: Bump for snapshot. +Sat Apr 17 11:25:44 1999 Michael Hayes -Tue Jul 7 01:03:03 1998 Mumit Khan + * config/c4x/c4x.md (mulqf3_clrqf_clobber, mulqi3_clrqi_clobber): + New patterns to support parallel multiply and load of zero. - Support for dllimport and dllexport attributes for i386-pe. +Fri Apr 16 01:23:47 1999 Jason Merrill - * tree.h (DECL_NON_ADDR_CONST_P): New accessor macro. - (struct tree_decl): Add non_addr_const_p field. - * tree.c (staticp): Use. + * tree.c (valid_machine_attribute): If we're modifying the + FUNCTION_TYPE within a POINTER_TYPE and we don't get a decl, + update the POINTER_TYPE. - * i386/cygwin32.h (CPP_PREDEFINES): Map __declspec(x) to GCC - attributes. - (SUBTARGET_SWITCHES): Switches to turn on/off dllimport|export - attributes. Also accept -mwindows option. - (VALID_MACHINE_DECL_ATTRIBUTE): New macro. - (MERGE_MACHINE_DECL_ATTRIBUTE): New macro. - (REDO_SECTION_INFO_P): New macro. - (DRECTVE_SECTION_FUNCTION): New macro. - (drectve_section): Cover function to implement above. - (SWITCH_TO_SECTION_FUNCTION): New macro. - (switch_to_section): Covert function to implement above. - (EXTRA_SECTIONS): Add in_drectve. - (EXTRA_SECTION_FUNCTIONS): Add in_drectve and switch_to_section. - (ENCODE_SECTION_INFO): Delete old macro and redefine as a function. - (STRIP_NAME_ENCODING): Handle new attributes. - (ASM_OUTPUT_LABELREF): New macro. - (ASM_OUTPUT_FUNCTION_NAME): New macro. - (ASM_OUTPUT_COMMON): New macro. - (ASM_OUTPUT_DECLARE_OBJECT_NAME): New macro. +Fri Apr 16 00:19:31 1999 Jan Hubicka - * i386/mingw32.h (CPP_PREDEFINES): Map __declspec(x) to GCC - attributes. + * i386.c (x86_adjust_cost): Move break statement to correct place. - * i386/winnt.c (i386_pe_valid_decl_attribute_p): New function. - (i386_pe_merge_decl_attributes): New function. - (i386_pe_check_vtable_importexport): New function. - (i386_pe_dllexport_p): New function. - (i386_pe_dllimport_p): New function. - (i386_pe_dllexport_name_p): New function. - (i386_pe_dllimport_name_p): New function. - (i386_pe_mark_dllexport): New function. - (i386_pe_mark_dllimport): New function. - (i386_pe_encode_section_info): New function. - (i386_pe_unique_section): Strip encoding from name first. +Thu Apr 15 23:17:33 1999 Jerry Quinn -Tue Jul 7 00:50:17 1998 Manfred Hollstein (manfred@s-direktnet.de) + * pa.h (HAVE_PRE_INCREMENT, HAVE_POST_INCREMENT, + HAVE_PRE_DECREMENT, HAVE_POST_DECREMENT): Fix pa_cpu value from + 8000 to PROCESSOR_8000. - * libgcc2.c (L_exit): Provide a fake for atexit on systems which - define ON_EXIT but not HAVE_ATEXIT. +Thu Apr 15 20:46:57 1999 Donn Terry (donn@interix.com) -Tue Jul 7 00:44:35 1998 Franz Sirl + * expr.c (expand_assignment): Force pointers to proper mode if + POINTERS_EXTEND_UNSIGNED is defined. - * m68k.md (zero_extend QI to HI): Correctly handle TARGET_5200. + * xm-alpha.h (alloca.h): Add Interix to list of special machines + that don't like alloca.h, pending using autoconf results. -Tue Jul 7 00:36:41 1998 Ulrich Drepper + * except.c (start_catch_hadler): Be sure rtime_address is Pmode + if POINTERS_EXTEND_UNSIGNED. - * i386.c: Remove random whitespace at end of lines. + * except.c (expand_eh_return): Force pointers to proper mode if + POINTERS_EXTEND_UNSIGNED. - * i386.c (ix86_epilogue): For pentium processors, try to deallocate - 4 or 8 byte stacks with pop instructions instead of an add instruction. +Thu Apr 15 23:13:35 1999 Michael Hayes -Tue Jul 7 00:30:08 1998 Klaus Kaempf + * config/c4x/c4x.h: Tweaked comment formatting. + * config/c4x/c4x.c: Likewise. - * alpha.c: Include tree.h before expr.h. +Thu Apr 15 02:45:19 1999 Mumit Khan -Mon Jul 6 22:50:48 1998 Jason Merrill + * aclocal.m4 (GCC_FUNC_MKDIR_TAKES_ONE_ARG): Define. + * configure.in: Use. + * configure: Rebuilt. + * acconfig.h (MKDIR_TAKES_ONE_ARG): Add. + * config.in: Rebuilt. + * system.h: Use. - * c-parse.in (struct_head, union_head, enum_head): New nonterminals. - (structsp): Use them. Update files generated from c-parse.in. - * extend.texi (Type Attributes): Document it. +Thu Apr 15 01:03:21 1999 Jan Hubicka + Jeff Law - * c-decl.c: Add warn_multichar. - (c_decode_option): Handle -Wno-multichar. - * c-lex.c (yylex): Check it. - * c-tree.h: Declare it. - * toplev.c (lang_options): Add it. - * invoke.texi: Document it. + * i386.md (QImode add pattern): Support lea instruction. + (HImode add pattern): Likewise. + + * i386.md (ashlsi patterns): Call output_ashl instead of output_ashlsi3. + (ashlqi): Use expander, separate LEA and SAL / ADD patterns; call + output_ashl. + (ashlhi): Likewise. + * i386.h (output_ashl): Renamed from output_ashlsi3. + * i386.c (output_ashl): Likewise; support HImode and QImode operands + as well. + + * i386.md (notsi, nothi, xorsi, xorhi, and xorqi patterns): Call + memory_address_displacement_length instead of memory_address_length. + * i386.c (memory_address_info): Renamed from memory_address_length. + Accept new argument DISP_LENGTH. All callers changed. If DISP_LENGTH, + then return the displacement length. Else return length of the + entire memory address. Handle MULT case correctly. + * i386.h (memory_address_info): Update declaration. + + * i386.md (memory_bit_test): Fix paren error. + +Wed Apr 14 21:29:18 1999 Andrew Haley + + * flow.c: (make_edges): Always make edges from a basic block + to its exception handlers, even if the block ends with a jump. + +1999-04-14 23:26 -0400 Zack Weinberg + + * graph.c (node_data): Return void. Ignore result of + print_rtl_single. Change caller to match. + * integrate.c (subst_constants): Initialize op0_mode to an + invalid mode, and abort before use if it's still invalid. + (Can only happen if the RTX_CLASS, RTX_FORMAT tables are corrupted.) + * objc/objc-act.c (get_objc_string_decl, + build_selector_translation_table, generate_protocol_list, + synth_id_with_class_suffix, build_keyword_selector, + build_selector_expr, gen_declarator): Abort when the tree + structure is corrupted. + +Wed Apr 14 19:57:49 1999 Jeffrey A Law (law@cygnus.com) + + * configure.in (alpha interix): Use symbolic names to set + target_cpu_default. + * configure: Rebuilt. -Mon Jul 6 22:47:55 1998 J"orn Rennecke + * explow.c (allocate_dynamic_stack_space): Undo last change. Use + convert_memory_address instead. + +Wed Apr 14 19:42:02 1999 Donn Terry (donn@interix.com) + + * alpha/lib1funcs.asm: New file. + * alpha/t-interix (lib1funcs.asm): Add to build. + + * explow.c (allocate_dynamic_stack_space): Correctly convert TARGET + to Pmode. + +Wed Apr 14 14:26:36 1999 John Wehle (john@feith.com) + + * i386.md (truncxfdf): Output the template supplied + by output_move_double with the correct operands. + + * i386.md (extendsfdf, extendsfxf, extenddfxf): Use + output_float_extend instead specifying '#' as the template. + * i386.c (output_float_extend): Define. + * i386.h (output_float_extend): Declare. + +Wed Apr 14 10:48:03 1999 Catherine Moore + + * config/mips/elf.h, config/mips/elf64.h + (CTORS_SECTION_ASM_OP): Define. + (DTORS_SECTION_ASM_OP): Define. + (EXTRA_SECTIONS): Define. + (INVOKE__main): Define. + (NAME__MAIN): Define. + (SYMBOL__MAIN): Define. + (EXTRA_SECTIONS_FUNCTIONS): Define. + (SECTION_FUNCTION_TEMPLATE): Define. + (ASM_OUTPUT_CONSTRUCTOR): Define. + (ASM_OUTPUT_DESTRUCTOR): Define. + (CTOR_LIST_BEGIN): Define. + (CTOR_LIST_END): Define. + (DTOR_LIST_BEGIN): Define. + (DTOR_LIST_END): Define. + (LIB_SPEC): Define. + (STARTFILE_SPEC): Define. + (ENDFILE_SPEC): Define. + * config/mips/linux.h: Undefine all of the above. + * config/mips/rtems64.h: Likewise. + * config/mips/t-r3900: Likewise. + * config/mips/t-elf: New file. + * config/mips/vxworks.h: New file. + * configure.in (mips-wrs-vxworks): Use mips/vxworks.h. + (mips*-*-*elf*): Use t-elf instead of t-ecoff. + * configure: Regenerate. - * reload.c (find_equiv_reg): When looking for stack pointer + const, - make sure we don't use a stack adjust. +Wed Apr 14 09:59:38 1999 Richard Henderson - * reload.c (find_equiv_reg): If need_stable_sp is set, - check if stack pointer is changed directly. + * reload1.c (emit_reload_insns): Also find equivalent mems + for subregs of pseudos. - * reload1.c (delete_dead_insn): Don't delete feeding insn - if that insn has side effects. + * alpha.c (aligned_memory_operand): Recognize the output of + LEGITIMIZE_RELOAD_ADDRESS. Examine reg_equiv_memory_loc in + the event of a pseudo. + (unaligned_memory_operand): Likewise. Don't otherwise accept + completely illegal addresses. + (normal_memory_operand): Likewise. Handle subregs of pseudos. + (get_aligned_mem): Revert previous change. Abort if we don't have a + mem. During reload, call find_replacement on all illegal memories. + (get_unaligned_address): Likewise. + * alpha.h (SECONDARY_INPUT_RELOAD_CLASS): Use !aligned_memory_operand + instead of unaligned_memory_operand. + * alpha.md: Revert extra argument to get_aligned_mem. + (reload_inqi): Use any_memory_operand in constraints. Abort if + we're not given some sort of mem. + (reload_inhi): Likewise. + (reload_outqi, reload_outhi): Likewise. - * flow.c (find_auto_inc): Clear UNCHANGING bit of register that is - changed. +Wed Apr 14 09:39:20 1999 Richard Henderson - * reload1.c (reload_reg_free_before_p): RELOAD_FOR_OPADDR_ADDR - precedes RELOAD_FOR_OUTADDR_ADDRESS. + * i386.md (neghi): Use the whole register when widening the op. - * gcse.c (hash_scan_insn): New argument IN_LIBCALL_BLOCK. Changed - caller. +1999-04-14 12:37 -0400 Zack Weinberg -Mon Jul 6 22:21:56 1998 Kamil Iskra + * cpperror.c, cppexp.c, cpplib.c: Never call abort. + * cpphash.c: Only call abort when we detect corruption of the + malloc arena. + * cppmain.c: Don't define fatal or fancy_abort. - * m68k.c (output_scc_di): Use cmpw #0 instead of tstl when - testing address registers on the 68000. +Wed Apr 14 09:19:39 1999 Jan Hubicka -Mon Jul 6 22:17:19 1998 Alasdair Baird + * i386.c (x86_adjust_cost): Agi stall takes 1 cycle on Pentium, fst + requires value to be ready one extra cycle. - * i386.c (is_fp_test): Fix thinko. +Wed Apr 14 11:28:34 1999 Dave Brolley - * jump.c (jump_optimize) Check for CONST_INT before using INTVAL. + * config/i386/i386.c (memory_address_length): Add missing parenthesis. -Mon Jul 6 22:14:31 1998 Richard Henderson (rth@cygnus.com) +Wed Apr 14 13:59:27 1999 Martin von Loewis - * print-rtl.c (print_rtx): Display the real-value equivalent of - a const_double when easy. + * extend.texi (Deprecated Features): New node. + * invoke.texi (-Wdeprecated): Document. - * real.h (REAL_VALUE_TO_TARGET_SINGLE): Use a union to pun types. - Zero memory first for predictability. - (REAL_VALUE_TO_TARGET_DOUBLE): Likewise. - * varasm.c (immed_real_const_1): Notice width of H_W_I == double. +Wed Apr 14 00:18:22 1999 Jan Hubicka - * regclass.c (allocate_reg_info): Initialize the entire reg_data - virtual array. + * i386.md (SImode logical compare): Avoid outputing non-pariable testw + and testl on Pentium. + (register and memory bit tests): Likewise. + (setcc, normal and reversed conditional branches): Use shorter + sequence for testing flags stored in EAX. -Mon Jul 6 22:09:32 1998 Ian Lance Taylor - Jeff Law + * i386.md (xorsi3): Do not output NOT instrctions on Pentium. + (xorqi3): Likewise. + (xorhi3): Likewise. + (notsi2): Likewise. + (notqi2): Likewise. + (nothi2): Likewise; do not output prefixed opcodes when possible. + * i386.md (neghi2): Do not output prefixed opcode when possible. + (ashlhi3): Likewise. - * i386/cygwin32.h: Add some declaration of external functions. - (ASM_DECLARE_FUNCTION_NAME): Define. - (ASM_OUTPUT_EXTERNAL, ASM_OUTPUT_EXTERNAL_LIBCALL): Define. - (ASM_FILE_END): Define. - * i386/winnt.c (i386_pe_declare_function_type): New function. - (struct extern_list, extern_head): Define. - (i386_pe_record_external_function): New function. - (i386_pe_asm_file_end): New function. +Wed Apr 14 00:08:46 1999 Richard Henderson - * cpplib.c (cpp_options_init): Initialize cplusplus_comments to 1, - matching July 18, 1995 change to cccp.c. If -traditional then - disable cplusplus_comments. + * i386.c (memory_address_length): New function. + * i386.h (memory_address_length): Declare it. -Mon Jul 6 21:28:14 1998 Jeffrey A Law (law@cygnus.com) +Tue Apr 13 22:52:04 1999 Donn Terry (donn@interix.com) + Martin Heller (Ing.-Buero_Heller@t-online.de) - * combine.c (expand_compound_operation): Fix thinko in code to optimize - (zero_extend:DI (subreg:SI (foo:DI) 0)) to foo:DI. + * configure.in (interix Alpha): Add. + (winnt Alpha): Use alpha32.h + (interix i386): Parallel Alpha32. + * configure: Rebuilt. - * Disable the following change from gcc2. Not appropriate for egcs: + * config/interix.h: Move common elements from i386-interix.h. + * config/i386/i386-interix.h: Delete same. + * config/alpha/alpha-interix.h: New file. - Sun Jun 7 09:30:31 1998 Richard Kenner - * reload.c (find_reloads): Give preference to pseudo that was the - reloaded output of previous insn. + * config/alpha/alpha32.h: New file, part fron win-nt.h. + * config/alpha/win-nt.h: Deletions (-> alpha32.h). + * config/alpha/interix.h: New file -Mon Jul 6 21:07:14 1998 Kaveh R. Ghazi + * config/alpha/alpha.md (interix): Comment. - * aclocal.m4 (GCC_FUNC_PRINTF_PTR): Don't define HOST_PTR_PRINTF. - Instead, define a new macro HAVE_PRINTF_PTR which only signifies - whether we have the %p format specifier or not. + * config/alpha/xm-alpha-interix.h: New file. - * acconfig.h: Delete stub for HOST_PTR_PRINTF, add HAVE_PRINTF_PTR. - - * machmode.h (HOST_PTR_PRINTF): When determining the definition, - check HAVE_PRINTF_PTR to see whether "%p" is okay. + * config/alpha/t-interix: New file. - * mips-tfile.c: Include machmode.h to get HOST_PTR_PRINTF. + * fixinc/mkfixinc.sh (interix/Alpha): Add. - * Makefile.in (mips-tfile.o): Depend on machmode.h. +1999-04-13 Mike Stump -Mon Jul 6 10:42:05 1998 Mark Mitchell + * i386/vxi386.h (CPP_CPU_SPEC): Define appropriately for vxworks. + (CPP_PREDEFINES, LIB_SPEC, STARTFILE_SPEC, ENDFILE_SPEC): likewise. - * jump.c (duplicate_loop_exit_test): Don't refuse to copy a - section of code just because it contains - NOTE_INSN_BLOCK_{BEG,END}. - * stmt.c (expand_end_loop): Likewise. Also, don't refuse to - move CALL_INSNs or CODE_LABELs. When moving code, don't move - NOTE_INSN_BLOCK_{BEG,END}. +Tue Apr 13 21:01:36 1999 Jason Merrill -Mon Jul 6 09:38:15 1998 Mark Mitchell + * c-common.c (default_valid_lang_attribute): New fn. + (valid_lang_attribute): New callback ptr. + (decl_attributes): Call it. Move init_priority support into + C++ frontend. - * cse.c (CSE_ADDRESS_COST): New macro, based on ADDRESS_COST, but - dealing with ADDRESSOF. - (find_best_addr): Use it. +Tue Apr 13 17:47:14 1999 John Wehle (john@feith.com) -Mon Jul 6 09:27:08 1998 Richard Henderson + * i386.md (movdi): Add splitter. - * alpha/vms.h (TRAMPOLINE_TEMPLATE): Revert last change. +Wed Apr 14 10:04:27 1999 Michael Hayes -Mon Jul 6 09:25:06 1998 Dave Love + * config/c4x/c4x.md (storeqf_int, storeqf_int_clobber, loadqf_int, + loadqf_int_clobber): Add new patterns with corresponding splitters + to handle moves of floating point values into and out of intager + registers by using memory. - * libgcc2.c (__eprintf): Make args consistent with prototype in - assert.h. + * config/c4x/c4x.c (c4x_check_legit_addr): Disallow PRE_INC for modes + other than QFmode and QImode. + (mixed_subreg_operand): New function. + (c4x_emit_move_sequence): If moving a floating point value into or + out of an integer register, use the new patterns storeqf_int_clobber + or loadqf_int_clobber. + (reg_imm_operand, *_reg_operand): Call reg_operand instead of + register_operand. + (reg_operand, src_operand): Disallow operand if it satisifes + mixed_subreg_operand. -Mon Jul 6 00:28:43 1998 Mark Mitchell + * config/c4x/c4x.h (mixed_subreg_operand): Add prototype. - * cse.c (cse_insn): When SETting (MEM (ADDRESSOF (X))) to Y, - don't claim that the former is equivalent to the latter. +Tue Apr 13 14:49:13 1999 Jan Hubicka -Sun Jul 5 23:58:19 1998 Jeffrey A Law (law@cygnus.com) + * i386.c (agi_dependent): Handle push operation more correctly. - * cse.c (cse_insn): Second arg is an RTX now. Update all callers. - (cse_basic_block): Keep track of the current RETVAL insn for a - libcall instead of just noting that we're in a libcall. +Tue Apr 13 14:45:17 1999 Jan Hubicka - * combine.c (simplify_comparison): Do not commute a AND into - a paradoxical SUBREG if not WORD_REGISTER_OPERATIONS. + * i386.md (anddi3): Add % constraint. + (iordi3, xordi3): Likewise. - * i386/freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Protect with - HAVE_GAS_MAX_SKIP_P2ALIGN. - * i386/linux.h: Likewise. - -Fri Jul 3 02:33:35 1998 David S. Miller - - * sparc.c (sparc_operand, move_operand, arith_operand, - arith11_operand, arith10_operand, arith_double_operand, - arith11_double_operand, arith10_double_operand, small_int, - uns_small_int): Recognize CONSTANT_P_RTX. - (output_sized_memop, output_move_with_extension, - output_load_address, output_size_for_block_move, - output_block_move, delay_operand): Remove, has not been - enabled or referenced for years. - * sparc.md (movstrsi, block_move_insn): Likewise. - * sparc.h (PREDICATE_CODES): Define. - * linux-aout.h (MACHINE_STATE_{SAVE,RESTORE}): Override with - version which uses getcc/setcc traps to save/restore condition - codes. - * linux64.h: Likewise. - * sunos4.h: Likewise. - * linux.h: Likewise. - * sol2.h: Likewise. - * sun4o3.h: Likewise. - -Fri Jul 3 02:28:05 1998 Richard Henderson - - * alpha.c (alpha_initialize_trampoline): Hack around Pmode/ptr_mode - lossage on VMS. Reported by kkaempf@rmi.de. - * alpha/vms.h (TRAMPOLINE_TEMPLATE): Add missing 0. - -Thu Jul 2 17:41:14 1998 Nick Clifton - - * config/m32r/m32r.h (MUST_PASS_IN_STACK): Override default - version. - -Thu Jul 2 14:34:48 1998 David Edelsohn - - * expr.h (STACK_SIZE_MODE): New macro. - * explow.c (allocate_dynamic_stack_space): Use it for - mode of allocate_stack pattern increment operand. - * tm.texi (STACK_SAVEAREA_MODE, STACK_SIZE_MODE): Document. - * md.texi (stack_save_block, ...): Reflect use of macro. - - * rs6000.h (PROMOTE_MODE): Always promote to word_mode. - (PROMOTE_FUNCTION_ARGS): Define. - (PROMOTE_FUNCTION_RETURN): Define. - (FUNCTION_VALUE): Promote to word_mode if smaller. - Convert to gen_rtx_FOO. - * rs6000.md (call_indirect): Store doubleword in 64-bit mode. - Convert to gen_rtx_FOO. - * rs6000.c: Convert to gen_rtx_FOO. - -Thu Jul 2 14:16:11 1998 Michael Meissner +Tue Apr 13 14:29:58 1999 Jan Hubicka - * varray.{c,h}: New files to provide virtual array support. + * i386.md (extendhisi2): Output mov instead of cw instruction for K6 + to improve decoding bandwidth. + * i386.md (extendhiqi2): Likewise. - * Makefile.in (OBJS): Add varray.o. - (varray.o): Add new file. - (REGS_H): New variable for dependencies for files including - regs.h. Add varray.h and files it includes. Change all regs.h - dependencies to $(REGS_H). +Tue Apr 13 14:26:31 1999 Jan Hubicka - * toplev.c (x{m,re}alloc): If size is 0, allocate 1 byte. - (xcalloc): Provide frontend for calloc. - * {tree,rtl}.h (xcalloc): Add declaration. + * i386.md (movsf_push): Handle memory to memory case too, new splitter. + (movdf_push, movxf_push): Likewise. + (movsf_push_memory, movdf_push_memory, movxf_push_memory): Remove. - * basic-block.h (REG_BASIC_BLOCK): Convert reg_n_info to be a - varray. +Tue Apr 13 14:14:06 1999 Jan Hubicka - * regs.h (toplevel): Include varray.h. - (reg_n_info): Switch to use a varray. - (REG_*): Ditto. - (allocate_reg_info): Change num_regs argument to be size_t. + * i386.md: Do not output mov %0,reg on AMD K6. - * regclass.c (reg_info_data): New structure to remember groups of - reg_info structures allocated that are to be zeroed. - ({pref,alt}class_buffer): New statics to hold buffers - allocate_reg_info allocates for {pref,alt}class_buffer. - (regclass): Use {pref,alt}class_buffer to initialize - {pref,alt}class. - (allocate_reg_info): Switch to make reg_n_info use varrays. - Allocate buffers for the preferred and alter register class - information. Change num_regs argument to be size_t, not int. +Tue Apr 13 12:14:07 1999 Dave Brolley - * flow.c (reg_n_info): Switch to use varrays. + * cppinit.c (cpp_start_read): Fix buffer overwrite. + * Makefile.in (cppinit.o): Typo in dependencies. -Thu Jul 2 10:11:47 1998 Robert Lipe +Tue Apr 13 05:04:59 1999 Richard Earnshaw (rearnsha@arm.com) - * install.texi (sco3.2v5): Document new --with-gnu-as flag. - * config/i386/sco5.h (JUMP_TABLES_IN_TEXT_SECTION): Defined as - in other targets. - (USE_GAS): Conditionalize away native assembler usage. - * config/i386/sco5gas.h: New file. - * config/i386/t-sco5gas: New file. - * configure.in (ix86-sco3.2v5*): Use new files if --with-gnu-as + * arm.h (function prototypes for arm.c): Ifdef these out if + HAVE_CONFIG_H is not defined. -Thu Jul 2 08:20:00 1998 Catherine Moore +Tue Apr 13 02:11:11 1999 Jeffrey A Law (law@cygnus.com) - * haifa-sched.c (alloc_EXPR_LIST): Change to use - unused_expr_list. + * pa.c: Avoid Using immediate zero for register zero. + * pa.md: Likewise. -Thu Jul 2 14:13:28 1998 Dave Love + * pa.c (print_operand, case 'f'): New case for FP register or 0.0. + (print_operand, case 'r'): Use %r0 for zero value. + * pa.md (move patterns, fcmp patterns): Use new %f output arg. - * Makefile.in (install-info): Don't use $realfile. Ignore - possible errors from the install-info program. + * pa.c: Use a register name, not a raw immediate in branch, + compare/clear, sub, subb, uaddcm and vshd instructions. + * pa.md: Likewise. -Thu Jul 2 01:53:32 1998 Alasdair Baird + * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. - * combine.c (simplify_comparison): Apply SUBREG_REG to SUBREGs. + * pa.c: Use a register name, not a raw immediate in "bv" instructions. + * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. -Wed Jul 1 23:06:03 1998 Richard Henderson + * pa.c: Remove space register specification in memory addresses, + except where it is actually needed. + * pa.md, pa.h, ee.asm, ee_fp.asm, lib2funcs.asm: Likewise. - * i386.h (HARD_REGNO_MODE_OK): Kill spurrious test. - (MODES_TIEABLE_P): Tie SImode and HImode. +Mon Apr 12 23:34:35 1999 Jeff Law (law@cygnus.com) -1998-07-01 Andreas Jaeger + * version.c: Bump for snapshot. - * invoke.texi (Optimize Options): Fix typo. +Mon Apr 12 14:58:30 1999 Jan Hubicka -Wed Jul 1 22:25:43 1998 Jim Wilson + * reg-stack.c (check_stack_regs_mentioned): Remove variable SIZE. - * xcoffout.c (xcoffout_begin_function): Call xcoffout_block for - the zero'th block. +Mon Apr 12 19:15:17 1999 Daniel Jacobowitz -Wed Jul 1 23:12:58 1998 Ken Raeburn + * rs6000/sysv4.h (CPP_OS_LINUX_SPEC): Add missing backslash. + +Mon Apr 12 19:11:38 1999 Mumit Khan + + * i386/cygwin.h (SUBTARGET_SWITCHES): Add -mconsole; fix + -mno-nop-fun-dllimport and minor doc fixes. + (STARTFILE_SPEC): Cygwin DLLs don't have dllcrt0. + (LINK_SPEC): Add -mconsole support. + * i386/mingw32.h (LIB_SPEC): Make libraries consistent with + Cygwin. + (LINK_SPEC): Remove. Use Cygwin's version. + (MATH_LIBRARY): Make it null. + * i386/crtdll.h (MATH_LIBRARY): Likewise. + +Fri Apr 12 15:00:52 1999 Stan Cox + + * c-decl.c (c_decode_option, start_decl, start_function, + finish_function) : Recognize -Wno-main so we can avoid warnings. + +1999-04-12 Zack Weinberg + + * cpphash.c (collect_expansion, macroexpand, + push_macro_expansion): Make the escape character in macro + buffers '\r', not '@'. Remove code to protect literal + occurences of the escape character; '\r' cannot appear + in a macro buffer unless we put it there. + * cpplib.c (skip_comment, copy_comment, cpp_skip_hspace, + copy_rest_of_line, cpp_get_token, parse_string, + parse_assertion): '\r' might be a backslash-newline marker, or + it might be a macro escape marker, depending on + CPP_BUFFER (pfile)->has_escapes. '@' is not a special + character. + * cpplib.h: Update commentary. + +Mon Apr 12 09:30:03 1999 Richard Earnshaw (rearnsha@arm.com) + + * arm.h (target_fp_name, structure_size_string, arm_cpu_select): + Const-ify. + * arm.c (target_fp_name, structure_size_string): Const-ify. + + * arm.md (reload_inhi, reload_outhi): Make the scratch DImode. + * arm.c (arm_reload_in_hi): Handle cases when the input is still + a pseudo, make use of scratch registers for reloading the address + as appropriate. + (arm_reload_outhi): Similarly for when the output is still a pseudo. + + * riscix.h (SUBTARGET_SWITCHES): Document. + +1999-04-12 Bruce Korb + + * fixincludes: + make fixincludes behave like the scripts in fixinc/ + + * Makefile.in( stmp-fixinc ): + ensure the SHELL value is that of the make + + * fixincl/inclhack.tpl: + the file name lists ought to be restricted to "*.h" anyway + C++ files may be named .../[a-z]++/... also + Adding copyright year and attribution to output + + * fixincl/inclhack.def: + fixed broken expression + Clarify a some comments + + * fixincl/fixincl.tpl: + Clarify a some comments + Remove dead template text + Correct the counting of regular expressions + +Mon Apr 12 03:07:44 1999 Richard Henderson + + * alpha.c (aligned_memory_operand): Handle out of range stack slots. + Take a new SCRATCH argument for the occasion. Update all callers. + (get_unaligned_address): Abort on out of range stack slots. + * alpha.md (adddi3 splitter): Check s_p_rtx not REGNO. + (reload_inqi): Check for aligned mems before unaligned. + (reload_inhi): Likewise. + +Mon Apr 12 03:11:30 1999 Jeffrey A Law (law@cygnus.com) + + * flow.c (flow_delete_insn): If we delete a CODE_LABEL, also remove + it from the nonlocal_goto_handler_labels list. + * jump.c (delete_insn): Likewise. + (jump_optimize_1): Also recompute LABEL_NUSES when we are just + marking labels. + * rtl.h (remove_node_from_expr_list): Declare. + * rtlanal.c (remove_node_from_expr_list): New function. + +Mon Apr 12 02:37:02 1999 Jan Hubicka + + * reg-stack.c: Update comment, include varray.h. + (stack_regs_mentioned_data): New global variable. + (check_stack_regs_mentioned): New function. + (stack_regs_mentioned): New function. + (reg_to_stack): Initialize and free stack_regs_mentioned_data, + use stack_regs_mentioned. + (record_asm_reg_life): Change insn type cache for changed insn. + (record_reg_life): Do not change the insn mode. + (emit_pop_insn): Likewise. + (emit_swap_insn): Likewise. + (move_for_stack_reg): Likewise. + (stack_reg_life_analysis): Use stack_regs_mentioned. + (emit_swap_insn): Likewise. + (subst_stack_regs): Likewise. + (convert_regs): Likewise. + * jump.c (find_cross_jump): Use stack_regs_mentioned. + * rtl.h (stack_regs_mentioned): Declare. - * h8300.c (print_operand): Delete %L support. - * h8300.md (branch_true, branch_false): Use %= with a prefix - instead of %L for local branch labels. +Mon Apr 12 00:57:10 1999 Theodore Papadopoulo -Wed Jul 1 21:27:13 1998 J"orn Rennecke + * integrate.c (INTEGRATE_THRESHOLD): Sync it with the comment. - * reload1.c (emit_reload_insns): Use proper register classes for - SECONDARY_INPUT_RELOAD_CLASS / SECONDARY_MEMORY_NEEDED code. +Sun Apr 11 10:24:18 1999 Mark Mitchell -Wed Jul 1 21:17:36 1998 J"orn Rennecke + * rtl.h (rtx_def): Update documentation for jump and call. - * reload.c (find_reloads): If there are multiple - RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads for - one operand, change RELOAD_FOR_INPADDR_ADDRESS / - RELOAD_FOR_OUTADDR_ADDRESS for all but the first - RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_OUTPUT_ADDRESS reloads. +Sun Apr 11 07:43:44 1999 Kaveh R. Ghazi -Wed Jul 1 17:23:23 1998 J"orn Rennecke + * jump.c (jump_optimize_1): Make the definition static to match + the prototype. - * regmove.c (fixup_match_2): Check that P has RTX_CLASS 'i' before - using its PATTERN. +Sat Apr 10 22:51:53 1999 Jan Hubicka -Wed Jul 1 05:04:41 1998 Richard Henderson + * flow.c (life_analysis): New parameter remove_dead_code. + (life_analysis_1): Likewise. + (propagate_block): Likewise; use it. + * output.h: Update prototype. + * toplev.c: Update calls to life_analysis. - * expr.c (emit_group_load, emit_group_store): Rewrite considering - the size and alignment of the structure being manipulated. - * expr.c, calls.c, function.c: Update all callers. - * expr.h: Update prototypes. - * cse.c (invalidate): Cope with parallels. +Sat Apr 10 22:12:12 1999 Jan Hubicka -Wed Jul 1 04:22:23 1998 Richard Henderson + * recog.c (constrain_operands): Ignore unary operators when + matching operands. Recognize '5'..'9' as well. - * sparc.c (function_arg_record_value): Take a MODE arg with which to - create the PARALLEL. Update all callers. +Sat Apr 10 21:53:02 1999 Philipp Thomas (kthomas@gwdg.de) + Richard Henderson -Wed Jul 1 04:10:35 1998 Richard Henderson + * configure.in: Set target_cpu_default2 for target_alias k6. + * i386.h (TARGET_SWITCHES): Remove no- entries. + (CC1_CPU_SPEC): Likewise. + (CPP_CPU_DEFAULT_SPEC): Streamline definition. Add K6 version. + (CPP_K6_SPEC): New. + (CPP_CPU_SPEC): Add K6 variant. + (EXTRA_SPECS): Likewise. - * expr.c (expand_assignment, store_constructor, expand_expr): Use - convert_memory_address instead of convert_to_mode when possible. +Fri Apr 9 11:29:17 1999 Richard Henderson -Wed Jul 1 03:48:00 1998 Richard Henderson + * flow.c (merge_blocks_nomove): Rewrite to properly handle two + blocks that vanish entirely during merging. - * alpha.c (alpha_initialize_trampoline): Take arguments describing - the layout. Use ptr_mode. Disable hint generation. Use gen_imb. - * alpha.h (INITIALIZE_TRAMPOLINE): Pass extra args to the init func. - (TRANSFER_FROM_TRAMPOLINE): Move ... - * alpha/osf.h: ... here. - * alpha/vms.h (INITIALIZE_TRAMPOLINE): Use alpha_initialize_trampoline. - (TRANSFER_FROM_TRAMPOLINE): Remove undef. - * alpha/win-nt.h: Likewise. - * alpha/vxworks.h: Likewise. +Sat Apr 10 20:09:55 1999 John Wehle (john@feith.com) - * alpha/linux.h: Revert gcc2 merge lossage. + * i386.md (floatsisf2, floatdisf2, floatsidf2, floatdidf2, + floatsixf2, floatdixf2, movsicc, movhicc, movsfcc, movdfcc, + movxfcc, movdicc): Remove unused register constraints from + the splitters. -Wed Jul 1 10:56:55 1998 Andreas Schwab + * i386.md (fixuns_truncsfsi2, fixuns_truncdfsi2, + fixuns_truncxfsi2): Delete. - * c-decl.c (grokdeclarator): Don't warn about implicit int in - `typedef foo = bar'. + * reg-stack.c (delete_insn_for_stacker): Ensure that + the only side effects of a PARALLEL are clobbers. + (subst_stack_regs): Handle subst_stack_regs_pat deleting + a PARALLEL. + * i386.md (extendsfdf2, extenddfxf2, + extendsfxf2): Rewrite using a splitter. + * i386.c (output_op_from_reg): Remove. + * i386.h: Likewise. -Wed Jul 1 02:12:33 1998 Robert Lipe +Sat Apr 10 13:09:18 1999 Nick Clifton - * i386.c (asm_output_function_prefix): Make 686 function - prologues not issue .types for non-global lables. + * config/arm/arm.c (di_operand): Allow SUBREGs as well. + (soft_df_operand): Allow SUBREGs as well. -Tue Jun 30 23:46:53 1998 Dmitrij Tejblum +Sat Apr 10 06:14:31 1999 Jan Hubicka - * i386/freebsd.h (WCHAR_TYPE): Chagne to an "int". - (WCHAR_TYPE_SIZE): Update appropriately. + * extend.texi (Assembler Instructions with C Expression Operands): + Document the i386 floating point operands. -Tue Jun 30 23:16:39 1998 Jeffrey A Law (law@cygnus.com) +1999-04-10 Mike Stump - * flow.c (recompute_reg_usage): Does not return a value. - * rtl.h (recompute_reg_usage): Update prototype. + * configure.in (*-*-vxworks): Add vxWorks thread support for all + vxWorks targets. + * configure.in (thumb-wrs-xvworks): Add vxWorks support for thumb. + * configure: Rebuilt. - * jump.c (jump_optimize): Show that the jump chain is not - valid when not optimizing. +Sat Apr 10 06:04:50 1999 Donn Terry (donn@interix.com) + + * i386/t-interix: Use mostly system headers unchanged. + Use system assert.h + * fixinc/fixinc.interix: Ditto (make almost no-op). + * config/x-interix.h (_ALL_SOURCE): add -D + * config/x-interix.h (crti.o): Delete dependency. + * config/xm-interix.h (ONLY_INT_FIELDS): Define only when bootstrapping. + * i386/xm-i386-interix.h: New file. + * i386/interix.h (ASM_OUTPUT_LIMITED_STRING): Fix warnings. + * i386/i386-interix.h: Renamed from interix.h. + * configure.in (interix): Use new files. + * configure: Rebuilt. -Tue Jun 30 16:01:01 1998 Richard Henderson +Sat Apr 10 05:25:28 1999 Daniel Jacobowitz + + * rs6000/sysv4.h (CPP_OS_LINUX_SPEC): Fix conditions + for -Dunix and -Dlinux, and remove duplicate definition. + Change -Asystem(linux) to -Asystem(posix). + (CPP_OS_SOLARIS_SPEC): Fix conditions for -Dunix, -Dsun, + -DSVR4, -D__EXTENSIONS__. + + * rs6000/linux.h (CPP_PREDEFINES): Remove -Dunix, + -Dlinux, -Asystem(linux), and -Asystem(unix). + +Sat Apr 10 05:14:50 1999 Mark Elbrecht + + * i386/djgpp.h (SET_ASM_OP): Define. + + * cccp.c (DIR_SEPARATOR): Move to the top of the file. + (is_dir_separator): New function. + (simplify_filename): Use it. + * collect2.c (find_a_file): Use HAVE_DOS_BASED_FILE_SYSTEM in place + of the DIR_SEPARATOR test. + Consider any file starting with a drivename to be absolute. + If the absolute filename test fails and EXECUTABLE_SUFFIX is + defined, append EXECUTABLE_SUFFIX to the file and try again. + * cppinit.c (base_name): Use HAVE_DOS_BASED_FILE_SYSTEM + in place of __MSDOS__ and _WIN32. + * cppfiles.c (simplify_pathname): Likewise. + * gcc.c (IS_DIR_SEPARATOR): Define new macro. Returns true if a + character is a directory separator. + (find_a_file): Use it. + (convert_filename): Likewise. + (process_command): Likewise. + (do_spec_1): Likewise. + (is_directory): Likewise. + (main): Likewise. + * prefix.c (IS_DIR_SEPARATOR): Define. Tests whether a character is + a directory separator. + (translate_name): Use it. + (update_path): Change DIR_SEPARATOR_2 to DIR_SEPARATOR. Fix + warning in block where '/' is changed to DIR_SEPARATOR. + * i386/xm-djgpp.h (DIR_SEPARATOR): Set to '/'. + (DIR_SEPARATOR_2): New macro. Set to '\'. + (HAVE_DOS_BASED_FILESYS): Define. + * i386/xm-mingw32.h: Updated copyright. Set + DIR_SEPARATOR_2 to '/'. Define HAVE_DOS_BASED_FILE_SYSTEM. + * i386/xm-os2.h: Likewise. + * winnt/xm-winnt.h: Likewise. + * i386/xm-dos.h: Likewise. Add copyright. + +1999-04-10 Joseph S. Myers + + * pdp11.h (TARGET_SWITCHES): Add option to vary assembler syntax. + (TARGET_DEFAULT): Possibly use UNIX syntax. + (TARGET_UNIX_ASM, TARGET_UNIX_ASM_DEFAULT): New macros. + (REGISTER_NAMES): Use "r5" instead of "fp". + (ASM_OUTPUT_ALIGN): Use ".even" directive, and abort for any + greater alignment. + * 2bsd.h (TARGET_UNIX_ASM_DEFAULT): Default to UNIX assembler + syntax for 2BSD. + * pdp11.c (output_ascii): Use working syntax for ".byte". + (print_operand_address): Use "*" instead of "@" when using UNIX + assembler syntax. + +Sat Apr 10 03:50:12 1999 Jeffrey A Law (law@cygnus.com) + + * rtl.h (rebuild_jump_labels): Declare. + * jump.c (jump_optimize_1): Renamed from jump_optimize. Make static. + Add new argument MARK_LABELS_ONLY. Quit after mark_all_labels if + requested. + (jump_optimize, rebuild_jump_labels): New wrapper functions for + jump_optimize_1. + * toplev.c (rest_of_compilation): Use rebuild_jump_labels instead of + running the entire jump optimizer. + + * rtl.h (local_alloc): Returns an integer now. + * local-alloc.c (recorded_label_ref): New file scoped variable. + (local_alloc): Initialize recorded_label_ref to zero. Return its + value when local allocation has completed. + (update_equiv_regs); If we create an equivalence for a LABEL_REF, + set recorded_label_ref. + * toplev.c (rest_of_compilation): Run the jump optimizer after + register allocation and reloading if needed. + +Fri Apr 9 21:02:57 1999 Krister Walfridsson (cato@df.lth.se) + + * i386/gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Fix typo. + * i386/freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. + +1999-04-09 Zack Weinberg + + * cpphash.c (special_symbol): When expanding __LINE__, use the + top file buffer, not the top buffer. + +Fri Apr 9 13:41:04 1999 Jim Wilson + + * Makefile.in (check-g++, check-gcc, check-g77, check-objc): Add + cd .. to TCL_LIBRARY command. + +Fri Apr 9 13:04:52 1999 Nick Clifton + + * config/arm/unknown-elf.h (SUBTARGET_CPU_DEFAULT): Only define if + not already specified. + +Fri Apr 9 11:18:55 1999 Jason Merrill + + * c-common.c (decl_attributes, A_INIT_PRIORITY): Allow arrays + of classes, too. + +Fri Apr 9 10:40:10 1999 Kaveh R. Ghazi + + * rs6000.c (rs6000_override_options, ptt, rs6000_file_start, + rs6000_float_const, rs6000_replace_regno, debug_stack_info, + rs6000_output_load_toc_table, output_prolog, output_epilog): + Const-ify a char*. + (output_mi_thunk): Likewise. Mark parameter `thunk_fndecl' with + ATTRIBUTE_UNUSED. Hide unused variables `r0', `sp', `toc', + `schain', `r12', `buf' and `labelno'. + (output_ascii): Const-ify a char*. + (rs6000_gen_section_name): Initialize variable `last_period'. + (rs6000_adjust_priority): Mark parameter `insn' with + ATTRIBUTE_UNUSED. + (rs6000_trampoline_template, rs6000_dll_import_ref, + rs6000_longcall_ref, rs6000_encode_section_info): Const-ify a char*. - * rtl.def (CONSTANT_P_RTX): New. - * rtl.h (CONSTANT_P): Recognize it. - * cse.c (fold_rtx): Eliminate it. - * expr.c (can_handle_constant_p): New variable. - (init_expr_once): Initialize it. - (expand_builtin): Generate CONSTANT_P_RTX if the expression is not - immediately recognizable as a constant. + * rs6000.h (offsettable_mem_operand, optimization_options): Add + prototypes. - * alpha.c (reg_or_6bit_operand): Recognize CONSTANT_P_RTX. - (reg_or_8bit_operand, cint8_operand, add_operand): Likewise. - (sext_add_operand, and_operand, or_operand): Likewise. - (reg_or_cint_operand, some_operand, input_operand): Likewise. - * alpha.h (PREDICATE_CODES): Add CONSTANT_P_RTX where needed. + * rs6000.md (movdi, define_split): Cast a value to HOST_WIDE_INT + when comparing against one. -1998-06-30 Benjamin Kosnik +Thu Apr 8 19:20:18 1999 Jeffrey A Law (law@cygnus.com) - * dbxout.c (dbxout_type_methods): Remove warn_template_debugging. + * expr.c (expand_expr, case ARRAY_REF, COMPONENT_REF, BIT_FIELD_REF): + Do not try to optimize a aggregate address which has VOIDmode. + Mirrors March 23 change to expand_assignment. -Tue Jun 30 14:03:34 1998 Kaveh R. Ghazi + * flow.c (delete_unreachable_blocks): Do not require EDGE_FALLTHRU + for an edge when tidying an edge which connects consecutive basic + blocks. - * aclocal.m4 (GCC_NEED_DECLARATION): Accept an optional second - argument, which is typically preprocessor code used to draw in - additional header files when looking for a function declaration. - (GCC_NEED_DECLARATIONS): Likewise. + * flow.c (can_delete_label_p): Do not convert a label into a + deleted label here. - * configure.in (GCC_NEED_DECLARATIONS): Add checks for getrlimit - and setrlimit, search for them in sys/resource.h. + * cse.c (flush_hash_table): New function. + (cse_insn): Flush the hash table when we encounter a volatile asm. + (cse_basic_block): Use flush_hash_table instead of doing it + inline. - * acconfig.h: Add stubs for NEED_DECLARATION_GETRLIMIT and - NEED_DECLARATION_SETRLIMIT. + * reload1.c (reload_cse_regs_1): Flush known register values if + we encounter a volatile asm. - * system.h: Prototype getrlimit/setrlimit if necessary. + * loop.c (strength_reduce): Re-enable Joern's loop improvements. -Tue Jun 30 10:54:48 1998 Mark Mitchell +Thu Apr 8 09:37:40 1999 Nick Clifton - * rtl.texi: Don't say that RTX_INTEGRATED_P is not depended - upon. + * config/arm/arm.c (arm_print_operand): Undo previous change - + always print large constants in decimal. -Tue Jun 30 13:11:42 1998 Franz Sirl +Thu Apr 8 10:22:23 1999 Kaveh R. Ghazi - * rs6000/sysv4.h (asm output): add tabs for asm directives. + * configure.in (host_xm_file, build_xm_file): Include hwint.h. + Use case statements instead of "if test -a ... -a ... -a ..." -Tue Jun 30 13:11:42 1998 David Edelsohn + * machmode.h: Don't define HOST_WIDE_INT, etc. Wrap use of + HOST_WIDE_INT in #ifdef. - * Makefile.in (FLAGS_TO_PASS): Set AR_FLAGS to AR_FOR_TARGET_FLAGS. + * mips.h: Include hwint.h instead of providing definitions for + HOST_WIDE_INT, etc. Wrap uses of HOST_WIDE_INT in #ifdef. -Tue Jun 30 08:59:15 1998 Kaveh R. Ghazi +Thu Apr 8 06:16:14 1999 John Wehle (john@feith.com) - * gansidecl.h (ATTRIBUTE_UNUSED): Use __unused__ not `unused'. - Don't define NULL here. Also, remove all vestiges of autoconf - based checks for bcmp/bcopy/bzero/index/rindex. + * i386.md (truncdfsf2, truncxfsf2, + truncxfdf2): Rewrite using a splitter. - * system.h: Immediately after including stdio.h, check for and if - necessary provide a default definition of NULL. +Thu Apr 8 01:26:05 1999 Arg Haas (ahaas@neosoft.com) + Jeffrey A Law (law@cygnus.com) -Tue Jun 30 08:22:05 1998 Michael Meissner + * freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Avoid ambiguous + else statement. + * gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. + * linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. + * openbsd.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Likewise. - * reload1.c (reload_cse_simplify_operands): Call - fatal_insn_not_found, not abort. +Wed Apr 7 22:40:19 1999 Jim Wilson -Tue Jun 30 02:34:02 1998 Jeffrey A Law (law@cygnus.com) + * i960/i960.c (i960_function_prologue): Don't save static chain + pointer. + * i960/i960.h (STACK_CHAIN_REGNUM): Change from r3 to g12. + (TRAMPOLINE_TEMPLATE): Likewise. + (FRAME_POINTER_REQUIRED): Check current_function_has_nonlocal_goto. + * i960/i960.md (nonlocal_goto): Rewrite. - * choose-temp.c (make_temp_file): Accept new argument for the - file suffix to use. Allocate space for it and add it to the - template. - * mkstemp.c (mkstemps): Renamed from mkstemp. Accept new argument - for the length of the suffix. Update template struture checks - to handle optinal suffix. - * collect2.c (make_temp_file): Update prototype. - (main): Put proper suffixes on temporary files. - * gcc.c (make_temp_file): Update prototype. - (do_spec_1): Put proper suffixes on temporary files. +Tue Apr 6 17:49:49 1999 Philip Blundell -Tue Jun 30 00:56:19 1998 Bruno Haible + * config/arm/lib1funcs.asm: Test for __ELF__ not __elf__. - * invoke.texi: Document new implicit structure initialization - warning. +Wed Apr 7 14:07:34 1999 Jeffrey A Law (law@cygnus.com) -Mon Jun 29 22:12:06 1998 Jeffrey A Law (law@cygnus.com) + * h8300.c (h8300_adjust_insn_length): Also avoid recognizing + ADDR_VEC and ADDR_DIFF_VEC insns. - * Merge from gcc2 June 9, 1998 snapshot. See ChangeLog.13 for - details. + * h8300.c (h8300_adjust_insn_length): Avoid trying to recognize + USE, CLOBBER or SEQUENCE insns. - * pa.c, pa.h, pa.md: Convert to gen_rtx_FOO. + * unroll.c (unroll_loop): For HAVE_cc0 machines, adjust copy_end_luid + to account for the uncopied insn that sets cc0 at the end of the loop. -Mon Jun 29 20:12:41 1998 Kaveh R. Ghazi + * unroll.c (copy_loop_body): Always ensure at least two insns + are in the copied loop. - * Makefile.in (fix-header): Don't needlessly depend on cpperror.o. +Wed Apr 7 14:52:18 1999 Catherine Moore - * alias.c (CHECK_ALIAS_SETS_FOR_CONSISTENCY): Cast expansion to - void since it is evaluated in a comma list. + * config/mips/elf.h (MAKE_DECL_ONE_ONLY): Define. + (UNIQUE_SECTION_P): Define. - * mips.h (ASM_GENERATE_INTERNAL_LABEL): Always sprintf `NUM' - argument as a long and cast `NUM' to long to ensure it is of the - proper width. Wrap macro arguments in parens when they appear in - the expansion. +1999-04-07 Bruce Korb - * sol2.h (ASM_GENERATE_INTERNAL_LABEL): Likewise. + * fixinc/inclhack.tpl & fixincl.tpl: + Remove dynamic content from generated files - * sparc.h (ASM_GENERATE_INTERNAL_LABEL): Likewise. - (ASM_DECLARE_RESULT): Fix fprintf format specifier to match - function argument return type. - (REGNO_OK_FOR_INDEX_P, REGNO_OK_FOR_BASE_P, REGNO_OK_FOR_FP_P, - REGNO_OK_FOR_CCFP_P): Use `(unsigned)' not `U'. +Wed Apr 7 13:16:22 1999 John Wehle (john@feith.com) - * cpplib.c (cpp_message_from_errno): Remove unneeded argument to - cpp_message. + * i386.c (output_move_memory): Remove. + * i386.h: Likewise. - * dbxout.c: Fix the comments after an #endif to reflect the actual - condition tested in the preceding #if. + * i386.md (movsi, movhi, movstricthi, movqi, movstrictqi, + movsf, movdf, movxf, movdi): Check no_new_pseudos instead + of (reload_in_progress | reload_completed). - * except.c (find_all_handler_type_matches): Switch to old-style - function definition. +Wed Apr 7 03:16:45 1999 Richard Henderson - * expr.c (expand_builtin): Remove unused variable `type' twice. + * alpha.c (reg_no_subreg_operand): New function. + * alpha.h (PREDICATE_CODES): Add it. + * alpha.md (floatdi?f patterns): Use it for op1. - * gbl-ctors.h (DO_GLOBAL_CTORS_BODY): Cast -1 before comparing it - to an unsigned long. + * alpha.c (alpha_end_function): Don't flag weak functions. - * haifa-sched.c (print_insn_chain): Remove unused function. +Wed Apr 7 02:11:55 1999 Richard Henderson - * objc/objc-act.c (build_msg_pool_reference): Hide prototype and - definition. + * expr.c (expand_builtin) [BUILT_IN_RETURN_ADDRESS]: Use + copy_to_mode_reg; don't force constants into a register. - * toplev.c: When testing whether to include dbxout.h, also include - it when XCOFF_DEBUGGING_INFO is defined. +Tue Apr 6 22:55:25 1999 Richard Henderson - * unroll.c (unroll_loop): Add parentheses around assignment used - as truth value. + * toplev.c (compile_file): Typo flow_dump -> flow2_dump. -Mon Jun 29 12:18:00 1998 Catherine Moore +1999-04-06 Joseph S. Myers - * config/lb1spc.asm (.div, .udiv): Replace routines. + * pdp11.c (simple_memory_operand): Add default case in switch. + * pdp11.h (TARGET_SWITCHES): Add help strings. + (NOTICE_UPDATE_CC): Don't include excess argument to format. + (ASM_OUTPUT_DOUBLE_INT): Remove. -Mon Jun 29 09:44:24 1998 Mark Mitchell +Tue Apr 6 22:09:40 1999 Richard Henderson - * rtl.h: Update comment about special gen_rtx variants. - * emit-rtl.c (gen_rtx): Handle MEMs using gen_rtx_MEM. + * expr.c (expand_builtin_setjmp): Put setjmp return label on + nonlocal_goto_handler_labels for flow. -Sun Jun 28 20:58:51 1998 Jeffrey A Law (law@cygnus.com) +Tue Apr 6 22:05:21 1999 Jan Hubicka + Richard Henderson - * choose-temp.c (choose_temp_base): Restore original variant of - this function for compatibility. - (make_temp_file): This is the new, preferred interface to create - temporary files. - * collect2.c (choose_temp_base): Delete declaration. - (make_temp_file): Declare. - (temp_filename_length, temp_filename): Delete. - (main): Use make_temp_file to get temporary files. Use --lang-c - to force the resulting ctort/dtor file to be compiled with the C - compiler. Make sure to remove temporary files on all exit paths. - * gcc.c (make_temp_file): Provide prototype if MKTEMP_EACH_FILE is - defined. - (choose_temp_base): Only provide prototype if MKTEMP_EACH_FILE is - not defined. - (do_spec): Use make_temp_file if MKTEMP_EACH_FILE is defined. + * flow.c (verify_flow_info): New function. + (find_basic_blocks): Call it if ENABLE_CHECKING. + (merge_blocks): Don't merge if there are non-deletable labels. + * toplev.c (fatal_insn): Allow a printf-style arg list. + * toplev.h (fatal_insn): Update prototype. -Sun Jun 28 08:57:09 1998 Kaveh R. Ghazi +Tue Apr 6 16:18:58 1999 Jan Hubicka - * configure.in (GCC_NEED_DECLARATIONS): Add strerror, getcwd and - getwd. + * flow.c (split_edge) update correctly flow graph, disable + EDGE_CRITICAL flag on the split edge, update NUSES for new label. - * acconfig.m4: Add stubs for NEED_DECLARATION_STRERROR, - NEED_DECLARATION_GETCWD and NEED_DECLARATION_GETWD. +Tue Apr 6 15:47:51 1999 Richard Henderson - * cccp.c: Remove strerror()/sys_nerr/sys_errlist decls. - (my_strerror): Add prototype and make it static. + * emit-rtl.c (gen_rtx_CONST_DOUBLE): Use XWINT not XINT. + Clear third and following slots, if they exist. - * collect2.c: Likewise. +Tue Apr 6 15:45:28 1999 Richard Henderson - * cpplib.c: Likewise. + * flow.c (create_basic_block): Make sure the bb note is in the block. + (can_delete_note_p): Rename from delete_note_p. + (delete_insn_chain): Preserve undeleteable labels too. + (tidy_fallthru_edge): Use next_real_insn instead of confusing + inline code. - * gcc.c: Likewise, but keep `my_strerror' extern. +1999-04-06 Zack Weinberg - * protoize.c: Likewise. + * cppexp.c (parse_charconst): Initialize c. + (cpp_parse_expr): Initialize rprio. + * cppfiles.c (merge_include_chains): Initialize prev. + (finclude): Set fp->line_base to fp->buf before returning. + * cpphash.c (macroexpand): Initialize token. + * cppspec.c (lang_specific_driver): Change suff to + const char *const *. - * pexecute.c (my_strerror): Add argument to prototype. +1999-04-06 Zack Weinberg - * system.h: Add prototypes for getcwd, getwd and strerror. Add - extern decls for sys_nerr and sys_errlist. Make abort decl - explicitly extern. + * cppinit.c (install_predefs): Delete function. + (cpp_start_read): Don't call install_predefs. + (cpp_handle_option): Remove case 'u' and all refs to + opts->inhibit_predefs. + (print_help): Don't mention -undef. + (initialize_builtins): Define __HAVE_BUILTIN_SETJMP__, to + match cccp. + * cpplib.h (struct cpp_options): Remove inhibit_predefs + member. - * getpwd.c: Remove decls for getwd and getcwd. + * cccp.c (predefs): Delete variable. + (main): Remove case 'u' in argument parse loop, + 'inhibit_predefs' variable, and the code block that would + process CPP_PREDEFINES. + (initialize_builtins): Don't define __OBJC__, the driver will + do that. -Sun Jun 28 02:11:16 PDT 1998 Jeff Law (law@cygnus.com) + * gcc.c (default_compilers): Remove -undef from all specs that + invoke a C preprocessor. + * ch/lang-specs.h: Likewise. + * cp/lang-specs.h: Likewise. + * f/lang-specs.h: Likewise. + * objc/lang-specs.h: Likewise. - * version.c: Bump for snapshot. +Mon Apr 5 11:55:31 1999 Donn Terry (donn@interix.com) -Sat Jun 27 23:32:25 1998 Richard Henderson - - * jump.c (jump_optimize): Use side_effects_p & may_trap_p instead - of rtx_unsafe_p. Use modified_between_p instead of reg_set_between_p. - Allow FP moves to be optimized. - (rtx_unsafe_p): Delete. - -Sat Jun 27 23:02:04 1998 Richard Henderson - - * objc/archive.c: Remove prototypes. - -Sat Jun 27 22:37:05 1998 Jeffrey A Law (law@cygnus.com) - - * tm.texi (NEED_MATH_LIBRARY): Document new target macro. - - * Makefile.in (gencheck): Remove $(TREE_H) dependency. - -Sat Jun 27 20:20:00 1998 John Carr - - * dsp16xx.h (FIRST_PSEUDO_REGISTER): Add parentheses to definition. - * dsp16xx.c (next_cc_user_unsigned): New function. - Remove save_next_cc_user_code. - (print_operand): Use HOST_WIDE_INT_PRINT_* macros. - * dsp16xx.md: Call next_cc_user_unsigned instead of using - save_next_cc_user_code. - Use gen_rtx_* functions instead of gen_rtx. - -Sat Jun 27 20:18:34 1998 Franz Sirl - - * rs6000.h: Add trap_comparison_operator to PREDICATE_CODES. - -Sat Jun 27 16:45:42 1998 Jeffrey A Law (law@cygnus.com) - - * flow.c (count_reg_sets): New function. - (count_reg_sets_1, count_ref_references): Likewise. - (recompute_reg_usage): Likewise. - * rtl.h (recompute_reg_usage): Add prototype. - * toplev.c (rest_of_compilation): Call recompute_reg_usage just - before local register allocation. - -Sat Jun 27 13:15:30 1998 Richard Henderson - - * alpha.md (negsf, negdf): Revert Jan 22 change. - -Sat Jun 27 07:35:21 1998 Kaveh R. Ghazi - - * mkstemp.c: Include gansidecl.h. Rename uint64_t to gcc_uint64_t. - (mkstemp): Remove size specifier for variable `letters'. Call - gettimeofday, not __gettimeofday. - - * Makefile.in (EXPR_H): New dependency variable. - (c-typeck.o): Depend on $(EXPR_H) instead of expr.h. - (c-iterate.o): Likewise. - (gencheck): Depend on $(TREE_H) instead of tree.h, etc. - (stor-layout.o): Depend on $(EXPR_H) instead of expr.h. - (toplev.o): Likewise. Also depend on $(RECOG_H) instead of recog.h. - (varasm.o): Depend on $(EXPR_H) instead of expr.h. - (function.o): Likewise. - (stmt.o): Likewise. - (except.o): Likewise. - (expr.o): Likewise. - (calls.o): Likewise. - (expmed.o): Likewise. - (explow.o): Likewise. - (optabs.o): Likewise. - (sdbout.o): Likewise. - (dwarf2out.o): Likewise. - (emit-rtl.o): Likewise. - (integrate.o): Likewise. - (jump.o): Likewise. - (cse.o): Likewise. - (gcse.o): Likewise. Also depend on $(BASIC_BLOCK_H) instead of - basic-block.h. - (loop.o): Depend on $(EXPR_H) instead of expr.h. - (unroll.o): Likewise. - (combine.o): Likewise. - (reload.o): Likewise. - (reload1.o): Likewise. - (caller-save.o): Likewise. - (reorg.o): Likewise. - (alias.o): Don't depend on insn-codes.h. - (regmove.o): Depend on $(RECOG_H)/$(EXPR_H) instead of recog.h/expr.h. - (insn-emit.o): Depend on $(EXPR_H) instead of expr.h. - (insn-opinit.o): Likewise. - -Sat Jun 27 01:35:14 1998 Jeffrey A Law (law@cygnus.com) - - * choose-temp.c (choose_temp_base): Remove MPW bits. Use mkstemp - instead of mktemp. - * gcc.c (MKTEMP_EACH_FILE): Define. - (main): No need to call choose_temp_base if we are going to - use choose_temp_base to create each file later. - * mkstemp.c: New file. Adapted from glibc. - * Makefile.in (xgcc, colect2, protoize, unprotoize): Link in mkstemp.o - (mkstemp.o): Add dependencies. - - * configure.in (gettimeofday): Check for its existance. - * config.in (HAVE_GETTIMEOFDAY): Define. - * configure: Rebuilt. + * Makefile.in (SUBDIR_FLAGS_TO_PASS): Fix misapplied patch. -1998-06-26 Michael Meissner +Mon Apr 5 11:51:38 1999 Jeffrey A Law (law@cygnus.com) - * rs6000.md (ne 0, non power case): Add missing & constraint. - Name pattern ne0. - (negative abs insns): Add pattern names. + * m68k.md (movdf): Hide GPR sources & destinations from regclass. -Fri Jun 26 17:36:42 1998 Dave Love +Mon Apr 5 09:54:42 1999 Jeff Law (law@cygnus.com) - * Makefile.in (install-info): Run install-info program in separate - loop. + * version.c: Bump for snapshot. -Fri Jun 26 16:03:15 1998 Michael Meissner +Mon Apr 5 05:55:15 1999 Bruce Korb - * haifa-sched.c (schedule_block): Add hooks for the machine - description to reorder the ready list, and update how many more - instructions can be issued this cycle. - * tm.texi (MD_SCHED_{INIT,REORDER,VARIABLE_ISSUE}): Document. - -Fri Jun 26 11:54:11 1998 David S. Miller - - * config/sparc/sparc.h (REGNO_OK_FOR_{INDEX,BASE,FP,CCFP}_P): - Explicitly mark the constant being compared against as unsigned. - * config/sparc/sparc.c (sparc_select, cpu_default, cpu_table): - Fully initialize final members. - (mem_aligned_8): Explicit init of offset to zero. - (output_function_prologue): Explicit init of n_regs to zero. - (output_function_epilogue): Likewise, and mark arg size as - unused. - (init_cumulative_args): Mark libname and indirect as unused. - (function_arg_pass_by_reference): Likewise for cum and named. - (sparc_builtin_saveregs): Likewise for arglist. - (sparc_flat_eligible_for_epilogue_delay): Likewise for slot. - -Fri Jun 26 06:58:54 1998 Richard Earnshaw (rearnsha@arm.com) - - * arm.h (SECONDARY_INPUT_RELOAD_CLASS): Only need a secondary reload - if reloading a MEM. - - * arm.h (arm_adjust_cost): Renamed bogus prototype from - arm_adjust_code. - (bad_signed_byte_operand): Add prototype. - * arm.c (arm_override_options): Make I unsigned. - (const_ok_for_arm): Add casts to the constants. - (load_multiple_operation): Don't redeclare elt in sub-block. - (arm_gen_movstrqi): Delete external declaration of optimize. - (gen_compare_reg): Declare parameter fp. - - * arm.c (final_prescan_insn): Only initialize scanbody if the insn - has a pattern. - -Fri Jun 26 09:31:24 1998 Kaveh R. Ghazi - - * alpha.c: Include system.h and toplev.h. - (cint8_operand): Mark parameter `mode' with ATTRIBUTE_UNUSED. - (const48_operand): Likewise. - (mode_width_operand): Likewise. - (mode_mask_operand): Likewise. - (mul8_operand): Likewise. - (current_file_function_operand): Likewise. - (signed_comparison_operator): Likewise. - (divmod_operator): Likewise. - (any_memory_operand): Likewise. - (alpha_return_addr): Likewise for parameter `frame'. - (alpha_builtin_saveregs): Likewise for parameter `arglist'. - (vms_valid_decl_attribute_p): Likewise for parameters `decl' and - `attributes'. - (alpha_start_function): Likewise for parameter `decl'. Use - HOST_WIDE_INT_PRINT_DEC in call to fprintf. Fix various format - specifiers. Remove unused variables `lab' and `name'. - (alpha_end_function): Mark parameter `decl' with ATTRIBUTE_UNUSED. - (check_float_value): Likewise for parameter `overflow'. - (alpha_need_linkage): Likewise for parameters `name' and `is_local'. - - * alpha.h (ASM_IDENTIFY_GCC, ASM_IDENTIFY_LANGUAGE): Define as - taking an argument. - (ASM_OUTPUT_SHORT): Cast argument to `int' in call to fprintf. - (ASM_OUTPUT_CHAR): Likewise. - (ASM_OUTPUT_BYTE): Likewise. - (PRINT_OPERAND_ADDRESS): Use HOST_WIDE_INT_PRINT_DEC in call to - fprintf. - (PUT_SDB_EPILOGUE_END): Mention argument `NAME' in definition. - Add prototypes for functions in alpha.c. - - * alpha.md (ashldi3): Add default case in switch. - -1998-06-26 Manfred Hollstein - - * Makefile.in (gcc_version, gcc_version_trigger): New macros. - (version): Initialize from $(gcc_version). - - * configure.in (version): Rename to gcc_version. - (gcc_version_trigger): New variable; call AC_SUBST for it and - emit it into the generated config.status. - * configure: Regenerate. + * fixincl.tpl: Separate "-e" from its argument, a la + the Sat Apr 3 17:05:13 1999 fix. + * genfixes: Ensure that the server shell is _NOT_ csh. -Thu Jun 25 12:47:41 1998 Mark Mitchell +Mon Apr 5 03:52:30 1999 Jeff Law (law@cygnus.com) - * fold-const.c (make_range): Don't go looking at TREE_OPERANDs of - nodes that are not expressions. + * version.c: Bump for snapshot. -Thu Jun 25 15:08:16 1998 Mark Mitchell +Mon Apr 5 04:47:14 1999 Jeffrey A Law (law@cygnus.com) - * invoke.texi (-fstrict-aliasing): Document. - * rtl.texi (MEM_ALIAS_SET): Document. + * i386.c (x86_double_with_add): Turn off for Pentium and PPro. + (small_shift_operand, output_ashlsi3): New functions. + * i386.h (small_shift_operand, output_ashlsi3): Declare. + * i386.md (ashlsi3): Simplify ahlsi3 patterns. Remove splitters + that are no longer needed. - * flags.h (flag_strict_aliasing): Declare. - * toplev.c (flag_strict_aliasing): Define. - (f_options): Add -strict-aliasing. - (main): Set flag_strict_aliasing if -O2 or higher. +Sun Apr 4 04:05:04 1999 Jeffrey A Law (law@cygnus.com) - * tree.h (tree_type): Add alias_set field. - (TYPE_ALIAS_SET): New macro. - (TYPE_ALIAS_SET_KNOWN_P): Likewise. - (get_alias_set): Declare. - * tree.c (lang_get_alias_set): Define. - (make_node): Initialize TYPE_ALIAS_SET. - (get_alias_set): New function. - * print-tree.c (print_node): Dump the alias set for a type. + * stmt.c (expand_loop_end): When copying the loop exit test, + do not walk into a nested loop. - * c-tree.h (c_get_alias_set): Declare. - * c-common.c (c_get_alias_set): New function. - * c-decl.c (init_decl_processing): Set lang_get_alias_set. +Sun Apr 4 00:14:54 1999 Jeffrey A Law (law@cygnus.com) - * expr.c (protect_from_queue): Propogage alias sets. - (expand_assignment): Calculate alias set for new MEMs. - (expand_expr): Likewise. - * function.c (put_var_into_stack): Likewise. - (put_reg_into_stack): Likewise. - (gen_mem_addressof): Likewise. - (assign_parms): Likewise. - * stmt.c (expand_decl): Likewise. - * varasm.c (make_decl_rtl): Eliminate redundant clearing of - DECL_RTL. Calculate alias set for new MEMs. - - * rtl.def (REG): Add dummy operand. - (MEM): Add extra operand to store the MEM_ALIAS_SET. - * rtl.h (MEM_ALIAS_SET): New macro. - (gen_rtx_MEM): Declare. - * emit-rtl.c (gen_rtx_MEM): New function. - * gengenrtl.c (sepcial_rtx): Make MEMs special. - - * alias.c (CHECK_ALIAS_SETS_FOR_CONSISTENCY): New macro. - (DIFFERENT_ALIAS_SETS_P): Likewise. - (canon_rtx): Propogate the alias set to the new MEM. - (true_dependence): Check the alias sets. - (anti_dependence): Likewise. - (output_dependence): Likewise. - * explow.c (stabilize): Progoate alias sets. - * integrate.c (copy_rtx_and_substitute): Likewise. - * final.c (alter_subreg): Make sure not to leave MEM_IN_STRUCT_P - in an unpredictable state. Propogate alias sets. - * reload1.c (reload): Clear MEM_ALIAS_SET for new MEMs about which - we have no alias information. - -Thu Jun 25 16:59:18 EDT 1998 Andrew MacLeod - - * except.h (CATCH_ALL_TYPE): Definition moved to eh-common.h. - (find_all_handler_type_matches): Add function prototype. - * eh-common.h (CATCH_ALL_TYPE): Definition added. - * except.c (find_all_handler_type_matches): Add function to find all - runtime type info in the exception table. - (output_exception_table_entry): Special case for CATCH_ALL_TYPE. - -Thu Jun 25 15:47:55 1998 Kaveh R. Ghazi - - * Makefile.in (xcoffout.o): Depend on toplev.h, output.h and dbxout.h. - - * config/fp-bit.c (_fpmul_parts): Move variables `x', `ylow', - `yhigh' and `bit' into the scope in which they are used. - (_fpdiv_parts): Remove unused variables `low', `high', `r0', `r1', - `y0', `y1', `q', `remainder', `carry', `d0' and `d1'. - - * rs6000.c: Move include of output.h below tree.h. Include toplev.h. - (any_operand): Mark unused parameters `op' and `mode' with - ATTRIBUTE_UNUSED. - (count_register_operand): Likewise for parameter `mode'. - (fpmem_operand): Likewise. - (short_cint_operand): Likewise. - (u_short_cint_operand): Likewise. - (non_short_cint_operand): Likewise. - (got_operand): Likewise. - (got_no_const_operand): Likewise. - (non_add_cint_operand): Likewise. - (non_logical_cint_operand): Likewise. - (mask_operand): Likewise. - (current_file_function_operand): Likewise. - (small_data_operand): Likewise for parameters `op' and `mode' but - only when !TARGET_ELF. - (init_cumulative_args): Mark parameters `libname' with - ATTRIBUTE_UNUSED. - (function_arg_pass_by_reference): Likewise for parameters `cum', - `mode' and `named'. - (expand_builtin_saveregs): Likewise for parameter `args'. - (load_multiple_operation): Likewise for parameter `mode'. - (store_multiple_operation): Likewise. - (branch_comparison_operator): Likewise. - (secondary_reload_class): Likewise. - (print_operand): Add parentheses around & operation. - (output_prolog): Mark parameter `size' with ATTRIBUTE_UNUSED. - (output_epilog): Likewise. Cast argument to fprintf to int. - (rs6000_adjust_cost): Mark parameter `dep_insn' with ATTRIBUTE_UNUSED. - (rs6000_valid_decl_attribute_p): Likewise for parameters `decl', - `attributes', `identifier' and `args'. - (rs6000_valid_type_attribute_p): Likewise for parameter `attributes'. - (rs6000_comp_type_attributes): Likewise for parameters `type1' and - `type2'. - (rs6000_set_default_type_attributes): Likewise for parameter `type'. - - * rs6000.h (RTX_COSTS): Add parentheses around & operation. - (toc_section, private_data_section, trap_comparison_operator): Add - prototypes. + * fixinc/hackshell.tpl: Skip links to directories, to avoid + removing them. + * fixinc/inclhack.tpl: Likewise. + * fixinc/fixinc.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Rebuilt. - * dbxout.h (dbxout_parms, dbxout_reg_parms, dbxout_syms): Add - prototypes. +Sat Apr 3 23:46:13 1999 David Edelsohn - * xcoffout.c: Include toplev.h, outout.h and dbxout.h. + * rs6000.md (addsi3, iorsi3, xorsi3, adddi3, iordi3, xordi3, + movsi_got, movsi, movsf): Use no_new_pseudos. + * rs6000.c (rs6000_got_register): Likewise. + (offsettable_mem_opereand): Use || not |. - * xcoffout.h (stab_to_sclass, xcoffout_begin_function, - xcoffout_begin_block, xcoffout_end_epilogue, - xcoffout_end_function, xcoffout_end_block, - xcoff_output_standard_types, xcoffout_declare_function, - xcoffout_source_line): Add prototypes. +Sat Apr 3 22:02:56 1999 Jeffrey A Law (law@cygnus.com) -Thu Jun 25 09:54:55 1998 Nick Clifton + * acconfig.h (ENABLE_CHECKING): Remove redundant #undef. + * config.in: Rebuilt. - * config/arm/arm.h (REG_ALLOC_ORDER): Add ARG_POINTER_REGNUM, - noticed by grahams@rcp.co.uk. +Sat Apr 3 16:22:59 1999 Toshiyasu Morita (tm@netcom.com) -Thu Jun 25 11:12:29 1998 Dave Brolley + * gcc.texi: Add info on regmove pass. - * gcc.c (default_compilers): Use new | syntax to eliminate - string concatenation. + * regmove.c (fixup_match_1): Consistently evaluate + HAVE_POST_INCREMENT and HAVE_POST_DECREMENT. -Thu Jun 25 01:00:48 1998 Richard Henderson +Sat Apr 3 19:21:05 1999 Alexandre Oliva - * alpha.c (alpha_function_name): Delete. - (alpha_ra_ever_killed): Notice current_function_is_thunk. - (alpha_sa_mask, alpha_sa_size, alpha_does_function_need_gp): Likewise. - (alpha_start_function): Reorg from output_prologue. - (alpha_end_function): Reorg from output_epilogue. - * alpha.h (ASM_DECLARE_FUNCTION_NAME): Call alpha_start_function. - (ASM_DECLARE_FUNCTION_SIZE): New. - (FUNCTION_PROLOGUE, FUNCTION_EPILOGUE): Delete. - (PROFILE_BEFORE_PROLOGUE): Set. - (ASM_OUTPUT_MI_THUNK): Remove bits now output by start/end_function. - * alpha/win-nt.h (ASM_OUTPUT_MI_THUNK): Likewise. + * configure.in (DEFAULT_LINKER, DEFAULT_ASSEMBLER): Use grep + instead of test and sed to check whether they're GNU programs. + * configure: Rebuilt. -Thu Jun 25 01:18:47 1998 John Wehle (john@feith.com) +Sat Apr 3 17:57:35 1999 Alexandre Oliva - * i386/freebsd-elf.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Define. + * Makefile.in (install-headers-tar, install-headers-cpio): Avoid + problems with CDPATH. + Reported by Ralf Canis -1998-06-25 Herman A.J. ten Brugge +Sat Apr 3 13:50:16 1999 Jeffrey A Law (law@cygnus.com) - * expr.c (expand_assignment): Rework address calculation for structure - field members to expose more invariant computations to the loop - optimizer. - (expand_expr): Likewise. + * fixinc.x86-linux-gnu: Deleted. -Wed Jun 24 22:44:22 1998 Jeffrey A Law (law@cygnus.com) +Sat Apr 3 17:05:13 1999 Alexandre Oliva - * local-alloc.c (block_alloc): Do not try to avoid false dependencies - when SMALL_REGISTER_CLASSES is nonzero. + * inclhack.tpl: Insert spaces between `sed -e' and '...'. + Reported by Kaveh R. Ghazi + * fixinc/fixincl.sh, fixinc/fixincl.x, fixinc/inclhack.sh: Regen. -Wed Jun 24 17:55:15 1998 Klaus Kaempf +Sat Apr 3 14:54:46 1999 Craig Burley - * alpha.md (call_vms, call_value_vms): Strip leading * from symbol. + * tree.def (BLOCK): Fix typo in comment. -Wed Jun 24 16:27:23 1998 John Carr +Sat Apr 3 00:53:29 1999 John Wehle (john@feith.com) - * expr.c (get_memory_rtx): New function. - (expand_builtin): Call get_memory_rtx for MEM arguments to builtin - string functions. + * i386.md (floatsisf2, floatdisf2, floatsidf2, floatdidf2, + floatsixf2, floatdixf2): Rewrite using a splitter. - * expmed.c (init_expmed): Initialize all elements of *_cost arrays. +Fri Apr 2 17:36:10 1999 Nick Clifton - * optabs.c: Use gen_rtx_FOO (...) instead of gen_rtx (FOO, ...). - * expr.c: Likewise. - * explow.c: Likewise. - * combine.c: Likewise. - * reload1.c: Likewise. - * gcse.c: Likewise. + * config/arm/arm.c (arm_print_operand): Print large constants in + hex rather than decimal. -Wed Jun 24 15:13:01 1998 Dave Brolley +Fri Apr 2 17:23:58 1999 Nick Clifton - * README.gnat: Add patch for new lang_decode_options interface. + * print-rtl.c (print_rtx): Use both HOST_WIDE_INT_PRINT_DEC + and HOST_WIDE_INT_PRINT_HEX to display constants. -Wed Jun 24 09:14:04 EDT 1998 Andrew MacLeod +1999-04-02 Zack Weinberg - * except.c (start_catch_handler): Do nothing if EH is not on. + * config/i386/i386.h: Document all TARGET_SWITCHES or add + explicit null initializer. -1998-06-24 Manfred Hollstein + * config/i386/cygwin.h: Document all SUBTARGET_SWITCHES. + * config/i386/dgux.h: Likewise. + * config/i386/osf1elf.h: Likewise. + * config/i386/win32.h: Likewise. + * config/i386/osfrose.h: Likewise. Drop obsolete -mno-ident option. - * configure.in (gxx_include_dir): Initialize default value depending on - new flag --enable-version-specific-runtime-libs; remove superfluous - default initialization afterwards. - * configure: Regenerate. +Fri Apr 2 17:49:44 1999 Toshiyasu Morita -Wed Jun 24 01:32:12 1998 David S. Miller + * regmove.c (fixup_match_1): Remove now useless if (0). - * toplev.c (rest_of_compilation): Revert May 15 change. +Sat Apr 3 11:37:20 1999 Michael Hayes -Tue Jun 23 21:27:27 1998 Ken Raeburn + * tm.texi (USE_LOAD_POST_DECREMENT, USE_LOAD_PRE_DECREMENT, + USE_STORE_POST_DECREMENT, USE_STORE_PRE_DECREMENT): Document. + (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, + USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Fix documentation. - * reload.c (find_reloads): Fix check for failure to match any - alternative, to account for Mar 26 change in initial "best" cost. + * rtl.h (USE_LOAD_POST_DECREMENT, USE_LOAD_PRE_DECREMENT, + USE_STORE_POST_DECREMENT, USE_STORE_PRE_DECREMENT, + USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, + USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Provide default + definition. -Tue Jun 23 16:44:21 1998 Dave Brolley + * expr.c (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_INCREMENT, + USE_STORE_POST_INCREMENT, USE_STORE_PRE_INCREMENT): Delete default + definition. - * cpplib.c (do_line): Typo broke #line directive. - (cpp_message_from_errno): New function. - (cpp_error_from_errno): Call cpp_message_from_errno. - * cpplib.h (cpp_message_from_errno): New function. +Fri Apr 2 16:03:05 1999 Jeffrey A Law (law@cygnus.com) -Tue Jun 23 13:38:18 EDT 1998 Andrew MacLeod + * fixinc.dgux, fixinc.interix, fixinc.irix, fixinc.ptx: Deleted. + * fixinc.sco, fixinc.svr4, fixinc.winnt, fixinc.wrap: Likewise. - * libgcc2.c (__get_eh_table_version, __get_eh_table_language): New - functions to return exception descriptor information. - (find_exception_handler): Pass match_info field to runtime matcher, - not a descriptor table entry. +Fri Apr 2 15:46:25 1999 Donn Terry (donn@interix.com) -Tue Jun 23 09:30:58 1998 Dave Love + * configure.in: Set and substitute quoted_cc_set_by_configure. + * configure: Rebuilt. + * Makefile.in (SUBDIR_FLAGS_TO_PASS): Fix quoting problem with ``. - * cpp.texi, gcc.texi: Add @dircategory, @direntry meant to - accompany previous Makefile.in (install-info) change. +Fri Apr 2 14:35:45 1999 Stan Cox + + * config/i386/cygwin.h (CPP_SPEC): Use mingw_include_path instead + of a hardcoded path for -mno-cygwin. + (mingw_include_path): New. + +1999-04-02 Joseph S. Myers -Tue Jun 23 10:06:07 EDT 1998 Andrew MacLeod + * pdp11.c: Include "recog.h". + (output_function_prologue): Remove unused variables `nregs', `i', + `offset'. + (output_function_epilogue): Remove unused variables + `may_call_alloca', `nregs', `regno', `adjust_fp'. + (output_ascii): Mark as returning void. + (print_operand_address: Likewise. + (simple_memory_operand): Remove unused variables `plus0', `plus1', + `offset'. + * pdp11.h: Declare functions `arith_operand', + `const_immediate_operand', `expand_shift_operand', + `legitimate_address_p', `notice_update_cc_on_set', `output_ascii', + `output_function_epilogue', `output_function_prologue', + `print_operand_address', `register_move_cost', + `simple_memory_operand'. + (HARD_REGNO_MODE_OK): Parenthesize `REGNO' arg. + (REGNO_REG_CLASS): Likewise. + * pdp11.md: Add explicit `int' to `static count' (in two places). + (addhi3): Add explicit braces to avoid ambiguous else. + (addqi3): Likewise. + (ashlhi3): Likewise. - * eh-common.h (struct __eh_info): Remove coerced value field. - * libgcc2.c (find_exception_handler): Don't set coerced_value field. - * except.c (get_dynamic_handler_chain, get_dynamic_cleanup_chain): Use - POINTER_SIZE instead of Pmode. - (expand_start_all_catch): Call start_catch_handler() if we are not - using new style exceptions. +Fri Apr 2 14:17:10 1999 Jerry James -Tue Jun 23 06:45:00 1998 Catherine Moore + * gcc/invoke.texi: Add documentation for additional supported + MIPS CPU types, options -mips16 and -mentry, and ABI and ISA + defaults. - * varasm.c (assemble_variable): Remove reference to warn_bss_align. +Fri Apr 2 14:12:06 1999 John Wehle (john@feith.com) -Mon Jun 22 23:57:31 1998 David S. Miller + * i386.md: Delete floating point compare, add, subtract, + multiply, and divide patterns which allowed integer + operands. + * i386.c (output_387_binary_op): Delete unused code. + (output_float_compare): Likewise. - * config/sparc/sparc.md (zero_extendhidi2, extendhisi2, - extendqihi2, extendqisi2, extendqidi2, extendhidi2, adddi3, - subdi3, negdi2, call, call_value, untyped_return, nonlocal_goto, - splits and peepholes): Change remaining generic gen_rtx calls to - specific genrtl ones. - * config/sparc/sparc.c: Likewise. - -Mon Jun 22 22:21:46 1998 Richard Henderson +Fri Apr 2 11:53:37 1999 John Wehle (john@feith.com) - * gcc.c (handle_braces): Recognize | between options as an or. + * i386.md (movsf+1, movdf+1, movxf+1): Update constraints + so that SECONDARY_MEMORY_RELOAD is used. Remove dead code. -Mon Jun 22 23:13:47 1998 John Wehle (john@feith.com) +1999-04-02 Bruce Korb - * i386/freebsd-elf.h (JUMP_TABLES_IN_TEXT_SECTION): Define as flag_pic. - * i386/sysv4.h (JUMP_TABLES_IN_TEXT_SECTION): Define as flag_pic. + * fixinc/mkfixinc.sh: Added support for x86-interix. + * fixinc/fixinc.interix: Fixincludes script, slight changes + from ./fixinc.interix. Untested (needs interix box). + * fixinc/inclhack.def: + Complete the change to the 'fixinc.tmp' file. + Fixed regex for finding C++ headers. + * fixincl.x, fixincl.sh, inclhack.sh: Regenerate. - * i386.md (exception_receiver): Define. +Fri Apr 2 11:36:12 1999 Jan Hubicka (hubicka@paru.cas.cz) -Mon Jun 22 12:01:48 1998 Jim Wilson + * i386.c (print_operand_address, case REG): Do not use ESI addressing + mode for the K6. - * Makefile.in (PROTOIZE_INSTALL_NAME, UNPROTOIZE_INSTALL_NAME, - PROTOIZE_CROSS_NAME, UNPROTOIZE_CROSS_NAME): New variables. - (install-common): Use them. + * i386.c (print_operand_address, case MULT): Use more efficient + encoding (mult (reg) (const_int 2)). - * gcse.c (add_label_notes): New function. - (pre_insert_insn): Call it. - * unroll.c (unroll_loop): Look for insns with a REG_LABEL note, and - pass the label to set_label_in_map. +Thu Apr 1 17:01:50 1999 Richard Henderson -Mon Jun 22 19:01:14 1998 Dave Love + Move over patch from Bernd Schmidt from GC branch: + * emit-rtl.c (gen_rtx_CONST_DOUBLE): New function. + (gen_rtx): Call it. Tidy cases. + * rtl.h (gen_rtx_CONST_DOUBLE): Prototype it. + * gengenrtl.c: Add commentary. + (special_rtx): Also match CONST_DOUBLE. + (gencode): Emit call to memset instead of bzero. - * Makefile.in (install-info): Fix typpo in previous change. +Fri Apr 2 12:58:26 1999 Michael Hayes -Mon Jun 22 11:10:00 1998 Catherine Moore + * config/c4x/c4x.md (ashlhi3, lshrhi3, ashrhi3): Force operand 1 + into a register if shift count not constant. + (ashlhi3_reg, lshrhi3_reg, ashrhi3_reg): Ensure that operand 1 + is a register. - * varasm.c (assemble_variable): Emit alignment warning. +Fri Apr 2 12:19:17 1999 Michael Hayes -Mon Jun 22 08:18:46 1998 Kaveh R. Ghazi + * config/c4x/c4x.md (*db): Enable pattern if TARGET_LOOP_UNSIGNED + is non-zero. + (movstrqi_small, movstrqi_large, *cmpstrqi): Add + modifier to address + register constraints. + (*movhi_clobber+1): Modify splitter pattern to handle destination + register that is used in the source address. + (*xorhi3_clobber): Replace AND with XOR in call to legitimize_operands. - * Makefile.in (varasm.o): Depend on sdbout.h. - (sdbout.o): Depend on toplev.h. +Fri Apr 2 12:16:15 1999 Michael Hayes - * collect2.c (scan_prog_file): Cast fprintf argument to `long' and - use %ld specifier. + * config/c4x/c4x.h: Added more comments. - * final.c (shorten_branches): Cast first arg of `bzero' to char *. +Fri Apr 2 11:58:22 1999 Michael Hayes - * genextract.c (main): When creating insn-extract.c, mark variable - `i' with ATTRIBUTE_UNUSED. + * config/c4x/c4x.c (c4x_emit_move_sequence): Force invalid QImode + constants into memory if we get called directly from gen_move_insn + rather than emit_move_insn. + (c4x_legitimize_address): Fix up LABEL_REF addresses. - * genpeep.c (main): When creating insn-peep.c, mark variables - `insn', `x' and `pat' with ATTRIBUTE_UNUSED. +Thu Apr 1 12:04:05 1999 Jim Wilson - * objc/init.c (__objc_tree_print): Wrap function definition in - macro `DEBUG'. + * expr.c (store_field): When check direct_store, assume all complex + modes can be directly stored. - * objc/objc-act.c (encode_array): Cast sprintf argument to `long' - and use %ld specifier. - (adorn_decl): Likewise, twice. +1999-04-01 Bruce Korb - * reload1.c (reload_cse_regs): Cast first arg of `bzero' to char *. + * fixinc/genfixes: New shell script that runs autogen + to create the generated files. - * sdbout.c: Include output.h and toplev.h. - (PUT_SDB_INT_VAL): Use HOST_WIDE_INT_PRINT_DEV to print argument - `a'. Cast `a' to HOST_WIDE_INT to force it to always be so. - (PUT_SDB_SIZE): Likewise. +1999-04-01 Manfred Hollstein - * sdbout.h (sdbout_mark_begin_function): Add prototype. + * Makefile.in (cppmain$(exeext)): Depend on intl.o. Link in intl.o. - * stmt.c (check_for_full_enumeration_handling): Cast argument of - `warning' to long and use %ld specifier. +Thu Apr 1 03:48:34 1999 H.J. Lu (hjl@gnu.org) - * toplev.c (main): Likewise for `fprintf'. + * i386.c (output_fp_conditional_move): Abort for LT, LE, GE, and GT + signed integer comparisons. - * toplev.h (output_file_directive): Add prototype. + * i386.c (output_int_conditional_move): Use "enum rtx_code" for code + type. - * unroll.c (unroll_loop): Use HOST_WIDE_INT_PRINT_DEC specifier in - call to `fprintf'. - (precondition_loop_p): Likewise. + * i386.c (notice_update_cc): No need to check the INT mode for + conditional moves since FLOAT conditional moves don't affect cc0. - * varasm.c Include sdbout.h. - (assemble_static_space): Move sometimes-unused variable `rounded' - into the scope in which it is used. - - * mips.c (gpr_mode): Don't say `static' twice. +Thu Apr 1 02:17:18 1999 Jeffrey A Law (law@cygnus.com) - * cpplib.c (cpp_handle_option): Don't pass unneeded NULL to cpp_fatal. + * fixinc/inclhack.def (zzz_ki_syscalls, zzz_time): Fix trigger + string to only match on hpux11. + * fixinc/fixincl.x, fixinc/inclhack.sh, fixinc/fixinc.sh: Rebuilt. - * objc/objc-act.c (init_selector): Hide prototype and definition. +Thu Apr 1 01:09:27 1999 Alexandre Oliva - * optabs.c (gen_cond_trap): Remove unused variable `icode'. - - * regmove.c (copy_src_to_dest): Likewise for `i'. + * fixinc/hackshell.tpl: Complete transition to fixinc.tmp. + * fixinc/inclhack.sh: Rebuilt. - * mips-tfile.c (add_local_symbol): Cast width format specifier to int. - (add_ext_symbol): Likewise. - (add_file): Likewise. - (parse_def): Likewise. - (write_varray): Use HOST_PTR_PRINTF to print a pointer. Fix - remaining format specifiers and arguments. - (write_object): Likewise, several times. - (read_seek): Likewise. - (out_of_bounds): Likewise. - (allocate_cluster): Likewise. - (xmalloc): Likewise. - (xcalloc): Likewise. - (xrealloc): Likewise. - (xfree): Likewise. - - * mips-tdump.c (print_symbol): Likewise. - -Sun Jun 21 17:05:34 1998 Dave Love + * fixinc/inclhack.def: Fix typos in c_asm.h fix. + * fixinc/fixincl.x, fixinc/inclhack.sh, fixinc/fixinc.sh: Rebuilt. - * Makefile.in (install-info): Use install-info program if - available, per GNU standard. +Wed Mar 31 17:20:11 1999 Jeffrey A Law (law@cygnus.com) -Sun Jun 21 18:56:44 1998 Jeffrey A Law (law@cygnus.com) + * toplev.c (rest_of_compilation): Allow dbr_schedule to write to + the dump file too. - * invoke.texi: Document -mrelax for the mn10300 and mn10200. +Wed Mar 31 12:32:43 1999 Richard Henderson - * basic-block.h (init_regset_vector): Delete declaration. - * flow.c (init_regset_vector): Make it static and add a prototype. + * flow.c (find_basic_blocks): New argument `do_cleanup'. + Conditionally call delete_unreachable_blocks. + (free_basic_block_vars): Zero ENTRY/EXIT data. + (allocate_for_life_analysis): Kill. Split into... + (allocate_bb_life_data, allocate_reg_life_data): ... new functions. + (life_analysis_1): Update. + * gcse.c (gcse_main): Update find_basic_blocks call. + * toplev.c (rest_of_compilation): Likewise. + * stupid.c (stupid_life_analysis): Update life data calls. + * rtl.h, output.h: Update prototypes. - * bitmap.h (debug_bitmap): Declare. +Wed Mar 31 12:10:00 1999 Bruce Korb - * haifa-sched.c (debug_ready_list): Make static. + * inclhack.def (several): Added spaces in tests to ensure + correct shell syntax. Added c_asm.h fix from fixincludes. + Also corrected the corrected fix to C++ comments :-} - * toplev.h (fancy_abort): Declare. + * inclhack.tpl: Changed method of traversing symlink trees + so that file name matching will work correctly. -Sun Jun 21 18:30:13 1998 H.J. Lu (hjl@gnu.org) + * fixincl.c, hackshell.tpl: Fallout from above. + * fixincl.x, inclhack.sh, fixincl.sh: Rebuilt. - * basic-block.h (init_regset_vector): New declaration. +Tue Mar 30 10:43:49 1999 Philip Blundell - * Makefile.in (sdbout.o): Add insn-codes.h to dependency. + * config/arm/aout.h (DBX_DEBUGGING_INFO): Avoid redefinition if + dbxelf.h was previously included. + (CPP_APCS_PC_DEFAULT_SPEC): No need to undefine. - * global.c: Include machmode.h amd move hard-reg-set.h before - rtl.h. + * config/arm/linux-elf.h (FP_DEFAULT): Correctly override the + definition from arm.h. - * haifa-sched.c (insn_issue_delay, birthing_insn_p, - adjust_priority, print_insn_chaino): New declaration. - (schedule_insns): Remove declaration. - (init_target_units, get_visual_tbl_length, - init_block_visualization): Add prototype. +Wed Mar 31 10:33:37 1999 Kaveh R. Ghazi - * integrate.c (pushdecl, poplevel): Remove declaration. + * Makefile.in (c-gperf.h): Generate using gperf language 'C', not + 'KR-C', so gperf uses the `const' keyword on strings. - * rtl.h (expand_expr): Remove declaration. + * c-parse.gperf (resword): Const-ify a char*. - * loop.c (oballoc): Remove declaration. - (replace_call_address): Add prototype. +Wed Mar 31 01:49:31 1999 Ian Lance Taylor -Sun Jun 21 01:08:17 PDT 1998 Jeff Law (law@cygnus.com) + * t-rtems (LIMITS_H_TEST, LIBGCC2_INCLUDES): Define. - * version.c: Bump for snapshot. +Wed Mar 31 00:50:48 1999 Jeffrey A Law (law@cygnus.com) -Sun Jun 21 01:16:38 1998 John Wehle (john@feith.com) + * system.h (STDERR_FILENO): Fix typo. - * i386.c (output_fp_conditional_move): Don't bother handling - (cc_prev_status.flags && CC_NO_OVERFLOW) since the INSN patterns - prevent this from happening. + * inclhack.def (bool): Also fix bogus bool in curses_colr/curses.h. + * fixincl.x, inclhack.sh, fixincl.sh: Rebuilt. - * i386.md (nonlocal_goto_receiver): Delete. +Tue Mar 30 20:51:40 1999 Mark Mitchell -Sun Jun 21 00:42:20 1998 H.J. Lu (hjl@gnu.org) + * alias.c (alias_set_compare): Remove. + (record_alias_subset): Use splay_tree_compare_ints instead of + alias_set_compare. + (init_alias_once): Likewise. + * cse.c: Include splay-tree.h. + (reg_qty): Remove. + (reg_tick): Likewise. + (reg_table): Likewise. + (cse_reg_info): New structure. + (cse_reg_info_free_list): New variable. + (cse_reg_info_tree): Likewise. + (cached_regno): Likewise. + (cached_cse_reg_info): Likewise. + (all_minus_one): Remove. + (consec_ints): Likewise. + (GET_CSE_REG_INFO): New macro. + (REG_TICK): Likewise. Use throughout instead of reg_tick. + (REG_IN_TABLE): Likewise. Use throughout instead of reg_in_table. + (REG_QTY): Likewise. Use throughout instead of reg_qty. + (get_cse_reg_info): New function. + (free_cse_reg_info): Likewise. + (new_basic_block): Reinitialize cse_reg_info_tree instead of + reg_tick, all_minus_one, and consec_ints. + * Makefile.in (cse.o): Depend on splay-tree.h - * Makefile.in (crtbeginS.o, crtendS.o): Add -fno-exceptions and - -DCRTSTUFFS_O. - (INSTALL): cd $(srcdir) before make. +Tue Mar 30 13:19:36 1999 Jason Merrill - * flow.c (allocate_for_life_analysis, init_regset_vector): - Remove declaration. + * libgcc2.c (throw_helper): Just return the SP offset, rather than + a whole udata. Include args_size in the offset. + (__throw, __rethrow): Adjust. - * function.h (get_first_block_beg): New declaration. +Tue Mar 30 11:39:27 1999 Craig Burley - * gbl-ctors.h (__do_global_dtors): Add prototype. + * extend.texi (Extended Asm): Delete spurious `b' before + `@end example', which was confusing texi2html. - * gcov-io.h (__fetch_long): New declaration. - (__store_long): Likewise. - (__read_long): Likewise. - (__write_long): Likewise. +Tue Mar 30 00:26:34 1999 Jason Merrill - * gcov.c (print_usage): New declaration. + * dwarf2out.c (output_line_info): Don't emit redundant info. + Do start a new row if the file changes and the line # doesn't. - * Makefile.in (c-iterate.o): Depend on insn-codes.h too. +Mon Mar 29 15:48:39 1999 Jason Merrill -Sat Jun 20 00:36:16 1998 Jeffrey A Law (law@cygnus.com) + * invoke.texi (Invoking G++, C++ Dialect Options): Update. - * calls.c (expand_call): Initialize "src" and "dest". - * stmt.c (expand_return): Likewise. - * expmed.c (extract_split_bit_field): Similarly for "result" - * gcse.c (compute_hash_table): Mark first arg as unused. - * jump.c (jump_optimize): Initialize reversep. - * tree.c (make_node): Initialize length. +Mon Mar 29 15:05:39 1999 Richard Henderson - * c-common.c (check_format_info): Initialize length_char and - fci to keep -Wall quiet. + * except.c (start_dynamic_handler): Force jmp_buf address to + and operand before moving to memory. - * except.c (jumpif_rtx): Put declaration and definition - inside a suitable #ifdef. - (jumpifnot_rtx): Delete dead function. +Mon Mar 29 15:11:10 1999 Craig Burley - * i386.h (output_int_conditional_move): Declare. - (output_fp_conditional_move): Likewise. - (ix86_can_use_return_insn_p): Likewise. + * invoke.texi (Code Gen Options): Attempt to clarify + -fcheck-memory-usage. Minor edits to -fprefix-function-name. - * optabs.c (init_traps): Put prototype inside a suitable #ifdef. +Mon Mar 29 20:52:47 1999 J"orn Rennecke -Sat Jun 20 00:27:40 1998 Graham + * loop.c (maybe_eliminate_biv): For libcalls that set a giv, skip to + end of libcall. - * alias.c: Include toplev.h - * caller-save.c: Include toplev.h - * combine.c: Include toplev.h - * flow.c Include toplev.h - * global.c: Include toplev.h - * jump.c: Include toplev.h - * local-alloc.c: Include toplev.h - * loop.c: Include toplev.h - * regmove.c: Include toplev.h - * stupid.c: Include toplev.h - * unroll.c: Include toplev.h - * Makefile.in: Add toplev.h dependencies. +Mon Mar 29 20:35:49 1999 J"orn Rennecke -Fri Jun 19 22:40:25 1998 Jason Merrill + * sh.md (mulsi3): Tag an extra REG_EQUAL note to the middle insn. - * regmove.c (copy_src_to_dest): Add decl for loop_depth. +Mon Mar 29 11:50:34 1999 Jerry Quinn - * svr4.h (ASM_GENERATE_INTERNAL_LABEL): Cast arg to unsigned. - * dwarf2out.c (ASM_OUTPUT_DWARF_DATA1): Likewise. - Add parens to various macros. + * pa.h (HAVE_PRE_INCREMENT): Disable when optimizing for a PA8000 + class machine. + (HAVE_PRE_DECREMENT, HAVE_POST_INCREMENT): Likewise. + (HAVE_POST_DECREMENT): Likewise. -Fri Jun 19 23:22:42 1998 Bruno Haible +Mon Mar 29 08:24:43 1999 Bruce Korb - * c-typeck.c (pop_init_level): Warn about implicit zero initialization - of struct members. + * fixinc/mkfixinc.sh: Fix portability problems with old shells. -Fri Jun 19 23:06:33 1998 Jason Merrill + * fixinc/README: Updated for release announcement - * varasm.c (assemble_start_function): Add weak_global_object_name. - * tree.c (get_file_function_name): Use it. +Sun Mar 28 20:26:55 1999 Kaveh R. Ghazi -Fri Jun 19 22:55:14 1998 Jeffrey A Law (law@cygnus.com) + * recog.h (insn_outfun, insn_operand_predicate): Add prototype + arguments. - * except.c (jumpif_rtx): Make static and add prototype. - (jumpifnot_rtx): Likewise. + * rtl.h (note_stores): Likewise. - * README.gnat: Add a build patch from Fred Fish. + * rtlanal.c (note_stores): Likewise. - * c-lang.c (GNU_xref_begin, GNU_xref_end): Deleted. +Sun Mar 28 15:34:28 1999 Richard Henderson - * Makefile.in (c-iterate.o): Depend on expr.h. + * varasm.c (output_constant_pool): Always mark the constant pool. -Fri Jun 19 20:38:34 1998 H.J. Lu (hjl@gnu.org) +Sun Mar 28 16:09:01 1999 Jerry Quinn - * except.h (emit_unwinder, end_eh_unwinder): Removed. + * pa.md (pa7100LCshiftmem, pa7100LCalu): Change simultaneity. Use + shift/mem ops in pa7100LCalu. - * dwarfout.c (getpwd): Add prototype. - (is_pseudo_reg, type_main_variant, is_tagged_type, - is_redundant_typedef): New declaration. - (output_decl): Add prototype for FUNC. - (type_main_variant): Make it static. - (is_tagged_type): Likewise. - (is_redundant_typedef): Likewise. + * pa.c (pa_adjust_cost): Don't do cost adjustments on pa8000. + (pa_reorg): Don't call pa_combine_instructions on pa8000. - * expr.c (do_jump_by_parts_greater_rtx): Removed. - (truthvalue_conversion): Likewise. +Sun Mar 28 15:27:26 1999 Jeffrey A Law (law@cygnus.com) - * c-iterate.c: Include "expr.h". - (expand_expr): Use proper values when calling the function. + * reload1.c (reload): Remove accidental code duplication. - * explow.c (emit_stack_save): Add prototype for FCN. - (emit_stack_restore): Likewise. +Sun Mar 28 12:22:12 1999 Robert Lipe (robertlipe@usa.net) - * dwarf2out.c (getpwd): Add prototype. + * i386/sysv5.h: New file to describe UnixWare7/SVR5. + * configure.in (i?86-UnixWare7*-sysv): Use it. + * i386/udk.h: Use sysv5.h. Now uses Dwarf-2. - * dwarf2out.h (debug_dwarf, debug_dwarf_die): New declarations. +Sun Mar 28 01:15:04 1999 Jeff Law (law@cygnus.com) - * c-typeck.c (c_expand_asm_operands): Use proper values when calling - expand_expr. + * version.c: Bump for snapshot. - * c-lex.c (yyprint): Add prototype. - (check_newline, build_objc_string): Remove declaration. +Sun Mar 28 00:44:27 1999 Jeffrey A Law (law@cygnus.com) - * c-tree.h (comptypes_record_hook): Removed. - (finish_incomplete_decl): New prototype. + * sdbout.c (sdbout_symbol): Do not call build_pointer_type, build + one on the fly and do not cache the result. - * alias.c (find_base_value): Add prototype. - (true_dependence): Add prototype for function argument. + * gcc.cps, cpp.cps: Delete unwanted files. - * c-aux-info.c (xmalloc): Remove declaration. +Sat Mar 27 23:37:40 1999 John Wehle (john@feith.com) -Fri Jun 19 20:23:05 1998 Robert Lipe + * i386.md (movdicc+3, movdicc+4): Rewrite using split_di. + * i386.c (output_int_conditional_move): Delete unused code. - * i386.c: Include system.h. Remove redundant includes. - (optimization_options): Mark param 'size' with ATTRIBUTE_UNUSED. - (i386_cc_probably_useless_p): Likewise for 'decl', 'attributes', - 'identifier', 'args'. - (i386_valid_type_attribute_p): Likewise for 'attributes'. - (i386_comp_type_attribute_p): Likewise for 'type1', 'type2'. - (function_arg_partial_nregs): Likewise for 'cum', 'mode', 'type', - and 'named'. - (symbolic_operand): Likewise for 'mode'. - (call_insn_operand): Likewise. - (expander_call_insn_operand): Likewise. - (ix86_logical_operator): Likewise. - (ix86_binary_operator_ok): Likewise. - (emit_pic_move): Likewise. - (VOIDmode_compare_op): Likewise. - (is_mul): Likewise. - (str_immediate_operand): Likewise. - (ix86_uary_operator_ok): Likewise for 'code', 'mode', and 'operands'.yy - (asm_output_function_prefix): Likewise for 'name'. - (function_prologue): Likewise for 'file', and 'size'. - (function_epilogue): Likewise. +Sat Mar 27 21:17:36 1999 David Edelsohn -1998-06-19 Jim Wilson + * rs6000/{aix41.h,aix43.h} (ASM_CPU_SPEC): Add 604e. - * loop.h (struct induction): Clarify comment for unrolled field. - * unroll.c (find_splittable_givs): Move set of unrolled field - after address validity check. +Sat Mar 27 16:13:50 1999 Jeffrey A Law (law@cygnus.com) -Fri Jun 19 18:38:04 1998 Michael Meissner + * flow.c (mark_used_regs): Improve handling of ASMs. - * config/fp-bit.c (INLINE): Only define if not already defined. +1999-03-26 Zack Weinberg -1998-06-19 Manfred Hollstein + * Makefile.in (xcpp, cppspec.o): New targets. + (CPP_INSTALL_NAME): New macro. + (install-cpp): Install xcpp. Use CPP_INSTALL_NAME. + (all.build, start.encap): Build xcpp. - * Makefile.in (installdirs): Loop over directories in $(libsubdir) - creating probably missing ones, instead of single if statements. + * cppspec.c: New file, implements argument filtering for a + user-visible C preprocessor. + * cpp.sh: Removed. -Fri Jun 19 10:43:52 1998 Andreas Schwab +Fri Mar 26 20:41:46 1999 Jim Wilson - * c-common.c (truthvalue_conversion): Protect side effects in the - expression when splitting a complex value. - * fold-const.c (fold): Likewise. + * Makefile.in (stmp-fixinc): Use tooldir instead of gcc_tooldir. -Fri Jun 19 02:31:16 1998 Klaus Kaempf (kkaempf@progis.de) +Fri Mar 26 16:02:37 1999 Nick Clifton - * cccp.c (hack_vms_include_specification): rewrite to handle - '#include ' correctly. + * configure.in (arm-*-vxworks*): Just include arm/vxarm.h. + * configure: Regenerate. + * config/arm/vxarm.h: Define SUBTARGET_CPU_DEFAULT before + including arm/coff.h -Fri Jun 19 02:24:11 1998 H.J. Lu (hjl@gnu.org) +1999-02-16 Scott Bambrough - * config/i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Defined. + * configure.in (arm*-*-linux-gnu*): Set thread_file to 'posix' if + --enable-threads[={yes,pthreads,posix}] is passed as a command + line parameter to configure. -Fri Jun 19 02:10:10 1998 John Wehle (john@feith.com) + * configure: Regenerate. - * i386.c (notice_update_cc): Integer conditional moves don't - affect cc0. + * gcc/config/arm/t-linux (TARGET_LIBGCC2_CFLAGS): Include -fPIC. - * i386.md (movsfcc, movdfcc, movxfcc): Use emit_store_flag - to support LT, LE, GE, and GT signed integer comparisons. - (movsfcc+1, movsfcc+2, movdfcc+1, movdfcc+2, - movxfcc+1, movxfcc+2): Pattern doesn't match if the comparison - is LT, LE, GE, or GT. - (movdicc): Remove code resulting from an earlier patch which - didn't apply correctly. +Fri Mar 26 19:42:19 1999 J"orn Rennecke -Fri Jun 19 02:00:19 1998 Richard Kenner + * loop.c (combine_givs): Fix index into can_combine when doing + benefit adjustment for remaining givs when having combined a giv. - * reload1.c (reload_cse_regno_equal_p): If -ffloat-store, don't - consider a MEM in FP mode as equal. +Fri Mar 26 11:38:01 1999 Nick Clifton -Fri Jun 19 01:02:17 1998 Jeffrey A Law (law@cygnus.com) + * config/arm/t-arm-elf (EXTRA_MULTILIB_PARTS): Define. - * c-decl.c (duplicate_decls): Avoid setting TREE_ASM_WRITTEN for - duplicate declarations of a function. +Fri Mar 26 10:48:27 1999 Nick Clifton -Fri Jun 19 00:33:33 1998 H.J. Lu (hjl@gnu.org) + * config/arm/linux-elf.h: Include dbxelf.h - * config/float-i386.h: New. +Fri Mar 26 10:43:47 1999 Nick Clifton - * configure.in (i[34567]86-*-linux-*): Set float_format to i386. + * config/svr4.h: Include new header file dbxelf.h. + (DBX_DEBUGGING_INFO): Remove definition. + (DBX_USE_BINCL): Remove definition. + (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition. + (ASM_IDENTIFY_GCC): Remove definition. + (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition. + (ASM_OUTPUT_SOURCE_LINE): Remove definition. + (DBX_FUNCTION_FIRST): Remove definition. + (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Remove definition. -Thu Jun 18 20:11:00 1998 Jim Wilson + * config/elfos.h: Include new header file dbxelf.h. + (DBX_DEBUGGING_INFO): Remove definition. + (DBX_BLOCKS_FUNCTION_RELATIVE): Remove definition. + (ASM_IDENTIFY_GCC): Remove definition. + (ASM_IDENTIFY_GCC_AFTER_SOURCE): Remove definition. + (ASM_OUTPUT_SOURCE_LINE): Remove definition. + (DBX_FUNCTION_FIRST): Remove definition. - * sched.c (schedule_insns): Use xmalloc not alloca for max_uid - indexed arrays. Call free at the end of the function for them. - * haifa-sched.c (schedule_insns): Likewise. + * config/dbxelf.h: New header file. + (DBX_DEBUGGING_INFO): Define. + (DBX_BLOCKS_FUNCTION_RELATIVE): Define. + (DBX_FUNCTION_FIRST): Define. + (DBX_USE_BINCL): Define. + (DBX_CONTIN_LENGTH): Define. + (ASM_IDENTIFY_GCC): Define. + (ASM_IDENTIFY_GCC_AFTER_SOURCE): Define. + (ASM_OUTPUT_SOURCE_LINE): Define. + (DBX_OUTPUT_MAIN_SOURCE_FILE_END): Define. -Thu Jun 18 18:16:01 1998 Jim Wilson +Fri Mar 26 01:59:15 1999 "Charles M. Hannum" - * dwarf2out.c (size_of_string): Do count backslashes. + * fold-const.c (fold_truthop): Optimize bitfield references with + different masks as long as their size and bit position are the same. -Thu Jun 18 11:43:54 1998 Nick Clifton + * fold-const.c (fold_truthop): Build a type for both the lhs and + rhs and use it appropriately. - * config/arm/thumb.h (GO_IF_LEGITIMATE_ADDRESS): Disallow REG+REG - addressing when one register is the frame pointer or stack - pointer. Disallow REG+CONST addressing in HI mode. + * fold-const.c (fold_truthop): Mask the lhs and rhs after merging + adjacent bitfield references. -Thu Jun 18 17:30:39 1998 J"orn Rennecke + * fold-const.c (fold_truthop): Verify that the lhs and rhs are + in the same bit position when optimizing bitfield references + which have the same mask. - * reload.c (find_reloads): Don't narrow scope of RELOAD_OTHER to - RELOAD_FOR_INSN. +Thu Mar 25 22:53:27 1999 Martin von Löwis -Thu Jun 18 09:36:50 1998 Kaveh R. Ghazi + * gcc.texi (Copy Assignment): New node. - * Makefile.in (c-lang.o): Depend on output.h. +1999-03-25 Zack Weinberg - * c-lang.c: Include output.h. + * gcc.c: Compile unconditionally all code formerly dependent + on #ifdef LANG_SPECIFIC_DRIVER. + * gccspec.c: New file with stub lang_specific_driver, + lang_specific_pre_link. + * Makefile.in: Link gccspec.o into xgcc. Add rule to compile - * sparc.c (sparc_builtin_saveregs): Remove unused variable `fntype'. +Thu Mar 25 21:08:02 1999 Jason Merrill - * except.c (expand_builtin_eh_stub): Likewise for variable `jump_to'. + * gcc.texi (Temporaries): Update. - * genrecog.c (write_subroutine): When writing insn-recog.c, mark - variables `insn', `pnum_clobbers', `x[0 .. max_depth]' and `tem' - with ATTRIBUTE_UNUSED. +Thu Mar 25 16:53:53 1999 Richard Henderson - * regmove.c (copy_src_to_dest): Make function static to match its - prototype. + * combine.c (distribute_notes): Place REG_LABEL also where + REG_EQUAL indicates. - * reload1.c Include hard-reg-set.h before rtl.h to get macro - HARD_CONST. Include machmode.h before hard-reg-set.h. +Thu Mar 25 12:46:37 1999 Jim Wilson - * rtl.h: Prototype `retry_global_alloc' and wrap with macro - HARD_CONST to protect usage of typedef HARD_REG_SET. + * a29k/a29k.h (TARGET_SWITCHES): Add doc strings. + * i960/i960.h (TARGET_SWITCHES): Add doc strings. + * invoke.texi (a29k): Add documentation for -mno-multm option. - * tree.c: Prototype `_obstack_allocated_p'. +Thu Mar 25 14:04:54 1999 Andrew MacLeod - * varasm.c: Wrap prototype of `asm_output_aligned_bss' in macro - BSS_SECTION_ASM_OP. + * rtl.texi (RTX_FRAME_RELATED_P): Add documentation. + * rtl.h (struct rtx_def): Update comment for frame_related field. + (set_unique_reg_note): Declare prototype. + * dwarf2out.c (dwarf2out_frame_debug_expr): Split out from + 'dwarf2out_frame_debug' to handle only expressions, and process + component parts of a PARALLEL expression. + (dwarf2out_frame_debug): Process insns only, and call + new function 'dwarf2out_frame_debug_expr' for patterns. + * emit-rtl.c (set_unique_reg_note): New function to add a reg note, + but if there is an existing one, delete it first. + * expmed.c (expand_mult, expand_divmod): Use set_unique_reg_note. + * optabs.c (add_equal_note, expand_binop): Use set_unique_reg_note. + (emit_no_conflict_block, emit_libcall_block): Use set_unique_reg_note. + (expand_fix): Use set_unique_reg_note. -Thu Jun 18 09:20:47 1998 Kaveh R. Ghazi +Thu Mar 25 11:47:49 1999 Art Haas - * pa.c: Include system.h and toplev.h. Remove redundant code. - (call_operand_address): Mark parameter `mode' with ATTRIBUTE_UNUSED. - (symbolic_operand): Likewise. - (symbolic_memory_operand): Likewise. - (pic_label_operand): Likewise. - (fp_reg_operand): Likewise. - (pre_cint_operand): Likewise. - (post_cint_operand): Likewise. - (ireg_or_int5_operand): Likewise. - (int5_operand): Likewise. - (uint5_operand): Likewise. - (int11_operand): Likewise. - (uint32_operand): Likewise. - (ior_operand): Likewise. - (lhs_lshift_cint_operand): Likewise. - (pc_or_label_operand): Likewise. - (legitimize_pic_address): Likewise. - (hppa_legitimize_address): Likewise for parameter `old'. - (output_block_move): Likewise for parameter `size_is_constant'. - (output_function_prologue): Likewise for parameter `size'. - (output_function_epilogue): Likewise. - (return_addr_rtx): Likewise for parameter `count'. - (output_mul_insn): Likewise for parameter `unsignedp'. - (hppa_builtin_saveregs): Likewise for parameter `arglist'. - (output_bb): Likewise for parameter `operands'. - (output_bvb): Likewise. - (function_label_operand): Likewise for parameter `mode'. - (plus_xor_ior_operator): Likewise. - (shadd_operand): Likewise. - (non_hard_reg_operand): Likewise. - (eq_neq_comparison_operator): Likewise. - (movb_comparison_operator): Likewise. - (pa_combine_instructions): Likewise for parameter `insns'. + * tlink.c (symbol_hash_newfunc): Remove redundant call to + hash_newfunc. + (file_hash_newfunc, demangled_hash_newfunc): Likewise. - * pa.h: Add prototypes for functions `output_deferred_plabels', - `override_options', `output_ascii', `output_function_prologue', - `output_function_epilogue', `print_operand', - `symbolic_expression_p', `reloc_needed', `compute_frame_size', - `hppa_address_cost', `and_mask_p', `symbolic_memory_operand', - `pa_adjust_cost', `pa_adjust_insn_length' and - `secondary_reload_class'. +Thu Mar 25 10:05:56 1999 Richard Henderson -Wed Jun 17 22:28:48 1998 Jason Merrill + * i386.h (PREFERRED_STACK_BOUNDARY): Set to 128. - * configure.in: Don't turn on collect2 unconditionally. +1999-03-25 Philip Blundell -Wed Jun 17 20:20:48 1998 Mark Mitchell + Based on patch from Jim Studt : + * config/arm/linux-elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Copy + definitions from config/linux.h. + (DBX_BLOCKS_FUNCTION_RELATIVE): Define to 1. - * cse.c (cse_basic_block): Don't include NOTE insns in the count - that is used to decide whether or not it is time to erase the - equivalence table. +Thu Mar 25 02:12:42 1999 Finn Hakansson -Wed Jun 17 18:30:43 1998 Franz Sirl + * loop.c (strength_reduce): Correct a comment. - * rs6000/linux.h (JUMP_TABLES_IN_TEXT_SECTION): Define to zero. + * rtl.h (MEM_COPY_ATTRIBUTES): Remove unnecessary ending backslash. -Wed Jun 17 19:05:03 1998 John Carr +Thu Mar 25 02:02:13 1999 Axel Thimm - * haifa-sched.c (haifa_classify_insn): TRAP_IF is risky. - (sched_analyze_2): Allow scheduling TRAP_IF. + * Makefile.in (RANLIB_TEST): Improve test. - * reorg.c (mark_referenced_resources): Examine operands of TRAP_IF. +Thu Mar 25 01:15:33 1999 Donn Terry - * rtl.h (TRAP_CODE): New macro. + * combine.c (force_to_mode, case PLUS): Use sign extended mask + when masking the low bits out of a constant. - * rtl.def (TRAP_IF): Change second operand type to rtx. +Tue Mar 23 15:45:25 1999 Richard Earnshaw (rearnsha@arm.com) + Jeff Law - * optabs.c (gen_cond_trap): New function. - (init_traps): New function. - (init_optabs): Call init_traps. - * expr.h: Declare gen_cond_trap. + * fold-const.c (make_range): If orig_type is unset, set it as soon + as we know the type. Remove now unnecessary set of orig_type for + conversions. - * jump.c (jump_optimize): Optimize jumps to and around traps. +Wed Mar 24 23:27:25 1999 Mark Elbrecht + Jeff Law - * sparc.md: Define trap instructions. + * system.h (STDIN_FILENO): Provide default definition if one is not + provided by the system header files. + (STDOUT_FILENO, STDERR_FILENO): Likewise. - * rs6000.md: Define trap instructions. - * rs6000.c (print_operand): New code 'V' for trap condition. - (trap_comparison_operator): New function. + * i386/xm-djgpp.h (COLLECT2_HOST_INITIALIZATION): New macro. + * collect2.c (main): Use it. + (pexecute_pid): New variable. Holds return value from call to pexecute. + (collect2_execute): Rework to use pexecute instead of fork. + (collect2_wait): Use pwait() instead of wait(). - * m88k.md: Update use of TRAP_IF. + * i386/djgpp.h: Fix typo. - * tree.h (enum built_in_function): New function code BUILT_IN_TRAP. - * c-decl.c (init_decl_processing): New builtin __builtin_trap. - * expr.c (expand_builtin): Handle BUILT_IN_TRAP. +Wed Mar 24 23:24:30 1999 Jeffrey A Law (law@cygnus.com) - * expr.c (expand_builtin): Error if __builtin_longjmp second argument - is not 1. + * fixinc/mkfixinc.sh: Recognize cygwin* instead of only + cygwin32. -Wed Jun 17 15:20:00 PDT 1998 Catherine Moore +Wed Mar 24 15:44:12 1999 Nick Clifton - * reload1.c (spill_hard_reg): Check mode of register when - spilling from scratch_list. - -Wed Jun 17 16:25:38 EDT 1998 Andrew MacLeod (amacleod@cygnus.com) + * config/m32r/m32r.c (init_idents): Accept both NAME and __NAME__ + versions of attribute names and values. + (m32r_valid_machine_decl_attribute): Likewise. + (m32r_encode_section_info): Likewise. - * except.c (add_new_handler): fix bug in finding last region handler. - * libgcc2.c (find_exception_handler): Pass exception table pointer - to runtime type matcher, not the match info field. +Wed Mar 24 21:42:15 1999 J"orn Rennecke -Wed Jun 17 15:57:48 EDT 1998 Andrew MacLeod (amacleod@cygnus.com) + * reload1.c (choose_reload_regs): If output-reloading for a + simple move insn, try to inherit an equivalence for the input. - * eh-common.h (struct eh_context): Add comment for hidden use of - field dynamic_handler_chain. - * except.c (get_dynamic_handler_chain): Comment on, and use the - correct offset of the dynamic_handler_chain field. +1999-02-24 Mike Stump -1998-06-17 12:46:56 1998 Jim Wilson + * arm/aout.h (DBX_OUTPUT_MAIN_SOURCE_FILENAME): Fix quoting. - * mips/iris6.h (LINK_SPEC): Add -woff 131. +1999-03-24 Jim Blandy -1998-06-17 Jason Merrill + * libgcc2.c (__CTOR_LIST__, __DTOR_LIST__): Initialize on all + platforms. - * dwarf2out.c: Disable EH_FRAME_SECTION if we don't have .init. +Wed Mar 24 01:35:01 1999 Geoff Keating - * configure.in: Don't disable collect2 when we have GNU ld. + * fold-const.c (fold): Recognize a rotate by an unsigned amount. -Wed Jun 17 08:38:13 1998 Jeffrey A Law (law@cygnus.com) +Tue Mar 23 23:32:14 1999 Jeffrey A Law (law@cygnus.com) - * fold-const.c (make_range): Do not widen the type of the expression. + * pa.md (rotlsi3): New expander. Synthesize a variable rotate + left using a variable rotate right. Provide anonymous pattern for + rotate left by a constant value. - * expr.c (check_max_integer_computation_mode): New function. - (expand_expr): Avoid integer computations in modes wider than - MAX_INTEGER_COMPUTATION_MODE. - * fold-const.c (fold): Likewise. - * tree.h (check_max_integer_computation_mode): Declare. - * tm.texi (MAX_INTEGER_COMPUTATION_MODE): Document it. + * expr.c (expand_assignment): Do not try to optimize a aggregate + address which has VOIDmode. - * configure.in (nm): Make a link to "nm" in the build tree too. +Tue Mar 23 22:51:48 1999 Mumit Khan + Donn Terry - * mn10300.md (andsi3): Fix typo. + * protoize.c (abspath): Preserve multiple leading slashes for + _WIN32 and Interix. -Tue Jun 16 22:58:40 1998 Richard Henderson +1999-01-23 Mike Stump - * reload1.c (reload_cse_regs): Call bzero instead of looping. + * arm/vxarm.h: Split out vxWorks support into separate headerfile + and vxify. + * arm/arm.c (cpu_defaults): Allow arm710 as default. -Tue Jun 16 18:30:35 1998 Jim Wilson + * configure.in: Split out vxWorks support for Arm. + * configure: Rebuilt. - * dwarf2out.c (stripattributes): Prepend '*' to the section name. +Tue Mar 23 11:20:03 1999 Per Bothner + + * tree.c (first_rtl_op, has_cleanups): Handle GOTO_SUBROUTINE_EXPR. + +Tue Mar 23 09:00:39 1999 Nick Clifton + + * config/arm/riscix1.h (SUBTARGET_SWITCHES): Add doc string. + * config/arm/riscix1-1.h (SUBTARGET_SWITCHES): Add doc string. + +Tue Mar 23 07:50:20 1999 Mark Mitchell + + * function.c: Include hash.h. + (insns_for_mem_entry): New struct. + (put_reg_into_stack): Take an optional hash-table mapping MEMs to + the INSNs that use them. + (fixup_var_refs): Likewise. + (put_addressof_into_stack): Likewise. + (purge_addressof_1): Likewise. Keep the hash-table up to date if + we add new instructions. + (fixup_var_refs_insns): Use it to avoid searching the entire + instruction chain. + (insns_for_mem_newfunc): New function. + (insns_for_mem_comp): Likewise. + (insns_for_mem_walk): Likewise. + (compute_insns_for_mem): Likewise. + (pop_function_context_from): Pass NULL for the hash-table. + (put_var_into_stack): Likewise. + (gen_mem_addressof): Likewise. + (flush_addressof): Likewise. + (purge_addressof): Call compute_insns_for_mem to pre-compute the + hash table. + * Makefile.in (OBJS): Include hash.o. + (function.o): Depend on hash.h. -Tue Jun 16 16:49:26 1998 Richard Henderson +Tue Mar 23 00:39:14 1999 Jeffrey A Law (law@cygnus.com) - * alpha.c (alpha_expand_prologue, alpha_expand_epilogue): New fns. - (output_prologue, output_epilogue): Merge VMS and OSF versions; - Remove anything related to the actual code generation. - (output_end_prologue): New function. - (alpha_sa_mask, alpha_sa_size): Merge VMS and OSF versions. - (alpha_does_function_need_gp): Return false for VMS. - (alpha_function_needs_gp): Make static. - (add_long_const): Delete. - (summarize_insn): Don't assume a SUBREG is of a REG. - Prototype all static functions. Rename VMS-specific global - variables vms_*. - * alpha.h (TARGET_CAN_FAULT_IN_PROLOGUE): Default to 0. - (FUNCTION_BOUNDARY): Align to cache line. - (LOOP_ALIGN, ALIGN_LABEL_AFTER_BARRIER): Align to octaword. - (FUNCTION_END_PROLOGUE): New macro. - * alpha.md (attribute length): New. Mark all insns. - (return_internal, prologue_stack_probe_loop) New patterns. - (prologue, init_fp, epilogue): New patterns. - Disable peepholes. - * linux.h (TARGET_CAN_FAULT_IN_PROLOGUE): Define. + * i386/openbsd.h (TARGET_DEFAULT): Use symbolic names instead of + numbers. + * i386/netbsd.h, i386/freebsd.h: Likewise. -Tue Jun 16 17:36:35 1998 Dave Brolley + * crtstuff.c: Use ANSI function definitions. Fix minor whitespace + problems. - * toplev.c (lang_options): Add -trigraphs option for cpplib. + * i386/openbsd.h (TARGET_DEFAULT): Define. + * configure.in: Do not set TARGET_CPU_DEFAULT for x86 OpenBSD + configurations. + * configure: Rebuilt. -Tue Jun 16 23:33:24 1998 J"orn Rennecke +Tue Mar 23 00:39:10 1999 John Wehle (john@feith.com) - * reload1.c (reload_reg_free_before_p): RELOAD_FOR_OUTADDR_ADDRESS - is earlier than RELOAD_FOR_OUTPUT_ADDRESS; RELOAD_FOR_INPADDR_ADDRESS - is earlier than RELOAD_FOR_INPUT_ADDRESS. + * i386/freebsd.h (TARGET_DEFAULT): Define instead + of TARGET_CPU_DEFAULT. + * i386/netbsd.h (TARGET_DEFAULT): Likewise. -Tue Jun 16 13:15:16 1998 Jim Wilson +Mon Mar 22 23:52:01 1999 Mumit Khan + Donn Terry - * libgcc1-test.c (memcpy): Define. + * sdbout.c (syms.h): Don't include on Interix. + * toplev.c (main): No sbrk on Interix. -Tue Jun 16 13:44:02 1998 Michael Meissner + * configure.in: Add i386-pc-interix support. + * configure: Regenerate. + * fixinc.interix: New file. + * config/interix.h: New file. + * config/x-interix: New file. + * config/xm-interix.h: New file. + * i386/interix.h: New file. + * i386/interix.c: New file. + * i386/t-interix: New file. + +Mon Mar 22 23:41:49 1999 Jeffrey A Law (law@cygnus.com) - * genattrtab.c (struct attr_desc): Change int flags to bit - fields. Add bit fields for this being function_units_used - or *_blockage_range attributes. - (write_unit_name): New function to print a function unit name - given unit #. - (expand_units): Indicate whether this is function_units_used or - *_blockage_range attributes. - (write_toplevel_expr): Print function_units_used and - *_blockage_range attributes in a more friendly fashion. - (make_internal_attr): Indicate whether this attribute is either - function_units_used or *_blockage_range. + * i386.h (PREFERRED_STACK_BOUNDARY): Define. + +Mon Mar 22 23:41:31 1999 John Wehle (john@feith.com) + + * i386.c (ix86_compute_frame_size): New function. + (ix86_prologue, ix86_epilogue): Use it. + * i386.h (INITIAL_ELIMINATION_OFFSET): Likewise. + * reload1.c: Provide default for PREFERRED_STACK_BOUNDARY. + +Mon Mar 22 18:06:59 1999 Jim Wilson + + * mips/mips.h (TARGET_SWITCHES, TARGET_OPTIONS): Add option doc + strings. + * mips/abi64.h (SUBTARGET_TARGET_OPTIONS): Likewise. + +Mon Mar 22 16:18:27 1999 Nick Clifton + + * config/arm/elf.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother + passing ATTRIBUTES to arm_valid_machine_decl_attribute. + + * config/arm/coff.h (VALID_MACHINE_DECL_ATTRIBUTE): Do not bother + passing ATTRIBUTES to arm_valid_machine_decl_attribute. + + * config/arm/arm.h (DEFAULT_RTX_COSTS): Do not bother passing + OUTER_CODE to arm_rtx_costs - it is not used. + (arm_compare_fp): Delete declaration. + (FINAL_PRESCAN_INSN): Do not bother passing OPVEC or NOPERANDS to + arm_final_prescan_insn - they are not used. + (const_ok_for_op): Remove prototype. + (arm_rtx_costs): Fix prototype. + (arm_valid_machine_decl_attribute): Fix prototype. + (final_prescan_insn): Fix prototype. + + * config/arm/arm.md: Remove references to arm_compare_fp. + + * config/arm/arm.c (arm_compare_fp): Delete. + (const_ok_for_op): Make function static. Add prototype. Remove + mode parameter - it is unused. + (arm_rtx_costs): Remove outer_code parameter. + (reload_memory_operand): Declare mode parameter unused. + (power_of_two_operand): Declare mode parameter unused. + (equality_operator): Declare mode parameter unused. + (load_multiple_operation): Declare mode parameter unused. + (store_multiple_operation): Declare mode parameter unused. + (multi_register_push): Declare mode parameter unused. + (arm_valid_machine_decl_attribute): Remove attributes parameter - + it is unused. + (select_dominance_cc_mode): Remove op parameter - it is unused. + (gen_compare_reg): Remove fp parameter - it is unused. + (final_prescan_insn): Remove opvec and noperands parameters - they + are unused. + +Mon Mar 22 14:35:28 1999 Nick Clifton + + * tm.texi (MD_SCHED_INIT): Add missing closing parenthesis. + +Mon Mar 22 22:24:30 1999 J"orn Rennecke + + * reload1.c (reload_as_needed): Set reload_is_output_reload / + reload_has_output_reload for auto_inc expressions that could be + reloaded. Call forget_old_reloads for REG_INC notes. + +Mon Mar 22 21:51:57 1999 J"orn Rennecke + + * cse.c (cse_insn): Don't change the result register of a libcall. + +Mon Mar 22 21:08:59 1999 J"orn Rennecke + + * rtl.h (shallow_copy_rtx): Declare. + * rtl.c (shallow_copy_rtx): New function. + * reload.c (find_reloads_toplev): Use shallow_copy_rtx instead of + copy_rtx. + +Mon Mar 22 10:44:33 1999 Vladimir Makarov + + * config/h8300/h8300.md (adjust_length): New attribute. + (modhi3+1, andsi3+1, iorsi3+1, extzv+1, extzv+2): Change insn + default value of attribute "adjust_length" onto "no". + + * config/h8300/h8300.c (h8300_adjust_insn_length): Adjust + length only if the attribute "adjust_length" value is "yes". + Use 0 if the shift is negative. + + * final.c (shorten_branches): Check insn length after its + adjusting. + +Sun Mar 21 17:33:48 1999 Jeffrey A Law (law@cygnus.com) + + * i860.h (TARGET_SWITCHES): Add documentation for default case. + * i860/paragon.h (TARGET_SWITCHES): Add documentation for default case. + * i370.h (TARGET_SWITCHES): Add documentation for default case. + * fx80.h (TARGET_SWITCHES): Add documentation for default case. + * elxsi.h (TARGET_SWITCHES): Add documentation for default case. + * clipper.h (TARGET_SWITCHES): Add documentation for default case. + * 1750a.h (TARGET_SWITCHES): Add documentation for default case. + * pa.h (TARGET_SWITCHES): Add documentation for default case. + (TARGET_OPTIONS): Likewise for default case. + * mn10300.h (TARGET_SWITCHES): Add documentation for default case. + * h8300.h (TARGET_SWITCHES): Add documentation for default case. -Mon Jun 15 17:06:43 1998 Michael Meissner - Jim Wilson + * gcse.c (dump_hash_table): Fix whitespace in declaration. + (compute_transpout): Renamed from pre_compute_transpout. + (compute_pre_*): Deleted. + (pre_expr_reaches_here_p): New argument, CHECK_PRE_COMP. All + callers changed. + (insert_insn_end_bb): Renamed from pre_insert_insn. + (pre_*): Delete unused variables. Only leave local properties and + global redundant/optimal computation points. + (alloc_pre_mem, free_pre_mem): Corresponding changes. + (compute_pre_data): Simplify and call pre_lcm to run the lazy + code motion dataflow analysis. + (pre_insert, pre_insert_copies, pre_delete): Revamp to use LCM + based redundant and optimal computation points. + + * basic-block.h (pre_lcm, pre_rev_lcm): Declare. + + * toplev.c (main): A debug option without a level defaults to + level 2. + +Sun Mar 21 12:13:01 1999 Nick Clifton + + * flow.c (can_delete_label_p): Do not allow user specified + labels to be deleted. + * dwarf2out.c (gen_label_die): Generate addresses for deleted + (programmer specified) labels. + * dwarfout.c (output_label_die): Generate addresses for deleted + (programmer specified) labels. + +1999-03-21 Manfred Hollstein + + * Makefile.in (xgcc$(exeext)): Add intl.o to list of files to be + linked with. - * regmove.c (copy_src_to_dest): Do not copy src to dest if either - the source or destination is special. +Sun Mar 21 01:15:03 1999 Jeff Law (law@cygnus.com) -Mon Jun 15 13:20:33 1998 Jim Wilson + * version.c: Bump for snapshot. - * c-decl.c (shadow_tag_warned): Use specs not declspecs in for loop. +Sat Mar 20 22:26:23 1999 Kaveh R. Ghazi -Mon Jun 15 07:16:29 PDT 1998 Jeff Law (law@cygnus.com) + * sparc.h (TARGET_SWITCHES): Add null description to default case. - * version.c: Bump for snapshot. +Sat Mar 20 21:46:06 1999 Kaveh R. Ghazi -Sat Jun 13 13:10:40 1998 Krister Walfridsson - - * config/sparc/netbsd.h (DEFAULT_PCC_STRUCT_RETURN): Undefine before - redefining it. - -Fri Jun 12 18:06:45 1998 Doug Evans - - * m32r/m32r.h (STARTFILE_SPEC): Delete crtsysc.o. - (ENDFILE_SPEC): Add -lgloss. - -Fri Jun 12 14:57:59 1998 Kaveh R. Ghazi - - * mips.c (small_int): Mark parameter `mode' with ATTRIBUTE_UNUSED. - (large_int): Likewise. - (pc_or_label_operand): Likewise. - (call_insn_operand): Likewise. - (consttable_operand): Likewise. - (m16_uimm3_b): Likewise. - (m16_simm4_1): Likewise. - (m16_nsimm4_1): Likewise. - (m16_simm5_1): Likewise. - (m16_nsimm5_1): Likewise. - (m16_uimm5_4): Likewise. - (m16_nuimm5_4): Likewise. - (m16_simm8_1): Likewise. - (m16_nsimm8_1): Likewise. - (m16_uimm8_1): Likewise. - (m16_nuimm8_1): Likewise. - (m16_uimm8_m1_1): Likewise. - (m16_uimm8_4): Likewise. - (m16_nuimm8_4): Likewise. - (m16_simm8_8): Likewise. - (m16_nsimm8_8): Likewise. - (m16_usym8_4): Likewise. - (m16_usym5_4): Likewise. - (mips_move_1word): Change type of variable `i' from int to size_t. - (mips_move_2words): Likewise. - (output_block_move): Mark parameter `libname' with ATTRIBUTE_UNUSED. - (function_arg_advance): Use HOST_PTR_PRINTF to print an address. - (function_arg): Likewise. - (function_arg_partial_nregs): Mark parameter `named' with - ATTRIBUTE_UNUSED. - (override_options): Use ISDIGIT instead of isdigit. - (mips_output_external): Mark parameter `file' with ATTRIBUTE_UNUSED. - (final_prescan_insn): Likewise for parameters `opvec' and `noperands'. - (save_restore_insns): Cast HOST_WIDE_INT arguments passed to - function `fatal' to long before printing. Use - HOST_WIDE_INT_PRINT_DEC in fprintf. Both changes done several - times in this function. - (function_prologue): Mark parameter `size' with ATTRIBUTE_UNUSED. - (function_epilogue): Likewise for parameters `file' and `size'. - Print an int with "%d" not "%ld". - (mips_select_rtx_section): Mark parameter `x' with ATTRIBUTE_UNUSED. - (mips_function_value): Likewise for parameter `func'. - (function_arg_pass_by_reference): Likewise for parameters `cum' - and `named'. - (extend_operator): Likewise for parameter `mode' - (highpart_shift_operator): Likewise. + * c-lex.c (yylex): Remove unused variable `bytes'. - * mips.md (mul_acc_si): Remove unused variable `macc'. + * flow.c (print_rtl_with_bb): Cast the return value of alloca. -Fri Jun 12 09:33:44 1998 Richard Henderson + * function.c (assign_parms): Wrap variable `varargs_setup' in + macro SETUP_INCOMING_VARARGS. + (thread_prologue_and_epilogue_insns): Mark parameter `f' with + ATTRIBUTE_UNUSED. - * fold-const.c (fold): Revert last change. It breaks constant - expressions somehow. + * local-alloc.c (no_equiv): Likewise for parameter `store'. -Fri Jun 12 10:23:36 1998 Andreas Schwab + * sched.c (schedule_insns): Remove unused variables `insn' and `next'. - * expr.c (do_jump, case EQ_EXPR, NE_EXPR): When comparing complex - prevent operands from being evaluated twice. + * tlink.c (symbol_hash_newfunc, symbol_hash_lookup, + file_hash_newfunc, file_hash_lookup, demangled_hash_newfunc, + demangled_hash_lookup, symbol_push, symbol_pop, file_push, + file_pop, tlink_init, tlink_execute, frob_extension, + obstack_fgets, tfgets, pfgets, freadsym, read_repo_file, + maybe_tweak, recompile_files, read_repo_files, + demangle_new_symbols, scan_linker_output): Add static prototype. -Fri Jun 12 00:50:27 1998 Sergey Okhapkin + (symbol_hash_newfunc, file_hash_newfunc, demangled_hash_newfunc): + Make the third argument a `hash_table_key'. - * toplev.c (lang_options): Add -remap as a preprocessor option. + * toplev.c (debug_start_source_file): Mark parameter `filename' + with ATTRIBUTE_UNUSED. -Fri Jun 12 00:30:32 1998 John Wehle (john@feith.com) +Sun Mar 21 02:28:21 1999 Andreas Schwab - * i386.md (cmpsi_1, cmphi_1, cmpqi_1): Remove code - which set CC_REVERSED since reload should ensure that - the operands are already the correct type. + * tm.texi (Varargs): Don't split argument of @item across lines. -Thu Jun 11 17:14:15 1998 Jim Wilson + * invoke.texi: Fix use of @item vs @itemx. - * except.c (expand_builtin_eh_stub): Call emit_move_insn rather than - calling gen_rtx_SET. +Sun Mar 21 09:59:54 1999 Michael Hayes -Thu Jun 11 18:45:49 1998 David Edelsohn + * config/c4x/c4x.h (TARGET_SWITCHES): Add null description to + default case. - * config/rs6000/x-aix43 (AR): Delete. - (AR_FOR_TARGET_FLAGS): Add -X32_64 here. +Sat Mar 20 23:33:54 1999 Michael Hayes -Thu Jun 11 16:19:17 1998 David W. Schuler + * loop.c (check_dbra_loop): Fix debug message. - * config/i386/aix386ng.h (CPP_SPEC): Remove extraneous quote. +Sat Mar 20 15:54:35 1999 Michael Hayes -Thu Jun 11 12:40:27 1998 Jim Wilson + * config/c4x/c4x.md (decrement_and_branch_on_count): Emit rptb_end + pattern instead of decrement_and_branch_until_zero pattern. - * mips.c (override_options): Replace word_mode with explicit - TARGET_64BIT check. +Sat Mar 20 11:39:58 1999 Michael Hayes -Thu Jun 11 14:50:02 1998 Michael Meissner + * config/c4x/c4x.h (TARGET_SWITCHES): Add documentation. + * config/c4x/c4x.h (TARGET_OPTIONS): Add documentation. - * regmove.c (regmove_optimize): If we can't replace the - destination in an insn that sets the source, generate an explicit - move of the source to the destination. - (copy_src_to_dest): New function. - (toplevel): Include basic-block.h +Fri Mar 19 23:26:29 1999 Martin von Löwis - * Makefile.in (regmove.o): Add basic-block.h dependencies. + * expr.c (expand_expr): Handle ERROR_MARK much earlier. -Thu Jun 11 10:30:09 1998 Dave Brolley +Fri Mar 19 15:28:38 1999 Kaveh R. Ghazi - * toplev.c (lang_options): Add missing options (nostdinc, idirafter). + * cccp.c (create_definition): Cast to U_CHAR* when assigning to one. -Wed Jun 10 23:39:32 1998 Mark Mitchell + * cppfiles.c (read_and_prescan): Likewise. + Start a #define in column 0. - * rtl.h (rtx_def): Improve documentation. - (MEM_IN_STRUCT_P): Likewise. + * cpplib.c (cpp_define): Cast to U_CHAR* when assigning to one. + (cpp_push_buffer): Likewise for cpp_buffer*. + (do_include): Change the type of `fbeg' and `fend' to unsigned char*. + (do_endif): Cast to char* when assigning to one. + (do_assert): Likewise. + (do_unassert): Likewise. + (cpp_read_check_assertion): Change the type of `name' to U_CHAR*. + Don't do unnecessary cast to char* anymore. -Wed Jun 10 23:23:17 1998 Graham + * genrecog.c (make_insn_sequence): Cast to char** when assigning + to one. Cast the first argument of bzero to PTR. - * c-decl.c (start_decl): Correct test for -Wmain. + * loop.c (strength_reduce): Remove unused variable `note'. - * c-decl.c (grokdeclarator): Remove unused variable "last". + * reload1.c (new_insn_chain): Cast to struct insn_chain* when + assigning to one. -Wed Jun 10 14:52:27 1998 Jim Wilson + * rtl.c (copy_rtx): Use memcpy instead of bcopy. - * expr.c (expand_builtin_setjmp): Store const1_rtx in target. - (expand_builtin_longjmp): Abort if value isn't const1_rtx. - Delete code storing value in static_chain_rtx. - (expand_builtin, case BUILT_IN_LONGJMP): Pass NULL_RTX for target - to second expand_expr call. +Fri Mar 19 11:19:31 1999 Kaveh R. Ghazi -Wed Jun 10 13:08:41 1998 Mark Mitchell + * calls.c (initialize_argument_information): Mark parameters + `num_actuals' and `n_named_args' with ATTRIBUTE_UNUSED. - * mips/mips.c: Remove -mabi=o32 and -mabi=n64. + * dbxout.c (dbxout_start_new_source_file): Likewise for parameter + `filename'. + (dbxout_finish): Likewise for parameters `file' and `filename'. + (dbxout_prepare_symbol): Likewise for parameter `decl'. + (dbxout_begin_function): Likewise. -Wed Jun 10 13:41:23 1998 Dave Brolley + * explow.c (hard_function_value): Likewise for parameter `func'. - * cppmain.c (fatal): New function. - * configure.in (cpp_main): New configuration variable. - * configure: Regenerated. - * Makefile.in (CCCP): Use a configuration variable to select basex - for cccp. - (cppmain$(exeext)): Add @extra_cpp_objs@. + * function.c (locate_and_pad_parm): Likewise for parameter `fndecl'. -Wed Jun 10 13:07:02 1998 Dave Brolley + * expmed.c (expand_divmod): Omit unused argument to `expand_abs'. + * expr.c (expand_expr): Likewise. + * expr.h (expand_abs): Delete unused argument from prototype. + * optabs.c (expand_abs): Remove unused parameter `unsignedp'. - * objc/objc-act.c: Add cpplib declarations. - (lang_decode_option): Initialize cpplib if necessary. - (lang_decode_option): New argc/argv interface. - * tree.h (lang_decode_option): New argc/argv interface. - * toplev.c (lang_options): Add cpp options. - (main): New interface for lang_decode_option. - * gcc.c (default_compilers): Don't call cpp for a cpplib-enabled C compiler - unless -E, -M or -MM is specified. - * cpplib.h (cpp_handle_option): New function. - * cpplib.c (cpp_handle_option): New function. - (cpp_handle_options): Now calls cpp_handle_option. - * c-tree.h (c_decode_option): New argc/argv interface. - * c-lex.c (init_parse): cpplib now initialized in c_decode_option. - * c-lang.c (lang_decode_option): New argc/argv interface. - * c-decl.c: Add cpplib declarations. - (c_decode_option): New argc/argv interface. - (c_decode_option): Call cpp_handle_option. - (c_decode_option): Now returns number of strings processed. + * sdbout.c (sdbout_init): Mark parameter `syms' with ATTRIBUTE_UNUSED. + (sdbout_end_block): Likewise for parameter `n'. -Wed Jun 10 09:47:13 1998 Richard Earnshaw (rearnsha@arm.com) + * toplev.c (debug_define): Likewise for parameters `lineno' and + `buffer'. + (debug_undef): Likewise. - * unroll.c (verify_addresses): Use validate_replace_rtx to undo the - changes. Abort if the undo fails. + * varasm.c (named_section): Likewise for parameter 'reloc'. + (assemble_external): Likewise for parameter `decl'. + (assemble_alias): Likewise for parameter `target'. -1998-06-10 Vladimir N. Makarov +Fri Mar 19 01:54:30 1999 Theodore Papadopoulo - * config/rs6000/rs6000.c (output_prolog): Change locations and - directions of saving and restoring arguments of main on the stack. + * toplev.c (read_integral_parameter): Constify. Better control of + error messages. + (main): Use read_integral_parameter to set optimize, id_clash_len, + larger_than_size, and the debugging level. + * toplev.h (read_integral_parameter): Update prototype. -Wed Jun 10 08:56:27 1998 John Carr +Fri Mar 19 01:42:05 1999 Zack Weinberg - * reload1.c (reload_cse_simplify_operands): Do not call gen_rtx_REG - for each alternative. Do not replace a CONST_INT with a REG unless - the reg is cheaper. + * system.h: Use putc_unlocked, fputc_unlocked, and + fputs_unlocked only if putc_unlocked has a prototype already. + Prototype fputs_unlocked if necessary. + * configure.in: Check for prototypes of putc_unlocked and + fputs_unlocked. + * acconfig.h: Updated. + * config.in, configure: Rebuilt. -Wed Jun 10 02:11:55 1998 Jeffrey A Law (law@cygnus.com) +Fri Mar 19 02:45:12 1999 Alexandre Oliva - * decl.c (init_decl_processing): Fix typo. + * Makefile.in (INTL_TARGETS): New macro. + ($(INTL_TARGETS)): Depend on generated sources; drop dependencies + on cp/parse.c and objc/objc-parse.c. + ($(srcdir)/cp/parse.c): Move to cp/Make-lang.in. + * objc/Make-lang.in ($(INTL_TARGETS)): Depend on objc/objc-parse.c. - * mips.c (gpr_mode): New variable. - (override_options): Initialize gpr_mode. - (compute_frame_size): Use "gpr_mode" instead of "word_mode" to - determine size and offset of general purpose registers save slots. - (save_restore_insns, mips_expand_prologue): Similarly. +Thu Mar 18 22:28:53 1999 Jeffrey A Law (law@cygnus.com) - * reload.c (find_reloads_toplev): Use gen_lowpart common to convert - between constant representations when we have (SUBREG (REG)) with - REG equivalent to a constant. + * i860.h (TARGET_SWITCHES): Add documentation. + * i860/paragon.h (TARGET_SWITCHES): Add documentation. + * i370.h (TARGET_SWITCHES): Add documentation. + * fx80.h (TARGET_SWITCHES): Add documentation. + * elxsi.h (TARGET_SWITCHES): Add documentation. + * clipper.h (TARGET_SWITCHES): Add documentation. + * 1750a.h (TARGET_SWITCHES): Add documentation. + * pa.h (TARGET_SWITCHES): Add documentation. + (TARGET_OPTIONS): Likewise. + * mn10300.h (TARGET_SWITCHES): Add documentation. + * h8300.h (TARGET_SWITCHES): Add documentation. -Wed Jun 10 01:39:00 1998 Juha Sarlin +Thu Mar 18 15:58:26 1999 Nick Clifton - * h8300.c (get_shift_alg): Add special cases for shifts of 8 and 24. + * loop.c (strength_reduce): Do not perform pseudo replacements + if the loop contains volatile memory references. -Tue Jun 9 22:05:34 1998 Richard Henderson +Thu Mar 18 19:09:50 1999 J"orn Rennecke - * fold-const.c (fold): Even with otherwise constant trees, look for - opportunities to combine integer constants. + * reload.c (find_reloads_toplev): When processing X recursively, + don't alter it destructively except by filling in constants. -Wed Jun 3 23:41:24 EDT 1998 John Wehle (john@feith.com) +Thu Mar 18 10:14:18 1999 Kaveh R. Ghazi - * i386.c (notice_update_cc): Clear cc_status.value2 in the - case of UNSPEC 5 (bsf). + * cccp.c (default_include): Initialize structure members. + (pass_thru_directive): Change the type of 'keyword_length' to int. + (main): Cast `bindtextdomain' and `textdomain' to (void). - * i386.md (movsfcc, movdfcc, movxfcc): The floating point - conditional move instructions don't support signed integer - comparisons. + * collect2.c (main): Likewise. -Tue Jun 9 14:31:19 1998 Nick Clifton + * cppmain.c (main): Likewise. - * config/v850/t-v850 (TCFLAGS): Add assembler options to warn of - overlfows. + * gcc.c (main): Likewise. - * config/v850/lib1funcs.asm (__return_interrupt): Use 'addi - 16,sp,sp' ratehr than 'add 16,sp'. Patch courtesy of Biomedin - . + * gcov.c (main): Likewise. -Tue Jun 9 16:23:13 EDT 1998 Andrew MacLeod + * protoize.c (main): Likewise. - * except.c (expand_start_catch): Rename to start_catch_handler. - (expand_end_catch): Delete function. - (expand_end_all_catch): Remove catch status that expand_end_catch - use to do. - * except.h (expand_start_catch): Rename prototype. - (expand_end_catch): Delete prototype. + * toplev.c (main): Likewise. -Tue Jun 9 12:57:32 1998 Mark Mitchell +1999-03-18 Gavin Romig-Koch - * invoke.texi: Add documentation for -mips4 and -mabi=*. + * config/mips/mips.c (mips_explicit_type_size_string): Correct + its type. -Tue Jun 9 12:12:34 1998 Klaus Kaempf (kkaempf@progis.de) +Thu Mar 18 01:24:25 1999 Jeffrey A Law (law@cygnus.com) - * alpha/vms.h (EXTRA_SECTIONS): Add in_ctors and in_dtors. - (EXTRA_SECTION_FUNCTIONS): Add ctors_section and dtors_section. - (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Define. + * configure.in: Use "exit 1", not "exit (1)". + * configure: Rebuilt. -Tue Jun 9 12:10:27 1998 John Carr +Wed Mar 17 23:17:42 1999 Mark Kettenis + + * config/t-gnu (SYSTEM_HEADER_DIR): New variable. Set to + `/include' in order to find the system's limits.h. + +Wed Mar 17 23:00:18 1999 Robert Lipe + + * fixinc/fixincl.c: Include auto-host.h instead of config.h. + * fixinc/procopen.c: Likewise. + * fixinc/regex.c: Likewise. + * fixinc/server.c: Likewise. + +Wed Mar 17 22:46:13 1999 Mark Elbrecht + Jeff Law - * mips.c (gpr_mode): New variable. - (override_options): Initialize gpr_mode. - (compute_frame_size): Use "gpr_mode" instead of "word_mode" to - determine size and offset of general purpose registers save slots. - (save_restore_insns, mips_expand_prologue): Similarly. + * pa.md: Add real PA8000 scheduling information. - * Makefile.in (LIB2FUNCS_EH): Define. Just "_eh" for now. - (LIBGCC2_CFLAGS): Remove -fexceptions. - (LIB2FUNCS): Remove "_eh". - (libgcc2.a): Iterate over LIB2FUNCS_EH and build everything in - it with -fexceptions. + * pa.h (processor_type): Add PROCESSOR_8000 symbol. + (ISSUE_RATE): Revamp, including PA8000 support. + * pa.c (override_options): Add 8000 as -mschedule= option. + Do not call strcmp if pa_cpu_string is null. + * pa.md (attr cpu): Add 8000. + * invoke.texi: Add documentation for PA8000 scheduling. - * Makefile.in (local-alloc.o): Depend on insn-attr.h. - * local-alloc.c (block_alloc): Avoid creating false - dependencies for targets which use instruction scheduling. +Wed Mar 17 18:20:24 1999 David S. Miller -Tue Jun 9 02:40:49 1998 Richard Henderson + * config/sparc/sparc.h (TARGET_SWITCHES, TARGET_OPTIONS): + Add descriptions. + * config/sparc/sp64-elf.h (SUBTARGET_SWITCHES): Likewise. + * config/sparc/splet.h (SUBTARGET_SWITCHES): Likewise. - * mips/elf.h (ASM_DECLARE_OBJECT_NAME): Define. - (ASM_FINISH_DECLARE_OBJECT): Define; - * mips/elf64.h: Likewise. +Wed Mar 17 14:51:19 1999 Richard Henderson -Tue Jun 9 01:08:47 1998 Richard Henderson + * flow.c (compute_immediate_dominators): New function. + * basic-block.h (compute_immediate_dominators): Declare it. - * toplev.c (flag_new_exceptions): Remove extraneous `extern'. + * alpha.h (HARD_REGNO_MODE_OK): Allow only 4 and 8 byte unit modes + in FP regs. + (MODES_TIEABLE_P): Define asymmetricly wrt modes illegal in FP regs. -Mon Jun 8 23:24:48 PDT 1998 Jeff Law (law@cygnus.com) +Wed Mar 17 14:41:41 1999 Nick Clifton + + * config/arm/aout.h (ASM_GENERATE_INTERNAL_LABEL): Fix compile + time warning. + * config/arm/arm.md: Fix various compile time warnings. + * config/arm/arm.h: Fix various compile time warnings. Add + function prototypes. + * config/arm/arm.c: Fix various compile time warnings. + (arm_override_options): Reorganize to separate tuning from + targetting. + (bit_count): New function: Return a count of the number of bits + set in a word. + +Wed Mar 17 21:29:12 1999 J"orn Rennecke + + * reload1.c (eliminate_regs): Don't keep REG_DEAD notes around for + things that were eliminated. + +Wed Mar 17 12:16:26 1999 Richard Henderson + + * function.c (fixup_var_refs_1): First try moving the expression + directly into a register. Don't separate cc0 setter and user. + +Wed Mar 17 11:20:29 1999 Dave Brolley + + * cppfiles.c (PIPE_BUF): #define PIPE_BUF if not defined already. + +Wed Mar 17 09:25:06 1999 Kaveh R. Ghazi + + * c-lex.c: Don't include setjmp.h. + (parse_float): New static function. + (pf_args): New struct. + (yylex): Use them in call to `do_float_handler'. + +1999-03-16 Andreas Schwab + + * cexp.y (yyerror): Call verror to get a useful error message. + * cexp.c: Rebuilt. + + * .gdbinit: Move command to put breakpoint at abort to end of file + so that gdb does not bail out early. + +Tue Mar 16 15:30:19 1999 Nick Clifton + + * rtl.h: Rename prototype for free_bb_memory to free_bb_mem. + +Tue Mar 16 23:40:09 1999 J"orn Rennecke + + * sh.md (movsi_i): Move t/r alternative after r/rI alternative. + +Tue Mar 16 13:44:50 1999 Jim Wilson + + * mn10200/mn10200.md (addsi3, subsi3, ashlsi3, lshrsi3, ashrsi3): + Delete emit_library_call_value declaration. + +1999-03-16 Zack Weinberg + + * cppfiles.c (read_and_prescan): Map backslash-newline to '\r' + (which cannot otherwise appear in the processed buffer) and + move it out of tokens that it appears in the middle of. + Improve performance. + (find_position): New function. + + * cpplib.c: \r (one character) indicates backslash + newline, not \\\n (two characters). It cannot appear in the + middle of a token. Call CPP_BUMP_LINE (pfile) whenever + parsing moves past \n or \r. Increment pfile->lineno whenever + a \n is placed into token_buffer. Only one mark can exist at + a time, and CPP_BUMP_LINE must not be used while it is + active. It is automatically cleared by cpp_pop_buffer and + parse_goto_mark. \r is not in is_hor_space or is_space. + + (NEWLINE_FIX, NEWLINE_FIX1, adjust_position, + update_position, count_newlines, parse_move_mark): Removed. + (parse_string, copy_comment): New functions. + (parse_name): Returns void. + (parse_set_mark, parse_clear_mark, parse_goto_mark): Take only + one argument, a cpp_reader *. Change for new marking scheme. + (skip_comment): Handle CHILL line comments too. Second + argument is now first character of comment marker; all callers + changed. Issue error for unterminated block comment here. + (cpp_skip_hspace): Recognize CHILL comments. + (copy_rest_of_line): Likewise. Call skip_comment and + parse_string directly, don't go through cpp_get_token. Emit + "/**/" for block comments if -traditional (create_definition + needs this). + (do_define): Don't play with put_out_comments. + (cpp_push_buffer): Initialize ->mark to -1. + (cpp_buf_line_and_col): Just read out the values in the buffer + structure. + (output_line_command): Use cpp_buf_line_and_col. Fix + formatting. Remove stale code. + (cpp_get_token): Break out string parsing code to + parse_string. Use skip_comment for CHILL comments too. Use + copy_comment for put_out_comments instead of dinking with + marks. Remove stale code. Don't call output_line_command + unless it's necessary. + + * cpplib.h (parse_marker): Removed. + (struct cpp_buffer): Line_base is now a unsigned char *; add + `mark' [long], remove `marks' [struct parse_marker *]. + (parse_set_mark, parse_clear_mark, parse_goto_mark): Update + prototypes. + (CPP_BUMP_LINE, CPP_BUMP_BUFFER_LINE): New macros. + * cppinit.c (is_hor_space, is_space): '\r' is not considered + whitespace. + * cppexp.c (cpp_parse_expression): Use cpp_skip_hspace, not + SKIP_WHITE_SPACE. + * cpphash.c (macarg): Disable line commands while expanding. + +Tue Mar 16 11:30:19 1999 Gavin Romig-Koch + + * c-lex.c (yylex) : Remove warning for integer literals being + larger than the largest target int. Add warning for integer + literal being larger than than its chosen type. + +Tue Mar 16 10:53:17 1999 Gavin Romig-Koch + + * invoke.texi: Add -mlong32 documentation. + * config/mips/mips.h (mips_explicit_type_size_string): New. + (TARGET_SWITCHES): Add 'long32'. + (TARGET_OPTIONS): Add 'explicit-type-size'. + (CC1_SPECS): Set -mexplicit-type-size. + (LONG_MAX_SPEC): Change a use of 'no-long64' to 'long32'. + * config/mips/abi64.h (LONG_MAX_SPEC): Same. Add 'mabi=32'. + * config/mips/mips.c (mips_explicit_type_size_string): New. + (override_options): Use it. + * config/mips/osfrose.h (CC1_SPECS): Set -mexplicit-type-size. + + * config/mips/mips.h (SUBTARGET_CPP_SIZE_SPEC): + Pointer size now depends on both size longs and size of GP + registers. + +Tue Mar 16 10:22:22 1999 Gavin Romig-Koch + + * config/mips/iris.h (CTORS_SECTION_ASM_OP,DTORS_SECTION_ASM_OP, + dtors_section): Use Pmode == DImode rather than TARGET_LONG64. + * config/mips/mips.c (override_options): Allow -mlong64 and + -mint64 with -mips2 or less. + * config/mips/mips.h (MASK_LONG64): Fix comment. + (POINTER_SIZE): Use Pmode == DImode rather than TARGET_LONG64. + (Pmode): Make Pmode the smaller of longs or gp registers. + * invoke.texi: Note the new size for pointers. + +Mon Mar 15 22:45:25 1999 David Edelsohn + + * rs6000.h (ASM_OUTPUT_{DOUBLE,FLOAT}): Always generate IEEE 754 + bit-pattern directly. + (ASM_OUTPUT_REG_{PUSH,POP}): Delete. + * rs6000.c (first_reg_to_save): If profiling and context needed, + allocate a reg to save static chain for all ABIs. For AIX + profiling, calculate parameter registers to save based on need. + (output_function_profiler): Save and restore static chain around + profile call for all ABIs. + +1999-03-15 Zack Weinberg + + * cppinit.c: Instead of one pending list, keep separate lists + for each category of pending option: -D/-U, -A, -include, + -imacros. Move the four partial include-path lists into the + pending block. Use head and tail pointers so we don't ever + have to reverse the lists. + + (cpp_start_read): Break out blocks of code to their own + functions: install_predefs and initialize_dependency_output. + Use path_include for C_INCLUDE_PATH and friends as well as + CPATH. Remove include_defaults gunk. Warn about the + combination of -lang-chill and -trigraphs. Optimize string + bashing. Walk each pending list once, deallocating as we go. + + (append_include_chain): Brought over from cppfiles.c. Mark + dirs as system include dirs if and only if appending to + system include path. If opts->verbose, print a notice when a + dir is dropped from the include path because it doesn't + exist. Fix memory leak: this function is not supposed to copy + its DIR argument. + + (nreverse_pending, push_pending): Removed. + (APPEND): New macro for adding to pending lists. + (path_include): Can now add to any partial include path. + (base_name): Bring over from cccp.c. + (cpp_options_init): Allocate the pending block. + (cpp_handle_option): Add --version. Exit after --help. Fix + formatting. Order -ifoo options by frequency of usage. + (install_predefs): New function, simplified version of code + that was in cpp_start_read. + (initialize_dependency_output): Likewise. Understand OBJECT_SUFFIX. + + * cppfiles.c (simplify_pathname): Export. + (merge_include_chains): Don't nreverse the lists. If + opts->verbose, print a notice when a duplicate dir is detected + and dropped from the include path. + (finclude): Fix excessive cleverness in setting + fp->system_header_p. + (actual_directory): Set x->sysp from + CPP_BUFFER (pfile)->system_header_p so that one system header + may include another with "". + (deps_output): Fix double adjustment of deps_size which would + cause all dependencies after the first two lines to be lost. + + * cpplib.c (cpp_unassert): New function. + * cpplib.h: Lay out struct cpp_pending here. Adjust + prototypes. Add include_prefix_len to struct cpp_options. + +Mon Mar 15 16:01:52 1999 Jim Wilson + + * config/misp/mips.h (REGISTER_MOVE_COST): Make the cost of moving + from HI/LO/HILO/MD into general registers the same as for one + of moving general registers to HI/LO/HILO/MD. + +Mon Mar 15 12:39:38 1999 Nick Clifton + + * config/m32r/m32r.c (init_idents): New function. Initialize + static tree nodes for m32r specific attribute identifiers. Remove + leading and trailing double underscores from the attribute names. + (m32r_valid_machine_decl_attribute): Call init_idents. + (m32r_encode_section_info): Call init_idents. + +Mon Mar 15 10:20:20 1999 Mark Mitchell + + * reload.c (find_reloads): Add a REG_LABEL note if we substitute a + LABEL_REF for something else. + +Mon Mar 15 08:24:17 1999 Kaveh R. Ghazi + + * fold-const.c (exact_real_inverse): Move variable `float_error' + into the scope where it is used. + (const_binop_1): New static function. + (cb_args): New struct. + (const_binop): Use them in call to `do_float_handler'. + (fold_convert_1): New static function. + (fc_args): New struct. + (fold_convert): Use them in call to `do_float_handler'. + +Mon Mar 15 22:50:18 1999 Michael Hayes + + * rtlanal.c (auto_inc_p): New function. + * rtl.h (auto_inc_p): Prototype it. + * reload1.c (add_auto_inc_notes): New function. + (reload): Strip REG_INC notes and call add_auto_inc_notes + for each insn to restore them correctly. + +1999-03-15 Manfred Hollstein + + * fixinc/Makefile.in (procopen.o): List the actual + dependencies. + +Sun Mar 14 16:22:10 1999 Kaveh R. Ghazi + + * cse.c (check_fold_consts): New static function. + (cfc_args): New struct. + (simplify_relational_operation): Use them in call to + `do_float_handler'. + + * toplev.c (do_float_handler): New function to wrap calls to + setjmp/set_float_handler. + + * toplev.h (do_float_handler): Add extern prototype. + + * tree.c (build_real_from_int_cst_1): New static function. + (brfic_args): New struct. + (build_real_from_int_cst): Use them in call to + `do_float_handler'. + +Sun Mar 14 01:15:06 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. -Mon Jun 8 23:24:58 1998 David Edelsohn - - * rs6000.md (mulsidi3): Add !TARGET_POWERPC64 constraint. - (mulsidi3_ppc64): Delete. - -Mon Jun 8 20:57:40 1998 Kaveh R. Ghazi - - * Makefile.in (varasm.o): Depend on dbxout.h. - (cse.o): Depend on toplev.h and output.h. - (gcse.o): Depend on output.h. - - * mips.c: Include system.h and toplev.h and remove redundant code. - Include output.h after tree.h so all its prototypes get activated. - * mips.md (table_jump): Remove unused variable `dest'. - - * sparc.h: Add prototype for `v8plus_regcmp_op'. - - * crtstuff.c (fini_dummy, init_dummy): Mark function definitions - with __attribute__ ((__unused__)). - (__frame_dummy): Provide prototype before use, wrap it with - EH_FRAME_SECTION_ASM_OP. - - * cse.c: Move inclusion of above local headers. - Include toplev.h and output.h. - - * dbxout.h: Add prototype for `dbxout_begin_function'. - - * final.c (final_scan_insn): Wrap variable `max_skip' in macro - ASM_OUTPUT_MAX_SKIP_ALIGN. - - * gcse.c: Include system.h and output.h. - (dump_cuid_table, dump_rd_table, dump_cprop_data, dump_pre_data): - Make extern instead of static. - (compute_can_copy): Only declare variables `reg' and `insn' when - AVOID_CCMODE_COPIES is not defined. - (record_set_info): Mark parameter `setter' with ATTRIBUTE_UNUSED. - (hash_scan_clobber): Likewise for `x' and `insn'. - (hash_scan_call): Likewise. - (record_last_set_info): Likewise for `setter'. - (mark_call): Likewise for `pat'. - (pre_insert_insn): Wrap variable `note' in macro HAVE_cc0. - - * libgcc2.c (__bb_init_prg): Replace bzero with memset and fix the - length parameter so that it multiplies the number of elements by - the sizeof(element). - - * output.h: Add prototype for `weak_finish'. - - * recog.h: Likewise for `validate_replace_src'. - - * rtl.h: Likewise for `optimize_save_area_alloca', - `fix_sched_param', `purge_addressof', `gcse_main', - `regmove_optimize', `dbr_schedule', `branch_prob' and - `end_branch_prob'. - - * toplev.h: Likewise for `set_float_handler' and - `output_quoted_string'. - - * varasm.c: Include dbxout.h. - -Mon Jun 8 18:12:06 1998 Jim Wilson - - * mips.c (mips_secondary_reload_class): Use gp_reg_p instead of - GP_REG_P. Use gr_regs instead of GR_REGS. - -Mon Jun 8 16:54:12 1998 Ken Raeburn - Jeff Law - - * Revamped multiply support for MIPS chips. - * mips.c (extend_operator): New function. - (highpart_shift_operator): Likewise. - * mips.h: Declare new functions. - (PREDICATE_CODES): Add support for new predicates. - * mips.md (mulsi3 expander): Simplify. - (mulsi_mult3): Add another constraint alternative. Support - 3 operand multiply instructions as found on various mips - parts. - (mulsi3_r4650): Delete pattern, now handled by mulsi_mult3. - (mul_acc_si): New pattern and associated splitters. - (mulsidi3 expander): Rework to use mulsidi3_64bit and - mulsidi3_internal. - (umulsidi3): New expander. - (mulsidi3_internal): Accept either sign or zero extended - operands and generate code as appropriate appropriately. - (mulsidi3_64bit): Similarly. - (smulsi3_highpart): Turn into an expander and generate code - to match new patterns. - (umulsi3_highpart): Likewise. - (xmulsi3_highpart_internal): New pattern. - (maddi patterns): Delete. Replace with: - (mul_acc_di, mul-acc_64bit_di): New patterns. - -Mon Jun 8 14:16:15 EDT 1998 Andrew MacLeod - - * eh-common.h: Remove NEW_EH_MODEL compile time flag, and replace with - flag_new_exceptions runtime flag. - (struct old_exception_table): New struct which represents what - the exception table looks like without the new model. - (NEW_EH_RUNTIME): New value used as a tag in the exception table to - flag that this is a new style table. - * except.h: Remove compile time flag NEW_EH_MODEL. - (expand_builtin_eh_stub_old): New prototype. - * tree.h (enum built_in_function): Add BUILT_IN_EH_STUB_OLD. - * expr.c (expand_builtin): New builtin func BUILT_IN_EH_STUB_OLD. - * c-decl.c (init_decl_processing): Add new builtin function - __builtin_eh_stub_old. - * final.c (final_scan_insn): Replace compile time flag NEW_EH_MODEL. - * flags.h (flag_new_exceptions): New runtime flag. - * toplev.c (flag_new_exceptions): Initialize default to 0, - -fnew-exceptions sets to 1. - * except.c (output_exception_table_entry): Output New style exception - identifier into table, and replace compile time flag NEW_EH_MODEL - with runtime flag flag_new_exceptions. - (output_exception_table): Replace compile time flag NEW_EH_MODEL. - (expand_builtin_eh_stub_old): Duplicates original functionality of - expand_builtin_eh_stub. - (expand_builtin_eh_stub): Replace compile time flag NEW_EH_MODEL. - * libgcc2.c (find_exception_handler): Remove NEW_EH_MODEL #ifdefs. - (old_find_exception_handler): New func, same as find_exception_handler - except it works on the old style exception table. - (__throw): Replace NEW_EH_MODEL. Detect new model based on presence - of identifier in the exception table, and call appropriate routines. - -Mon Jun 8 01:21:13 1998 Jason Merrill - - * function.c: Define current_function_cannot_inline. - (push_function_context_to): Save it. - (pop_function_context_from): Restore it. - * function.h (struct function): Provide it a home. - * output.h: Declare it. - * integrate.c (function_cannot_inline_p): Check it. +Sat Mar 13 17:37:18 1999 Richard Henderson -Mon Jun 8 10:43:15 1998 Richard Henderson + * haifa-sched.c (sched_analyze_1): Only clear reg_last_uses on a SET. - * expr.c (force_operand): Detect PIC address loads before - splitting arithmetic. +Sat Mar 13 11:36:16 1999 Richard Earnshaw (rearnsha@arm.com) -Mon Jun 8 09:22:38 PDT 1998 Jeff Law (law@cygnus.com) + * arm.c (arm_split_constant): Don't try to force a constant to + memory after arm_reorg has run. + (after_arm_reorg): New static variable. + (arm_reorg): Set it. + (output_func_epilogue): Clear it. - * version.c: Bump for snapshot. +Fri Mar 12 20:26:32 1999 David Edelsohn -Mon Jun 8 02:55:56 1998 Graham + * configure.in ({rs6000,powerpc}-ibm-aix*): Set float_format to none. + * configure: Rebuilt. - * tree.c (tree_class_check): Add braces to eliminate ambigious - else warning. - (tree_check): Likewise. +Fri Mar 12 20:45:30 1999 J"orn Rennecke -Mon Jun 8 02:49:23 1998 H.J. Lu (hjl@gnu.org) + * unroll.c (loop_iterations): Don't return a final value for EQ + comparison loops. - * reg-stack.c (subst_stack_regs_pat): Make sure the top of - stack is the destination for conditional move insn. +Fri Mar 12 12:35:01 1999 Jim Wilson -Mon Jun 8 01:21:13 1998 Jason Merrill + * reload1.c (calculate_needs_all_insns): When ignore equivalence + setting insn, clear need_elim, need_reload, and need_operand_change. - * tree.h (TREE_VEC_END): Cast unused value to void. +Fri Mar 12 07:54:43 1999 Bruce Korb - * i386.c (print_operand): Use %lx for long operand. + * fixinc/fixinc.*: Some changes from the fixincl-branch + were not applied (??!!). Corrected. -Mon Jun 8 00:04:07 1998 Richard Henderson + * fixinc/Makefile.in: Same thing. - * alpha.c (summarize_insn): Ignore rtl slot format 'i'. +Fri Mar 12 00:51:43 1999 Jeffrey A Law (law@cygnus.com) -Sun Jun 7 14:15:45 1998 John Carr + * expr.c (expand_expr): Allow a CALL_EXPR with a mode wider than + MAX_INTEGER_COMPUTATION_MODE. - * sol2.h (INIT_SUBTARGET_OPTABS): Use Solaris libc float/long long - conversion functions. +Thu Mar 11 14:00:58 1999 Richard Henderson -Sun Jun 7 14:02:58 1998 Richard Henderson + * alpha.h (HARD_REGNO_MODE_OK): Disallow QI/HImode in fp regs. + (MODES_TIEABLE_P): Update. - * toplev.c (flag_exceptions): Default to 0. - (compile_file): Remove flag_exceptions == 2 hack. - (main): Call lang_init_options. - * tree.h: Declare it. - * c-lang.c: Implement it. - * objc/objc-act.c: Likewise. - -Sun Jun 7 12:27:30 1998 David Edelsohn + * alpha.md (ev5_e0): Conflict loads and stores. - * rs6000.md (restore_stack_block): Generate MEM and specify mode. - * rs6000.h (STACK_SAVEAREA_MODE): SAVE_FUNCTION is VOIDmode. - * rs6000.c (rs6000_output_load_toc_table): Use fputs. - (output_function_profiler): Use asm_fprintf and fputs. +Thu Mar 11 13:55:52 1999 Richard Henderson -Sat Jun 6 12:17:12 1998 Kaveh R. Ghazi + * machmode.h (smallest_mode_for_size): Prototype. + * stor-layout.c (smallest_mode_for_size): Remove static. - * gencheck.c: Remove redundant stdio.h include. Add a definition - of xmalloc for when we are forced to link with alloca.o. +Thu Mar 11 21:25:59 1999 J"orn Rennecke - * reload1.c (reload_reg_free_for_value_p): Use `(unsigned)1' - instead of `1U'. + * loop.c (strength_reduce): Don't do biv increment -> DEST_REG giv + conversion if we don't know the lifetime. - * fold-const.c (constant_boolean_node): Make definition static to - match the prototype. +Thu Mar 11 20:37:59 1999 J"orn Rennecke -Fri Jun 5 15:53:17 1998 Per Bothner + * reload.1c (delete_address_reloads_1): Check for reloads of + CURRENT_INSN even if it sets DST. - * gcc.c (lang_specific_pre_link): New LANG_SPECIFIC_DRIVER function. - (lang_specific_extra_outfiles): New LANG_SPECIFIC_DRIVER variable. - (do_spec, input_filename, input_filename_length): Make public. - (main): Adjust outfiles allocation by lang_specific_extra_outfiles. - Call lang_specific_pre_link befor elinking. +Thu Mar 11 10:29:50 1999 Jason Merrill -Fri Jun 5 12:29:28 1998 Jeffrey A Law (law@cygnus.com) + * dwarf2out.c (add_AT_lbl_offset): Rename from add_AT_section_offset. + (print_die, size_of_die, value_format, output_die): Adjust. - * haifa-sched.c (rank_for_schedule): For "equally good insns", prefer - the insn which has the most insns dependent on it. +Thu Mar 11 10:27:42 1999 Robert Lipe -Fri Jun 5 09:03:22 1998 John Carr + * dwarf2out.c (TEXT_SECTION_LABEL, DEBUG_LINE_SECTION_LABEL, + DEBUG_INFO_SECTION_LABEL, ABBREV_SECTION_LABEL, + text_section_label, debug_line_section_label, + debug_info_section_label, abbrev_section_label): New. + (output_compilation_unit_header): Emit label associated + with section instead of section name itself. + (out_pubnames, output_aranges, output_line_info, + dwarf2out_finish): Likewise. + (dwarf2out_init): Build internal label names for sections + from static labels. - * alias.c (find_base_value): Avoid reading past end of reg_base_value. +Thu Mar 11 17:28:32 1999 J"orn Rennecke -Fri Jun 5 03:05:34 1998 Richard Henderson + * sh.md (mulsi3): End mul.l sequence with a no-op move. - * alpha.md (insxh-1): New insxl pattern for combine. +Thu Mar 11 08:52:02 1999 Bruce Korb -Fri Jun 5 01:12:15 1998 H.J. Lu (hjl@gnu.org) + * Makefile.in: Activated fixinc/mkfixinc.sh. + * configure.in: Activated fixinc/mkfixinc.sh. - * i386/i386.c (output_fp_conditional_move): New function - to output floating point conditional move. - (output_int_conditional_move): New function to output integer - conditional move. +Thu Mar 11 01:38:02 1999 Mumit Khan - * i386/i386.md (movsicci+5, movhicc+5, movdicc+5): Call - output_int_conditional_move () to output int conditional move. - (movsfcc+5, movdfcc+5, movxfcc+5): Call - output_fp_conditional_move () to output floating point - conditional move. + * cppfiles.c (INO_T_EQ): Handle UWIN. - * i386/i386.c (put_condition_code): In INT mode, check - cc_prev_status.flags & CC_NO_OVERFLOW for GE and LT. - -Thu Jun 4 16:09:51 1998 Dave Brolley - - * dbxout.c (dbxout_type): Output arrays of bits as if - they were bitstrings for Chill - -Thu Jun 4 14:35:27 1998 David Edelsohn - - * tree.c (get_inner_array_type): New function. - * tree.h (get_inner_array_type): Prototype. - * expr.h (STACK_SAVEAREA_MODE): New macro. - * expr.c (expand_builtin_setjmp): Initialize sa_mode using - STACK_SAVEAREA_MODE. - (expand_builtin_longjmp): Likewise. - * explow.c (emit_stack_save): Likewise. - (allocate_dynamic_stack_space): Use Pmode not insn_operand_mode. - - * rs6000/aix41.h (ASM_CPU_SPEC): Define relative to ASM_DEFAULT_SPEC. - (CPP_CPU_SPEC): Define relative to CPU_DEFAULT_SPEC. - * rs6000/aix43.h: New file. - * rs6000/t-aix43: New file. - * rs6000/x-aix41: New file. - * rs6000/x-aix43: New file. - * configure.in (rs6000-ibm-aix*): Use them. - * rs6000/powerpc.h: Delete. - * rs6000/sysv4.h: Move necessary powerpc.h definitions to here. - * rs6000/netware.h: and here. - * rs6000/win-nt.h: and here. - - * rs6000/rs6000.c (processor_target_table, 620): Do not affect - MASK_POWERPC64. - (rs6000_override_options): Ignore flag_pic for AIX. - (rs6000_immed_double_const): Delete. - (u_short_cint_operand): Don't assume 32-bit CONST_INT. - (reg_or_u_short_operand): Don't assume 32-bit CONST_INT. - (num_insns_constant): mask64_operand() is 2 insns. - (logical_operand): Don't assume 32-bit CONST_INT. - (non_logical_cint_operand): Don't assume 32-bit CONST_INT. - (easy_fp_constant): Any CONST_DOUBLE_HIGH is okay for 64-bit. - (mask_constant): HOST_WIDE_INT parameter. - (non_and_cint_operand): Delete. - (mask64_operand): New function. - (and64_operand): New function. - (function_arg_advance): DImode arguments do not need special - alignment when 64-bit. - (function_arg): Likewise. - (setup_incoming_varargs): Reverse reg_size assignment. - (print_operand): HOST_WIDE_INT second parameter. - (print_operand, 'B'): New case. - (print_operand, 'M'): Fix typo in lossage string. - (print_operandm 'S'): New case. - (rs6000_stack_info): Reverse reg_size assignment. Use total_raw_size - to compute AIX push_p. Use reg_size to compute {cr,lr}_save_offset. - (rs6000_output_load_toc_table): Reverse init_ptr assignment. Use - TARGET_64BIT not TARGET_POWERPC64. Convert fprintf to fputs. - Load GOT highpart, don't add it. Add lowpart with {cal|la}. - (rs6000_allocate_stack_space): Use {cal|la}. - (output_epilog): Use {cal|la} - (output_function_profiler): Add call glue to mcount call. - Load GOT highpart, don't add it. Add lowpart with {cal|la}. - - * rs6000/rs6000.h (TARGET_SWITCHES): Add powerpc64. - (STACK_BOUNDARY): Depend on TARGET_32BIT. - (ADJUST_FIELD_ALIGN): Calculate array alignment using innermost type. - (CONST_OK_FOR_LETTER_P): Don't assume 32-bit CONST_INT. - (EXTRA_CONSTRAINTS): Remove NT 'S' and 'T'. Replace 'S' with - 64-bit mask operand. - (RS6000_SAVE_TOC): Depend on TARGET_32BIT. - (STACK_SAVEAREA_MODE): New macro. - (LEGITIMATE_CONSTANT_P): DImode okay for 64bit. - (LEGITIMIZE_RELOAD_ADDRESS): New macro. - (RTX_COSTS, AND/IOR/XOR): Reflect current machine description. - (ASM_FILE_START): Emit 64-bit ABI directive. - (ASM_DECLARE_FUNCTION_NAME): Align CSECT on doubleword in 64-bit mode. - (ASM_OUTPUT_SPECIAL_POOL_ENTRY): DImode okay for 64-bit. - (PREDICATE_CODES): Add "and64_operand" and "mask64_operand". - Delete "non_and_cint_operand". "input_operand" includes CONST_DOUBLE. - - * rs6000/rs6000.md (iorsi3, xorsi3): Use HOST_WIDE_INT for mask. - Restore define_splits. - (floatsidf2, floatunssidf2): Remove !TARGET_POWERPC64 final constraint. - (floatsidf2_internal, floatunssidf2_internal2): Likewise. - Do not specify base register operand mode. - (floatsidf2_loadaddr): Do not specify base register operand mode. - (floatsidf2_store1, floatsidf2_store2): Operand 1 must be base - register; do not specify mode. Remove !TARGET_POWERPC64 final - constraint. - (floatsidf2_load): Do not specify base register operand mode. Remove - !TARGET_POWERPC64 final constraint. - (fix_truncdfsi2_internal, fix_truncdfsi2_{store,load}): Do not specify - base register operand mode. - (adddi3): Split large constants early. - (absdi3): Shift by 63, not 31. - (*mulsidi3_ppc64): New pattern. - (rotldi3): Add masking combiner patterns. - (anddi3): Add rldic{r,l} masking. Remove split of large constants - because PPC insns zero-extend. - (iordi3, xordi3): Split large constants early. - (movsi matcher): Remove S and T constraints. - (movsf const_double): create SImode constant from TARGET_DOUBLE. - (movdf_hardfloat32): Add default abort() case. - (movdf easy_fp_const): create DImode constant from TARGET_DOUBLE. - (movdi): Remove 64-bit constant generator. Try to convert - CONST_DOUBLE to CONST_INT. Handle TOC memory constants. - (movdi_32): Add default abort() case. - (movdi_64): Add numerous ways to split 64-bit constants. - Make catch-all define_split more optimal and never FAIL. - (movti_ppc64): Add default abort() case. - (allocate_stack): Remove operand modes. Use Pmode. - (restore_stack_block): Remove operand modes. Generate Pmode - temporary. - (save_stack_nonlocal, restore_stack_nonlocal): Generate Pmode - temporary. Save area is double Pmode. - (call_indirect_aix64, call_value_indirect_aix64): New patterns. - (call, call_value): Do not specify address operand mode. Choose - appropriate AIX ABI. - (*call_local64, *ret_call_local64): New patterns. - (*call_nonlocal_aix64, *ret_call_nonlocal_aix64): New patterns. - (*ret_call_nonlocal_aix32): Use call_value_indirect for REG. - (compare): Materialize DImode truthvalues. + * c-common.c (decl_attributes): Flag unrecognized attribute + functions as warnings instead of as errors. -Thu Jun 4 01:26:57 1998 Craig Burley + Support for i386-pc-uwin. + * i386/uwin.h: New file. + * i386/xm-uwin.h: New file. + * i386/t-uwin: New file. + * i386/uwin.asm: New file. + * configure.in (i[3456]86-*-uwin*): Define. + Add Workaround for vfork bug when hosted on uwin. + * configure: Regenerate. - * expr.c (safe_from_p): Avoid combinatorial explosion - over duplicate SAVE_EXPRs by ensuring we never recurse - on one that has already been visited. + * cccp.c (INO_T_EQ): Undefine. UWIN has inodes. + (absolute_filename): UWIN uses POSIX pathnames only. + * libgcc2.c (getpagesize): Do not define for UWIN. + (mprotect): Likewise. + * protoize.c (dirent.h): Conditionally include. + (fputc): Prototype only if it's not a macro. -Thu Jun 4 00:54:21 1998 Graham +Wed Mar 10 02:49:04 1999 Jason Merrill - * loop.c (check_dbra_loop): Initialise final_value before - normalizing the loop. + * configure.in: Remove init_priority stuff. -Wed Jun 3 20:00:04 1998 J"orn Rennecke +1999-03-11 Colin Smith - * reload1.c (reload_reg_free_for_value_p): New arguments out and - reloadnum. Changed all callers. + * sdbout.c (plain_type_1): Make boolean types work better with sdb. -1998-06-03 Ulrich Drepper +Thu Mar 11 00:20:52 1999 Alexandre Oliva - * system.h: Add _() and N_() macros in preparation for gettext. + * gcc.texi: Update bug reporting instructions to match + current ezmlm list reality. -Wed Jun 3 11:02:24 1998 Andreas Schwab +Wed Mar 10 23:11:19 1999 Kaveh R. Ghazi + + * gcc.c (print_file_name, print_prog_name, spec_machine, + read_specs, set_spec, lookup_compiler, build_search_list, + putenv_from_prefixes, find_a_file, record_temp_file, + delete_if_ordinary, handle_braces, do_spec, do_spec_1, find_file, + is_directory, validate_switches, used_arg, default_arg, + pfatal_with_name, perror_with_name, pfatal_pexecute, fatal, error, + notice, add_preprocessor_option, add_assembler_option, + add_linker_option, process_command, execute, + unused_prefix_warnings, clear_args, fatal_error, + lang_specific_driver, user_specs, compiler, link_command_spec, + option_map, translate_options, make_temp_file, temp_name, + programname, path_prefix, machine_suffix, just_machine_suffix, + gcc_exec_prefix, standard_exec_prefix, standard_exec_prefix_1, + md_exec_prefix, md_startfile_prefix, md_startfile_prefix_1, + standard_startfile_prefix, standard_startfile_prefix_1, + standard_startfile_prefix_2, tooldir_base_prefix, tooldir_prefix, + multilib_dir, temp_filename, temp_file, command, switchstr, + infile, outfiles, input_filename, input_basename, input_suffix, + check_live_switch, main): Qualify a char* with the `const' keyword. + +Wed Mar 10 20:28:29 1999 Jeffrey A Law (law@cygnus.com) + + * lcm.c: New file. + * Makefile.in (OBJS): Add lcm.o. + (lcm.o): Add dependencies. + + * gcse.c (compute_pre_local_properties): Delete. + (compute_pre_data): Use compute_local_properties instead of + compute_pre_local_properties. + + * gcse.c: More comments, whitespace and similar fixes. + (dump_cuid_table, maybe_set_rd_gen, dump_cprop_data): Delete. + (dump_pre_data, compute_cprop_local_properties): Likewise. + (one_classic_gcse_pass): Lose unused argument. All callers changed. + (compute_hash_table, compute_expr_hash_table): Likewise. + (compute_set_hash_table, one_pre_gcse_pass, mark_call): Likewise. + (cprop_insn, cprop, one_cprop_pass): Add new argument ALTER_JUMPS. + All callers changed. Only alter jumps if ALTER_JUMPS is nonzero. + Lose unused argument. + (gcse_main): Always run a cprop pass after finishing global cse. + (compute_local_properties): New function. + (hash_scan_pat, hash_scan_insn): No longer call maybe_set_rd_gen. + (compute_cprop_data): Use compute_local_properties. + + * gcse.c: Update various comments. + (current_function_calls_longjmp): Delete declaration. + + * gcse.c (run_jump_opt_after_gcse): New variable. + (gcse_main): Returns an integer. + (hash_scan_set): Record initializations from CONST_DOUBLEs too. + (try_replace_reg): Update some comments. + (cprop_insn): Allow propagation into some JUMP_INSNs too. + * rtl.h (gcse_main): Update prototype. + * toplev.c (rest_of_compilation): If gcse_main returns nonzero, + then run a jump optimization pass. + * jump.c (delete_barrier_successors): Delete nop jumps too. + +Wed Mar 10 19:04:31 1999 J"orn Rennecke + + * sh.c (fp_arith_reg_operand): Actually test if reg is suitable + for FP arithmetic. Changed caller. + * sh.md (subsf3, subsf_i): Use fp_arith_reg_operand. + +Wed Mar 10 18:56:31 1999 J"orn Rennecke + + * reload1.c (choose_reload_regs): When inheriting from the frame + pointer, don't clobber it. + +Wed Mar 10 08:01:52 1999 Bruce Korb + + * fixinc/fixinc.*: Resync-ed with the files in this + directory. - * c-common.c (check_format_info): Put back check for C9x `hh' - length modifier. Warn about %n format writing into const. Remove - obsolete comment. - (format_char_info): Fix comments. + * fixinc/mkfixinc.sh: The machine case elements were + out-of-order. (the ix86-*-linux-gnu* entry needed to + be earlier). - * configure.in: Set float_format to m68k for all m68k targets that - do not override LONG_DOUBLE_TYPE_SIZE. - * config/float-m68k.h: New file. +Wed Mar 10 00:01:24 1999 J"orn Rennecke -Tue Jun 2 23:14:01 1998 Richard Henderson + * reload1.c (reload_combine_note_store): Fix calculation of number + of affected registers. - * jump.c (jump_optimize): Remove debug messages accidentally left in - with the previous change. +Tue Mar 9 15:48:15 1999 Richard Henderson -Tue Jun 2 22:46:08 1998 Richard Henderson + * flow.c (tidy_fallthru_edge): Be more careful finding the last + BARRIER of a list. Delete the cc0 setter as well as a cond jump. - * expr.c (store_expr): Revert stray patch associated with - 1998-05-23 commit. +Tue Mar 9 15:26:02 1999 Hans-Peter Nilsson -Tue Jun 2 21:59:01 1998 Richard Henderson + * i386.md (ashlsi3 splitter): Fix typo in last change. - * jump.c (rtx_unsafe_p): New function. - (jump_optimize): Use it on if/then/else transformations and - conditional move transformations. +Tue Mar 9 11:35:20 1999 Richard Henderson -Tue Jun 2 22:50:10 1998 Andreas Schwab + * reg-stack.c (stack_reg_life_analysis): Use returnjump_p + instead of an explicit test for RETURN. - * fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST - or VAR-- == CONST construct a proper mask if VAR is a bitfield. - Cope with CONST being out of range for the bitfield. +Tue Mar 9 09:33:16 1999 Kaveh R. Ghazi -Tue Jun 2 22:28:31 1998 Bernd Schmidt + * Makefile.in (toplev.o): Depend on $(BASIC_BLOCK_H). - * expr.c (emit_move_insn_1): When moving complex values in several - steps, emit a CLOBBER to show the destination dies. + * toplev.c: Include basic-block.h. -Tue Jun 2 22:17:26 1998 Jeffrey A Law (law@cygnus.com) +Tue Mar 9 02:08:17 1999 Jeffrey A Law (law@cygnus.com) - * Makefile.in (site.exp): Use the object testsuite directory as - the temporary directory. + * calls.c (load_register_parameters): New function. + (expand_call): Use it. - * expr.c (expand_expr, case ADDR_EXPR): Handle taking the - address of an ADDRESSOF rtx. + * calls.c (expand_call): Slightly reorganize code. -1998-06-02 Mike Stump + * calls.c (compute_argument_addresses): New function. + (rtx_for_function_call): New function. + (expand_call): Use them. - * expr.c (expand_builtin_setjmp): Handle BUILTIN_SETJMP_FRAME_VALUE. - * i960.h (SETUP_FRAME_ADDRESSES, BUILTIN_SETJMP_FRAME_VALUE): Define. - * i960.md (ret, flush_register_windows): Define. - (nonlocal_goto): Likewise. Nested function nonlocal gotos don't - work yet. - * tm.texi (BUILTIN_SETJMP_FRAME_VALUE): Document new macro. + * i386.md (zero_extendhisi2): Split into an expander and anonymous + pattern. Add new anonymous pattern for use when optimizing for + size or for the PPro. + (zero_extendqihi2, zero_extendqisi2): Likewise. -Tue Jun 2 14:02:38 1998 Richard Henderson +Mon Mar 8 23:43:47 1999 Richard Henderson - * alpha.md (divsi3, udivsi3, modsi3, umodsi3): Enable, and work - around an OSF/1 library bug wrt sign-extension of inputs. + * haifa-sched.c (sched_analyze_1): Fix last change -- add clobber + dependencies to sets in the non-hard-reg case too. -Tue Jun 2 13:02:44 1998 Richard Henderson +Mon Mar 8 18:55:21 1999 Marc Espie - * vax/netbsd.h (DWARF2_UNWIND_INFO): Must be undef, not defined 0. + * config/openbsd.h (HANDLE_SYSV_PRAGMA): Define. -Mon Jun 1 03:44:03 1998 Catherine Moore +Mon Mar 8 16:04:44 1999 Jim Wilson - * config/sh/sh.h (MAX_OFILE_ALIGNMENT): Define. + * local-alloc.c (combine_regs): Don't combine if we have a hard reg + for which CLASS_LIKELY_SPILLED_P is true. - * varasm.c (assemble_variable): Augment alignment warning. + * unroll.c (loop_iterations): Only call loop_find_equiv_value if we + have a REG or SUBREG. -Mon Jun 1 12:14:28 1998 Michael Meissner +Mon Mar 8 15:27:42 1999 Jeffrey A Law (law@cygnus.com) - * config/fp-bit.c (_fp{add,div}_parts): Return correct IEEE result - in the presence of IEEE negative 0's. + * i386.md (ashlsi3): Revise comments. Provide new anonymous + pattern for Pentium and PPro/PII. Reverse constraints in + generic ashlsi3 anonymous pattern. -Sun May 31 16:11:41 1998 John Wehle (john@feith.com) + * calls.c (initialize_argument_info): Accept a pointer to + CUMULATIVE_ARGS. + (expand_call): Pass the address of CUMULATIVE_ARGS. - * reload.c (find_reloads): Record the existing mode if - operand_mode == VOIDmode before replacing a register with - a constant. - * i386.md (tstsi, tsthi, tstqi, tstsf, tstdf, tstxf): Set - i386_compare_op1 to const0_rtx for the benefit of the - conditional move patterns. - (movsicc, movhicc, movsfcc, movdfcc, movxfcc, movdicc): Rewrite - based on suggestions from Jim Wilson. + * rs6000/xm-sysv4.h (HOST_BITS_PER_LONGLONG): Remove #if 0. -Sun May 31 00:44:02 PDT 1998 Jeff Law (law@cygnus.com) + * mn10300.h (CASE_DROPS_THROUGH): Delete. + * mn10200.h (CASE_DROPS_THROUGH): Delete. + * h8300.h (CASE_DROPS_THROUGH): Delete. - * version.c: Bump for snapshot. + * flow.c (merge_blocks_nomove): For HAVE_cc0 targets, make sure + to also delete the cc0 setter when deleting a conditional branch + to the next block. -Sun May 31 00:34:17 1998 Bruce Korb +Mon Mar 8 18:47:11 1999 J"orn Rennecke - * Makefile.in (fixinc.sh): Update rules again. + * regmove.c (copy_src_to_dest): New argument max_old_uid. -Sun May 31 00:27:47 1998 Jeffrey A Law (law@cygnus.com) +Mon Mar 8 08:23:00 1999 Bruce Korb - * extend.texi: Bring back reference to trampoline paper. + * ChangeLog: Merged entries from fixincl-branch. -Sun May 31 00:22:34 1998 Ulrich Drepper +Sun Mar 7 11:48:56 1999 Richard Henderson - * Makefile.in (USER_H): Add stdbool.h. - * ginclude/stdbool.h: New file. + * haifa-sched.c (ENCODE_BLOCKAGE): Don't shift unit too far. + (print_exp): Special case addition of a constant. + (print_value) [CONST_INT]: Use HOST_WIDE_INT_PRINT_HEX. -Fri May 29 01:48:25 1998 Jeffrey A Law (law@cygnus.com) +Sun Mar 7 11:21:02 1999 Richard Henderson - * jump.c (thread_jumps): Do not look at the NOTE_LINE_NUMBER - of a non-note insn. + * haifa-sched.c (reg_last_clobbers): New. + (reg_pending_clobbers, bb_reg_last_clobbers): New. + (compute_block_backward_dependences): Allocate memory for them. + (schedule_region): Likewise. + (sched_analyze_1): Clobbers don't interfere with one another. + They do interfere with sets ... + (sched_analyze_2): ... and uses. + (sched_analyze): Likewise. + (sched_analyze_insn): Update reg_last_clobbers appropriately. - * gcse.c (pre_delete): Fix code to determine the mode of - the reaching pseudo register. +Sun Mar 7 08:30:37 1999 Kaveh R. Ghazi -Fri May 29 01:07:28 1998 Bernd Schmidt + * gmon-sol2.c: Include config.h and system.h. Don't redundantly + include system header files. + (sccsid): Remove. + (moncontrol, monstartup, _mcleanup, internal_mcount): Prototype. + (_mcleanup): Add the `const' keyword to a char*. + (internal_mcount): Declare `etext' as a char[] not a function. + Cast `etext' to char* when calling `monstartup'. - * Makefile.in (GEN): Add gencheck - (STAGESTUFF): Add tree-check.h and gencheck. + * sparc.c (frame_base_name, save_regs, restore_regs, + build_big_number, sparc_cmodel_string, sparc_align_loops_string, + sparc_align_jumps_string, sparc_align_funcs_string, code_model, + cpu_default, cpu_table, output_function_prologue, + output_function_epilogue, output_return, + sparc_flat_output_function_prologue, ultra_code_names, + sparc_flat_output_function_epilogue): Constify a char*. + (hypersparc_adjust_cost): Add a default case in a switch. -Fri May 29 00:57:37 1998 Bruce Korb + * sparc.h (sparc_cmodel_string, OVERRIDE_OPTIONS, + sparc_cpu_select, sparc_align_loops_string, + sparc_align_jumps_string, sparc_align_funcs_string, + output_return): Constify a char*. - * Makefile.in (cstamp-h.in): Remove before trying to recreate. - (fixinc.sh): Set some additional environment variables before - calling mkfixinc.sh. + * sparc.md (movdi): Change the comparison of HOST_BITS_PER_WIDE_INT + so that we check "== 32", instead of "!= 64". Cast a value to + HOST_WIDE_INT when comparing against one. Hide the declaration + for variable `chain'. -Thu May 28 12:57:05 1998 Jeffrey A Law (law@cygnus.com) +Sun Mar 7 08:05:27 1999 Kaveh R. Ghazi - * reload.c (find_reloads): Do not force a reloads of match_operators. + * system.h (const, inline): Move the stage2 handling of these + keywords-as-macros from here... -Thu May 28 10:22:22 EDT 1998 Andrew MacLeod + * gansidecl.h (const, inline): ...to here. - * except.h (remove_handler): Add new prototype. - * except.c (remove_handler): New function to remove handlers - from an exception region. - * flow.c (find_basic_blocks_1): Remove handlers from regions when - handler label is deleted; remove exception regions with no handlers. +Sun Mar 7 02:44:15 1999 Richard Henderson -Thu May 28 09:36:39 1998 Michael Meissner + * recog.c (push_operand, pop_operand): VOIDmode needn't match modes. - * except.h (rtx): Define rtx type correctly if needed. - * function.h (rtx): Ditto. - (tree): Define tree type correctly if needed. +Sun Mar 7 01:58:47 1999 Richard Henderson - * c-pragma.c (toplevel): Include rtl.h. + * cse.c (canon_hash): Never reject hard regs in CCmode. - * stor-layout.c (toplevel): Move include of rtl.h before - except.h. +Sun Mar 7 01:15:04 1999 Jeff Law (law@cygnus.com) - * Makefile.in (c-pragma.o): Add except.h, rtl.h dependencies. - (tree.o): Add except.h dependency. + * version.c: Bump for snapshot. -Wed May 27 22:02:40 1998 Jeffrey A Law (law@cygnus.com) +Sat Mar 6 17:18:44 1999 Richard Earnshaw (rearnsha@arm.com) + Richard Henderson - * reload1.c: Revert accidental checkin. + * flow.c (make_edges): Handle casesi that jump to default branch. + If CASE_DROPS_THROUGH, force fallthru to block after casesi. - * configure.lang: Fix thinko when adding a definition for - target_alias to the Makefile. +Sat Mar 6 07:49:23 1999 Kaveh R. Ghazi -Wed May 27 02:50:00 1998 Catherine Moore (clm@cygnus.com) + * c-aux-info.c (data_type, affix_data_type, gen_decl, + gen_formal_list_for_type, gen_formal_list_for_func_def, gen_type): + Qualify a char* with the `const' keyword. - * config/sparc/lb1spc.asm (.rem and .urem): Replace - routines. + * c-common.c (declare_hidden_char_array, add_attribute, if_elt, + declare_function_name, decl_attributes, format_char_info, + check_format_info, binary_op_error): Likewise. -Wed May 27 02:48:31 1998 Richard Earnshaw (rearnsha@arm.com) + * cexp.y (yyerror, error, pedwarn, warning, token): Likewise. - * arm.c (arm_gen_constant): Rework to eliminate uninitialized - variable warnings. Don't generate scratch registers if only - counting insns. - (find_barrier): Eliminate unused variable SRC. + * gcse.c (dump_hash_table): Likewise. -1998-05-27 Manfred Hollstein + * integrate.c (function_cannot_inline_p): Likewise. - * toplev.h (rtx_def): Provide global declaration to avoid - `limited scope' warnings. + * optabs.c: Include insn-config.h earlier. + (init_libfuncs, init_integral_libfuncs, init_floating_libfuncs): + Qualify a char* with the `const' keyword. -Tue May 26 23:47:52 1998 Mumit Khan + * real.c (asctoe24, asctoe53, asctoe64, asctoe113, asctoe, + asctoeg, mtherr, ereal_atof): Likewise. - * Makefile.in (gencheck.o): Use HOST_CC. - * i386/t-mingw32: New file. - * configure.in (i386-*-mingw32*): Use. + * real.h (ereal_atof): Likewise. -Tue May 26 07:31:04 1998 Richard Earnshaw (rearnsha@arm.com) + * sbitmap.c (dump_sbitmap_vector): Likewise. - * arm.c (bad_signed_byte_operand): New predicate function. - * arm.h (PREDICATE_CODES): Add it to the list. - * arm.md (*extendqi[sh]i_insn): Split any addresses that ldrsb - can't handle. - (define_split): Two new splits for above insns. + * sbitmap.h (dump_sbitmap_vector): Likewise. - * arm.c: Include toplev.h. - (arm_override_options): Add parentheses around use of tune_flags. - (arm_split_constant): Remove unused variable. - (arm_gen_constant, arm_gen_movstrqi, add_constant): Likewise. - (output_func_prologue, arm_expand_prologue): Likewise. - (arm_canonicalize_comparison): Make I unsigned; rework constants - accordignly. Add missing paratheses around << operation. - (arm_rtx_costs): Correctly parenthesise MULT costs. Add a DEFAULT - clause. - ({load,store}_multiple_sequence): Initialize BASE_REG. - (select_dominance_cc_mode): Add DEFAULT clauses. - (broken_move): Return zero if the destination is not a register. - (arm_reorg): Move unused REGNO declaration into the dead code. - * arm.h (CANONICALIZE_COMPARISON): Ensure OP1 is updated. + * stmt.c (nesting, n_occurrences, expand_start_case): Likewise. -Mon May 25 22:49:56 PDT 1998 Jeff Law (law@cygnus.com) + * toplev.c (rest_of_compilation): Likewise. - * version.c: Bump for snapshot. + * tree.h (function_cannot_inline_p, expand_start_case): Likewise. -Mon May 25 11:56:24 PDT 1998 Jeff Law (law@cygnus.com) +Fri Mar 5 23:16:42 1999 David Edelsohn - * version.c: Bump for snapshot. + * rs6000.h (ASM_OUTPUT_REG_{PUSH,POP}): Add 64-bit support and do + not overwrite AIX link register save area. -Mon May 25 14:00:13 1998 Dave Brolley +Fri Mar 5 23:08:01 1999 J"orn Rennecke - * cpperror.c (v_cpp_message): Remove static prototype. - * cpplib.c (v_cpp_message): Move prototype to cpplib.h. - * cpplib.h (v_cpp_message): Add protoptype. - (stdarg.h,varargs.h): Needed for v_cpp_message prototype. + * reload.c (find_reloads_subreg_address): Actually create the USE + for the register, not the new memory location. -Sun May 24 20:36:15 PDT 1998 Jeff Law (law@cygnus.com) +Fri Mar 5 21:41:07 1999 J"orn Rennecke - * version.c: Bump for snapshot. + * reload1.c (emit_reload_insns): If pseudo that can't be replaced + with its equivalent constant, fall back to reload_in. -Sun May 24 02:08:57 PDT 1998 Jeff Law (law@cygnus.com) +Fri Mar 5 13:20:39 1999 Richard Henderson - * version.c: Bump for snapshot. + * Makefile.in: Delete .flow2 debugging files. -1998-05-24 Andreas Schwab +Fri Mar 5 11:36:11 1999 Nick Clifton - * m68k.h: Declare more functions used in macros. - (REG_CLASS_CONTENTS): Completely embrace initializer. - * m68k.md (adddi3, subdi3): Add abort call to avoid warning - about returning no value. - * cse.c (find_best_addr): Declare p and found_better only if - needed. - * dbxout.c (dbxout_continue): Define only if DBX_CONTIN_LENGTH > 0. - * dwarfout.c (string_length_attribute): #if 0 away. - * function.c (expand_function_end): Define varible blktramp only - if needed. - * jump.c (find_insert_position): Define only if !HAVE_cc0. - * loop.c (combine_givs_p): Define variable tem only if needed. - * real.c: Comment out unused functions eabs, eround, - e{24,53,64,113}toasc and eiinfin. + * config/arm/arm.c (arm_override_options): Change default target + cpu selection so that enabling TARGET_APCS_32 does not override + default target CPU. +Fri Mar 5 19:26:23 1999 J"orn Rennecke -Sat May 23 23:44:53 1998 Alexandre Oliva + * sh.h (SLOW_BYTE_ACCESS): Define to 1. + (BOOL_TYPE_SIZE): Define. - * Makefile.in (boostrap2-lean, bootstrap3-lean, - bootstrap4-lean): New targets. +Fri Mar 5 02:14:54 1999 John Wehle (john@feith.com) -Sat May 23 23:35:14 1998 Jeffrey A Law (law@cygnus.com) + * function.c (assign_stack_temp_for_type): Abort + if mode == Blkmode and align is less than + BIGGEST_ALIGNMENT / BITS_PER_UNIT. + (assign_stack_temp_for_type): Round the size parameter + passed to assign_stack_local instead of size itself. - * warn_summary, test_summary: Moved into the contrib directory. +Thu Mar 4 15:00:35 1999 Richard Henderson -1998-05-23 Manfred Hollstein + * flow.c (delete_unreachable_blocks): Mark blocks as they + are put on to the worklist, not as they are taken off. - * Makefile.in (ENQUIRE_CFLAGS, ENQUIRE_LDFLAGS): Move down to the end - of the Makefile. - (FLOAT_H_TEST): Likewise. - (ENQUIRE): Likewise. - (float.h-nat): Likewise. - (float.h-cross): Likewise. - (enquire): Likewise. - (enquire.o): Likewise. - (stmp-int-hdrs): Fix comment about enquire; depend upon gfloat.h. - (stmp-headers): Move actions to stmp-int-hdrs, retaining only a - no-op. - (FLOAT_H): Remove old float.h-nat version; move current definition - to CROSS_FLOAT_H location. - (all.cross): Remove comments about enquire stuff. +Thu Mar 4 00:05:44 1999 Jeffrey A Law (law@cygnus.com) - * Makefile.in (all.cross): Swap $(LIBGCC) and $(STMP_FIXPROTO). - (rest.encap): Likewise. - (libgcc2.ready): Depend upon $(STMP_FIXPROTO) + * function.c (current_function_has_computed_jump): Remove duplicate + definition. - * toplev.h (tree_node): Provide global declaration to avoid - `limited scope' warnings. +Wed Mar 3 19:09:11 1999 Jim Wilson -Sat May 23 23:23:35 1998 Robert Lipe + * m68k/m68020-elf.h (INIT_SECTION_ASM_OP, FINI_SECTION_ASM_OP): Undef. + (STARTFILE_SPEC, ENDFILE_SPEC): Define to empty string. - * test_summary: Display section breaks for each entry - in a multilibbed target's output. + * sparc/elf.h (MULDI3_LIBCALL, DIVDI3_LIBCALL, UDIVDI3_LIBCALL, + MODDI3_LIBCALL, UMODDI3_LIBCALL, STDC_0_IN_SYSTEM_HEADERS): Undef. + (INIT_SUBTARGET_OPTABS): Define to empty. -1998-05-23 Richard Henderson +Wed Mar 3 00:00:37 1999 J"orn Rennecke - * expr.c (expand_expr): For {BITFIELD,COMPONENT,ARRAY}_REF, if the - offset's mode is not ptr_mode, convert it. + * sh.c (force_into): New function. + (expand_block_move): Use it. -1998-05-22 Jason Merrill +Tue Mar 2 10:39:43 1999 Nick Clifton - * fold-const.c (ssize_binop): New fn. - * tree.h: Declare it. + * cccp.c (struct default_include): Add 'included' field. + (main): Set 'included' field when a default include directory + is added to the chain. If -v is specified list all default + include directories which do not get appended to the chain. -Fri May 22 03:42:05 1998 Richard Earnshaw (rearnsha@arm.com) +Tue Mar 2 09:24:10 1999 Nick Clifton - * genextract.c (print_path): Handle zero-length path as a special - case. + * configure.in (gxx_include_dir): Rename to + gcc_gxx_include_dir in order to prevent it being overridden by + a top level Makefile. + (gcc_tooldir): If $exec_prefix != $prefix then use the + difference between the two as the basis for gcc_tooldir. -Fri May 22 01:38:07 1998 Hans-Peter Nilsson + * configure: Rebuild. - * cplus-dem.c (MBUF_SIZE): Bumped from 512 to 32767. + * Makefile.in: Rename gxx_include_dir to gcc_gxx_include_dir. -Fri May 22 00:57:00 1998 Bernd Schmidt (crux@pool.informatik.rwth-aachen.de> +Tue Mar 2 16:45:31 1999 J"orn Rennecke - * final.c (JUMP_TABLES_IN_TEXT_SECTION): Provide a default value. - (shorten_branches, final_scan_insn): Test value of - JUMP_TABLES_IN_TEXT_SECTION instead of just testing whether it - is defined. - * tm.texi (JUMP_TABLES_IN_TEXT_SECTION): Corresponding changes. - * arm/coff.h: Define JUMP_TABLES_IN_TEXT_SECTION to 1. - * arm/tcoff.h: Likewise. - * i386/386bsd.h: Likewise. - * i386/freebsd-elf.h: Likewise. - * i386/freebsd.h: Likewise. - * i386/netbsd.h: Likewise. - * i386/ptx4-i.h: Likewise. - * i386/sysv4.h: Likewise. - * pa/pa.h: Likewise. - * rs6000/linux.h: Likewise. - * rs6000/rs6000.h: Likewise. - * sh/sh.h: Likewise. - * sparc/sp64-elf.h: Likewise. - * v850/v850.h: Likewise. - * rs6000/sysv4.h: Define JUMP_TABLES_IN_TEXT_SECTION to 0. - * i386/linux.h: Define JUMP_TABLES_IN_TEXT_SECTION to (flag_pic). - -Thu May 21 19:50:13 1998 J"orn Rennecke - - * regmove.c (gen_add3_insn): New function. - (fixup_match_2): Use it instead of calling gen_addsi3. - -Thu May 21 23:09:50 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (gencheck): Depend on HOST_LIBDEPS. - - * alias.c (rtx_equal_for_memref_p): Handle SCRATCH as a memory - address. - -Thu May 21 20:18:13 1998 Martin von Loewis - - * Makefile.in (TREE_H): Add tree-check.h. - (tree-check.h, gencheck): New targets. - * gencheck.c: New file. - * tree.c (tree_check, tree_class_check): New functions. - * tree.h (TREE_CHECK, TREE_CLASS_CHECK): Define. - (TYPE_CHECK, DECL_CHECK): Define. - Modify all access macros to use generated checking macros. - -Wed May 20 23:44:28 EDT 1998 John Wehle (john@feith.com) - - * acconfig.h (HAVE_GAS_MAX_SKIP_P2ALIGN): New tag. - * configure.in: Check for it. - * i386/gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Use it. - * final.c (uid_align, uid_shuid, label_align): Make static. - (label_align): Change type to struct label_alignment pointer. - (LABEL_TO_ALIGNMENT, shorten_branches): Update due to type change. - (LABEL_TO_MAX_SKIP): Define. - (LABEL_ALIGN_MAX_SKIP, LOOP_ALIGN_MAX_SKIP, - LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP): Provide defaults. - (shorten_branches): Record the maximum bytes to skip when - aligning a label. - (final_scan_insn): Use the maximum bytes to skip when aligning a label - if ASM_OUTPUT_MAX_SKIP_ALIGN is available. - * i386.h (LOOP_ALIGN_MAX_SKIP, - LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP): Define. - * i386.c (override_options): i386_align_jumps and i386_align_loops - default to 4 if ASM_OUTPUT_MAX_SKIP_ALIGN is available. - * invoke.texi: Document new i386 align-loops and align-jumps behavior. - -1998-05-21 Mark Mitchell - - * cplus-dem.c (do_type): Handle volatile qualification. - -Thu May 21 12:23:17 1998 Per Bothner - - * function.c (init_function_start): Don't call emit_line_note if - lineno is 0. (Can happen when compiling Java .class files.) - -Thu May 21 19:50:13 1998 J"orn Rennecke - - * reload1.c (reload_reg_free_for_value_p): Fix RELOAD_FOR_INPUT - end of lifetime and RELOAD_FOR_OUTPUT start of lifetime. - -Thu May 21 19:32:27 1998 J"orn Rennecke - - * combine.c (nonzero_bits): For paradoxical subregs, take - LOAD_EXTENDED_OP into account. - -Thu May 21 11:51:15 1998 Dave Brolley - - * configure.in (extra_c_objs): add prefix.o. - (extra_cxx_objs): extra objects for C++ with cpplib. - * configure: Regenerate. + * unroll.c (copy_loop_body): Don't make extra copies of + NOTE_INSN_LOOP_CONT notes. - * c-tree.h: (get_directive_line): Different prototype for cpplib. - (GET_DIRECTIVE_LINE): Macro wrapper for get_directive_line. +Tue Mar 2 07:44:56 1999 Mark Mitchell - * c-lex.h: (get_directive_line): Not needed here for cpplib. + * tree.c (save_tree_status): Don't treat functions with no context + as nested. - * c-lex.c: (yy_cur,yy_lim,yy_get_token): Move to c-common.c. - (GET_DIRECTIVE_LINE): Move to c-common.c and rename to get_directive_line. +Tue Mar 2 09:37:05 1999 Robert Lipe - * c-common.c (parse_in,parse_options,cpp_token): Declare for cpplib. - (yy_cur,yy_lim,yy_get_token,get_directive,line): Moved here from c-lex.c + * Makefile.in (MAKEINFO): Use makeinfo built from sibling + tree when available. -Thu May 21 09:04:42 1998 Kaveh R. Ghazi +Tue Mar 2 10:12:48 1999 Kaveh R. Ghazi - * gengenrtl.c (type_from_format, accessor_from_format): Change - type of parameter `c' from `char' to `int'. + * alpha.c (alpha_cpu_name, alpha_cpu_string, alpha_tp_string, + alpha_fprm_string, alpha_fptm_string, alpha_mlat_string, + current_function_file): Add the `const' keyword. + (normal_memory_operand): Mark parameter `mode' with + ATTRIBUTE_UNUSED. + (alpha_expand_unaligned_load): Add a default case to a switch. -Wed May 20 22:28:34 1998 Jeffrey A Law (law@cygnus.com) + * alpha.h (alpha_cpu_string, alpha_fprm_string, alpha_fptm_string, + alpha_tp_string, alpha_mlat_string): Add the `const' keyword. + (normal_memory_operand): Add prototype. - * warn_summary, test_summary: New scripts from - Kaveh Ghazi and Alexandre Oliva respectively. + * alpha.md: Cast an expression to `unsigned HOST_WIDE_INT' when + comparing against one. - * gcse.c (current_function_calls_longjmp): Declare. +Tue Mar 2 10:00:21 1999 Kaveh R. Ghazi -1998-05-20 Jason Merrill + * mips.c (abort_with_insn): Make function static, add a prototype, + constify 2nd parameter and mark with ATTRIBUTE_NORETURN. + (current_function_file, mips_cpu_string, mips_isa_string, + mips_abi_string, mips_no_mips16_string, mips_entry_string, + mips_move_1word, mips_move_2words, output_block_move, load_store, + override_options, make_temp_file, mips16_fp_args): Qualify a char* + with the `const' keyword. - * dwarf2out.c (base_type_die): Use int_size_in_bytes. + * mips.h (current_function_file, mips_cpu_string, mips_isa_string, + mips_abi_string, mips_entry_string, mips_no_mips16_string, + mips_move_1word, mips_move_2words, output_block_move): Likewise. + (abort_with_insn): Remove extern prototype. -Wed May 20 01:11:02 1998 Doug Evans (devans@cygnus.com) - Jeff Law (law@cygnus.com) + * mips.md: Qualify a char* with the `const' keyword. + Remove many unused variables named `label'. - * Global CSE and constant/copy propagation. - * Makefile.in (OBJS): Add gcse.o - (STAGESTUFF): Add *.gcse. - (gcse.o): Add dependencies. - (mostlyclean): Remove *.gcse and */*.gcse. - * gcse.c: New file. - * loop.c (loop_optimize): Move call to init_alias_analysis. - * recog.c (validate_replace_src): New function. - * toplev.c (gcse_dump): New global variable. - (flag_gcse, gcse_time): Likewise. - (compile_file): Initialize gcse_time and clean out the gcse dump - file if necessary. - (rest_of_compilation): Call gcse_main as requested. Dump RTL - after gcse if requested. - (main): Enable gcse for -O2 and above. Handle -dG. Enable gcse - dumps for -da. - * gcc.texi: Add gcse related internal documentation. - * invoke.texi: Note new command line options for gcse. - * tm.texi: Document AVOID_CCMODE_COPIES. - * mips.h (AVOID_CCMODE_COPIES): Define. +Tue Mar 2 01:27:52 1999 H.J. Lu (hjl@gnu.org) -Tue May 19 22:31:20 1998 Jeffrey A Law (law@cygnus.com) + * Makefile.in (cpp_install_dir, INSTALL_CPP, UNINSTALL_CPP): New + variables. + (install-cpp, uninstall-cpp): New targets. + (install-normal): Depend on $(INSTALL_CPP). + (uninstall): Depend on $(UNINSTALL_CPP). + * configure.in (cpp_install_dir): New, substitute. + (tmake_file): Added t-install-cpp for --enable-cpp. + * configure: Rebuilt. + * cpp.sh: New cpp script. + * config/t-install-cpp: New target fragment. - * Makefile.in (deduced.h): Only run scan-types if $(SYSTEM_HEADER_DIR) - exists. - (stmp-fixproto): Simlarly for running fixproto. - * cross-make (SYSTEM_HEADER_DIR): Now $(tooldir)/sys-include. +Tue Mar 2 01:40:01 1999 Franz Sirl + Jeffrey A Law (law@cygnus.com) -Tue May 19 19:08:52 1998 Jim Wilson + * cse.c (fold_rtx): Update comments for (const (minus (label) (label))) + case. + (cse_insn): Avoid creating a bogus REG_EQUAL note for + (const (minus (label) (label))) + (record_jump_cond): Fix mismatched paren in comment. - * config/mips/mips.c (double_memory_operand): Accept any MEM during - reload when TARGET_64BIT. +Tue Mar 2 01:07:12 1999 Dan Nicolaescu -Tue May 19 18:21:25 1998 Jim Wilson + * final.c (end_final): There are 11 words in the "main header" + structure, not 10. - Finish incomplete change started by Kenner. - * configure.in (*-*-linux-gnu*): Delete NO_STAB_H from xm_defines. - (powerpcle-*-cygwin32): Delete xm_defines. - * final.c, mips-tfile.c, xcoffout.c, config/mips/mips.c: Use - HAVE_STAB_H instead of NO_STAB_H. - * config/xm-linux.h (NO_STAB_H): Delete. - (HAVE_STAB_H): Undefine. - * config/i386/xm-go32.h (NO_STAB_H): Delete. +Tue Mar 2 00:09:18 1999 Marc Espie -1998-05-19 Jim Wilson + * extend.texi: Reference __extension__ in the index. - * dwarfout.c (dwarfout_file_scope_decl, case TYPE_DECL): Ignore - LANG_TYPE trees with DECL_SOURCE_LINE of 0. +Mon Mar 1 19:09:32 1999 Jim Wilson -Tue May 19 15:07:54 1998 Todd Vierling + * Makefile.in (CROSS_FLOAT_H): Delete. + (FLOAT_H): Use float_h_file. + (rest.cross, stmp-int-hdrs): Delete gfloat.h dependency. + (gfloat.h): Delete. + (stmp-int-hdrs): Use FLOAT_H instead of gfloat.h. + (mostlyclean): Delete gloat.h reference. + (install-cross-rest, install-float-h-cross, stmp-headers): Update + comments. + * configure.in (sparcv9-*-solaris2*): Set float_format to none. + (sparc-*-solaris2*): Set float_format to none for 2.5 and higher. + (float_h_file): Set from float_format. Substitute into Makefile.in. + (float_format): No longer substitute into Makefile.in. + * cross-make (FLOAT_H): Delete. + * config/mips/t-cross64 (FLOAT_H): Delete. + * configure: Rebuilt. - * arm/netbsd.h: Ensure DWARF2_UNWIND_INFO is undefined. +Mon Mar 1 16:36:18 1999 Jeffrey A Law (law@cygnus.com) -Tue May 19 17:19:16 1998 J"orn Rennecke + * mips.md (div_trap_normal, div_trap_mips16): Require the dependent + insn to be an INSN before looking at its pattern. - * reload1.c (reload_reg_free_for_value_p): New function. - (allocate_reload_reg, choose_reload_regs): Use it. +Mon Mar 1 15:03:51 1999 Jim Wilson -Tue May 19 11:51:00 EDT 1998 Andrew MacLeod (amacleod@cygnus.com) + * config/m68k/lb1sf68.asm (udivsi3): Change jmi to jcs. Fix comments. + * config/m68k/m68k.h (LEGITIMATE_INDEX_REG_P): Reject SIGN_EXTEND of + HImode reg when TARGET_5200. - * except.c (expand_start_catch): Correct logic for when to - generate a new handler label, and when to use the old one. +Mon Mar 1 21:44:30 1999 J"orn Rennecke -Tue May 19 11:08:52 1998 Kaveh R. Ghazi + From Toshiyasu Morita: + * sh.h (CACHE_LOG): SH2 has cache, too. - * Makefile.in (print-rtl.o): Depend on bitmap.h. - (dbxout.o): Depend on toplev.h. - ($(SCHED_PREFIX)sched.o): Likewise. - ($(out_object_file)): Likewise for system.h and toplev.h. - (cppmain.o): Depend on gansidecl.h. - (cpplib.o): Likewise. - (cpperror.o): Likewise. - (cppexp.o): Likewise. - (cpphash.o): Likewise. - (cppalloc.o): Likewise. - (fix-header.o): Depend on cpplib.h and cpphash.h. - (scan-decls.o): Depend on gansidecl.h. +Mon Mar 1 14:23:36 1999 Catherine Moore - * basic-block.h (free_regset_vector): Add prototype. + * toplev.c (compile_file): Disable -ffunction-sections and + debugging warning if the object format is elf. - * cccp.c (check_precompiled): Mark parameter `fname' with - ATTRIBUTE_UNUSED. - (do_assert): Likewise for `op' and `keyword'. - (do_unassert): Likewise. - (do_line): Likewise for `keyword'. - (do_error): Likewise for `op' and `keyword'. - (do_warning): Likewise. - (do_ident): Likewise for `keyword'. - (do_pragma): Likewise for `limit', `op' and `keyword'. - (do_sccs): Likewise. - (do_if): Likewise for `keyword'. - (do_elif): Likewise. - (do_else): Likewise. - (do_endif): Likewise. - - * collect2.c (getenv): Remove redundant prototype. - (collect_exit, collect_execute, dump_file): Likewise. - (dump_list): Wrap prototype and definition in COLLECT_EXPORT_LIST. - (dump_prefix_list): Hide prototype and definition. - - * sparc.c: Include toplev.h. - (intreg_operand): Mark parameter `mode' with ATTRIBUTE_UNUSED. - (symbolic_memory_operand): Likewise. - (sp64_medium_pic_operand): Likewise. - (data_segment_operand): Likewise. - (text_segment_operand): Likewise. - (splittable_symbolic_memory_operand): Likewise. - (splittable_immediate_memory_operand): Likewise. - (eq_or_neq): Likewise. - (normal_comp_operator): Likewise. - (noov_compare_op): Likewise. - (v9_regcmp_op): Likewise. - (v8plus_regcmp_op): Likewise. - (extend_op): Likewise. - (cc_arithop): Likewise. - (cc_arithopn): Likewise. - (small_int): Likewise. - (uns_small_int): Likewise. - (clobbered_register): Likewise. - (legitimize_pic_address): Likewise. - (delay_operand): Likewise. - (sparc_builtin_saveregs): Remove unused variable `stdarg'. +Mon Mar 1 11:46:25 1999 Vladimir N. Makarov - * sparc.h (order_regs_for_local_alloc, eligible_for_return_delay, - sparc_issue_rate, v8plus_regcmp_p): Add prototypes. + * config/h8300/h8300.c (print_operand): Use 16 bit addressing + when the data in 8-bit area and can not be addressed by 8-bit. - * sparc.md (cmpdi_v8plus): Add abort for default case in switch. +Sun Feb 28 16:40:00 1999 Richard Henderson - * cppalloc.c: Include gansidecl.h. + * flow.c (create_basic_block): Disregard integrated bb notes. - * cpperror.c: Include stdarg.h/varargs.h and gansidecl.h. - (cpp_file_line_for_message): Mark parameter `pfile' with - ATTRIBUTE_UNUSED. - (v_cpp_message): New function. - (cpp_message): Use it. Also convert to variable arguments. - (cpp_fatal): Likewise. - (cpp_pfatal_with_name): Constify parameter `name'. +Sun Feb 28 15:57:06 1999 Richard Henderson - * cppexp.c: Move gansidecl.h before cpplib.h. - * cpphash.c: Likewise. - * cpphash.h (hashf, delete_macro): Add prototypes. - - * cpplib.c: Include stdarg.h/varargs.h and move gansidecl.h before - cpplib.h. Don't include errno.h. - (update_path): Add arguments to prototype. - (cpp_fatal, cpp_file_line_for_message, cpp_message, delete_macro, - cpp_print_containing_files): Remove redundant prototypes. - (cpp_hash_cleanup, add_import, append_include_chain, - make_assertion, path_include, initialize_builtins, - initialize_char_syntax, finclude, validate_else, comp_def_part, - lookup_import, redundant_include_p, is_system_include, - read_name_map, read_filename_string, open_include_file, - check_macro_name, compare_defs, compare_token_lists, - eval_if_expression, change_newlines): Add prototype arguments. - (hashf): Remove redundant prototype. - (read_token_list, free_token_list, safe_read, xcalloc, savestring, - conditional_skip, skip_if_group): Add prototype arguments. - (fdopen): Remove redundant prototype. - (do_define, do_line, do_include, do_undef, do_error, do_pragma, - do_ident, do_if, do_xifdef, do_else, do_elif, do_endif, do_sccs, - do_once, do_assert, do_unassert, do_warning): Add prototype arguments. - (struct directive): Add prototype arguments to function pointer - member `func'. - (handle_directive): Add missing arguments to call to `do_line'. - (do_include): Mark parameters `unused1' and `unused2' with - ATTRIBUTE_UNUSED. - (do_line): Likewise for `keyword' and new parameters `unused1' and - `unused2'. - (do_error): Likewise for `keyword'. - (do_warning): Likewise. Also add missing argument `pfile' in call - to cpp_pedwarn. - (do_once): Mark parameter `keyword', `unused1' and `unused2' with - ATTRIBUTE_UNUSED. - (do_ident): Likewise for `keyword', `buf' and `limit'. - (do_pragma): Likewise. Also add missing arguments in call to do_once. - (do_sccs): Mark parameter `keyword', `buf' and `limit' with - ATTRIBUTE_UNUSED. - (do_if): Likewise for `keyword'. - (do_elif): Likewise. - (eval_if_expression): Likewise for `buf' and `length'. - (do_xifdef): Likewise for `unused1' and `unused2'. - (do_else): Likewise for `keyword', `buf' and `limit'. - (do_endif): Likewise. - (parse_name): Add missing argument `pfile' in call to cpp_pedwarn. - (cpp_handle_options): Remove superfluous NULL argument in call to - cpp_fatal. - (cpp_handle_options): Likewise. - (do_assert): Mark parameter `keyword', `buf' and `limit' with - ATTRIBUTE_UNUSED. - (do_unassert): Likewise. - (cpp_print_file_and_line): Add missing argument `pfile' in call to - cpp_file_line_for_message. - (v_cpp_error): New function. - (cpp_error): Use it. Also accept variable arguments. - (v_cpp_warning): New function. - (cpp_warning): Use it. Also accept variable arguments. - (cpp_pedwarn): Accept variable arguments. - (v_cpp_error_with_line): New function - (cpp_error_with_line): Use it. Accept variable arguments. - (v_cpp_warning_with_line): New function. - (cpp_warning_with_line): Use it. Accept variable arguments. Hide - definition. - (cpp_pedwarn_with_line): Accept variable arguments. - (cpp_pedwarn_with_file_and_line): Likewise. - (cpp_error_from_errno): Constify parameter `name'. Add missing - argument `pfile' in call to cpp_file_line_for_message. - (cpp_perror_with_name): Constify parameter `name'. - - * cpplib.h: Define PARAMS() in terms of PROTO(). - (fatal): Remove redundant prototype. - (cpp_error, cpp_warning, cpp_pedwarn, cpp_error_with_line, - cpp_pedwarn_with_line, cpp_pedwarn_with_file_and_line, - cpp_error_from_errno, cpp_perror_with_name, cpp_pfatal_with_name, - cpp_fatal, cpp_message, cpp_pfatal_with_name, - cpp_file_line_for_message, cpp_print_containing_files): Add - arguments to prototypes. - (scan_decls, cpp_finish): Add prototypes. - - * cppmain.c: Include gansidecl.h. - (main): Remove unused variable `i'. - - * dbxout.c: Include toplev.h. - - * demangle.h (do_tlink, collect_execute, collect_exit, - collect_wait, dump_file, file_exists): Add prototype. - - * dwarf2out.c (dwarf_type_encoding_name, decl_start_label): Hide - prototype and definition. - (gen_unspecified_parameters_die): Don't assign results of call to - function new_die() to unused variable `parm_die'. - (dwarf2out_line): Mark parameter `filename' with ATTRIBUTE_UNUSED. - (dwarf2out_define): Likewise for `lineno' and `buffer'. - - * dwarfout.c (output_unsigned_leb128, output_signed_leb128): Hide - prototype and definition. - (output_die): Add prototype arguments to function pointer arg. - (output_unspecified_parameters_die): Mark parameter `arg' with - ATTRIBUTE_UNUSED. + * sparc.md (blockage, nonlocal_goto_receiver): Set length to 0. - * except.c (output_exception_table_entry): Remove unused variable - `eh_entry'. +Sun Feb 28 14:47:53 1999 Arturo Montes - * except.h (expand_fixup_region_start, expand_fixup_region_end): - Add prototypes. + * config/i386/t-sco5gas (crti.o): New target. - * expr.c (do_jump_by_parts_equality_rtx): Remove prototype. +Sun Feb 28 15:10:17 1999 David Edelsohn - * expr.h (do_jump_by_parts_equality_rtx): Add prototype. + * rs6000.md (elf_high, movsi_got, *movsi_got_internal, + *movsi_got_internal_mem, GOT splitter, movdf_hardfloat32, + movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64, + load_multiple, allocate_stack, call_indirect_aix32, + call_indirect_aix64, call_value_indirect_aix32, + call_value_indirect_aix64, call_indirect_nt, + call_value_indirect_nt): Use gpc_reg_operand instead of + register_operand. - * fix-header.c: Include stdarg.h/varargs.h, move gansidecl.h - before cpplib.h, include cpphash.h, remove redundant prototype of - cpp_fatal, don't define `const', add a prototype for `fatal'. - (cpp_file_line_for_message): Add missing arguments `pfile'. - (v_cpp_message): New function. - (cpp_message): Use it. - (v_fatal): New function. - (fatal, cpp_fatal): Use it. - (cpp_pfatal_with_name): Constify parameter `name'. +Sun Feb 28 15:10:17 1999 Michael Meissner - * flow.c (free_regset_vector): Remove redundant prototype. + * rs6000.md (one_cmplsi2, andsi3, iorsi3, xorsi3, *eqvsi3, + *andcsi3, *iorcsi3, *nandsi3, *norsi3): Add alternatives to use CR + other than cr0. + * rs6000.c (and{,64}_operand): If the user did -ffixed-cr0, don't + allow andi. or andis. which always set cr0. - * function.c (round_down): Wrap prototype and definition with - macro ARGS_GROW_DOWNWARD. - (record_insns): Wrap prototype and definition with - defined (HAVE_prologue) || defined (HAVE_epilogue). +Sun Feb 28 01:15:04 1999 Jeff Law (law@cygnus.com) - * gansidecl.h (ATTRIBUTE_PRINTF_4, ATTRIBUTE_PRINTF_5): New macros. + * version.c: Bump for snapshot. - * gen-protos.c: Include gansidecl.h. - (hashf): Don't make it static, constify parameter `name'. +Sun Feb 28 02:00:38 1999 Jeffrey A Law (law@cygnus.com) - * genattrtab.c (check_attr_test): Change XEXP() to XSTR() to match - specifier %s in calls to function `fatal'. + * invoke.texi: Update information for PA scheduling. - * haifa-sched.c: Include toplev.h. - (find_rgns): Remove unused variable `j'. +Sat Feb 27 23:21:47 1999 Jerry Quinn + Mike Stump - * integrate.c (note_modified_parmregs): Mark parameter `x' with - ATTRIBUTE_UNUSED. - (mark_stores): Likewise. + * pa.c (override_options): Change default to 7100LC. - * jump.c (mark_modified_reg): Likewise. + * pa.h (REG_ALLOC_ORDER): Change order to allocate left half of + float regs before right half of float regs. - * output.h (insn_current_reference_address): Add prototype. - (eh_frame_section): Likewise. +Sat Feb 27 22:48:38 1999 H.J. Lu (hjl@gnu.org) + Jeffrey A Law (law@cygnus.com) - * print-rtl.c: Include bitmap.h. + * frame.h: Update some comments. + * defaults.h (TARGET_ATTRIBUTE_WEAK): Define. + * crtstuff.c (__register_frame_info, __deregister_frame_info): Declare + using TARGET_WEAK_ATTRIBUTE. + (__do_global_dtors_aux): Check if __deregister_frame_info is + zero before calling it. + (__do_global_dtors): Likewise. + (frame_dummy): Check if __register_frame_info is zero before + calling it. + (__frame_dummy): Likewise. - * reload1.c (reload): Wrap variables `note' and `next' in macro - PRESERVE_DEATH_INFO_REGNO_P. - (forget_old_reloads_1): Mark parameter `ignored' with - ATTRIBUTE_UNUSED. - (choose_reload_regs): Remove unused variable `in'. - (reload_cse_invalidate_mem): Mark parameter `ignore' with - ATTRIBUTE_UNUSED. - (reload_cse_check_clobber): Likewise. +Sat Feb 27 19:18:24 1999 Jeffrey A Law (law@cygnus.com) - * rtl.h (expand_null_return, reg_classes_intersect_p): Add prototype. - (mark_elimination): Fix typo in prototype. + * SERVICE: Update from the FSF. - * scan-decls.c: Include gansidecl.h. +Sat Feb 27 14:31:22 1999 Arturo Montes - * tree.h (using_eh_for_cleanups, supports_one_only): Add prototype. + * config/i386/t-sco5 (crti.o): New target. + * config/i386/sco5.h (STARTFILE_SPEC): Include crti.o when + linking -shared. + * configure.in (i[34567]86-*-sco3.2v5*): Add crti.o. -Mon May 18 22:37:33 1998 Jeffrey A Law (law@cygnus.com) +Sat Feb 27 01:12:40 1999 Jeffrey A Law (law@cygnus.com) - * function.c (identify_blocks): Fix thinko when setting the - block number for NOTE_INSN_BLOCK_END. + * md.texi (prologue,epilogue): Document named patterns. -Mon May 18 15:30:42 1998 Nick Clifton +Fri Feb 26 19:31:25 1999 Dave Love - * config/v850/lib1funcs.asm: Add .text pseudo op to start of - ___udivsi3. + * md.texi, invoke.texi: Fix unterminated @xrefs. - * config/v850/lib1funcs.asm: Fix .size pseudo ops to use three - underscores for the prefixes to the names of the maths functions. +Fri Feb 26 15:33:45 1999 Richard Henderson + + * genattrtab.c (simplify_knowing): Fix uninitialized read + in Feb 21 change. + + * genextract.c (main): Clear recog_operands before extracting. + +Fri Feb 26 02:24:57 1999 Jeffrey A Law (law@cygnus.com) + + * c-pragma.c (add_weak); Delete. Moved into... + * varasm.c (add_weak): New external function. + (declare_weak): If HANDLE_PRAGMA_WEAK, then add the function to + the list of weak functions. + * c-pragma (add_weak): Declare. + +Thu Feb 25 23:43:59 1999 Richard Henderson + + Flow rewrite to use basic block structures and edge lists: + + * basic-block.h (x_basic_block_head, x_basic_block_end): Kill. + (basic_block_computed_jump_target, basic_block_live_at_start): Kill. + (struct edge_def): New. + (struct basic_block_def): New. + (basic_block_info): New. + (BLOCK_HEAD, BLOCK_END): Update. + (ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR): New. + (uid_block_number): Kill. + (basic_block_for_insn, BLOCK_FOR_INSN): New. + (BLOCK_NUM): Update. + * flow.c (XNMALLOC): Kill. + (max_uid_for_flow): Kill. + (uid_block_number): Kill. + (uid_volatile): Turn into a bitmap. + (SET_INSN_VOLATILE): New. + (basic_block_info): New. + (entry_exit_blocks): New. + (x_basic_block_head, x_basic_block_end): Kill. + (basic_block_computed_jump_target, basic_block_live_at_start): Kill. + (flow_int_list_blocks, basic_block_succ, basic_block_pred): Kill. + (basic_block_loop_depth): Kill. + (basic_block_for_insn): New. + (find_basic_blocks): Split out initial block counting into + count_basic_blocks. Call functions split out of find_basic_blocks_1. + (count_basic_blocks): New. + (find_basic_blocks_1): Split out edge recognition, unreachable + block deletion. + (create_basic_block): New. + (compute_bb_for_insn): New. + (clear_edges): New. + (free_bb_memory): Kill. + (add_edge, add_edge_to_label): Kill. + (mark_label_ref): Kill. + (make_edges): Rewrite to use edge lists. + (make_edge, make_label_edge): New. + (mark_critical_edges): New. + (split_edge, insert_insn_on_edge): New. + (commit_one_edge_insertion, commit_edge_insertions): New. + (delete_unreachable_blocks): Rewrite to use edge lists. + Split out EH region manipulation into delete_eh_regions. + Call tidy_fallthru_edge and merge_blocks. + (delete_eh_regions): New. + (delete_note_p): New. + (delete_insn_chain): New. + (delete_block): Split out code into delete_insn_chain and + tidy_fallthru_edge. Update edge lists. + (expunge_block): New. + (flow_delete_insn): New? + (can_delete_label_p): New? + (merge_blocks_nomove, merge_blocks): New. + (tidy_fallthru_edge): New. + (calculate_loop_depth): New. + (life_analysis): Allocate and free uid_volatile. + (free_basic_block_vars): Update for new structures. + (record_volatile_insns): Use SET_INSN_VOLATILE. + (mark_regs_live_at_end): Tidy EXIT_IGNORE_STACK usage. + (mark_used_regs): Likewise. + (life_analysis_1): Use bb global_live_at_start, global_live_at_end, + local_set regsets. Use bb->aux to store new_live_at_end. Begin + life propagation from EXIT_BLOCK rather than last block. Clear + regs_ever_live after mark_regs_live_at_end. + (allocate_for_life_analysis): Update for new structures. + (propagate_block): Split out loop depth calculation to + calculate_loop_depth. + (regno_uninitialized): Use bb->global_live_at_start. + (regno_clobbered_at_setjmp): Likewise. + (dump_bb_data): Likewise. + (find_auto_inc): Use BLOCK_FOR_INSN instead of BLOCK_NUM. + (dump_flow_info): Update for new structures. + (dump_edge_info): New. + (print_rtl_with_bb): Update for new structures. + (compute_preds_succs): Do no work -- convert edge lists. + (set_block_for_insn): From corpse of old set_block_num. + (set_block_num): Call it. + + * rtl.c (note_insn_name): Add NOTE_INSN_BASIC_BLOCK. + * rtl.h (rtunion_def): Add bb entry. + (NOTE_BASIC_BLOCK): New. + (NOTE_INSN_BASIC_BLOCK): New. + + * varray.h (varray_data_tag): Add bb entry. + (VARRAY_BB_INIT, VARRAY_BB): New. + + * emit-rtl.c (emit_label_before): New. + + * except.c (expand_rethrow): Delete insns following the call to + rethrow. Put the REG_EH_RETHROW on the call. + + * jump.c (returnjump_p, returnjump_p_1): New. + + * expr.h (nonlocal_goto_handler_labels): New declaration. + * function.c (nonlocal_goto_handler_labels): Define it. + (push_function_context_to): Save it. + (pop_function_context_from): Restore it. + (init_function_start): Clear it. + (nonlocal_label_rtx_list): Kill. + * function.h (struct function): Add storage space for it. + * stmt.c (expand_nl_handler_label): Return the new label. + (expand_nl_goto_receivers): Collect a list of them in + nonlocal_goto_handler_labels. + + * Makefile.in (print-rtl.o): Depend on basic-block.h. + (flow.o): Depend on insn-flags.h. + + * function.c (thread_prologue_and_epilogue_insns): Do not + half-heartedly update bb structures. + + * toplev.c: Add flow2 dump as -dw. + (rest_of_compilation): Finish .greg before flow2. + + * graph.c (draw_edge): Handle class 3. + (print_rtl_graph_with_bb): Make abnormal edges red class 2, + change non-fall-thru but adjacent to green class 3. Update + to use new structures. + + * print-rtl.c (print_rtx): Handle NOTE_INSN_BASIC_BLOCK. + + * reg-stack.c (BLOCK_NUM): Convert to function. Abort if + block_number is -1. + (reg_to_stack): Initialize block_num to -1. + + * combine.c (set_nonzero_bits_and_sign_copies): Update reference + to basic_block_live_at_start to bb->global_live_at_start. + (try_combine): Likewise. + (reg_dead_at_p): Likewise. + * global.c (global_conflicts): Likewise. + Handle stack regs on all abnormal edges, not just computed jumps. + (mark_elimination): Update reference to basic_block_live_at_start. + (build_insn_chain): Likewise. + * haifa-sched.c (haifa_edge): Rename from edge for conflict. + (is_cfg_nonregular): Look at nonlocal_goto_handler_labels instead + of nonlocal_label_rtx_list. + (check_live_1): Update reference to basic_block_live_at_start. + (update_live_1): Likewise. + (find_pre_sched_live): Likewise. + (find_post_sched_live): Likewise. + * local-alloc.c (update_equiv_regs): Likewise. + (block_alloc): Likewise. + * reload1.c (reload, reload_combine): Likewise. + * regmove.c (mark_flags_life_zones): Likewise. + * resource.c (mark_target_live_regs): Likewise. + * sched.c (schedule_block): Likewise. - * dbxout.c (dbxout_parms): Revert to using DECL_ARG_TYPE. Add - comment explaining why. + * regclass.c (regset_release_memory): Don't free + basic_block_live_at_start. -Mon May 18 13:20:23 1998 Richard Henderson + * unroll.c (copy_loop_body): Don't duplicate NOTE_INSN_BASIC_BLOCK. - * tree.h (TYPE_SIZE_UNIT): New. - (struct tree_type): Add size_unit member. - * stor-layout.c (layout_type): Initialize it. - * expr.c (get_inner_reference) [ARRAY_REF]: Use it. - * tree.c (size_in_bytes, int_size_in_bytes): Likewise. +Thu Feb 25 21:32:34 1999 Jason Merrill -Mon May 18 12:07:37 1998 Richard Earnshaw (rearnsha@arm.com) + * fixinc.wrap: Also handle struct queue in sys/stream.h. + * fixinc.svr4: Likewise. - * stor-layout.c (layout_record): Fix off-by-one error when checking - length of the TYPE_BINFO vector. + * dwarf2out.c (scope_die_for): Set scope_die to comp_unit_die + rather than asserting it. -Mon May 18 10:59:23 1998 Nick Clifton +Thu Feb 25 23:33:06 1999 Kaveh R. Ghazi - * dbxout.c (dbxout_parms): Use TREE_ARG to compute the type of a - function parameter passed in memory. + * cppexp.c (left_shift, right_shift, parse_charconst, COMPARE, + cpp_parse_expr): Replace uses of long/HOST_BITS_PER_LONG with + HOST_WIDEST_INT/HOST_BITS_PER_WIDEST_INT. -Mon May 18 09:02:09 1998 Robert Lipe + * Makefile.in (cppmain.o, cpplib.o, cpphash.o, cppalloc.o, + cpperror.o, cppexp.o, cppfiles.o, cppinit.o, fix-header.o, + scan-decls.o): Don't depend on machmode.h. - * dwarfout.h, dwarf2out.h, dbxout.h, sdbout.h: New files. - Prototypes for externally used functions in respective C files. - * dwarfout.c, dbxout.c, dwarf2out.c, sdbout.c, toplev,c, - final.c: Include above files. - * Makefile.in (toplev.o): Add dependency for above four headers. - (final.o): Likewise. - (dwarfout.o, dbxout.o, dwarf2out.o, sdbout.o): Depend on four - respective header files. + * cppexp.c: Don't define CHAR_BIT or HOST_BITS_PER_WIDE_INT anymore. + Replace all instances of HOST_WIDE_INT with HOST_WIDEST_INT. -Mon May 18 01:23:33 1998 Jeffrey A Law (law@cygnus.com) + * cppfiles.c: Likewise. - * Makefile.in (TARGET_TOOLPREFIX): No longer define. - (AR_FOR_TARGET, RANLIB_FOR_TARGET): Define to use versions in - the build tree if they exist. - (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): Update - appropriately. - (objdir): Let configure substitute value. - (FLOAT_H): Let configure select a pre-built version from the - config subdir. - * build-make (INSTALL_TARGET, ALL): Disable, no longer needed. - * configure.in: Substitute for objdir. + * cpplib.c: Likewise. - * Makefile.in (build_canonical, host_canonical): Let configure - substitute values for these variables. - * configure.in: Substitute for build_canonical, host_canonical - and target_subdir in generated Makefile. + * cpplib.h: Likewise. Also don't include machmode.h anymore. - * output.h (find_basic_blocks): Declare. - (free_basic_block_vars, set_block_num, life_analysis): Likewise. +Thu Feb 25 18:46:26 1999 Richard Henderson - * Makefile.in (BISON): Use bison from the build tree if it exists. - (FLEX): Similarly. + * gcc.c (default_compilers): Define __FAST_MATH__ when appropriate. + * objc/lang-specs.h: Likewise. -Mon May 18 00:08:19 1998 Nick Clifton +Thu Feb 25 16:19:43 1999 Jeffrey A Law (law@cygnus.com) - * gcc.c (SWITCH_CURTAILS_COMPILATION): Definition. - (DEFAULT_SWITCH_CURTAILS_COMPILATION): True for options -S and -c. - (process_command): If HAVE_EXECUTABLE_SUFFIX is defined then scan - command line arguments to see if an executable is not being - created, and if so - do not append the suffix. + * pa.md (call patterns): Lose unused argument to output_call. - * tm.texi (SWITCH_CURTAILS_COMPILATION): Add description of new - driver macro. + * print-rtl.c (print_rtl): Print /j and /c for the jump/call flags. -Sun May 17 23:59:45 1998 John Wehle (john@feith.com) +1999-02-25 Zack Weinberg - * i386.h (ALIGN_DFmode): Delete. - (CONSTANT_ALIGNMENT): Define. - * varasm.c (force_const_mem): Use it. + * cpphash.c (install): Rename to cpp_install, add cpp_reader* + first argument. All callers changed. + (hashtab): Removed. + (cpp_lookup, cpp_install): Change all refs to hashtab to + pfile->hashtab. + (cpp_hash_cleanup): Removed. + * cpphash.h: Adjust prototypes. + * cpplib.h (struct cpp_reader): Add hashtab pointer. + * cppinit.c (cpp_reader_init): Also allocate space for the + hashtab. + (cpp_cleanup): Delete all macros and free the hashtab. -Sun May 17 19:31:05 1998 Richard Henderson +Thu Feb 25 21:52:54 1999 J"orn Rennecke - * alpha.c (alpha_emit_conditional_branch): Clear cmp_code after - using it with swap_condition, not before. + * sh.h (PASS_IN_REG_P): For TARGET_HITACHI, don't pass structures + in registers. -Sun May 17 13:44:32 1998 Jim Wilson + * expr.h (PRETEND_OUTGOING_VARARGS_NAMED): Provide default definition. + * function.c (assign_parms): Honour PRETEND_OUTGOING_VARARGS_NAMED. + * calls.c (expand_call): Likewise. - * alias.c (mode_alias_check): Delete. - (true_dependence, anti_dependence, output_dependence): Revert April 21 - change. + * sh.c (sh_expand_prologue): For TARGET_HITACHI, don't push varargs / + stdarg arguments. + * sh.h (CPP_SPEC): Add -D__HITACHI__ for -mhitachi. + (FUNCTION_ARG): For TARGET_HITACHI, don't pass unnamed + arguments in registers. + (PRETEND_OUTGOING_VARARGS_NAMED): Define. + * va-sh.h (entire file): If __HITACHI__ is defined, use sh[123] + flavor varargs. -Sun May 17 08:45:21 1998 Krister Walfridsson +Thu Feb 25 14:32:40 1999 Kaveh R. Ghazi - * toplev.c (output_lang_identify): Enable prototype and definition. + * cse.c (dump_class): Revert last change and make the prototype + extern. -Sun May 17 01:12:27 PDT 1998 Jeff Law (law@cygnus.com) +Thu Feb 25 19:13:42 1999 J"orn Rennecke - * version.c: Bump for snapshot. + * rtl.h (insn_first_p): Don't declare. + * rtlanal.c (insn_first_p): Delete. + * loop.c (loop_insn_first_p): Faster implementation. -Sat May 16 23:20:32 1998 Richard Henderson +Thu Feb 25 10:44:35 1999 Richard Earnshaw (rearnsha@arm.com) - * alpha/osf.h (HAVE_STAMP_H): Define. - * alpha.c: Use it. - * alpha/netbsd.h, alpha/netbsd-elf.h: New files. - * configure.in (alpha*-*-netbsd*): New. - Based on patches from Paul H. Anderson . + * arm.h (TARGET_SWITCHES): Delete deprecated switches -m[236]. + (TARGET_3, TARGET_6): Delete. + (ARM_FLAG_ARM[36]): Delete. + (CPP_CPU_ARCH_SPEC): No need to handle -m[236] any more. + (CC1_SPEC): Don't expand -m[236] into new equivalents. + (CPP_APCS_PC_SPEC): No need to handle -m[236] any more. + * arm.c (arm_override_options): Delete warnings about deprecated + options -m[236]. - * configure.in (alpha*-*-linux-*): Kill xm_defines. - (alpha*-*-linux-gnulibc1*) [fixincludes]: Define. - * alpha/xm-linux.h: Remove file. + * arm.c (arm_finalize_pic): Build the label into the special pic + adjustment insn instead of issuing it separately. + * arm.md (pic_add_dot_plus_eight): Rework to contain the label + that is needed. -Sat May 16 18:32:45 1998 Doug Evans + * arm.md (*zeroextractqi_compare0_scratch): Delete. + (*ne_zeroextractsi): New pattern. - * dbxout.c (dbxout_parms): If mode of type of parameter living - in memory doesn't match mode of DECL_RTL, make big endian correction. +Thu Feb 25 18:40:06 1999 J"orn Rennecke -Fri May 15 21:40:06 1998 John Wehle (john@feith.com) + * stmt.c (expand_end_loop): Grok code emitted by + expand_exit_loop_if_false. - * i386.md (movdi-1, movdi): Rewrite based on SI move patterns. +Thu Feb 25 10:17:32 1999 Nick Clifton -Fri May 15 18:55:22 1998 Jason Merrill + * config/arm/arm.c (return_in_memory): Float fields in unions + force a return in memory. + (load_multiple_sequence): Add comment explaining why two LDR + instructions can be better than an LDMIA instruction. - * tree.h (BINFO_SIZE, TYPE_BINFO_SIZE): New macros. - * stor-layout.c (layout_record): Set it. + * config/arm/arm.h (TARGET_SHORT_BY_BYTES): Add comment + describing the real meaning of this option. + (FIXED_REGISTERS): Default r10 to not-fixed. + (CALL_USED_REGISTERS): Default r10 to not-call-used. + (SUBTARGET_CONDITIONAL_REGISTER_USAGE): If not defined, define + as empty. + (CONDITIONAL_REGISTER_USAGE): Fix r10 if TARGET_APCS_STACK is + true. Invoke SUBTARGET_CONDITIONAL_REGISTER_USAGE after + performing other checks. -Fri May 15 18:49:30 1998 Mark Mitchell + * config/arm/arm.md (zero_extendhisi2): Undo previous change. + (extendhisi2): Undo previous change. + Also add comments describing why TARGET_SHORT_BY_BYTES can be + ignored for armv4(t) architectures. - * toplev.c (rest_of_compilation): Don't defer nested functions. + * config/arm/riscix.h (SUBTARGET_CONDITIONAL_REGISTER_USAGE): + Define to fix r10. -Fri May 15 17:42:52 1998 Bob Manson + * config/arm/riscix1-1.h + (SUBTARGET_CONDITIONAL_REGISTER_USAGE): Define to fix r10. + +Thu Feb 25 12:09:04 1999 Kaveh R. Ghazi + + * cse.c (dump_class): Make the function definition static to match + the prototype. + +Wed Feb 24 17:47:28 1999 Jim Wilson + + * dbxout.c (gstab.h): Use if CROSS_COMPILE. + + * dwarf2out.c (add_location_or_const_value_attribute): Add big + endian correction for parms passed in regs but living on the stack. + +Wed Feb 24 14:03:54 1999 Jeffrey A Law (law@cygnus.com) + + * calls.c (initialize_argument_information): New function extracted + from expand_call. + (expand_call): Use initialize_argument_information. Remove variables + which are no longer used due to cleanups. - * config/rs6000/rs6000.c (rs6000_stack_info): Align the stack bottom - to an 8-byte boundary if info_ptr->fpmem_p. + * calls.c (compute_argument_block_size): New function, extracted from + expand_calls. + (expand_calls): Use compute_argument_block_size. Delete + original_args_size, use unadjusted_args_size instead. + + * calls.c (precompute_arguments): New function, extracted from + expand_call. + (expand_call): Use precompute_arguments. + + * calls.c (finalize_must_preallocate): New function, extracted from + expand_call. + (expand_call): Use finalize_must_preallocate. + + * calls.c (store_one_arg): Mark "variable_size" as possibly unused. -Fri May 15 17:36:11 1998 Bill Moyer + * regclass.c (record_reg_classes, case 'p'): Set classes appropriately. + An alternative always fails if it needs a pseudo and no suitable + register class can be found. - * loop.c (basic_induction_var): Added test preventing - CCmode parameter passed to convert_modes(). +Wed Feb 24 19:47:56 1999 J"orn Rennecke + + * loop.h (loop_insn_first_p): Declare. + * loop.c (loop_insn_first_p): No longer static. + * unroll.c (iteration_info): Fix comparison to + reg_iv_type->num_elements. + Before accessing reg_biv_class, check index against + max_reg_before_loop. + Fix and enable code for giv iterators. + (loop_iterations): Compare with reg_iv_type->num_elements instead + of with max_reg_before_loop. + +Wed Feb 24 19:17:11 1999 J"orn Rennecke + + * unroll.c (unroll_loop): Avoid out-of-bounds index for local_regno. + +Wed Feb 24 11:26:41 1999 Vladimir N. Makarov + + * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Don't use + PIC_OFFSET_TABLE_REGNUM for register allocation when -fPIC. -Fri May 15 17:26:18 1998 Alexandre Petit-Bianco +Tue Feb 23 16:24:19 1999 Marc Lehmann + + * config/i386/i386.md: Fix typo. - * expr.c (expand_expr, case EXPR_WITH_FILE_LOCATION): Save/restore - input_filename and lineno around expand_expr call. Set them to values - in WFL before expand_expr call. +Mon Feb 22 19:36:33 1999 Andrew Cagney + + * config/mips/mips.c (mips_debugger_offset): When TARGET_MIPS16 && + frame_pointer_needed adjust frame size. + (function_prologue): Don't MIPS16 .mask GPOFFSET. Already adjusted + in .frame pseudo-op. + Frm Jim Wilson : + * mips.c (function_prologue): Adjust frame size in .frame pseudo-op + when TARGET_MIPS16 && frame_pointer_needed. + +1999-02-22 Nick Clifton + + * config/arm/arm.h: Add TARGET_CPU_strongarm1100. + Add -mno-sched command line switch to disable scheduling of + instructions into the function's prologue. + (enum processor_type): Remove. + (TARGET_OPTIONS): Add "fpe=" option to match documentation. + (struct arm_cpu_select): Replace 'set_tune_p' and 'set_arch_p' + fields with 'processors' field. + (CONDITIONAL_REGISTER_USAGE): Allow r10 to be used if stack + checking is not enabled. + (RETURN_IN_MEMORY): Always call arm_return_in_memory. -Fri May 15 12:44:57 1998 Benjamin Kosnik + * config/arm/arm.c (arm_cpu): Remove. + (tune_flags): Remove. + (arm_is_strong): New variable: true iff the target processor is a + StrongARM. + (arm_is_6_or_7): New variable: true iff the target processor is an + ARM6 or and ARM7. + (arm_select): Fields reorganised. + (struct processors): processor_type field removed. + (all_procs): Remove. + (all_cores): New array: Definitions of all known ARM cpu cores. + (all_architectures): New array: Definitions of all known ARM + architectures. + (streq): New macro. + (FL_SCHED): New processor flag: processor required load + scheduling. + (FL_STRONG): New processor flag: processor is a StrongARM. + (arm_override_options): Reorganized to make code clearer. + (use_return_insn): Test for "not (TARGET_APCS and + frame_pointer_needed)". + (arm_return_in_memory): Improve handling of structures. + + * config/arm/arm.md: Remove "cpu" attribute. Replace with + "is_strongarm" and "is_arm_6_or_7" attributes. + (zero_extendhisi2): Check for TARGET_SHORT_BY_BYTES before + arm_arch4. + (extendhisi2): Check for TARGET_SHORT_BY_BYTES before arm_arch4. + + * invoke.texi (ARM Options): Document -mtune= and -mfp= options. + +1999-02-22 Philip Blundell + + * config/arm/linux-gas.h (INITIALIZE_TRAMPOLINE): Replace default + definition with one including cache synchronization. + (CLEAR_INSN_CACHE): Correct syscall number and enable definition. + Move definition of inhibit_libc to... + * config/arm/xm-linux.h: ... here. + + * config/arm/t-linux: Disable multilib configurations since the + only effect for most people is to cause builds to fail. + + * config/arm/elf.h (ASM_FILE_START): Add .file directive. + (ASM_SPEC): Translate -mapcs-float to -mfloat for the assembler. + + * config/arm/linux-elf.h (DEFAULT_VTABLE_THUNKS): Define. + (HANDLE_SYSV_PRAGMA): Likewise. + (LIB_SPEC): Copy definition from generic Linux files. + (LIBGCC_SPEC): Include -lfloat if -msoft-float was given. + (FP_DEFAULT): Set to SOFT3 on 32-bit targets. + (DWARF2_DEBUGGING_INFO): Define. + (PREFERRED_DEBUGGING_TYPE): Define as DBX_DEBUG. - * stor-layout.c (set_sizetype): Set TYPE_NAME on bitsizetype. +Mon Feb 22 16:54:18 1999 Andrew MacLeod -Fri May 15 07:20:03 1998 Mark Mitchell + * loop.c (libcall_other_regs): Make extern. + * rtl.h (find_last_value): Add parameter to prototype. + (libcall_other_reg): Add extern declaration. + * rtlanal.c (find_last_value): Add another parameter to allow + a definition using a hardware register to be found as well. - * fold-const.c (constant_boolean_node): New function. - (fold): Use it. +Mon Feb 22 13:33:47 1999 Mark Mitchell -Fri May 15 11:21:16 1998 J"orn Rennecke + * cse.c (dump_class): New function. + (invalidate_memory): Fix typo in comment. + * function.c (temp_slot): Add an alias set field. + (assign_stack_temp): Only reuse slots if they will have the + same alias set as before. + (combine_temp_slots): Don't combine if -fstrict-aliasing; + that's unsafe. + * rtl.c (copy_rtx): Copy all the flags (in particular, + MEM_SCALAR_P). - * sh.c (gen_shl_and): Don't sign extend constant for kind two. - Abort if trying to split kind 3 or 4 outside of combine. +Mon Feb 22 14:13:23 1999 Vladimir N. Makarov -Fri May 15 01:47:37 1998 Jeffrey A Law (law@cygnus.com) + * configure.in (i[34567]86-*-linux-gnu*, + i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*, + i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as + fixincludes. - * mips.c (print_operand, case 'x'): Use HOST_WIDE_INT_PRINT_HEX. + * configure: Rebuilt. -Fri May 15 01:42:45 1998 Mumit Khan + * fixinc.x86-linux-gnu: New script for fixing asm-statements bug + on x86 linux. - * objc/Make-lang.in (OBJC_O): Add missing exeext. - (libobjc.a, runtime-info.h): Likewise. + * fixinc/fixinc.x86-linux-gnu: Copy of the previous one. -Fri May 15 01:29:39 1998 John Wehle (john@feith.com) + * fixinc/mkfixinc.sh (i[34567]86-*-linux-gnu*, + i[34567]86-*-linux-gnulibc1, i[34567]86-*-linux-gnuaout*, + i[34567]86-*-linux-gnuoldld*): Use fixinc.x86-linux-gnu as + fixincludes. - * i386.h (DATA_ALIGNMENT): Define. +Mon Feb 22 08:55:05 1999 Ovidiu Predescu -Fri May 15 05:35:37 1998 J"orn Rennecke + * objc/objc-act.c (encode_type): Temporary revert to the old + behavior of encoding types as the new one seems to break the + encoding of bitfields. - * reload1.c (delete_output_reload): Ignore single USE that - was emitted for the pseudo use of this INSN. - If the no reference to REG between OUTPUT_RELOAD_INSN and INSN - remains, we can always delete OUTPUT_RELOAD_INSN. +Mon Feb 22 11:40:44 1999 Craig Burley +Sat Feb 20 09:59:36 1999 Craig Burley -Thu May 14 18:38:50 1998 Jim Wilson + * Makefile.in (all.internal, all.cross): Depend on `doc' + target, to ensure docs get made before installation. - * reload.c (find_reloads): Don't penalize SCRATCH output reload. + Decrease spurious warnings from -fsyntax-only: + * stmt.c (expand_expr_stmt): Expand expr even when -fsyntax-only. -Thu May 14 15:10:30 1998 Jeffrey A Law (law@cygnus.com) +Mon Feb 22 10:55:00 1999 Gavin Romig-Koch - * Makefile.in (expr.o): Remove dependency on deleted modemap.def file. + * c-lex.c (yylex): Replace warning about integer constants being + larger than long-longs, with a warning about integer constants + being larger than the largest target integer. -Thu May 14 16:30:47 EDT 1998 Andrew MacLeod +Mon Feb 22 08:35:38 1999 Craig Burley - * eh-common.h: New file for basic EH data structures. - * except.h: Various prototypes and structures for NEW_EH_MODEL - * function.h (struct function): Add a struct eh_stack for the catch - clause stack. - * except.c (gen_exception_label): New function to generate an - exception label. - (push_eh_entry): Use gen_exception_label() and init 'label_used' field. - (push_entry): New function to push an existing entry onto a stack. - (receive_exception_label): New function to emit the code required - at the start of all catch blocks. - (struct func_eh_entry): New structure for maintaining handlers - associated with EH regions. - (new_eh_region_entry): New function to register an EH region. - (add_new_handler): New function to register a handler with a region. - (get_new_handler): Creates anew handler entry for registering. - (find_func_region): New function to convert a NOTE eh region number - to an Eh region index. - (get_first_handler): New function to get the first handler in a region. - (clear_function_eh_region): New function to release memory. - (duplicate_handlers): New function to duplicate a list of handlers. - (expand_eh_region_end): Create a new region entry node as well. - (expand_leftover_cleanups): Call receive_exception_label() and - register the cleanup as a handler to the current region. - (expand_start_catch): New function to start a catch clause. - (expand_end_catch): New function to end a catch clause. - (expand_start_all_catch): restructure to not do the equivilent of - what expand_start_catch() does now. Push the exception region being - handled onto the catch stack. - (output_exception_table_entry): Issue an entry for each handler - associated with a region. - (set_exception_lang_code): New function for setting the language code. - (set_exception_version_code): New function to set the version number. - (output_exception_table): Output version and language codes. - (find_exception_handler_labels): Find handler labels using new scheme. - (is_exception_handler_label): New function, returns 1 if label is - present as a handler in some exception region. - (check_exception_handler_labels): Use the new scheme. - (init_eh_for_function): Initialize the catch stack. - (save_eh_status): Save the catch stack. - (restore_eh_status): Restore the catch stack. - (scan_region): Don't remove unreferenced handler label. Flow does it. - (get_reg_for_handler): New function to get the eh_context pointer - passed by __throw. - (expand_builtin_eh_stub): Changes required for NEW_EH_MODEL only. - * final.c (final_scan_insn): With NEW_EH_MODEL, add EH table - entry when processing END region rather that START region. - * flow.c (find_basic_blocks_1): Find all potential handler regions - now that we don't automatically know what the labels might be. - Let scan_region() remove unreferenced EH BEGIN/END labels. - * integrate.c (get_label_from_map): Put inlined labels onto the - permanent obstack since we dont know which ones might be exception - labels. - (save_for_inline_copying): Make new copies of all the handlers. - (expand_inline_function): Make new copies of all the handlers. - * libgcc2.c: Remove local struct decls, and include eh-common.h. - (find_exception_handler): With NEW_EH_MODEL the first matching - region we find is the right one. Add eh_info as a new parameter. - (__throw): Pass eh_info to find_exception_handler. Set handler - and pass use different regs under NEW_EH_MODEL. - -Thu May 14 12:58:21 1998 Jim Wilson - - * i960.h (hard_regno_mode_ok): Changed to function from array of - unsigned. - (HARD_REGNO_MODE_OK): Call function instead of testing bit. - * i960.c (hard_regno_mode_ok): Changed to function from array of - unsigned. - -Thu May 14 08:41:46 1998 J"orn Rennecke - - * reload.c (remove_replacements): New function. - * reload.h (remove_replacements): Declare. - * reload1.c (choose_reload_regs): Disable some reloads that - belong to inherited reloads. - -Thu May 14 02:17:17 1998 J"orn Rennecke - - * loop.c (scan_loop): Don't call move_moveables for optimize_size. - - * reload1.c (merge_assigned_reloads): When merging, reset - reload_spill_index for the eliminated reload. - -Wed May 13 17:51:13 1998 Jeffrey A Law (law@cygnus.com) - - * haifa-sched.c (schedule_insns): Fix merge goof. - -1998-05-13 Jim Wilson - - * varasm.c (make_decl_rtl): Revert April 1 change. - * alpha/alpha.h, alpha/win-nt.h, arm/arm.h, i386/unix.h, i960/i960.h, - m68k/linux.h, pa/pa.h, sparc/sparc.h, vax/vax.h (ASM_OUTPUT_MI_THUNK): - Get function name from the SYMBOL_REF in the DECL_RTL, not from - DECL_ASSEMBLER_NAME. - * i386/winnt.c (gen_stdcall_suffix): Comment for questionable use of - DECL_ASSEMBLER_NAME. - -Wed May 13 13:09:19 1998 Jim Wilson - - * i386.c (notice_update_cc, output_float_compare): Disable - TARGET_CMOVE support. - -Wed May 13 15:28:59 1998 Michael Meissner - Jeff Law + Fix -fsyntax-only ICEs: + * varasm.c (assemble_zeros, assemble_variable, + output_constant_def): Do nothing when -fsyntax-only. - * rtlanal.c (find_reg_note): Ignore notes that are not on on - insns of class 'i'. - (find_regno_note): Likewise. - - * Makefile.in (stor-layout.o): Depend on except.h - (varasm.o, function.o): Likewise. - (expr.o): Depend on except.h, modemap.def and hard-reg-set.h. - - * Makefile.in (HOST_RTL): Add $(HOST_PREFIX)bitmap.o. - (rtl.o, emit-rtl.o): Add dependency on bitmap.h. - ($(HOST_PREFIX_1)rtl.o): Likewise. - ($(HOST_PREFIX_1)bitmap.o): New host object. - * emit-rtl.c (toplevel): Include bitmap.h. - (gen_rtx): Handle 't' and 'b' nodes. - * print-rtl.c (print_rtx): Handle printing NOTE_INSN_LIVE notes. - Print block number for block begin/end notes. Print 't' type - nodes as a pointer. Know that the 3rd argument of live range - start/stop notes is really a range_info rtx. If type is 'b', print - out argument as a bitmap. - * rtl.c: Include bitmap.c. - (copy_rtx): Copy tree nodes as is. Copy bitmaps if type is 'b'. - (note_insn_name): Add NOTE_INSN_RANGE_{START,END}, NOTE_INSN_LIVE. - * rtl.def (RANGE_LIVE): New node to hold live information while we - recalculate the basic blocks. - (RANGE_REG, RANGE_INFO): New rtl types for live range splitting. - (RANGE_VAR): New node, to hold information saved in symbol node for New - communicating live range information to the debug output functions. - * rtl.h (rtunion_def): Add rttree and rtbit fields. - (XBITMAP, XTREE): New accessor macros. - (NOTE_LIVE_INFO): Overload NOTE_SOURCE_FILE for NOTE_INSN_LIVE notes. - (NOTE_RANGE_INFO): Similarly for NOTE_INSN_RANGE_{START,END} notes. - (NOTE_BLOCK_LIVE_RANGE_BLOCK): Define. - (NOTE_INSN_RANGE_START, NOTE_INSN_RANGE_END, NOTE_INSN_LIVE): New notes. - (RANGE_LIVE_{BITMAP,ORIG_BLOCK}): New accessor macros. - (RANGE_REG_{SYMBOL,BLOCK}_NODE, RANGE_VAR_*): New accessor macros. - (RANGE_INFO_*): Likewise. - * sched.c (sched_analyze): Keep live range start/stop notes. - (unlink_other_notes): Likewise. - * haifa-sched.c (sched_analyze): Keep live range start/stop notes. - (unlink_other_notes): Likewise. - * tree.h (BLOCK_LIVE_RANGE_{START,END,VAR_FLAG}): New accessor macros. - (BLOCK_LIVE_RANGE_FLAG): Likewise. - (DECL_LIVE_RANGE_RTL): Likewise. - (struct tree_block): Add live_range_flag, live_range_var_flag, - live_range_start and live_range_end. - (struct tree_decl): Add live_range_rtl field. - * gengenrtl.c (type_from_format): Handle 'b' and 't'. - (accessor_from_format): Likewise. - - * haifa-sched.c (schedule_block): Make verbose output line up. - Also add a blank line in printing the individual ready lists. - -Wed May 13 15:43:44 1998 Kaveh R. Ghazi - - * Makefile.in (c-lang.o): Depend on c-tree.h, c-lex.h and toplev.h. - (c-lex.o): Depend on output.h. - (c-common.o): Likewise. - (stmt.o): Likewise. - (calls.o): Likewise. - (integrate.o): Depend on toplev.h. - (regclass.o): Depend on output.h. - (final.o): Depend on reload.h. - - * c-common.c: Include output.h. - (check_format_info): Remove unused variable `integral_format'. - - * c-decl.c (print_lang_decl): Mark parameters `file', `node' and - `indent' with ATTRIBUTE_UNUSED. - (print_lang_type): Likewise. - (maybe_build_cleanup): Likewise for parameter `decl'. - (copy_lang_decl): Likewise for parameter `node'. - - * c-lang.c: Include c-tree.h, c-lex.h and toplev.h. - (lang_print_xnode): Mark parameters `file', `node' and `indent' - with ATTRIBUTE_UNUSED. - (lookup_interface): Likewise for parameter `arg'. - (is_class_name): Likewise. - (maybe_objc_check_decl): Likewise for parameter `decl'. - (maybe_objc_comptypes): Likewise for parameters `lhs', `rhs' and - `reflexive'. - (maybe_objc_method_name): Likewise for parameter `decl'. - (build_objc_string): Likewise for parameters `len' and `str'. - - * c-lex.c: Include output.h. - - * c-lex.h (position_after_white_space): Correct typo in prototype. - - * c-tree.h (finish_file, c_expand_start_cond, c_expand_start_else, - c_expand_end_cond, init_iterators): Add prototypes. - - * caller-save.c (set_reg_live): Mark parameters `reg' and `setter' - with ATTRIBUTE_UNUSED. +Fri Feb 19 18:18:56 1999 Don Bowman - * calls.c: Include output.h. + * configure.in (mips*-*-vxworks*): Enable gthreads vxworks support. + * configure: Rebuilt. - * cccp.c (pipe_closed): Mark parameter `signo' with - ATTRIBUTE_UNUSED. +Sun Feb 21 20:34:44 1999 Jeff Law (law@cygnus.com) - * combine.c: Move inclusion of expr.h to after insn-config.h. + * version.c: Bump for snapshot. - * iris6.h (ASM_IDENTIFY_GCC, ASM_IDENTIFY_LANGUAGE): Don't define - as empty, rather define as ((void)0). +Sun Feb 21 20:35:10 1999 Jeffrey A Law (law@cygnus.com) - * sparc.c (sparc_check_64): Add braces around ambiguous `else'. - Add parentheses around assignment used as truth value. + * config/aoutos.h (ASM_OUTPUT_CONSTRUCTOR): Delete. + (ASM_OUTPUT_DESTRUCTOR, ASM_OUTPUT_GC_ENTRY): Likewise. + * tm.texi: Update docs for constructors and destructors. - * cplus-dem.c (squangle_mop_up): Change return type to void. - (internal_cplus_demangle): Remove unused parameter `options'. - All callers changed. - (cplus_demangle_opname): Remove function wide variable `int i' and - replace with `size_t i' at each location where it is used. - (cplus_demangle_opname): change type of `i' from int to size_t. +Sun Feb 21 17:11:18 1999 Richard Henderson - * cppexp.c (right_shift): Mark parameter `pfile' with - ATTRIBUTE_UNUSED. + * genattrtab.c (check_attr_value): Allow negative const_int if + negative_ok. Accept integral arithmetic operators. Accept + direct references to other attributes. Accept symbol_ref in + non-constant attributes. + (max_attr_value): Add new argument `unknownp'. Update all callers. + (or_attr_value): Likewise. + (simplify_knowing): Don't optimize if max_attr_value unknown. + (write_length_unit_log): Likewise with or_attr_value. + (find_and_mark_used_attributes): Don't fallthru case. + (write_attr_set): Pass thru all non-cond expressions. + (write_attr_value): Handle symbol_ref, attr, and arithmetic. - * cpphash.c (cpp_lookup): Likewise. - (cpp_hash_cleanup): Likewise. +Sun Feb 21 13:16:44 1999 Michael Hayes - * cpplib.c (parse_name): Add a prototype and make it static. - (null_underflow): Mark parameter `pfile' with ATTRIBUTE_UNUSED. - (null_cleanup): Likewise for parameters `pbuf' and `pfile'. - (macro_cleanup): Likewise for parameter `pfile'. - (file_cleanup): Likewise. + * regmove.c (discover_flags_reg): Use word_mode instead of SImode. - * cpplib.h (cpp_reader_init, cpp_options_init, cpp_start_read, - cpp_read_check_assertion, skip_rest_of_line): Add prototypes. +Sun Feb 21 13:15:40 1999 Richard Henderson - * crtstuff.c (force_to_data, __CTOR_LIST__, force_to_data, - __DTOR_END__, __FRAME_END__): Mark with ATTRIBUTE_UNUSED. + * regmove.c (discover_flags_reg): Remove cc0 code. + (mark_flags_life_zones) [HAVE_cc0]: Force use of cc0; bail if + a potential flags register was identified. - * cse.c (cse_check_loop_start): Mark parameter `set' with - ATTRIBUTE_UNUSED. +Sat Feb 20 16:16:07 1998 Franz Sirl - * dbxout.c (flag_minimal_debug, have_used_extensions, - source_label_number): Move inside macro wrapper check against - defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO). + * rs6000.md (scc plus ltu): Fix typo in last change. - * dwarf2out.c (gen_entry_point_die): Hide prototype and definition. +Sat Feb 20 09:08:44 1999 Richard Earnshaw (rearnsha@arm.com) - * except.h (doing_eh): Provide prototype. + * xm-arm.h (HOST_BITS_PER_LONGLONG): Define. - * expr.c: Move inclusion of expr.h to after insn-config.h. +Fri Feb 19 23:02:02 1999 Richard Henderson - * final.c: Include reload.h. - (shorten_branches): Cast the first argument of bzero to char *. + * regmove.c (discover_flags_reg): New function. + (flags_set_1, mark_flags_life_zones): New functions. + (regmove_optimize): Call them. + (fixup_match_1): Use insn modes rather than sets_cc0_p. - * fix-header.c (cpp_print_containing_files): Mark parameter - `pfile' with ATTRIBUTE_UNUSED. - (cpp_fatal): Likewise. +Fri Feb 19 22:47:01 1999 J"orn Rennecke - * flow.c (find_basic_blocks_1): Cast the first argument of bzero - to char *. + * rtlanal.c (insn_first_p): Fix return value for insn == reference. - * genattrtab.c (make_length_attrs): Change the type of variable - `i' from int to size_t. - (zero_fn): Mark parameter `exp' with ATTRIBUTE_UNUSED. - (one_fn): Likewise. + * loop.c (strength_reduce, check_final_value, check_dbra_loop): + Use loop_insn_first_p. - * genextract.c (main): When generating insn-extract.c, mark - variable `junk' with ATTRIBUTE_UNUSED. +Fri Feb 19 15:49:26 1999 Michael Meissner + David Edelsohn - * gengenrtl.c (gencode): When generating genrtl.c, cast the first - argument of bzero to char*. + * rs6000.md (scc plus eq): Fix output template. + (scc plus ltu): Fix output template and collapse variants + correcting early clobbers. + (scc plus geu): Fix output template. + (scc plus gt): Fix output template. + (scc plus gtu): Fix output template and collapse variants. - * integrate.c: Include toplev.h. +Fri Feb 19 15:43:59 1999 Kaveh R. Ghazi - * libgcc2.c: Wrap `struct exception_table' and - `find_exception_handler' in macro DWARF2_UNWIND_INFO. + * cppinit.c (print_help): Remove unescaped newline in string. - * objc/Make-lang.in (objc-act.o): Depend on toplev.h. +Fri Feb 19 19:55:06 1999 J"orn Rennecke - * objc/objc-act.c: Include toplev.h. - (lang_print_xnode): Mark parameters `file', `node' and `indent' - with ATTRIBUTE_UNUSED. - (finish_protocol): Likewise for parameter `protocol'. + * loop.c (strength_reduce): Check for intervening jumps when + converting biv increment to giv. - * output.h (declare_weak): Add prototype. - (decode_reg_name): Don't wrap with TREE_CODE macro. - (assemble_alias): Add prototype. +Thu Feb 18 16:36:58 1999 Per Bothner - * regclass.c: Include output.h. + * tree.def (TRY_FINALLY_EXPR, GOTO_SUBROUTINE_EXPR): New tree nodes, + * expr.c (expand_expr): Support new tree nodes. - * reload.h (reloads_conflict): Add prototype. +Fri Feb 19 10:17:56 1999 Andreas Schwab - * rtl.h (print_rtl_single, mark_elimiation, reg_class_subset_p, - output_func_start_profiler): Add prototypes. + * config/m68k/m68k.c (m68k_align_loops_string, + m68k_align_jumps_string, m68k_align_funcs_string): Add const. + * config/m68k/m68k.h (m68k_align_loops_string, + m68k_align_jumps_string, m68k_align_funcs_string): Likewise. - * rtlanal.c (reg_set_p_1): Mark parameters `x' and `pat' with - ATTRIBUTE_UNUSED. +Thu Feb 18 23:28:35 1999 Kaveh R. Ghazi - * scan-decls.c: Include scan.h. + * bitmap.c (bitmap_print): Qualify a char* with the `const' keyword. - * scan.h (recognized_function, recognized_extern): Add prototypes. + * bitmap.h (bitmap_print): Likewise. - * stmt.c: Include output.h. + * c-decl.c (builtin_function, grokdeclarator, grokfield): Likewise. - * toplev.c (error_for_asm, warning_for_asm): Remove prototypes. - (output_lang_identify): Hide prototype and definition. - (float_signal): Mark parameter `signo' with ATTRIBUTE_UNUSED. - (pipe_closed): Likewise. + * c-lang.c (build_objc_string): Likewise. - * toplev.h (count_error, strip_off_ending, error_for_asm, - warning_for_asm): Add prototypes. + * c-lex.c (yyerror, extend_token_buffer): Likewise. Don't include + limits.h or ctype.h. Remove unused variable `p'. -Wed May 13 12:54:19 1998 Michael Meissner + * c-lex.h (yyerror): Qualify a char* with the `const' keyword. - * toplev.c (rest_of_compilation): "Charge" final for any time - doing various cleanup operations after finishing compilation - of a function. + * c-pragma.c (handle_pragma_token): Likewise. - * flow.c (dump_flow_info): Also print number of sets and - whether or not the pseudo is a user variable. + * c-pragma.h (handle_pragma_token): Likewise. - * flow.c (reg_n_max): New global variable. - * regclass.c (allocate_reg_info): Keep reg_n_max up to date. - Delete regno_max variable. - * regs.h (REG_N_CHECK): Define. - (REG_N_REFS, REG_N_SETS, REG_N_DEATHS): Use REG_N_CHECK. - (REG_N_CHANGES_SIZE, REG_N_CALLS_CROSSED, REG_LIVE_LENGTH): Likewise. - (REGNO_FIRST_UID, REGNO_LAST_UID, REGNO_LAST_NOTE_UID): Likewise. + * c-tree.h (build_objc_string, builtin_function, grokfield, + build_indirect_ref, lvalue_or_else, readonly_warning, error_init, + pedwarn_init): Likewise. -Wed May 13 12:54:19 1998 Martin von Loewis + * c-typeck.c (convert_for_assignment, warn_for_assignment, + push_string, warning_init, incomplete_type_error, + build_indirect_ref, lvalue_or_else, readonly_warning, + build_c_cast, spelling, push_member_name, print_spelling, + error_init, pedwarn_init, start_init): Likewise. - * acconfig.h (ENABLE_CHECKING): Undefine. - * configure.in (--enable-checking): New option. + * objc/objc-act.c (build_objc_string): Likewise. -Wed May 13 08:52:08 1998 J"orn Rennecke + * print-tree.c (print_node_brief, print_node): Likewise. - * reload1.c (merge_assigned_reloads): Can merge - RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_OTHER_ADDRESS even - if RELOAD_FOR_INPUT with the same reload_reg_rtx is present. + * tree.h (lvalue_or_else, print_node, print_node_brief): Likewise. -Tue May 12 20:05:57 1998 Jim Wilson +Thu Feb 18 20:44:21 1999 David Edelsohn - * collect2.c (main): Ignore do_collecting when COLLECT_EXPORT_LIST. + * regclass.c (record_reg_classes): Correctly handle 'p' constraint. -Wed May 13 03:23:45 1998 J"orn Rennecke +Thu Feb 18 19:59:37 1999 Marc Espie + + * configure.in :Handle OpenBSD platforms. + * configure: Rebuilt. + * config/openbsd.h: New file. + * config/xm-openbsd.h: New file. + * config/t-openbsd: New file. + * config/t-openbsd-thread: New file. - * reload1.c (gen_reload): Create REG_EQUIV notes. +Thu Feb 18 18:47:09 1999 Jeffrey A Law (law@cygnus.com) + + * function.c (assign_stack_temp_for_type): Round SIZE before calling + assign_stack_local for BLKmode slots. + +Fri Feb 19 01:45:06 1999 J"orn Rennecke + + * loop.c (strength_reduce): For derived givs, replace the + giv this was derived from with its new_reg. + (recombine_givs): Don't set new_reg for derived giv. + And don't print it, print SUM instead. + +Thu Feb 18 15:52:49 1999 Jim Wilson + + * m68kelf.h (ASM_RETURN_CASE_JUMP): Add 5200 support. + +1999-02-18 Zack Weinberg + + * cpplib.c: Kill define of STDC_VALUE. Don't include output.h + or prefix.h. Change CPP_IS_MACRO_BUFFER to not refer to + macro_cleanup. + (GET_ENV_PATH_LIST, PATH_SEPARATOR, STANDARD_INCLUDE_DIR, + predefs, SIZE_TYPE, PTRDIFF_TYPE, WCHAR_TYPE, + CPP_WCHAR_TYPE, USER_LABEL_PREFIX, REGISTER_PREFIX, struct + cpp_pending, version_string, struct default_include, + include_defaults_array, path_include, cpp_options_init, + dump_special_to_buffer, initialize_builtins, cpp_start_read, + cpp_reader_init, nreverse_pending, push_pending, print_help, + cpp_handle_option, cpp_handle_options, cpp_finish, + cpp_cleanup): Move to cppinit.c. + (macro_cleanup, struct arglist, collect_expansion, + create_definition, compare_defs, comp_def_part, ARG_BASE, + struct argdata, macarg, change_newlines, timestamp, + monthnames, special_symbol, unsafe_chars, macroexpand, + push_macro_expansion): Move to cpphash.c. + (quote_string, check_macro_name, cpp_expand_to_buffer, + output_line_command, cpp_undef): Export. + (null_underflow, null_cleanup, handle_directive): Make static. + + * cpplib.h: Prototype now-exported functions. Adjust decls of + syntax tables so we can include cpplib.h in cppinit.c. + * cpphash.h: Prototype all functions exported by cpphash.c. + * cppinit.c: Make syntax tables initialized data if possible + (uses GCC designated-initializer extension). + * cppexp.c: Make cpp_lex static. + * Makefile.in: Move -D switches for the various include dirs + from cpplib.o rule to cppinit.o rule. Adjust dependencies. + +Thu Feb 18 13:15:56 1999 Marc Espie -Tue May 12 22:21:07 1998 J"orn Rennecke + * alpha/openbsd.h: New file. + * alpha/xm-openbsd.h: New file. + * sparc/openbsd.h: New file. + * sparc/xm-openbsd.h: New file. + * m68k/openbsd.h: New file. + * m68k/xm-openbsd.h: New file. + * i386/openbsd.h: New file, originally from netbsd. + * i386/xm-openbsd.h: New file. - * reload1.c (reload): Fix check for USEs to use code of pattern. - (choose_reload_regs): Remove dead variable use_insn. +1999-02-17 Zack Weinberg -Tue May 12 14:04:49 1998 Jeffrey A Law (law@cygnus.com) + * Makefile.in: Correct dependencies for cpplib object files. - * pa.h (DBX_CONTIN_LENGTH): Reduce to 3000 bytes. +Wed Feb 17 14:04:18 1999 Michael Meissner -Tue May 12 15:16:02 1998 Michael Meissner + * rs6000.md ({add,sub}si3 `.'): Add alternatives to use CR other + than cr0. - * haifa-sched.c (HAIFA_INLINE): Define to be __inline unless - already defined. - (find_insn_{,mem_}list): Use HAIFA_INLINE, not __inline. - (insn_{unit,issue_delay}): Ditto. - (blockage_range): Ditto. - (actual_hazard{,_this_instance}): Ditto. - (schedule_unit): Ditto. - (potential_hazard): Ditto. - (insn_cost): Ditto. - (swap_sort): Ditto. - (queue_insn): Ditto. - (birthing_insn_p): Ditto. - (adjust_priority): Ditto. - (get_block_head_tail): Ditto. - (init_rgn_data_dependences): Ditto. +Wed Feb 17 16:59:28 1999 J"orn Rennecke -Tue May 12 10:27:54 1998 Klaus Kaempf + * loop.c (strength_reduce): Don't move giv insn for biv turned giv + below scan_start. - * alpha/vms.h (COMMON_ASM_OP, ASM_OUTPUT_ALIGNED_COMMON): Define. +Wed Feb 17 10:56:24 1999 Kaveh R. Ghazi -Tue May 12 11:44:14 1998 Gavin Koch + * tree.c (tree_node_kind_names, print_obstack_name, + get_identifier, maybe_get_identifier, build_string, + build_expr_wfl, is_attribute_p, lookup_attribute, + print_obstack_statistics, get_file_function_name_long, tree_check, + tree_class_check, expr_check): Qualify a char* with the `const' + keyword. - * config/mips/mips.h (ASM_OUTPUT_ALIGN): Remove trailing semi-colon. + * tree.h (get_identifier, maybe_get_identifier, build_string, + build_expr_wfl, is_attribute_p, lookup_attribute, + print_obstack_statistics, print_obstack_name, tree_check, + tree_class_check, expr_check): Likewise. -Tue May 12 11:38:31 1998 Gavin Koch +Tue Feb 16 21:29:38 1999 Jeffrey A Law (law@cygnus.com) - * config/mips/mips.md (dslot): Move after definition of "cpu" - attribute. Handle r3900 case. + * i386/freebsd-elf.h, i386/gas.h, i386/linux.h: Fix minor spacing + errors. -Tue May 12 10:21:36 1998 Kaveh R. Ghazi + * calls.c (store_one_arg): Mark any slots used for the argument + as in-use immediately after we're done saving any slots which + will be overwritten by this argument. - * system.h: Define the STRINGIFY macro here. - * protoize.c: Not here. - * gengenrtl.c (DEF_RTL_EXPR): Use the STRINGIFY macro. +Tue Feb 16 21:02:07 1999 Anton Hartl -Tue May 12 00:47:33 1998 John Wehle (john@feith.com) + * rs6000.md (call_value): Fix typo. - * varasm.c (assemble_variable): Compute the alignment of the data - earlier so that both initialized and uninitialized variables are - effected by DATA_ALIGNMENT. - * tm.texi (DATA_ALIGNMENT): Updated appropriately. +Wed Feb 17 01:29:07 1999 J"orn Rennecke -Mon May 11 19:57:58 1998 Jeffrey A Law (law@cygnus.com) + * loop.c (strength_reduce): Calculate maybe_dead before + calling recombine_givs. - * mips.c: Prototype static functions. +Wed Feb 17 00:43:12 1999 J"orn Rennecke -Mon May 11 17:43:03 1998 Jim Wilson + * loop.c (strength_reduce): Dump biv increment -> giv conversions. - * regmove.c (fixup_match_2, find_matches, regmove_profitable): - Add explanatory comments. +Tue Feb 16 15:31:39 1999 Ovidiu Predescu - * sparc.h (SPARC_INCOMING_INT_ARG_FIRST): Support TARGET_FLAT. + * objc/objc-act.c (encode_type): Encode the type instead of + encoding the mode of the type (patch from Richard Frith-Macdonald + ). -Mon May 11 17:24:27 1998 Richard Henderson +Tue Feb 16 10:53:51 1999 Richard Earnshaw (rearnsha@arm.com) - * sparc.md (ffsdi2): Disable. Simplify the expression as well. + * config/arm/arm.md (*zeroextractqi_compare0_scratch): Re-add load + instruction killed in previous change. Simplify mask generation. + (*zeroextractsi_compare0_scratch): Simplify mask generation. -Mon May 11 13:30:44 1998 Jim Wilson +Tue Feb 16 09:52:26 1999 Nick Clifton - * varasm.c (make_decl_rtl): Disable April 1 change. + * config/arm/arm.md (zeroextractqi_compare0_scratch): Ensure that + bitfield does not overflow a byte boundary. -Mon May 11 09:14:41 1998 Richard Henderson +Tue Feb 16 01:37:33 1999 Charles G Waldman - * configure.in (alpha-*-linux-gnu): Undo lossage from gcc2 merge. + * c-common.c (shorten_compare): Get the min/max value from the + underlying type of an enumeration, not the enumerated type itself. -Mon May 11 08:24:18 1998 Richard Henderson +Mon Feb 15 23:04:48 1999 Jeffrey A Law (law@cygnus.com) - * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'. - * alpha.c (print_operand): Handle it. - * alpha.md (fix_truncdfsi2, fix_truncsfsi2): New patterns and - related define_splits. Also add peepholes for SImode reload - plus sign_extend lossage. + * jump.c: Include insn-attr.h. + (delete_computation): If reload has completed and insn scheduling + after reload is enabled, then do not depend on REG_DEAD notes. + * Makefile.in (jump.o): Depend on insn-attr.h. -Mon May 11 09:33:10 1998 Kaveh R. Ghazi +Mon Feb 15 16:57:38 1999 Richard Henderson - * genattr.c: Include stdarg.h/varargs.h. Change function - `fatal' to use variable arguments instead of faking it with - integer parameters. Provide a prototype which also - checks the format specifiers using ATTRIBUTE_PRINTF_1. + * i386.md (addsi3): Allow lea for any constant_p. - * genattrtab.c: Likewise. - * gencodes.c: Likewise. - * genconfig.c: Likewise. - * genemit.c: Likewise. - * genextract.c: Likewise. - * genflags.c: Likewise. - * genopinit.c: Likewise. - * genpeep.c: Likewise. - * genrecog.c: Likewise. - * genoutput.c: Likewise. Similarly for function `error'. +1999-02-15 Zack Weinberg -Sun May 10 02:27:03 1998 Kaveh R. Ghazi + * toplev.c (documented_lang_options): Remove -fident and + -fnoident, which are now handled by the language independent + option parser. - * acconfig.h (HAVE_VOLATILE): Insert stub for autoconf. - * alocal.m4 (GCC_C_VOLATILE): New autoconf test. - * configure.in: Use GCC_C_VOLATILE. - * system.h (volatile): Define as empty if no volatile support is - available. +1999-02-15 Zack Weinberg -Sun May 10 01:21:43 1998 Jeffrey A Law (law@cygnus.com) + * c-common.c (UNGETC [USE_CPPLIB=1]): Do nothing if c is EOF. + * c-lex.c: Likewise. + * cpplib.c (cpp_push_buffer, cpp_pop_buffer): Use a linked + list in malloced memory for the buffer stack. + (cpp_get_token): Don't pop the last buffer off the stack. + Calls after CPP_EOF has been returned produce CPP_EOF with no + state change. + (cpp_finish): Pop last buffer here. + (do_line): Don't free ip->last_nominal_fname if it is equal to + ip->fname. + (special_symbol): If a T_CONST is the empty string, push a + single `@ ' escape instead. + (macroexpand): Special symbol buffers have escapes too. + * cpplib.h (struct cpp_buffer): Remove unused fields, add prev + buffer pointer. + (struct cpp_reader): Remove buffer_stack. Add + buffer_stack_depth. + (CPP_PREV_BUFFER, CPP_NULL_BUFFER): Buffer stack is now a + linked list. + +Mon Feb 15 14:44:53 1999 Kaveh R. Ghazi + + * cccp.c: Don't define HOST_WIDE_INT. Replace all occurrences of + WIDE_INT with WIDEST_INT. - * genemit.c (output_add_clobbers): Removed unused variable 'i' from - generated fucntion. + * cexp.y: Likewise. + Don't define unsigned_HOST_WIDE_INT, CHAR_BIT or + HOST_BITS_PER_WIDE_INT. Replace occurrences of PRINTF_PROTO_1() + style with PVPROTO() ATTRIBUTE_PRINTF_1 style macros. Replace + occurrences of "unsigned_HOST" with "unsigned HOST". Provide a + definition of variable `c89' when compiling a test binary and set it. -Sat May 9 02:02:15 1998 Richard Henderson + * system.h: Don't define the PRINTF_PROTO_* macros. - * loop.c (get_condition): Don't combine when either compare is MODE_CC. - * alpha.c (alpha_emit_conditional_branch): New function. Taken from - the body of beq; additionally set the mode of the branch to CCmode for - FP compares and not fast_math. - (alpha_emit_conditional_move): Always use a compare insn for FP - when not fast_math, as well as setting CCmode on the cmov. - * alpha.md (beq, bne, blt, et al): Call alpha_emit_conditional_branch. +Mon Feb 15 11:33:51 1999 Jeffrey A Law (law@cygnus.com) - * machmode.h (COMPLEX_MODE_P): New macro. + * loop.c (mark_loop_jump): Handle LO_SUM. If we encounter something + we do not understand, mark the loop and containing loops as invalid. -Sat May 9 01:53:23 1998 Richard Henderson +Mon Feb 15 00:40:45 1999 J"orn Rennecke - * haifa-sched.c (print_exp): Fix typo. + * alias.c (init_alias_analysis): Avoid self-referential value + when setting reg_known_value from REG_EQUAL notes. -Fri May 8 21:48:50 PDT 1998 Jeff Law (law@cygnus.com) +Sun Feb 14 23:12:10 1999 Richard Henderson - * version.c: Bump for snapshot. + * i386.c (legitimate_address_p): Verify modes of base and index. -Fri May 8 18:23:08 1998 Michael Meissner - - * final.c (final_scan_insn): Call fatal_insn instead of abort if - we could not split an insn when required to. - - * m32r.md ({add,sub}di3): Add define_splits and appropriate low - level insns. - (peepholes): Disable peepholes that call dead_or_set_p. - (movsi): Rewrite to handle addresses better after last change. - Add define_split to split load of addresses in large/medium modes. - (prologue): Call m32r_expand_prologue. - (movsi_{push,pop}): Generators for push/pop. - (movsi): Support PRE_{INC,DEC}, POST_INC. - (mov{di,df}): Rewrite. Always split the insns. - (movsf): Add define_split to get register load in correct mode. - (cmp_ne_small_const_insn): Use 'N' instead of 'S' constraint. - (attributes): Rewrite attributes so that type indicates both the - type and the length of the insn directly. - (all insns): Change to use new type attributes. - (debug): New attribute to convey whether -mdebug was used. - (opt_space): New attribute to convey whether -Os was used. - (function units): Loads are 3 cycles, not 2. Better classify all - insns into short/long. - (load/store/extend insns): Add separate case for load/store - indirect operations without an offset. - (divsi3): Division is a long operation, not short. - - * m32r.h (LEGITIMATE_LO_SUM_ADDRESS_P): Do not allow LO_SUM for - modes > 1 word. - (GO_IF_MODE_DEPENDENT_ADDRESS): LO_SUM is now mode dependent. - (CONST_OK_FOR_LETTER_P): Make 'N' handle reverse 8 bit compares. - (EXTRA_CONSTRAINT): Remove 'S' special support. Add 'U' for - operands with PRE_{INC,DEC}, POST_INC. - (FUNCTION_PROFILER): Call abort instead of doing nothing. - (GO_IF_LEGITIMATE_ADDRESS): Allow PRE_{INC,DEC}, POST_INC of - SImode variables. - (gen_split_move_double): Declare. - (EXTRA_CONSTRAINT): Add 'T' for memory reference with no offset. - - * m32r.c (gen_split_move_double): Fix typo. Also, don't call - emit_move_insn, build up SET's directly. - (toplevel): Include system.h, not stdio.h. - (move_double_src_operand): Allow any DF or DI mode constant. - (gen_split_move_double): Split moves of DI or DF values into the - appropriate moves, loads, or stores. Don't handle use of auto - inc/dec if using dead index. Do handle overlapping moves, etc. - (m32r_frame_info): Remove prologue_size field. - (m32r_compute_frame_size): Don't calculate prologue size. - (m32r_output_function_prologue): Change to pretty much a NOP. - (m32r_expand_prologue): Expand prologue as a series of INSNs. - (m32r_print_operand): Add support for PRE_{INC,DEC}, POST_INC. - (m32r_print_operand_address): Ditto. - -Fri May 8 14:13:21 1998 H.J. Lu (hjl@gnu.org) - - * reload1.c (emit_reload_insns): When performing expensive - optimizations, do not output the last reload insn if OLD is - not the dest of NSN and is in the src and is clobbered by INSN. - -Fri May 8 09:47:29 1998 Kaveh R. Ghazi - - * Makefile.in (genrtl.o): Depend on system.h. - * gengenrtl.c (gencode): When creating genrtl.c, have it - include system.h. - -Fri May 8 10:57:33 1998 Andreas Schwab - - * config/m68k/t-linux: Remove extra stuff already included in - config/t-linux. - -Fri May 8 09:53:24 Paul Eggert - - * fixinc.wrap: Renamed from fixinc.math. Put wrapper around - curses.h if it contains `typedef char bool;', as suggested by - Manfred Hollstein . - - * configure.in: Rename fixinc.math to fixinc.wrap. - -Thu May 7 19:26:34 1998 Jim Wilson - - * gcc.c (read_specs): Handle missing blank line at end of specs file. - - * i386.md (movsicc, movhicc, movsicc_1, movhicc_1, movsfcc_1, - movdfcc_1): Disable. - -Thu May 7 15:39:14 1998 Jim Wilson - - * configure.in (enable_threads): Rename to enable_threads_flag before - main loop. Set enable_threads to enable_threads_flag inside main - loop. - -Thu May 7 17:38:03 1998 Michael Meissner - - * r6000/eabi.asm (__eabi): Restore LR in case __eabi is called - multiple times. - -Thu May 7 14:26:05 1998 Kaveh R. Ghazi - - * aclocal.m4 (GCC_FUNC_VFPRINTF_DOPRNT): New macro. - - * configure.in: Add a call to GCC_FUNC_VFPRINTF_DOPRNT. - (AC_CHECK_HEADERS): Remove unused check for varargs.h,sys/varargs.h. - (AC_CHECK_FUNCS): Remove unused check for vprintf. - - * Makefile.in: Add support for linking in vfprintf.c and doprint.c. - (cccp.o): Depend on gansidecl.h. - (cexp.o): Likewise. - - * cccp.c: Convert from using PRINTF_ALIST/PRINTF_DCL to VPROTO as - per the rest of gcc source. - * cexp.y: Likewise. Include gansidecl.h and remove all code made - redundant. - - * cccp.c: Remove checks for HAVE_VPRINTF and the associated code - used when vfprintf is missing. - * cexp.y: Likewise. - * gcc.c: Likewise. - * genattrtab.c: Likewise. - * mips-tfile.c: Likewise. - * toplev.c: Likewise. +Sun Feb 14 23:01:28 1999 Richard Henderson - * vfprintf.c: New file. - * doprint.c: New file. + * i386.c (legitimate_pic_address_disp_p): Remove static. + * i386.h (LEGITIMATE_PIC_OPERAND_P): Use it instead of + open-coding cases. -Thu May 7 10:18:41 1998 Jeffrey A Law (law@cygnus.com) +Sun Feb 14 21:03:28 1999 Jeffrey A Law (law@cygnus.com) - * config/linux.h (ASM_COMMENT_START): Remove from here, - * config/linux-aout.h (ASM_COMMENT_START): and here, - * config/i386/linux.h (ASM_COMMENT_START): to here, - * config/i386/linux-aout.h (ASM_COMMENT_START): and here. - * config/i386/linux-oldld.h (ASM_COMMENT_START): Define - here as '#' too. + * except.c (start_catch_handler): Use emit_cmp_and_jump_insns. + * explow.c (probe_stack_range): Likewise. + * expmed.c (do_cmp_and_jump): Likewise. + * expr.c (store_expr, expand_expr, expand_builtin): Likewise. + (do_tablejump): Likewise. + * stmt.c (expand_expr_stmt, expand_end_case): Likewise. + (do_jump_if_equal, emit_case_nodes): Likewise. + * optabs.c (emit_cmp_and_jump_insns): Clarify comments. If UNSIGNEDP, + then convert comparison to an unsigned code before emitting the jump. + (expand_float, expand_fix): Use emit_cmp_and_jump_insns. -Thu May 7 10:55:59 1998 Andreas Schwab +Sun Feb 14 02:24:15 1999 Jeff Law (law@cygnus.com) - * config/m68k/m68k.md (adddi3, subdi3): Properly negate the DImode - constant. + * version.c: Bump for snapshot. -Wed May 6 22:32:37 CDT 1998 Robert Lipe +Sun Feb 14 01:15:04 1999 Jeff Law (law@cygnus.com) - * Makefile.in (dwarfout.o) Add toplev.h dependency. - * dwarfout.c, i386.c: Include toplev.h - * toplev.h: (pfatal_with_name) Add prototype. + * version.c: Bump for snapshot. -Wed May 6 19:02:29 1998 Jason Merrill +Sun Feb 14 00:45:50 1999 Jeffrey A Law (law@cygnus.com) - * Makefile.in: Fix .SUFFIXES. + * loop.c: Disable recent loop changes. Temporary as Joern + continues to fix problems. -Wed May 6 19:31:32 1998 Alan Modra +Sat Feb 13 23:29:42 1999 Richard Henderson - * config/linux.h (ASM_COMMENT_START): Define as "#". - * config/linux-aout.h (ASM_COMMENT_START): Likewise. + * loop.c (combine_givs_used_by_other): Delete. + (combine_givs_benefit_from): Delete. + (combine_givs): Deny combination of givs only used once. Simplify + code with the death of combine_givs_benefit_from. -Wed May 6 15:51:39 1998 Jim Wilson +Sun Feb 14 11:24:05 1999 Michael Hayes - * objc/Make-lang.h (objc-parse.o): Add toplev.h dependency. - * objc/objc-parse.y, objc/objc-parse.c: Regenerate. + * loop.c (scan_loop): Call reg_in_basic_block_p before + loop_reg_used_before_p. - * toplev.c: Include toplev.h. - * Makefile.in (c-common.o, c-convert.o, c-decl.o, c-iterate.o, - c-lex.o, c-parse.o, c-pragma.o, c-typeck.o, calls.o, convert.o, - dwarf2out.o, except.o, expr.o, final.o, fold-const.o, function.o, - hash.o, profile.o, real.o, reg-stack.o, regclass.o, reload.o, - reload1.o, stmt.o, stor-layout.o, tlink.o, tree.o, varasm.o): Add - toplev.h dependency. +Sat Feb 13 05:32:00 1999 Richard Earnshaw (rearnsha@arm.com) - * mips/mips.c (save_restore_insns): Change FRAME_POINTER_REGNUM to - HARD_FRAME_POINTER_REGNUM. + * arm.md: Use gen_rtx_FOO instead of gen_rtx (FOO, ...). + * arm.h: Likewise. + * arm.c: Likewise. - * expr.c (target_temp_slot_level): Delete duplicate definition. + * arm.h (TARGET_OPTIONS): Reformat for clarity. + (GO_IF_LEGITIMATE_ADDRESS): When generating PIC, references to symbols + in the constant pool aren't valid. + (LEGITIMATE_PIC_OPERAND_P): Likewise. -Wed May 6 16:46:01 1998 Jeffrey A Law (law@cygnus.com) + * arm.c: Include "system.h", not stdio.h and string.h. - * stmt.c (mark_seen_cases): Make it have external linkage again. - * expr.h (mark_seen_cases): Add declaration, but only when tree.h - has been included. +Fri Feb 12 13:06:28 1999 Jim Wilson - * haifa-sched.c (print_value, case SUBREG): Fix typo. + * stmt.c (expand_return): Return if optimize_tail_recursion succeeded. + (optimize_tail_recursion): Change return type from void to int. + Add return statements. + * tree.h (optimize_tail_recursion): Change prototype to match. - * i386.c (output_387_binary_op): Add some braces to avoid warnings. - * i386.h (REG_CLASS_CONTENTS): Similarly. +Fri Feb 12 21:09:51 1999 J"orn Rennecke - * toplev.c (-fsched-max): Delete flag. - (-fsched-interblock-max-blocks,-fsched-interblock-max-insns): Likewise. - * haifa-sched.c: Remove -fsched-max-N, -fsched-interblock-max-blocks-N - and -fsched-interblock-max-insns-N support. Remove INTERBLOCK_DEBUG - conditionals. + * reload.c (find_reloads_subreg_address): New function, broken out of + find_reloads_toplev. + (find_reloads_toplev, find_reloads_address_1): Use it. - * haifa-sched.c (find_rgns): Correctly handle reducible loops with - inner loops which are not reducible. +Fri Feb 12 13:20:52 1999 Jeffrey A Law (law@cygnus.com) - * loop.c (regs_match_p): Fix typo in prototype. + * h8300.md (zero_extendhisi2 H8/300 variant): Correctly handle + extending a CONST_INT. - * regmove.c (try_auto_increment): Wrap declaration inside an - #ifdef AUTO_INC_DEC. + * h8300.md (peephole for combining memrefs): Delete incorrect peephole. -Wed May 6 17:07:47 1998 Michael Meissner +Fri Feb 12 18:29:11 1999 J"orn Rennecke - * final.c (output_operand_lossage): Call fatal with the operand - lossage message instead of calling abort. + * loop.c (loop_insn_first_p, biv_elimination_giv_has_0_offset): + New functions. + (maybe_eliminate_biv_1): Use biv_elimination_giv_has_0_offset. -Wed May 6 15:37:27 1998 Kaveh R. Ghazi +Fri Feb 12 16:56:10 1999 J"orn Rennecke - * c-common.c: Convert to using ctype macros defined in system.h. - * c-lex.c: Likewise. - * cccp.c: Likewise. - * collect2.c: Likewise. - * rs6000.c: Likewise. - * cpplib.c: Likewise. - * fix-header.c: Likewise. - * gcc.c: Likewise. - * gen-protos.c: Likewise. - * pexecute.c: Likewise. - * protoize.c: Likewise. - * rtl.c: Likewise. - * scan.c: Likewise. - * stmt.c: Likewise. - * tlink.c: Likewise. - * toplev.c: Likewise. + * loop.c (load_mems): Don't guess how to do a load / store, use + emit_move_insn. -Wed May 6 14:44:14 1998 Gavin Koch +Fri Feb 12 09:24:26 1999 Kaveh R. Ghazi - * config/mips/r3900.h (SUBTARGET_ASM_DEBUGGING_SPEC) : - Replace -gdwarf-2 with -g0. + * system.h: Provide a definition for HOST_WIDEST_INT, etc. -Wed May 6 11:43:18 1998 Kaveh R. Ghazi +Fri Feb 12 23:37:26 1999 Michael Hayes - * Makefile.in (mips-tfile.o, mips-tdump.o): Depend on system.h. - * mips-tdump.c: Include system.h, remove redundant headers. - * mips-tfile.c: Likewise. Also, convert all ctype function calls - to calls of the macro versions defined in system.h. + * config/c4x/c4x.c (c4x_address_cost): Revert 9 Feb change. - * objc/Make-lang.in (objc-act.o): Depend on system.h. - * objc/objc-act.c: Include system.h, remove redundant headers. +Fri Feb 12 00:51:26 1999 Jeffrey A Law (law@cygnus.com) -Wed May 6 11:21:06 1998 Kaveh R. Ghazi + * reload.c (find_reloads_address_1): Fix handling of an autoincremented + pseudo which is homed in the stack. - * configure.in (AC_CHECK_FUNCS): Add isascii. - (GCC_NEED_DECLARATIONS): Add atof. + * mips.c (save_restore_insns): Fix loop to save/restore FP registers. + (compute_frame_size): Change loop over FP regs to be consistent + with the loop in save_restore_insns. - * system.h: Provide prototypes for abort, atof, atol and sbrk here. - * rtl.c, rtl.h, toplev.c, tree.h: Not here. +Thu Feb 11 17:38:40 1999 Jim Wilson -Wed May 6 10:52:49 1998 Kaveh R. Ghazi + * i960/i960.h (OVERRIDE_OPTIONS): Warn if -mlong-double-64 is used. + (LONG_DOUBLE_TYPE_SIZE): Undef then unconditionally define to 96. - * system.h: Wrap time.h and sys/file.h in autoconf checks. - Provide default definitions for O_RDONLY and O_WRONLY here. +Thu Feb 11 15:11:35 1999 Jeffrey A Law (law@cygnus.com) - * cccp.c, cpplib.c, fix-header.c, gcc.c, protoize.c: Not here. + * mn10200.md (bset); Re-enable. -1998-05-06 Mark Mitchell +Thu Feb 11 15:20:49 1999 J"orn Rennecke - * tree.h (IS_EXPR_CODE_CLASS): Remove bogus '3'. + * sh.md (is_sfunc): New attribute. + * sh.h (INSN_SETS_ARE_DELAYED, INSN_REFERENCES_ARE_DELAYED): Use it. -Wed May 6 06:35:38 1998 Robert Lipe +Thu Feb 11 01:06:49 1999 Nathan Sidwell - * toplev.h: New file. Protypes for functions in toplev.c. - * tree.h, rtl.h: Deleted protos for functions in toplev.c. - * c-common.c, c-convert.c, c-decl.c, c-iterate.c, c-lex.c, - c-parse.in, c-parse.y, c-pragma.c, c-typeck.c, calls.c, - convert.c, dwarf2out.c, except.c, expr.c, final.c, fold-const.c, - function.c, hash.c, profile.c, real.c, reg-stack.c, regclass.c, - reload.c, reload1.c, stmt.c, stor-layout.c, tlink.c, tree.c, - varasm.c: include it. + * fold-const.c (range_binop): Take account of the bounded nature + of fixed length arithmetic when comparing unbounded ranges. -Wed May 6 01:09:01 1998 Jeffrey A Law (law@cygnus.com) - Jim Wilson (wilson@cygnus.com) +Thu Feb 11 00:08:17 1999 John Wehle (john@feith.com) - * haifa-sched.c (find_rgns): In no_loops case, fix test for leaf - blocks. Check for 1 successor which is the EXIT_BLOCK. + * function.c (assign_stack_temp_for_type): Clear best_p + when an exact match is found. - * haifa-sched.c (find_rgns): Detect unreachable blocks, including - unreachable loops with more than one block. + * i386.h (LOCAL_ALIGNMENT): Define. + * function.c (assign_stack_local, assign_outer_stack_local): Use it. + (assign_stack_temp_for_type): New function based on assign_stack_temp. + (assign_stack_temp): Call it. + (assign_temp): Use assign_stack_temp_for_type, not assign_stack_temp. + * stmt.c: Use assign_temp, not assign_stack_temp. + * tm.texi: Document LOCAL_ALIGNMENT. -Wed May 6 08:22:24 1998 Manfred Hollstein +Wed Feb 10 23:28:28 1999 Jeffrey A Law (law@cygnus.com) - * fix-header.c (write_rbrac): Add "abort" to functions which need to - be protected. + * reorg.c: Finish deleting half-deleted comment. -Wed May 6 00:09:36 1998 Jeffrey A Law (law@cygnus.com) +Wed Feb 10 17:12:21 1999 Jim Wilson - * Check in merge from gcc2. See ChangeLog.12 for details. + * emit-rtl.c (operand_subword): Sign extend REAL_VALUE_TO_TARGET_SINGLE + result. + * final.c (split_double): Sign extend REAL_VALUE_TO_TARGET_DOUBLE + result. + * real.c (endian): Delete sign extension code. + * config/m32r/m32r.md (movsf_insn+1): REAL_VALUE_TO_TARGET_SINGLE call + replaced with operand_subword call. -Tue May 5 14:33:49 1998 Jim Wilson +Wed Feb 10 15:16:39 1999 Richard Henderson - * c-common.c (scan_char_table): Separate 's' and 'c'. 'c' does not - accept 'a' flag. 'S' does accept 'a' flag. - (check_format_info): When pedantic, warn for m/C/S/a/A formats, - and `a' flag. + * alpha.md (cmov compound patterns): Delete. Jump can now + create the correct constructs in the first place. - * elf64.h (MULTILIB_DEFAULTS): Move definition after mips.h include. +Wed Feb 10 11:03:22 1999 Richard Henderson -Tue May 5 10:50:39 1998 Andreas Schwab + * configure.in (alphaev6*): Fix typo in target_cpu_default2. - * config/m68k/m68k.h: Declare functions from m68k.c used in - macros and machine description. - (ASM_OUTPUT_LONG_DOUBLE): Always use `l' flag in print format for - long values. - (ASM_OUTPUT_FLOAT): Likewise. - (ASM_OUTPUT_FLOAT_OPERAND): Likewise. +Wed Feb 10 13:59:18 1999 Dave Brolley -Tue May 5 01:28:12 1998 Jason Merrill + * mbchar.c (local_mb_cur_max): Handle the case where MB_CUR_MAX is 0. - * tree.def: Add NAMESPACE_DECL. - * dwarfout.c (type_ok_for_scope): Ignore NAMESPACE_DECLs for now. - * dwarf2out.c (push_decl_scope): Likewise. - (scope_die_for): Likewise. - * tree.c (decl_function_context): Use TREE_CODE_CLASS to determine - how to get next context level. +Wed Feb 10 10:35:05 1999 Jim Wilson -Tue May 5 01:43:16 1998 Jim Wilson + * tmp-emsgids.c: Delete. - * i386.c (output_fix_trunc): Add code to emulate non-popping DImode - case. +Wed Feb 10 09:57:08 1999 Mark Mitchell -Tue May 5 01:15:06 1998 Jeffrey A Law (law@cygnus.com) + * rtlanal.c (for_each_rtx): Fix declaration to conform to GNU + coding standards. - * h8300.h (ADDITIONAL_REGISTER_NAMES): Add "er" registers. +Wed Feb 10 10:09:41 1999 Jeffrey A Law (law@cygnus.com) - * reorg.c (fill_slots_from_thread): Update REG_DEAD/REG_UNUSED notes - for any insns skipped at the start of a block because they were - redundant. + * mn10200.md (bset, bclr): Operand 0 is a read/write operand. -Mon May 4 20:23:51 1998 Jim Wilson + * reload1.c (reload_combine_note_store): Second argument is no + longer unused/ignored. Handle multi-register hard regs. + (move2add_note_store): Simplify. - * alpha.h (DBX_CONTIN_LENGTH): Decrease to 3000. +Wed Feb 10 10:05:23 1999 Mumit Khan -1998-05-04 Ulrich Drepper + * collect2.c (collect_execute): Remove cygwin-specific code. - * c-common.c (format_char_info): Add new field hhlen. - (print_char_table, scan_char_table, time_char_table): Initialize - hhlen field appropriately. - (char_format_info): Recognize hh modifier and lookup correct char - table entry. +Tue Feb 9 17:27:29 1999 Nathan Sidwell -Mon May 4 19:15:29 1998 Jim Wilson + * system.h (_, N_): Remove dummy i18n macros. + * protoize.c: Move inclusion of intl.h to after system.h. + * cexp.y: Include intl.h. + * cexp.c: Rebuilt. - * expr.c (expand_expr, case INDIRECT_REF): Don't optimize string - reference if this is a store. +Tue Feb 9 16:52:22 1999 Mumit Khan -Mon May 4 17:25:17 1998 Richard Henderson + * i386/cygwin.h (SUBTARGET_OVERRIDE_OPTIONS): New macro to ignore + fpic/fPIC for windows32 targets. + * i386/xm-cygwin.h (GET_ENV_PATH_LIST): Replace '\\' in windows32 + paths with '/'. + * i386/mingw32.h (CPP_SPEC): Define. + (CPP_PREDEFINES): Add MINGW32 version id. + * i386/crtdll.h (CPP_PREDEFINES): Likewise. - * sparc.c (output_move_quad): Fix typo in mov_by_64 argument. + * Makefile.in (collect2$(exeext)): Delete redundant dependency and + add missing exeext to target. -Sun May 3 23:57:25 1998 Robert Lipe + * gcc.c (convert_filename): Handle null filename argument. - Make UnixWare 7 bootstrap support work with final shipping product. - * configure.in: (i[34567]86-*-sysv5): append, not overwrite, xm_file. - Pick up xm-siglist and xm-alloca. - (xm_defines): Add USG so dbxout will build. - * configure: Regenerate. +Wed Feb 10 15:46:10 1999 Michael Hayes -Sun May 3 13:51:34 PDT 1998 Richard Henderson - - Support for official Sparc V9 ABI: - * sparc.c (sparc_override_options): Force stack bias off for !arch64. - Care for flag_pcc_struct_return default. - (output_move_quad): Rewrite to move by halves on v9 and in the - proper direction. - (move_quad_direction): New function. - (output_fp_move_quad): Use it to determine the direction of copy. - (function_arg_slotno): Return -1 for FP reg overflow as well. - (function_arg_record_value*): New functions. - (function_arg): Use them. Streamline unprototyped parameter passing. - (function_arg_pass_by_reference): Pass TCmode by reference. - (function_value): New function. - * sparc.h (PTRDIFF_TYPE, SIZE_TYPE): For -pedantic's sake, don't use - long long in 64-bit mode. - (RETURN_IN_MEMORY): v9 returns structs < 32-bytes in regs. - (DEFAULT_PCC_STRUCT_RETURN): Make the default detectable. - (BASE_RETURN_VALUE_REG): Consider complex float types for arch64. - (BASE_OUTGOING_VALUE_REG, BASE_PASSING_ARG_REG): Likewise. - (BASE_INCOMING_ARG_REG): Likewise. - (FUNCTION_VALUE): Call function_value. - (FUNCTION_OUTGOING_VALUE, LIBCALL_VALUE): Likewise. - * sparc.md (movdi_sp32_v9): Disable for arch64. - (movsf, movdf, movtf): Sort all ulternatives using fp regs first. - (call_value_address_sp64): Remove register class constraints. - (call_value_symbolic_sp64): Likewise. - (nonlocal_goto): Pass label reg directly to goto_handlers. Constrain - v9 case to 32-bit constants. - (goto_handler_and_restore_v9): Provide a version for arch64. - * sparc/linux64.h (SIZE_TYPE, PTRDIFF_TYPE): Remove private definition. - * sparc/sp64-aout.h (TARGET_DEFAULT): Turn on stack bias. - (CPP_PREDEFINES): New. - * sparc/sp64-elf.h: Likewise. - (PREFERRED_DEBUGGING_TYPE): Dwarf2. - (ASM_OUTPUT_DWARF2_ADDR_CONST): New. - * sparc/sysv4.h (SIZE_TYPE, PTRDIFF_TYPE): Undo svr4.h's changes. - -Sat May 2 17:47:17 PDT 1998 Jeff Law (law@cygnus.com) + * config/c4x/c4x.md (*movhf_noclobber, *movhi_noclobber): Use + m constraint instead of QT. - * version.c: Bump for snapshot. +1999-02-09 Brendan Kehoe -Sat May 2 01:37:29 1998 J"orn Rennecke + * cpplib.c (special_symbol): Move IP to be declared in function + scope, rather than individual case statements. - * reload.c (find_reloads): Emit USEs to mark where a pseudo - is reloaded with the MEM of its stack slot. - * reload1.c (cannot_omit_stores): Delete. - (reload): Don't initialize it. - Don't apply avoid_return_reg logic to USEs. - When done, remove USEs that have a REG_EQUAL note on them. - (emit_reload_insns): Handle case where we have inherited a MEM. - (choose_reload_regs): Likewise. - (delete_output_reload): Don't use cannot_omit_stores. +1999-02-09 Zack Weinberg -Thu Apr 30 18:59:03 1998 Jim Wilson + * cppfiles.c (finclude): Handle pipes properly under old BSD + derivatives. - * Makefile.in (cpp.info, gcc.info): Put -o option before input file. +1999-02-09 Melissa O'Neill -Thu Apr 30 16:57:34 1998 Michael Meissner + * system.h: Provide fallback definitions for S_ISCHR, + S_ISSOCK, S_ISFIFO, O_NONBLOCK, and O_NOCTTY. - * haifa-sched.c (print_{exp,value}): Various changes to make the - debug output easier to read. Also, use only one buffer, and make - sure the buffer we are passed in doesn't overflow. - (safe_concat): Concatenate to a buffer without overflow. +1999-02-09 Zack Weinberg -Thu Apr 30 16:57:34 1998 Kaveh R. Ghazi + * cpplib.c (do_define): Allow redefining __STDC__ with -D. - * haifa-sched.c (alloc_{INSN,EXPR}_LIST): Make static to agree - with the prototype. +1999-02-09 Jim Blandy -Wed Apr 29 21:45:16 1998 J"orn Rennecke + * configure.in: For PowerPC configurations, accept "401", "ec603e", + "740", and "750" as valid arguments to --with-cpu. + * configure: Rebuilt. - * sched.c (new_insn_dead_notes): Check if the register was - used in the original instruction. - * haifa-sched.c (new_insn_dead_notes): Likewise. +Tue Feb 9 00:00:14 1999 Mark Kettenis -Wed Apr 29 13:46:03 1998 Jim Wilson + * configure.in (i[34567]86-*gnu*): Set float_format to i386. + * configure: Rebuilt. - * dwarf2out.c (scope_die_for): If could not find proper scope, - check for and handle tagged type with incorrect TYPE_CONTEXT. +Mon Feb 8 22:38:24 1999 Jeffrey A Law (law@cygnus.com) -Wed Apr 29 15:34:40 1998 John Carr + * rs6000.md: Revert "alternate use of crs if cr0 not available" + patches from 01-22-1999, 01-24-1999, 01-26-1999, and 02-08-1999. - * calls.c (expand_call): Fix recognition of C++ operator new. +Mon Feb 8 21:36:44 1999 Richard Henderson - * alias.c (mode_alias_check): Disable type based alias detection. + * output.h (current_function_has_computed_jump): Rename from + current_function_addresses_labels. + * function.h (struct function): Likewise for addresses_labels member. + * rtl.h (FUNCTION_FLAGS_HAS_COMPUTED_JUMP): Likewise. + * function.c (current_function_has_computed_jump): Likewise. + Update all references. + * integrate.c (function_cannot_inline_p): + Test current_function_has_computed_jump instead of addresses_labels. + (initialize_for_inline): Likewise save. + (output_inline_function): Likewise restore. -Wed Apr 29 15:06:42 1998 Gavin Koch + * expr.c (expand_expr): Don't reference addresses_labels variables. + * stmt.c (expand_computed_goto): Set has_computed_jump. - * config/mips/elf.h (ASM_OUTPUT_DEF,ASM_WEAKEN_LABEL, - ASM_OUTPUT_WEAK_ALIAS): Define. - * config/mips/elf64.h: Same. - * config/mips/r3900.h (ASM_OUTPUT_DEF,SUPPORTS_WEAK, - ASM_WEAKEN_LABEL): Removed. +1999-02-08 Michael Meissner -Wed Apr 29 10:53:29 1998 Andreas Schwab + This is being installed only to get it into the repository to help + with the revert, resubmit & review process for the massive rs6000.md + changes. + * rs6000.md (andsi3_internal1 splitter): Don't split if using the + rlwinm instruction. + (anddi3_internal1): Likewise. + (andsi3_internal{2,3}): Correct some insn lengths. + (anddi3*): Restore missing TARGET_POWERPC64, and don't emit old + mnemonics. + +Mon Feb 8 21:31:06 1999 Richard Henderson + + * loop.c (reg_single_usage): New file-scope variable ... + (scan_loop): ... moved out of here. Always initialize. + Test loop_has_call instead of reg_single_usage not zero. + Free reg_single_usage after strength reduction. + (count_loop_regs_set): Assume single_usage non-zero. + (combine_givs_used_by_other): Test reg_single_usage. + (load_mems_and_recount_loop_regs_set): Remove reg_single_usage + as a parameter. Assume non-zero. + +1999-02-08 Zack Weinberg + + * cpplib.c (special_symbol): Rewrite. Don't copy things + multiple times. Handle __STDC__ specially. T_CONST + indicates a constant /string/. Don't handle T_*_TYPE and + T_SPEC_DEFINED. Use cpp_buf_line_and_col instead of + adjust_position. Determine the file buffer only if needed. + (initialize_builtins): Handle __SIZE_TYPE__, + __PTRDIFF_TYPE__, __WCHAR_TYPE__, __USER_LABEL_PREFIX__, and + __REGISTER_PREFIX__ with T_CONST special hashtab entries. + Don't provide __OBJC__; the driver does that. Provide + __STDC_VERSION__, using T_CONST. Use T_STDC for + __STDC__. Give install the length of all symbols defined. + (eval_if_expression): Drop code to insert and remove the + "defined" special symbol. + + * cpplib.h: Remove SELF_DIR_DUMMY (no longer used). Remove + T_*_TYPE and T_SPEC_DEFINED from enum node_type; add T_STDC. + + * cpphash.c (install): Drop the `ivalue' parameter. Constify + the `value' parameter. All callers changed. + * cpphash.h (install): Change prototype to match. + (union hashval): Remove `ival' member. + * cppexp.c (cpp_lex): Handle `defined' here. + +Mon Feb 8 17:29:42 1999 Jeffrey A Law (law@cygnus.com) + + * pa.h (EXTRA_CONSTRAINT): Fix comment. + +Mon Feb 8 18:57:45 1999 Vladimir N. Makarov + + * c-typeck.c (check_init_type_bitfields): Use nonincremental + initialization of unions whose first member is a bitfield. + Remove unnecessary code for checking the declaration mode + after DECL_C_BIT_FIELD. + + * varasm.c (output_constructor): Additional comment about the + constructor of bitfield union initialization. + +Tue Feb 9 11:55:04 1999 Michael Hayes + + * config/c4x/c4x.md (*movhi_stik): New pattern. + (movhi): Allow some immediate constants to be directly + stored in memory. + +Tue Feb 9 11:34:15 1999 Michael Hayes + + * config/c4x/c4x.md (all call patterns): Add constraints "Ur". + (call, call_value): Force address into a register if not valid + for a call instruction. + (load_immed_address): Emit a USE of the SYMBOL_REF that is + forced into memory. + * config/c4x/c4x.c (c4x_print_operand): Fix 'C' and 'U' modifiers. + +Tue Feb 9 11:08:41 1999 Michael Hayes + + * config/c4x/c4x.c (call_address_operand, symbolic_address_operand): + Rename from call_operand and symbolic_operand respectively. All + callers changed. + * config/c4x/c4x.md (call_address_operand, symbolic_address_operand): + Likewise. + * config/c4x/c4x.h (call_address_operand, symbolic_address_operand): + Likewise. + (PREDICATE_CODES): Allow CONST, LABEL_REF for call_address_operand. - * calls.c (expand_call): Bump the length limit on the specially - recognized function names to 17. +Tue Feb 9 10:52:27 1999 Michael Hayes -Tue Apr 28 17:53:33 1998 Jim Wilson + * config/c4x/c4x.c (c4x_legitimize_address): Don't generate a + LO_SUM address for HImode or HFmode but instead force address into + a register so that it is offsettable. + (c4x_emit_move_sequence): Handle LO_SUM immediate address. - * ginclude/stddef.h: Add check for _MACHINE_ANSI_H_ for BSD/OS - when undefining macros at the end. +Tue Feb 9 10:46:42 1999 Michael Hayes - * expr.c (expand_builtin, case BUILT_IN_MEMSET): Break if either - val or len has TREE_SIDE_EFFECTS set. + * config/c4x/c4x.c (c4x_address_cost): Return cost of 1 for + REG+REG addressing if strength reduction enabled. - * sparc.md (mulsidi3): Call const v8plus and v8plus routines. - (mulsidi3_v8plus, const_mulsidi3_v8plus): Delete asterisk from name. - (smuldi3_highpart): Call const v8plus routine. - (smulsi3_highpart_v8plus): Renamed from smulsidi3_highpart_v8plus. - (const_smulsi3_highpart_v8plus): New pattern. - (smulsi3_highpart_sp32): Renamed from smulsidi3_highpart_sp32. - (umulsidi3): Call const v8plus routine. - (umulsi3_highpart): Handle const before v8plus. Call const v8plus - routine. - (umulsi3_highpart_v8plus): Renamed from umulsidi3_highpart_v8plus. - (umulsi3_highpart_sp32): Renamed from umulsidi3_highpart_sp32. +Tue Feb 9 10:10:31 1999 Michael Hayes -Tue Apr 28 08:55:26 1998 Michael Meissner + * config/c4x/t-c4x (LIBGCC2_CFLAGS): Delete. + (TARGET_LIBGCC2_CFLAGS): Define. - * m32r.c (*_oper{and|ator}): Change enum arguments and return - values to int, so they can be prototyped even in files that don't - include rtl.h. - ({small,large}_insn_p): Ditto. - (m32r_select_cc_mode): Ditto. - (gen_compare): Ditto. - (function_arg_partial_nregs): Ditto. - (m32r_setup_incoming_varargs): Ditto. - (init_reg_tables): Add prototype. - (m32r_frame_info): Add prolog_size field. - (m32r_compute_frame_size): Calculate the size of the prologue. - (m32r_first_insn_address): Return prologue size. - (m32r_output_function_prologue): Calculate frame size before - printing out information. Print out the prologue size. +1999-02-08 Nick Clifton - * m32r.h: Prototype all functions in m32r.c. - (FIRST_INSN_ADDRESS): Declare, returning prologue size. + * config/v850/v850.md: Replace \\n\\t with \\; - * m32r.md (bcc functions): Cast enum's to int. + * config/v850/v850.md: Enforce TARGET_LONG_CALLS option. + * config/v850/v850.c (construct_restore_jr, construct_save_jarl): + Enforce TARGET_LONG_CALLS option. - * m32r.c (conditional_move_operand): Silence a debug message. - ({small,long}_insn): New predicates. +Mon Feb 8 11:43:07 1999 Donn Terry - * m32r.h (TARGET_M32R): New macro. - (PREDICATE_CODES): Rearrange somewhat, add small_insn/long_insn. - (HAIFA_P): Define as 1/0 depending on whether the Haifa scheduler - was selected. - (ISSUE_RATE): Define as 2. + * real.c (PUT_REAL) [XFmode]: Zero the balance of the structure. - * m32r.md (insn_size): New attribute. - ({,rev_}branch_insn): Add .s qualifier to branches believed to be - short. - (m32r): New attribute. +Mon Feb 8 11:37:24 1999 Marc Espie (espie@cvs.openbsd.org) - * configure.in (enable_haifa): Switch m32r to Haifa by default. - * configure: Regenerate. + * m88k/t-luna-gas: Remove bash dependency. - (Changes from Nick Clifton ) - * m32r.h (EXTRA_CONSTRAINT): Implement 'S' constraint to perfoirm - the equivalent of a negated 'I' constraint. - (PRESERVE_DEATH_INFO_REGNO_P): Define in order to allow peephole - optimisation to work. +Mon Feb 8 11:34:44 1999 Graham - * m32r.md (cmp_ne_small_const_insn): Use 'S' constriant rather - than 'I' since the value is negated. - (peephole): Add peephole optimisation to cope with optimization of - divide and subtracts of the same operands. + * collect2.c (xrealloc): Fix typo in last change. - * m32r.c zero_and_one, emit_cond_move): Add support for MVFC. - * m32r.h: Ditto. - * m32r.md: Ditto. +Mon Feb 8 09:13:38 1999 Jeff Law (law@cygnus.com) - * m32r.h (PREDICATE_CODES): Add declaration of machine specific - predicates. + * version.c: Bump for snapshot. -Tue Apr 28 07:25:53 1998 Manfred Hollstein +Sun Feb 7 22:18:42 1999 Robert Lipe - * Makefile.in (libgcc2.ready): Revert last patch (Apr 24). + * tree.h (TYPE_CHECK): Make it clear to the preprocessor + that we do not want macro replacement within a character constant. + (TYPE_CHECK1): Likewise. -Mon Apr 27 18:39:47 1998 Nick Clifton +Sun Feb 7 15:37:10 1999 Jason Merrill - * config/arm/thumb.h (GO_IF_LEGITIMATE_ADDRESS): Check against - frame_pointer_rtx not FRAME_POINTER_REGNUM. + * tree.h (DECL_P): New macro. -Mon Apr 27 18:36:28 1998 Jim Wilson +Sun Feb 7 01:15:04 1999 Jeff Law (law@cygnus.com) - * reg-stack.c: Revert last patch (Apr 20). - (convert_regs): Set insn to PREV_INSN (next) after do while loop. + * version.c: Bump for snapshot. - * m68k/lb1sf68.asm (Laddsf$3): Fix typos in mcf5200 exg code. +Sat Feb 6 18:14:46 1999 Jeffrey A Law (law@cygnus.com) + + * mn10300.md (reload_insi): Do not earlyclobber the output operand. + + * README.g77, gcc.c, gcc.texi: Update email addresses. + * invoke.texi system.h: Likewise. + +Sat Feb 6 11:04:08 1999 Jim Wilson + + * unroll.c (find_splittable_givs): After express_from, call replace_rtx + to convert dest_reg to new_reg. + +Sat Feb 6 10:31:35 1999 Jeffrey A Law (law@cygnus.com) + + * reload1.c (reload_combine_note_store): Be more careful with + STRICT_LOW_PART, ZERO_EXTRACT and SIGN_EXTRACT. + (move2add_note_store): Likewise. + +Sat Feb 6 10:18:01 1999 Kaveh R. Ghazi + + * cppfiles.c (read_and_prescan): Cast the result of `xrealloc' to + U_CHAR* when assigning to one. Ensure the values of a ?: operator + have the same type. + + * cppinit.c (initialize_char_syntax): Use K&R function definition. + +Sat Feb 6 11:17:03 1999 Richard Earnshaw + + Support for ARM9 + * config/arm/arm.c (all_procs): Add arm9 and arm9tdmi. + * config/arm/arm.h ((TARGET_CPU_arm9, TARGET_CPUD_arm9tdmi): Define. + (TARGET_CPU_DEFAULT): Rework to support ARM9. + (CPP_CPU_ARCH_SPEC): Likewise. + (enum processor_type): Likewise. + * config/arm/arm.md (attr cpu): Add arm9. + + General scheduling changes + * config/arm/arm.c (MAX_INSNS_SKIPPED): Delete. + (max_insns_skipped): New variable. + (arm_override_options): If generating hard floating point code for + the FPA, emit code for version 3. + When optimizing for space, don't synthesize constants. + Reword several flags based on the requested processor and optimization + level. + (use_return_insn): New argument iscond, all callers changed. Don't + use a return insn if it will be conditional and that would be + expensive; eg on StrongARM. + (arm_adjust_cost): Anti- and output- dependencies normally have no + cost. + (load_multiple_sequence): Newer ARMs don't benefit from ldm if + the sequence is short. + (final_prescan_insn): Use max_insns_skipped instead of + MAX_INSNS_SKIPPED. Note whether we will make a return instruction + conditional, and aviod this if it would be expensive. + * config/arm/arm.md (scheduling attributes and function units): + Rewrite to better describe ARM8, 9 and StrongARM. + + * config/arm/arm.md (*movhi_insn_littleend): Make op0 predicate + s_register_operand. + (*ifcompare_plus_move): Use arm_rhs_operand in place of + arm_rhsm_operand. Rework constraints. + (*if_plus_move): Likewise. + (*ifcompare_move_plus): Likewise. + (*if_move_plus): Likewise. + (*ifcompre_arith_move): Likewise. + (*if_arith_move): Likewise. + (*ifcompare_move_arith): Likewise. + (*if_move_arith): Likewise. + + * config/arm/xm-netbsd.h: Don't include arm/xm-arm.h. + +1999-02-05 Michael Meissner - * loop.c (check_dbra_loop): New locals jump, first_compare, and - compare_and_branch. Call get_condition to set first_compare. - Set compare_and_branch to number of compare/branch instructions. - Replace PREV_INSN (PREV_INSN (loop_end)) with first_compare. - Replace '2' with compare_and_branch. + * loop.c (check_dbra_loop): A store using an address giv for which + we have no life information is not reversible. -Mon Apr 27 15:53:30 EDT 1998 Andrew MacLeod +Fri Feb 5 17:08:01 1999 Dave Brolley - * cplus-dem.c (demangle_qualified): Replace missing else. + * function.c (fixup_var_refs): Scan catch_clauses too. -Mon Apr 27 20:22:08 1998 J"orn Rennecke +Fri Feb 5 11:49:49 1999 Benjamin Kosnik - * sh.c (gen_ashift_hi): Don't make SUBREG of a SUBREG. + * c-common.c (decl_attributes): Fix reserved space for init_priority. + * tree.h (MAX_RESERVED_INIT_PRIORITY): New macro. -Mon Apr 27 18:23:51 1998 J"orn Rennecke +Fri Feb 5 12:37:05 1999 Jeffrey A Law (law@cygnus.com) - * sh.c (sh_expand_prologue, sh_expand_epilogue): - If TARGET_DOUBLE_ALIGN, preserve 64 bit stack alignment. - * sh.h (STACK_BOUNDARY): Likewise. + * loop.c (strength_reduce): Clear not_every_iteration when + passing the NOTE_INSN_LOOP_CONT note. -Mon Apr 27 17:22:48 1998 J"orn Rennecke + * haifa-sched.c (add_dependence): Do not add a dependency on a + note. - * sh.h (LEGITIMIZE_RELOAD_ADDRESS): Define. +Fri Feb 5 10:55:43 1999 Nick Clifton -Mon Apr 27 08:55:23 1998 Michael Meissner + * recog.c (split_block_insns): Only call update_flow_info if + instruction scheduling is enabled. - * system.h (abort): If abort is not defined, and neither is - USE_SYSTEM_ABORT, redefine abort to call fprintf and exit, - reporting the line and filename of the error. +1999-02-05 Zack Weinberg - * .gdbinit: Add breakpoints on exit and fancy_abort. + * Makefile.in (gen-protos): Use libcpp.a like everyone else. - * final.c (split_double): Avoid a compiler warning if - BITS_PER_WORD is less than or equal to HOST_BIT_PER_WIDE_INT. +Fri Feb 5 07:09:29 1999 J"orn Rennecke - * rtl.h (JUMP_{CROSS_JUMP,NOOP_MOVES,AFTER_REGSCAN}): New macros - for calling jump_optimize. + * loop.c (first_loop_store_insn): New file-scope variable. + (prescan_loop): Set it. + (check_dbra_loop): Check if a store depends on a register + that is set after the store. - * toplev.c (rest_of_compilation): Call jump_optimize using JUMP_* - macros, rather than 0/1's. +Fri Feb 5 06:55:15 1999 J"orn Rennecke + + * unroll.c (entire file): Remove tabs / spaces at end of lines. + Replace spaces with tabs where appropriate. + +Thu Feb 4 15:12:41 1999 J"orn Rennecke + + * loop.c (scan_loop): New argument loop_cont. Changed caller. + (strength_reduce): New argument loop_cont. Changed caller. + Before clearing not_every_iteration after a label, check if + we are not already past LOOP_CONT. + +1999-02-04 Zack Weinberg + + * cpperror.c (cpp_print_containing_files): Fix formatting + bug induced by merge. + +1999-02-04 Zack Weinberg + + * cpplib.c (initialize_char_syntax): Move to cppinit.c. + (cpp_define): Remove redundant syntax checks. + (make_assertion): Rename cpp_assert, remove redundant syntax + checks, export. + (cpp_options_init): Don't init things to zero twice. + (cpp_expand_to_buffer): Use memcpy, not a char-by-char loop. + (do_include): Kill excessively verbose #import warning that + snuck back in in the gcc2 merge. + (convert_string): Removed. + (do_line): Rewrite with simple last-name-used cache instead of + private hashtable. + (cpp_start_read): Call initialize_char_syntax here, not... + (cpp_reader_init): ...here. + (cpp_handle_options): Support the -std switch. + * cpplib.h (cpp_buffer): Add last_nominal_fname member. + (cpp_options): Add c9x flag. + Declare all the is_* tables and trigraph table here, as const. + Prototype cpp_assert and initialize_char_syntax. + * cppinit.c: New file. + * cppfiles.c (read_and_prescan): Optimize. + * Makefile.in (LIBCPP_OBJS): Add cppinit.o. + +Thu Feb 4 10:46:30 1999 Gavin Romig-Koch + + * config/mips/mips.md ([u]divmodsi4,[u]divmoddi4,[u]divsi3,[u]divdi3, + [u]modsi3,[u]moddi3) : Don't copy the "zero" argument to a register + before calling gen_div_trap. + +Wed Feb 3 21:56:27 1999 Jeffrey A Law (law@cygnus.com) + + * configure.in (hppa1.1-*-*, hppa2*-*): Use symbolic value rather + than numeric value for target_cpu_default.. + * configure: Rebuilt. -Sun Apr 26 23:19:10 1998 Richard Henderson +Wed Feb 3 21:55:56 1999 Marc Espie + + * Makefile.in (xgcc$(exeext)): Remove choose-temp, pexecute and + mkstemp. Get them from libiberty. + (COLLECT2_OBJS): Similarly for choose-temp, cplus-dem and mkstemp. + (PROTO_OBJS): Similarly for choose-temp, getopt, getopt1 and pexecute. + (cplus-dem.o, pexecute.o, choose-temp.o): Remove build rules. + (mkstemp.o, getopt1.o, getopt.o): Likewise. + + * pa-gas.h (TARGET_DEFAULT): Use symbolic values rather than numeric + values. + * pa-hpux.h (LINK_SPEC): Likewise. + * pa-hpux10.h (LINK_SPEC): Likewise. + * pa-hpux9.h (LINK_SPEC): Likewise. + * pa-osf.h (LINK_SPEC): Likewise. + * pa-pro.h (TARGET_DEFAULT): Likewise. + * pa1.h (TARGET_DEFAULT): Likewise. + * pa.h (MASK_*): New defines. + (TARGET_*): Use symbolic values rather than numeric values. + (TARGET_SWITCHES): Likewise. + (TARGET_DEFAULT): Likewise. + (CPP_SPEC): Likewise. + +Wed Feb 3 21:07:38 1999 Bernd Schmidt + + * reload1.c (reload_cse_regs_1): Undo Jan 16 patch. + * reload.c (find_reusable_reload): New function, broken out of + push_reload. Add code to verify that none of the involved + outputs are subject to earlyclobbers. + (push_reload): Break out new function find_reusable_reload. + Delete "register" keyword for IN, OUT args. + +Wed Feb 3 15:51:04 1999 Gavin Romig-Koch + + * config/mips/mips.c (true_reg_or_0_operand) : New function. + * config/mips/mips.h (PREDICATE_CODES): Add true_reg_or_0_operand. + * config/mips/mips.md (div_trap,div_trap_normal,div_trap_mips16): + Use true_reg_or_0_operand for div_trap. + +Wed Feb 3 20:44:59 1999 J"orn Rennecke + + * loop.h (express_from): Declare. + (struct induction): Replace derived flag with derived_from pointer. + * loop.c (strength_reduce, record_giv, recombine_givs): Likewise. + (express_from): No longer static. + * unroll.c (find_splittable_givs): Replace derived with derived_from. + When processing an address giv with which another giv has been + combined that has also been derived from a third giv, handle like + having combined with the third giv. + Set splittable_regs_updates appropriately for derived givs. + +Wed Feb 3 15:26:58 1999 Gavin Romig-Koch + + * config/mips/mips.md (div_trap_mips16): Remove nop's after branches. + +Wed Feb 3 11:56:23 1999 Jeffrey A Law (law@cygnus.com) + + * pa.c (insn_sets_and_refs_are_delayed): New function. + * pa.h (INSN_SETS_ARE_DELAYED): Use it. + (INSN_REFERENCES_ARE_DELAYED): Likewise. + +Wed Feb 3 06:24:49 1999 Richard Earnshaw (rearnsha@arm.com) + + * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Delete. + * config/arm/t-linux (LIBGCC2_CFLAGS): Delete. + (TARGET_LIBGCC2_CFLAGS): Define. + (LIBGCC2_DEBUG_CFLAGS): Define. + * config/arm/t-netbsd: Likewise. + * config/arm/t-semi: Likewise. + * config/arm/t-semiaof: Likewise. + * config/arm/t-riscix: Likewise. + +Wed Feb 3 10:59:07 1999 Andreas Schwab + + * config/m68k/m68k.c (print_operand_address): When printing a + SYMBOL_REF that ends in `.' put parentheses around it. + +Tue Feb 2 23:38:35 1999 David O'Brien - * alpha.h (CONST_COSTS): Zero is always free. - (RTX_COSTS): Add EV6 costs. Abort if alpha_cpu is unknown. + * i386/freebsd*.h now allows '$' in label names and does not use the + PCC struct return method. -Sun Apr 26 15:38:50 1998 Andreas Schwab +Tue Feb 2 22:38:23 1999 Jim Wilson - * cplus-dem.c (gnu_special): Fix off-by-one bug when checking the - length in the name of a virtual table. + * Makefile.in: Change all uses of AR to AR_FOR_TARGET. Change all uses + of HOST_AR to AR. Likewise for AR_FLAGS, RANLIB, and RANLIB_TEST. + (RANLIB_TEST): Test to see if ranlib exists. Only test absolute file + names if host == target. + (HOST_AR, HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Delete. + (AR_FLAGS_FOR_TARGET): Renamed from AR_FOR_TARGET_FLAGS. + (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): Delete rules + setting them to *_FOR_TARGET. + * cross-make (AR, AR_FLAGS, OLDAR, OLDAR_FLAGS, RANLIB, RANLIB_TEST): + Delete. -Sun Apr 26 01:21:06 1998 Richard Henderson +Tue Feb 2 22:38:19 1999 Theodore Papadopoulo - * alpha.c (print_operand): Don't add 'v' suffix for ALPHA_FPTM_N. + * toplev.h (read_integral_parameter): Declare. + * toplev.c (read_integral_parameter): New function. -Sat Apr 25 22:11:38 PDT 1998 Jeff Law (law@cygnus.com) +Fri Jan 29 21:00:56 1999 Bob Manson - * version.c: Bump for snapshot. + * resource.c, resource.h: New files. + * Makefile.in (OBJS): Add it. -Sat Apr 25 17:17:15 1998 Jeffrey A Law (law@cygnus.com) + * haifa-sched.c (regno_use_in): Moved to rtlanal.c. + (split_block_insns): Moved to recog.c. + (update_flow_info): Make public. + * rtl.h: Declare them. - * fold-const.c (fold_convert): Fix typo. + * reorg.c: Moved the functions dealing with computing resource + usage to resource.c. -Sat Apr 25 17:55:54 1998 John Carr + * sched.c (regno_use_in): Moved to rtlanal.c. + (update_flow_info): Make public. + (schedule_insns): Use split_block_insns. - * alias.c (alias_invariant): New variable. - (record_base_value): New argument INVARIANT. - (memrefs_conflict_p): If a register has an entry in the alias_invariant - array, try substituting that value for the register. + * recog.c (split_block_insns): New function. - * rtl.h: Declare record_base_value. +Tue Feb 2 22:03:26 1999 David Edelsohn - * loop.c, unroll.c: Update callers of record_base_value. + * rs6000/linux.h (LINK_START_DEFAULT_SPEC): Delete, unused. + (LINK_OS_DEFAULT_SPEC): Delete, unused. - * alias.c (find_base_value, find_base_term): SIGN_EXTEND and - ZERO_EXTEND do not affect base values. +Tue Feb 2 20:29:34 1999 Catherine Moore -Fri Apr 24 15:57:02 1998 Jeffrey A Law (law@cygnus.com) + * configure.in (arm-*-oabi): Support. + * configure: Regenerate. + * config/arm/unknown-elf-oabi.h: New file. - * dbxout.c (dbxout_type): Fix typo. - (dbxout_range_type): Another HOST_WIDE_INT_PRINT_DEC fix. +Tue Feb 2 19:43:59 1999 Jeffrey A Law (law@cygnus.com) - * configure.in: Use CC_FOR_BUILD, not BUILD_CC. + * i386.md (ashlsi3): Turn into a define_expand an anonymous pattern. + Make the anonymous pattern match when ! optimize_size. + (ashlsi3 size optimizer): New pattern. -Fri Apr 24 16:11:47 1998 John Carr + * intl/Makefile.in (uninstall): Add missing "; \". - * expr.c (expand_builtin, case MEMSET): Set MEM_IN_STRUCT_P - if the argument is the address of a structure or array. +Tue Feb 2 18:21:23 1999 Stan Cox - * configure.in: Enable Haifa scheduler by default for SPARC. + * sparc.h (TARGET_CPU_sparc86x): Added. TARGET_CPU_sparclite86x + synonym. -Fri Apr 24 20:55:47 1998 J"orn Rennecke +Tue Feb 2 20:24:11 1999 J"orn Rennecke - * cse.c (cse_set_around_loop): Don't do optimization when - new pseudos are created. + * loop.c (loop_optimize): Fix value max_uid_for_loop is reset + to after find_and_verify_loops call. -Fri Apr 24 11:00:18 1998 Jeffrey A Law (law@cygnus.com) +Tue Feb 2 19:48:29 1999 J"orn Rennecke - * dbxout.c (dbxout_type_fields): Use HOST_WIDE_INT_PRINT_DEC - appropriately. - (dbxout_type_method_1, dbxout_type): Likewise. - (print_int_cst_octal, print_octal, dbxout_symbol): Likewise. - (dbxout_type): Fix check for when to print a type range in - octal vs decimal. + * (recombine_givs): Don't use a giv that's likely to be dead to + derive others. -Fri Apr 24 16:45:03 1998 J"orn Rennecke + * loop.c (recombine_givs): Fix test for lifetime overlaps / loop + wrap around when deriving givs. - * (gen_shl_and, in case 1): Fix comparison with mask. +Mon Feb 1 20:00:40 1999 Richard Henderson -Fri Apr 24 06:46:40 1998 Nick Clifton + * recog.c (check_asm_operands): Treat indeterminate operand ok + results as success. Try harder to resolve a matching constraint. + * stmt.c (expand_asm_operands): Recognize when an output operand's + constraint does not allow memory. Treat indeterminate operand ok + results as failure. Try harder to resolve a matching constraint. - * config/arm/thumb.h (GO_IF_LEGITIMATE_ADDRESS): Disallow frame - pointer as second register in REG+REG pair. +Mon Feb 1 15:00:02 1999 Ken Raeburn -Fri Apr 24 09:22:23 1998 Kaveh R. Ghazi + Use varrays for constant-equivalence data: - * c-common.c (check_format_info): Don't check for the 'x' format - character twice, instead check for 'x' and 'X' + * varray.h (struct const_equiv_data): New type. + (union varray_data_tag): New element const_equiv. + (VARRAY_CONST_EQUIV_INIT, VARRAY_CONST_EQUIV): New macros. + (VARRAY_SIZE): New macro, returns number of elements. + * integrate.h: Include varray.h. + (struct inline_remap): Replace const_equiv_map, const_age_map and + const_equiv_map_size with a const_equiv_varray element. + (MAYBE_EXTEND_CONST_EQUIV_VARRAY): New macro; grows varray if + needed. + (SET_CONST_EQUIV_DATA): New macro; sets rtx and age fields + simultaneously, growing the varray if needed. -Fri Apr 24 08:02:30 1998 Manfred Hollstein + * integrate.c (global_const_equiv_map, + global_const_equiv_map_size): Deleted, replaced by.... + (global_const_equiv_varray): New variable. + (expand_inline_function): References changed. + * integrate.h: Update declarations. - * Makefile.in (libgcc2.ready): Add explicit dependancy from - $(STMP_FIXPROTO) to ensure all necessary include files have - been created and to guarantee proper parallel builds. + * integrate.c (process_reg_parm, expand_inline_function, + copy_rtx_and_substitute, try_constants, subst_constants, + mark_stores): Use varray allocation and accessor macros, new + integrate.h macros, and global_const_equiv_varray. Don't + conditionalize non-NULL stores on array size; instead, expand the + array as needed. + * unroll.c (unroll_loop): Likewise. -Fri Apr 24 04:42:35 1998 J"orn Rennecke + * unroll.c (unroll_loop): Initialize const_equiv_varray element to + zero. After allocating varray, always exit through bottom of + function, where it can be deallocated if needed. Don't explicitly + reallocate const_equiv_map storage; instead, just ensure the + varray has been initialized, and update the global reference. - * sh.c (sh_expand_prologue, in !SH3E code): Don't push an extra - register for stdarg functions. - * sh.h (current_function_varargs): Declare. - (FUNCTION_ARG): Ignore NAMED for stdarg functions. +Mon Feb 1 09:40:25 1999 Kaveh R. Ghazi -1998-04-23 Jim Wilson + * system.h (inline, const): Handle these for stage2 (and later) gcc. - * frame.c, libgcc2.c (stdlib.h, unistd.h): Don't include when - inhibit_libc is defined. + * dwarf2out.c (inline): Don't define. - * c-aux-info.c (gen_type): Use DECL_NAME only for TYPE_DECL. + * dwarfout.c (inline): Likewise. -Thu Apr 23 19:09:33 1998 Jim Wilson +Sun Jan 31 22:04:37 1999 Richard Henderson - * profile.c (tablejump_entry_p): New function. - (branch_prob): Add code to recognize MIPS tablejump entry branch. - Use tablejump_entry_p in MIPS and HPPA tablejump checking code. + * loop.c (recombine_givs): Dump recombination and derivation data. -Thu Apr 23 15:01:13 1998 Nick Clifton +Sun Jan 31 20:34:29 1999 Zack Weinberg - * config/arm/arm.c (find_barrier): Return as soon as a barrier is - found, rather than at end of the loop, after the insn has been - changed. + * flags.h: Declare flag_no_ident. + * toplev.c: Define flag_no_ident. Process -f(no-)ident here. + * c-tree.h: Don't declare flag_no_ident. + * c-decl.c: Don't define flag_no_ident. Don't process + -f(no-)ident switches here. -Thu Apr 23 20:21:06 1997 J"orn Rennecke + * config/elfos.h (ASM_FILE_END): Output final .ident directive + only if !flag_no_ident. + * config/ptx4.h: Likewise. + * config/svr4.h: Likewise. + * config/alpha/elf.h: Likewise. + * config/arm/linux-elf.h: Likewise. + * config/i386/sco5.h: Likewise. + * config/i860/fx2800.h: Likewise. + * config/mips/gnu.h: Likewise. + * config/i386/osfrose.h: Likewise. - * sh.c (gen_ashift_hi): Implement right shifts via gen_ashift. - * sh.md (ashrhi3_k, lshrhi3_k, lshrhi3_m, lshrhi3, lshrhi3+1): Delete. + * gcc.c (C specs): Map -Qn to -fno-ident. + * objc/lang-specs.h: Likewise. -Wed Apr 22 17:07:35 1998 Michael Meissner +Mon Feb 1 10:52:07 1999 Michael Hayes + + * configure.in: Don't remove loop.o and unroll.o when + enable-haifa is selected. + * configure: Rebuilt. - * loop.c (note_addr_stored): Correct function to take 2 arguments, - instead of 1. +Sun Jan 31 13:22:02 1999 John Wehle (john@feith.com) - * rtl.def (MATCH_INSN2): Add new matching pattern. - * genrecog.c (add_to_sequence): Support MATCH_INSN2. + * i386.md (movsicc, movhicc, movsfcc, movdfcc, + movxfcc, movdicc): Delete unconstrained alternatives. + * i386.c (output_fp_conditional_move, + output_int_conditional_move): Delete unused case. -Wed Apr 22 15:52:22 1998 John Carr +Sun Jan 31 01:15:04 1999 Jeff Law (law@cygnus.com) - * emit-rtl.c (gen_highpart): The high part of a CONST_INT is not zero - if HOST_BITS_PER_WIDE_INT is larger than BITS_PER_WORD. + * version.c: Bump for snapshot. - * final.c (split_double): Sign extend both halves of a split CONST_INT. +Sun Jan 31 00:52:37 1999 Richard Henderson -Wed Apr 22 10:42:45 1998 Jeffrey A Law (law@cygnus.com) + * alpha.md (mov patterns): Emit the assembler aliases mov and fmov + instead of bis and cpys. Combine alternatives where possible. - * mips.c (compute_frame_size): Change only argument to a HOST_WIDE_INT. +Sat Jan 30 23:14:13 1999 Kaveh R. Ghazi -Wed Apr 22 10:53:49 EDT 1998 Andrew MacLeod + * gcov.c (fnotice): Add missing FILE* parameter. + (function_summary): Fix format specifiers in calls to `fnotice'. + (output_data): Likewise. - * cplus-dem.c (struct work stuff): Add field for B and K mangle codes. - (cplus_demangle_opname): Call mop_up_squangle. - (cplus_demangle): Initialize squangle info, then call - internal_cplus_demangle. (Most code moved there as well) - (internal_cplus_demangle): New function, performs most of what use - to be done in cplus_demangle, but is only called with this file. - (squangle_mop_up): New function to clean up B and K code data. - (mop_up): set pointers to NULL after freeing. - (demangle_signature, demangle_template, demangle_class): Add - switch elements to handle K and B codes. - (demangle_prefix, gnu_special, demangle_qualified): Add - code to handle K and B codes. - (do_type, demangle_fund_type): Handle B and K codes. - (remember_Ktype): New function to store K info. - (register_Btype, remember_Btype): New functions for B codes. - (forget_B_and_K_types): New function to destroy B and K info. + * toplev.c (fnotice): Constify char* parameter. -1998-04-21 Jim Wilson + * toplev.h (fnotice): Add prototype. + Wrap prototype with BUFSIZ to protect FILE* usage. - * stmt.c (check_seenlabel): When search for line number note for - warning, handle case where there is no such note. +Sun Jan 31 15:33:09 1999 Michael Hayes -Tue Apr 21 20:48:37 1998 John Carr + * config/c4x/c4x.h (RTX_COSTS): Explicitly define c4x costs. - * genemit.c (gen_exp): Allow machine description to set mode of - MATCH_OP_DUP. +Sat Jan 30 08:27:23 1999 Jeffrey A Law (law@cygnus.com) -Tue Apr 21 16:36:01 1998 John Carr + * combine.c (distribute_notes): Handle REG_EH_REGION notes. - * alias.c (mode_alias_check): New function. - (true_dependence, anti_dependence, output_dependence): Call - mode_alias_check. + * alias.c (fixed_scalar_and_varying_struct_p): Add "static" to + function definition. + (aliases_everything_p, write_dependence_p):Likewise. -Tue Apr 21 12:05:32 1998 Jeffrey A Law (law@cygnus.com) + * install.texi: Fix merge lossages. - * mips.h (STACK_BOUNDARY): Allow specific targets to override. - (MIPS_STACK_ALIGN): Similarly. + * cccp.c (main): Only call setlocale (LC_MESSAGES, ...) if LC_MESSAGES + is defined. + * collect2.c (main): Likewise. + * cppmain.c (main): Likewise. + * gcc.c (main): Likewise. + * gcov.c (main): Likewise. + * protoize.c (main): Likewise. + * toplev.c (main): Likewise. - * c-common.c (type_for_mode): Handle TI types. - * c-decl.c (intTI_type_node, unsigned_int_TI_type_node): Define. - (init_decl_processing): Handle TI types. - * c-tree.h (intTI_type_node, unsigned_int_TI_type_node): Declare. + * pa.md (parallel shift and shiftadd): Mark output of shift as an + earlyclobber. - * mips.c (block_move_loop): Test Pmode == DImode instead of - TARGET_MIPS64. - (expand_block_move, save_restore_insns): Likewise. - (function_prologue, mips_expand_prologue): Likewise. - (mips_expand_epilogue): Likewise. - * mips.h (POINTER_SIZE): Allow specific targets to override. - (Pmode): Allow specific targets to override. - (FUNCTION_PROFILER): Test Pmode == DImode instead of TARGET_MIPS64 - (POINTER_BOUNDARY, FUNCTION_MODE): Likewise. - (TRAMPOLINE_TEMPLATE, TRAMPOLINE_SIZE): Likewise. - (TRAMPOLINE_ALIGNMENT, INITIALIZE_TRAMPOLINE): Likewise. - (CASE_VECTOR_MODE, ASM_OUTPUT_ADDR_VEC_ELT): Likewise. - (ASM_OUTPUT_ADDR_DIFF_ELT, SIZE_TYPE, PTRDIFF_TYPE): Likewise. - * mips.md (indirect, tablejump & casesi support): Test for - Pmode == DImode instead of TARGET_MIPS64. - (call patterns): Likewise. + * loop.c: Disable recent loop changes. Temporary as Joern + continues to fix problems. -Tue Apr 21 09:43:55 1998 Kaveh R. Ghazi +Sat Jan 30 03:24:37 1999 J"orn Rennecke - * objc/sendmsg.c: Define gen_rtx_MEM() to 1, as is already done - for gen_rtx(MEM, ...). + * loop.c (strength_reduce): Size reg_map according to reg_iv_type. -Tue Apr 21 02:15:36 1998 Richard Henderson +Fri Jan 29 18:26:07 1999 Dave Brolley - * sparc.h (MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): Rewrite - to not be so gross, and to properly function with PIC. + * emit-rtl.c (remove_insn): New function. + * rtl.h (remove_insn): Add prototype. + * function.c (reposition_prologue_and_epilogue_notes): Call remove_insn. -Mon Apr 20 20:44:25 1998 Jim Wilson +Fri Jan 29 22:34:41 1999 J"orn Rennecke - * frame.c (heapsort): Rename to frame_heapsort. + * loop.c (recombine_givs): Don't try to derive givs that have combined. - * gcc.c (do_spec_1, case '['): Move flag out of loop and initialize it. +Fri Jan 29 15:00:39 1999 Kaveh R. Ghazi -Mon Apr 20 12:43:09 1998 Doug Evans + * toplev.c (notice, fnotice): Check ANSI_PROTOTYPES, not __STDC__, + when declaring arguments and calling va_arg() to initialize them. - * flow.c (sbitmap_vector_alloc): Ensure sbitmaps properly aligned. + * collect2.c (notice): Likewise. -Mon Apr 20 15:04:14 1998 John Wehle (john@feith.com) + * loop.c (find_life_end): Use PROTO() macro in the prototype. - * i386.md (movsf_push, movdf_push, movxf_push): Allow memory - operands during and after reload. +Fri Jan 29 14:36:11 1999 Kaveh R. Ghazi -Mon Apr 20 22:37:50 1998 J"orn Rennecke + * collect2.c (error): Fix typo in declaration. - * final.c (shorten_branches, init_insn_lengths): Move code - to free label_align, uid_shuid, insn_lengths, insn_addresses - and uid_align from the former function into the latter one; - Add code to clear these variables. - * sh.h (label_align): Remove declaration. + * cpperror.c (cpp_message): Likewise. -Mon Apr 20 14:48:29 1998 Michael Meissner + * cpplib.c (cpp_warning): Likewise. - * gcc.c (lang_specific_driver): Declare prototype properly so - fatal can be passed to it without error. + * cpplib.h (cpp_notice): Use PVPROTO not VPROTO, also add + ATTRIBUTE_PRINTF_1. - * configure.in (AC_CHECK_FUNCS): Check for strchr and strrchr. - * configure: Regenerate. - * config.in: Add #undef's for strchr and strrchr. + * toplev.c (error): Fix typo in declaration. - * protoize.c (toplevel): If we have rindex, but not strrchr, map - rindex to strrchr. - (file_could_be_converted): Use strrchr, not rindex since rindex is - not defined on Linux systems when _POSIX_SOURCE is defined. - (file_normally_convertible): Ditto. - (process_aux_info_file): Ditto. - (main): Ditto. +Fri Jan 29 15:44:13 1999 J"orn Rennecke - * rs6000.md (mov{sf,df} define_splits): When splitting a move of - a constant to an integer register, don't split the insns that do - the simple AND and OR operations, rather just split each word, and - let the normal movsi define split handle it further. + * loop.c (strength_reduce): Fix HAVE_cc0 handling when scanning + forward from cont dominator. -Mon Apr 20 18:19:40 1998 J"orn Rennecke +Fri Jan 29 07:10:27 1999 Kaveh R. Ghazi - * sh.c (find_barrier): Fix bug in ADDR_DIFF_VEC handling. - (split_branches): Call init_insn_lengths. + * cccp.c (eprint_string): Constify a char*. + (notice): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. + (vnotice): Constify a char*. + (error): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. + (verror): Constify a char*. + (warning): Likewise. Use PVPROTO not VPROTO, add ATTRIBUTE_PRINTF_1. + (vwarning): Constify a char*. + (error_with_line): Likewise. Use PVPROTO not VPROTO, add + ATTRIBUTE_PRINTF_2. + (verror_with_line): Constify a char*. + (vwarning_with_line): Likewise. + (warning_with_line): Likewise. Use PVPROTO not VPROTO, add + ATTRIBUTE_PRINTF_2. + (pedwarn): Constify a char*. Use PVPROTO not VPROTO, add + ATTRIBUTE_PRINTF_1. + (pedwarn_with_line): Likewise with ATTRIBUTE_PRINTF_2. + (pedwarn_with_file_and_line): Likewise with ATTRIBUTE_PRINTF_4. + Also correct typo in parameter name declaration. + (make_assertion): Constify a char*. + (quote_string_for_make): Likewise. + (deps_output): Likewise. + (fatal): Likewise. Use PVPROTO not VPROTO, add + ATTRIBUTE_PRINTF_1. Use ATTRIBUTE_NORETURN not an explicit + "__attribute__ ((noreturn))". + (fancy_abort): Likewise for ATTRIBUTE_NORETURN. + (pfatal_with_name): Likewise. + (pipe_closed): Likewise. + (memory_full): Likewise. -Mon Apr 20 07:37:49 1998 Michael Meissner +Fri Jan 29 00:14:55 1999 J"orn Rennecke - * i386.c: Include expr.h to get the change_address prototype - declared. + * loop.c (strength_reduce): Grow set_in_loop / n_times_set / + may_not_optimize to proper size when converting biv increments + into givs. + If necessary, reallocate reg_iv_type / reg_iv_info before calling + recombine_givs. -Mon Apr 20 01:00:05 1998 H.J. Lu (hjl@gnu.org) +Thu Jan 28 23:24:08 1999 J"orn Rennecke - * reg-stack.c (subst_asm_stack_regs): Change to return the last - new insn generated by this function. - (subst_stack_regs): Likewise. - (convert_regs): Record the last newly generated insn and use - it for change_stack () instead of INSN. + * loop.c (recombine_givs): New parameter unroll_p. If set, don't + generate complex adds. Changed caller. + Don't generate adds that cost more than the original one. + (strength_reduce): Warning fixes. -Sun Apr 19 15:41:24 1998 Manfred Hollstein +Thu Jan 28 09:41:11 1999 Jeffrey A Law (law@cygnus.com) - * fix-header.c (enum special_file): Undefine enumerators if they - are already defined by include files. - * fixproto (rel_source_file in unistd.h stdlib.h): Prefix file protection - macro with '__' to not pollute user namespace. + * configure.in (hppa1.0-hp-hpux10*): Use t-pa. + * configure: Rebuilt. -Sun Apr 19 02:42:06 1998 Richard Henderson +Wed Jan 27 23:39:53 1999 J"orn Rennecke + + * rtl.h (insn_first_p, no_jumps_between_p): Declare. + * rtlanal.c (insn_first_p, no_jumps_between_p): New function. + * loop.h (varray.h): Include. + (struct induction): Change combined_with to unsigned. + New members derived, ix and last_use. + (reg_iv_type, reg_iv_info): Now varray_type. All references changed. + (REG_IV_TYPE, REG_IV_INFO): Define. + (first_increment_giv, last_increment_giv): Declare. + * loop.c (loop_number_loop_cont): New static variable. + (loop_number_cont_dominator): Likewise. + (reg_iv_type, reg_iv_info): Now varray_type. + (first_increment_giv, last_increment_giv): New variables. + (compute_luids, verify_dominator, find_life_end): New functions. + (cmp_recombine_givs_stats, recombine_givs): Likewise. + (loop_optimize): Allocate loop_number_loop_cont and + loop_number_cont_dominator. Use compute_luids. + (find_and_verify_loops): Initialize loop_number_loop_cont and + loop_number_cont_dominator. + (strength_reduce): Try to find bivs that can be expressed as givs + of another biv, and to convert biv increments into givs. + Call recombine_givs. Handle derived givs. + (record_biv): New argument location. All callers changed. + (record_giv): Initialize derived and last_use fields. + (basic_induction_var): New argument location. All callers changed. + (combine_givs): Don't combine a DEST_REG giv with a DEST_ADDR giv. + Increment combined_with instead of setting to 1. + * unroll.c (derived_regs): New static variable. + (unroll_loop): Initialize it. + Allocate local_regno according to max_reg_num. + (copy_loop_body): Cope with derived givs. + (find_splittable_givs): Check for Givs made from biv increments. + Set derived_regs for givs. + * Makefile.in (stmt.o, loop.o, unroll.o): Depend on loop.h . + +Wed Jan 27 19:31:36 1999 J"orn Rennecke + + * function.c (purge_addressof_1): Handle case when a register + has been used in a wider mode. + +1999-01-27 Bruce Korb + + * fixinc/fixincl.c, fixinc/server.[ch]: + Removed the last of the capitalized variable and proc names. + + * fixinc/server.c: Removed the process open code. + * fixinc/procopen.c: New file containing the proc open code. + * fixinc/inclhack.tpl: Added code to bypass a readability test + when a file is not present. A problem on some systems. + * fixinc/inclhack.sh, fixinc/fixincl.sh: Regenerated. + +Wed Jan 27 11:58:18 1999 Dave Brolley + + * cpplib.h (cpp_notice): Add prototype. + +Wed Jan 27 02:20:48 1999 Jeffrey A Law (law@cygnus.com) + + * Merge gcc2 snapshot 19980929. + + * cccp.c (PRINTF_PROTO): Remove. + (PRINTF_PROTO_{1,2,3,4}: Likewise. + * cexp.y: Likewise. + * system.h: Add PRINTF_PROTO and PRINTF_PROTO_{1,2,3,4}. + + * fix-header.c (cpp_file_lin_for_message): Delete. In libcpp. + (cpp_print_containing_files, v_cpp_message, cpp_message): Likewise. + (cpp_fatal, cpp-Pfatal_with_name): Likewise. + + * gen-protos.c (hashf): Delete in cpphash.o. + * gen-protos.c (hashf): Delete in cpphash.o. + + * expr.c: Do not merge SAVE_STACKAREA_MODE changes. + * expmed.c: Likewise. + * rs6000.md: Likewise. + + * rs6000.c, rs6000.md: Do not merge formatting changes yet. + +Wed Jan 27 01:13:42 1999 Richard Henderson + + * rs6000.c (input_operand): Don't expect CONST around CONSTANT_P_RTX. + * rs6000.md (movsi, movdi): Likewise. + +Tue Jan 26 13:31:38 1999 Jim Wilson + + * function.c (expand_function_end): Pass arg_pointer_save_area to + validize_mem before using it. Emit code into a sequence. + +Tue Jan 26 13:41:38 1999 David Edelsohn + + * rs6000.md (doz + set cr and or + set cr patterns): Add missing + '#' to split patterns. Correct indentation of some new patterns. + +1999-01-26 Zack Weinberg + + * cppfiles.c (safe_read): Deleted. + (read_and_prescan): New function, replaces safe_read, converts + and/or warns about trigraphs, silently converts odd line + terminators (\r, \n\r, \r\n). Warns about no newline at EOF. + (finclude): Use read_and_prescan; turn off nonblocking mode on + the input descriptor; remove file-size-examination and + no-newline-at-EOF gunk which is longer necessary; be more + careful about checking that we've been handed a legitimate + file to read (only real files, pipes, and ttys are acceptable). + * cpplib.h (cpp_options): Rename no_trigraphs flag to + `trigraphs' and invert its sense. + (trigraph_table): Declare. + (cpp_warning_with_line): Prototype. + * cpplib.c: Remove all references to trigraph_pcp. Define + trigraph_table; initialize it in initialize_char_syntax. Open + files in nonblocking mode. s/no_trigraphs/trigraphs/ + throughout, and invert sense. Put cpp_warning_with_line back + in and export it. + +Tue Jan 26 23:21:49 1999 Michael Hayes + + * config/c4x/c4x.h (COUNTER_REGS): New register class. + * config/c4x/c4x.md (*rptb_init): Change constraints. + (rptb_end): Emit alternate looping instructions if + RC register not allocated for loop counter. + (decrement_and_branch_on_count): Allow other registers + for loop counter. + +1999-01-25 Zack Weinberg + + * cppexp.c (struct arglist): Removed. + (parse_number): Use HOST_WIDE_INT for the accumulator. + Allow two `l' suffixes unless C89. Clean up. Make static. + (parse_charconst): New function broken out of cpp_lex. + Code cleaned up drastically. Don't use a token_buffer. + (token_buffer): Removed. + (cpp_lex): Don't call parse_number on a constant string. + Use parse_charconst. + (cpp_parse_expr): Properly handle an ERROR op returned by + cpp_lex. + +1999-01-25 Zack Weinberg + + * cpplib.c: Don't include signal.h, sys/times.h, or + sys/resource.h. Don't declare localtime. + (macroexpand): Handle special symbols here. + (push_macro_expansion): Chop off the trailing '@ ' if possible + here. + (cpp_get_token): Don't do either of the above two things here. + Move `string' label just after case '"' so that wide strings + don't crash the preprocessor. + +Sun Jan 24 20:13:45 1999 David Edelsohn + + * rs6000.md (left shift + set cr patterns): Add missing '#' to + split patterns. + (move register + set cr pattern): Likewise. + (movdi, !TARGET_POWERPC64 splitters): Add back in Jan. 15th patch, + inadvertently deleted. + +Sun Jan 24 08:07:59 1999 Jeffrey A Law (law@cygnus.com) + + * stmt.c (stmt_loop_nest_empty): New function. + * tree.h (stmt_loop_nest_empty): Declare it. + * rtl.def (CALL_PLACEHOLDER): New rtx code. + +Sun Jan 24 21:24:43 1999 Michael Hayes + + * config/c4x/c4x.c (c4x_emit_move_sequence, c4x_encode_section_info): + New functions. + (c4x_check_legit_addr): Remove USE and PLUS, allow + LO_SUM, and disable SYMBOL_REF, LABEL_REF, and CONST cases. + (c4x_legitimize_address): Penalize SYMBOL_REF, LABEL_REF, and + CONST cases. Add LO_SUM. + (c4x_print_operand): Modified 'C' and 'R' cases for calls. + Added 'U' case. Remove dependence on SYMBOL_REF_FLAG. + (c4x_print_operand_address): Handle LO_SUM. + (c4x_scan_for_ldp): Delete. Hooray! + (c4x_process_after_reload): Remove call to c4x_scan_for_ldp. + Split all insns. + (c4x_immed_int_constant): Renamed from c4x_int_constant. All callers + changed. + (c4x_immed_float_constant): Renamed from c4x_float_constant. All + callers changed. + (c4x_T_constraint): Allow LO_SUM, disable SYMBOL_REF, LABEL_REF, + and CONST. + (c4x_U_constraint, symbolic_operand): New functions. + (src_operand): Allow 'I' constants in HImode. Allow LO_SUM, + disable SYMBOL_REF, LABEL_REF, and CONST. + (lsrc_operand, tsrc_operand): Call src_operand instead of + general_operand. + (c4x_operand_subword): Update comments. + + * config/c4x/c4x.c (TARGET_LOAD_ADDRESS): New macro. + (LEGITIMATE_CONSTANT_P): Allow SYMBOL_REF, LABEL_REF, CONST, + plus HIGH and LO_SUM for the C40. + (ENCODE_SECTION_INFO): Define macro. + (symbolic_operand, c4x_U_constraint, c4x_emit_move_sequence): New + prototypes. + (PREDICATE_CODES): Add symbolic_operand. - * haifa-sched.c (queue_to_ready): Fix typo in prototype. + * config/c4x/c4x.md (movqi, movgqf, movhi, movhi): Call + c4x_emit_move_sequence. + (floatunsqiqf2, fixuns_truncqfqi2): Rework emitted RTL + to avoid symbol references. + (all patterns with g constraint): Replace 'g' constraint with 'rIm'. + (set_high): Renamed from set_high_use. + (set_lo_sum): Renamed from set_ior_lo_use. + (all call patterns): Make MEM explicit in call address operands. + Modified output templates to use 'U' modifier. -Sat Apr 18 23:52:35 PDT 1998 Jeff Law (law@cygnus.com) +Sun Jan 24 01:15:05 1999 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. -Sat Apr 18 18:30:22 1998 Jim Wilson +Sat Jan 23 22:34:57 1999 Kaveh R. Ghazi + + * final.c (bb_str): Qualify a char* with the keyword `const'. + (add_bb_string, final_scan_insn, output_asm_insn): Likewise. - * i386.md (fix_truncsfdi2+[123]): Add + to operand 1 constraints. + * fix-header.c (read_scan_file): Likewise. - * i386.h (CPP_CPU_DEFAULT): Renamed to CPP_CPU_DEFAULT_SPEC. - Add missing -Dpentium* options. - (CPP_CPU_SPEC): Delete redundant definition. Include cpp_cpu_default - instead of CPP_CPU_DEFAULT. - (EXTRA_SPECS): Add entry for cpp_cpu_default. + * genoutput.c (output_epilogue, process_template): Likewise. -Sat Apr 18 19:06:59 1998 David Edelsohn + * local-alloc.c (requires_inout, block_alloc): Likewise. - * rs6000.md (floatsidf2_loadaddr): rs6000_fpmem_offset will be - negative in a stackless frame. - * rs6000.c (rs6000_stack_info): Don't include fixed-size link area - in stackless frame size. Support 64-bit stackless frame size. - Combine fpmem offset calculations and don't add total_size to - offset if not pushing a stack frame. + * output.h (output_asm_insn, assemble_string): Likewise. -Sat Apr 18 15:41:16 1998 Jim Wilson + * recog.c (recog_constraints, check_asm_operands, + decode_asm_operands, extract_insn, preprocess_constraints, + constrain_operands): Likewise. - * regmove.c (fixup_match_1): In three places, in flag_exceptions - check, change p to q. + * recog.h (operand_alternative, recog_constraints, insn_template, + insn_outfun, insn_operand_constraint, insn_name): Likewise. -Sat Apr 18 15:30:49 1998 Jim Wilson + * regclass.c (record_reg_classes, scan_one_insn): Likewise. - * gcc.c (lang_specific_driver): Add new parm type to prototype. - (added_libraries): New file scope static variable. - (process_command): Initialize added_libraries. Pass it to - lang_specific_driver. - (main): Use added_libraries in check for no input files. + * regmove.c (find_matches): Likewise. -Sat Apr 18 01:23:11 1998 John Carr + * reload.c (alternative_allows_memconst): Likewise. - * sparc.c, sparc.h, sparc.md, sol2.h: Many changes related to V9 - code generation. Use 64 bit instructions in 32 bit mode when - possible. Use V9 return instruction. UltraSPARC optimizations. + * reload1.c (constraint_accepts_reg_p, + reload_cse_simplify_operands): Likewise. - * sparc.h: Change gen_rtx (CODE to gen_rtx_CODE (. + * rtl.h (decode_asm_operands): Likewise. -Fri Apr 17 22:38:17 1998 Jeffrey A Law (law@cygnus.com) + * scan.h (fn_decl): Likewise. - * global.c (global_alloc): Don't pass HARD_CONST (0) to find_reg, - just pass zero. That will work regardless of the size of HARD_REG_SET. + * varasm.c (assemble_string): Likewise. - * libgcc2.c (__floatdisf): Fix a couple typos. +Sat Jan 23 01:37:36 1999 Jeffrey A Law (law@cygnus.com) -Fri Apr 17 17:28:26 1998 Jim Wilson + * configure.in (gcc_tooldir): Handle case where exec_prefix has + not been explicitly set. + * configure: Rebuilt. + + * fold-const.c (lshift_double): Mark 'prec' arguments as possibly + unused. - * Makefile.in (mostlyclean): Delete *.mach and *.bp files. + * bitmap.h (bitmap_head_def): Make indx field unsigned. -Fri Apr 17 16:35:35 1998 Greg McGary + * configure.in (gcc_tooldir): When not making a relative gcc_tooldir, + use $exec_prefix/$target_alias for gcc_tooldir. + * configure: Rebuilt. - * emit-rtl.c (gen_highpart): initialize `word' properly for pseudo. +Fri Jan 22 11:48:56 1999 Richard Henderson -Fri Apr 17 14:30:37 1998 John Carr + * cppp.c (xrealloc): Fix typo last change. + * cppalloc.c, gcc.c, genattr.c, genattrtab.c, gencodes.c: Likewise. + * genconfig.c, genemit.c, genextract.c, genflags.c: Likewise. + * genopinit.c, genoutput.c, genpeep.c, genrecog.c: Likewise. - * emit-rtl.c (operand_subword_force): If a register can not be - accessed by words, copy it to a pseudo register. +1999-01-22 Michael Meissner -Fri Apr 17 14:30:37 1998 Jim Wilson + * rs6000.h (CR0_REGNO_P): New macro to test if cr0. + (CR_REGNO_NOT_CR0_P): New macro to test if cr, but not cr0. + (PREDICATE_CODES): Add cc_reg_not_cr0_operand. + (cc_reg_not_cr0_operand): Add declaration. - * rs6000/vxppc.h (CPP_SPEC): Add support for mrelocatable*. + * rs6000.c (cc_reg_not_cr0_operand): Return true if register is a + pseudo register, or a control register that is not CR0. -Fri Apr 17 17:01:25 1998 Michael Meissner + * rs6000.md (all combiner patterns building . instructions): For + all `.' instructions that do something and set cr0, add an + alternative that does the operation, and then sets a different + flag, in order to avoid using the costly mcrf instruction and also + allow cr0 to be clobbered in asm statements. Also fix a few + patterns that used the wrong register. - * tree.h (mark_seen_cases): Delete declaration. + * rs6000.h (rs6000_cpu_select): Make string, names be const char *. + (rs6000_debug_name): Make const char *, not char *. -Fri Apr 17 13:32:20 1998 Jeffrey A Law (law@cygnus.com) + * sysv4.h (rs6000_{abi,sdata}_name): Make const char *. - * stmt.c (mark_seen_cases): Make static and add prototype. + * rs6000.c (rs6000_{debug,abi,sdata}_name): Make const char *. + (rs6000_select): Use const char * in casts. -Fri Apr 17 11:21:43 1998 Kaveh R. Ghazi +Fri Jan 22 07:43:01 1999 Jeffrey A Law (law@cygnus.com) - * frame.c: Include stdlib.h and unistd.h to possibly get various - function prototypes. The fixproto script guarantees these header - files exist on the target system. - * libgcc2.c: Likewise. + * Makefile.in (gcc_tooldir): Move before first reference. + Let autoconf substitute in a value. + * configure.in (gcc_tooldir): Only use a relative path to the + tool directory if $exec_prefix == $prefix. + * configure: Rebuilt. - * gthr-single.h (__gthread_mutex_lock, __gthread_mutex_trylock, - __gthread_mutex_unlock): Add __attribute__ ((__unused__)) to the - function parameters. - * libgcc2.c (__udiv_w_sdiv): Likewise. + * Makefile.in (tooldir): Replace with gcc_tooldir. -Thu Apr 16 22:41:02 1998 Jeffrey A Law (law@cygnus.com) +Thu Jan 21 23:21:57 1999 Jeffrey A Law (law@cygnus.com) - * varasm.c (asm_output_bss): Add prototype. - (asm_output_aligned_bss): Likewise. + * m68k.md (ashldi_const): Disable for !TARGET_5200. Fix indentation. + (ashldi3 expander): Similarly. Update comments. + (ashrdi_const, lshrdi_const): Fix indentation. + (ashrdi3, lshrdi3): Fix indentation. Update comments. - * unroll.c (verify_addresses): Add prototype. +Thu Jan 21 21:53:36 1999 Richard Henderson - * toplev.c: Add many prototypes. Too many to mention here. + * emit-rtl.c (try_split): Don't try to split non-instructions. - * stmt.c (check_seenlabel): Add prototype. +Thu Jan 21 23:47:30 1999 Andrew MacLeod - * rtlanal.c (reg_set_p_1): Add prototype. - (reg_set_last_1): Likewise. + * expr.c (emit_push_insn): Fix dumb typo. - * reorg.c (find_dead_or_set_registers): Add prototype. +Thu Jan 21 20:24:02 1999 Richard Henderson - * regmove (try_auto_increment): Add prototype. + * rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Recognize and accept + transformations that we have performed earlier. + * alpha.h (LEGITIMIZE_RELOAD_ADDRESS): Likewise. - * reg-stack.c (pop_stack): Add prototype. + * alpha.md (prologue_stack_probe_loop): Don't do our own label + handling, call gen_label_rtx instead. - * recog.c (validate_replace_rtx_1): Add prototype. - (find_cosntant_term_loc): Likewise. +Thu Jan 21 17:45:18 1999 Richard Henderson - * loop.c (regs_patch_p): Add prototype. - (add_label_notes, count_nonfixed_reads): Likewise. - (find_single_use_in_loop): Likewise. - (express_from): Surround prototype with #ifdef. - (giv_sort): Similarly. + * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): Add missing `then'. - * jump.c (mark_modified_reg): Add prototype. + * cccp.c (xrealloc): Call malloc given a NULL old pointer. + * collect2.c, cppalloc.c, gcc.c, genattr.c, genattrtab.c: Likewise. + * gencodes.c, genconfig.c, genemit.c, genextract.c: Likewise. + * genflags.c, genopinit.c, genoutput.c, genpeep.c: Likewise. + * genrecog.c, mips-tfile.c, protoize.c: Likewise. - * haifa-sched.c (is_prisky): Add prototype. - (queue_to_ready): Likewise. +Thu Jan 21 19:44:55 1999 Michael Meissner - * genextract.c (gen_insn): Add prototype. + * configure.in ({rs6000|powerpc}-ibm-aix4.[12]*): If + --with-gnu-ld, use x-aix41-gld instead of x-aix41 to suppress + adding -Wl,-bbigtoc to BOOT_LDFLAGS. + * configure: Regenerate. - * genemit.c (max_operand_1): Add prototype. - (max_operand_vec, print_code, gen_exp, gen_insn): Likewise. - (gen_expand, gen_explit, output_add_clobbers): Likewise. - (output_init_mov_optab): Likewise. + * config/rs6000/x-aix41-gld: New file, don't set BOOT_LDFLAGS. - * genattrtab.c (attr_hash_add_rtx): Add prototype. - (attr_hash_add_string, write_length_unit_log): Likewise. +Thu Jan 21 15:48:03 1999 Dave Brolley - * genattr.c (init_range): Add prototype. + * cppexp.c (cpp_lex): Allocate token_buffer dynamically. - * combine.c (sets_function_arg_p): Add prototype. +Thu Jan 21 14:18:04 1999 Andrew MacLeod - * expr.c (store_constructor_field): Add prototype. - (get_memory_usage_from_modifier): Likewise + * expr.c (MOVE_BY_PIECES_P): Define condition for deciding to use + move_by_pieces. + (MOVE_MAX_PIECES): Define maximum number of bytes to move at once. + (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT): Define defaults. + (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define defaults. + (move_by_pieces): Use new macros. + (emit_block_move): Use new macros. + (clear_by_pieces): Use new macros. + (clear_storage): Use new macros. + (emit_push_insn): Use new macros. + (expand_expr): Use new macros. + * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_LOAD_PRE_DECREMENT): + Define. + (USE_STORE_POST_INCREMENT, USE_STORE_PRE_DECREMENT): Define. + (MOVE_BY_PIECES_P): Define based on alignment and TARGET_SMALLCODE. + (MOVE_MAX_PIECES): Move 8 bytes on SH4. + * tm.texi(MOVE_BY_PIECES_P, MOVE_MAX_PIECES, USE_LOAD_POST_INCREMENT, + USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT, + USE_STORE_PRE_DECREMENT): Describe new macros. - * expmed.c (synth_mult): Add prototype. - (choose_multiplier, invert_mod2n): Likewise. +Thu Jan 21 14:13:31 1999 Vladimir N. Makarov - * except.c (push_eh_entry): Add prototype. - (pop_eh_entry, enqueue_eh_entry, dequeu_eh_entry): Likewise. - (call_get_eh_context, start_dynamic_cleanup): Likewise. - (start_dynamic_handler, can_throw): Likewise. - (output_exception_table_entry, scan_region): Likewise. - (eh_regs, set_insn_eh_region): Likewise. + * varasm.c (output_constant_pool): Use floor_log2 instead of + exact_log2 for ASM_OUTPUT_ALIGN. - * dwarfout.c (decl_class_context): Add prototype. - (output_inheritance_die, type_ok_for_scope): Likewise. + * stor-layout.c (layout_type): Do machine-dependent extra alignment. - * c-lex.c (skip_white_space_on_line): Add prototype. + * emit-rtl.c (operand_subword): Handle case when a subword outside + the operand. - * alias.c (record_set): Add prototype. - (find_base_term, base_alias_check): Likewise. + * tm.texi (ROUND_TYPE_{SIZE,ALIGN}): More accurate descriptions of + the macros. - * function.c (assign_outer_stack_local): Make static and add prototype. +Thu Jan 21 01:59:30 1999 Richard Henderson - * haifa-sched.c (build_control_flow): Accept raw data as inputs - instead of computing it locally. Callers changed. - (find_rgns): Several new arguments. Callers changed. - Generally clean up and comment better. Use dominators to - identify reducible loops. Convert some flag arrays to bitmaps. - Convert most of the code to work on pred/succ lists instead of - an edge table. Add comments for future improvements. - (schedule_insns): Allocate temporary tables for flow data, call - routines to compute flow data and pass it along to children as - arguments. - (debug_control_flow): Delete. Use dump_bb_data instead. + * cse.c (fold_rtx): Revert 29 Dec change. + (cse_insn): Revert 12 Jan change. + * expr.c (expand_builtin): Don't emit CONST around CONSTANT_P_RTX. + * regclass.c (reg_scan_mark_refs): Revert 29 Dec change. + * rtl.def: Likewise. + * rtl.h (CONSTANT_P): Likewise. - * basic-block.h (compute_dominators): Declare. + * expr.c (emit_move_insn): Never try to flush CONSTANT_P_RTX + to memory. + * recog.c (immediate_operand): Accept CONSTANT_P_RTX. + * alpha.c (input_operand): Likewise. + * c4x.c (const_operand): Likewise. - * flow.c (dump_sbitmap, dump_sbitmap_vector): New debugging - functions. - * basic-block.h: Declare them. + * explow.c (allocate_dynamic_stack_space): Use register_operand + instead of arith_operand, which does not exist. -Thu Apr 16 13:45:51 1998 Jim Wilson + * 1750a.h: Fix comment closure. + * a29k.c (a29k_set_memflags): Fix typo in 19 Jan change. + * arc.md (one_cmplsi2_set_cc_insn): Fix set mode mismatch. + * arm.h (TARGET_SWITCHES): Fix typo. + * i370.md (anon mult and div patterns): Fix set mode mismatch. + * i860.c (output_delayed_branch): Fix operands to constrain_operands. + (output_delay_insn): Likewise. + * m88k.md (anon rotate insns): Fix set mode mismatch. + (anon BLKmode moves): Commonize and fix set mode mismatches. + * ns32k.md (udivmoddi[shq]i4_internal): Fix mode mismatch. + * romp.md (movdf): Fix typo. - * reg-stack.c (constrain_asm_operands): Set n_alternatives to zero if - no operands. +Thu Jan 21 00:29:35 1999 Nathan Sidwell -Wed Apr 15 11:33:09 1998 Alexandre Petit-Bianco + * Makefile.in (install-common): Remove extraneous chmod for gcov + install. - * tree.c (build_expr_wfl): Use NULL_TREE if the file name is NULL. - Propagate TREE_SIDE_EFFECTS and TREE_TYPE iff the encapsulated - node is non NULL. Cache last file name and file name identifier node. +Wed Jan 20 18:15:08 1999 Dave Brolley -1998-04-15 Mark Mitchell + * function.c (assign_parms): Save and restore setting of + TREE_USED (parm). - * c-common.c (declare_hidden_char_array): Use TYPE_DOMAIN to get - the length of an array, not TREE_TYPE. +Wed Jan 20 12:51:42 1999 Mark Mitchell -Wed Apr 15 15:31:34 1998 Jeffrey A Law (law@cygnus.com) + * arm.md: Use MEM_COPY_ATTRIBUTES where appropriate throughout. + Pass MEM_SCALAR_P to arm_gen_store_multiple where appropriate. - * flow.c (sbitmap_union_of_successors): New function. - * basic-block.h (sbitmap_union_of_successors): Declare it. +Tue Jan 19 21:20:52 1999 Richard Henderson -Wed Apr 15 12:38:03 1998 Jim Wilson + * recog.c (pop_operand): New function. + * recog.h (pop_operand): Declare it. + * genrecog.c (preds): Define it. - * configure.in (gnu_ld): Rename to gnu_ld_flag before main loop. - Set gnu_ld to gnu_ld_flag inside main loop. - (gas): Likewise. + * expr.c (do_jump_for_compare): Handle conditional branch expanders + emitting multiple jump instructions. + * jump.c (condjump_label): New function. + * rtl.h (condjump_label): Declare it. -Wed Apr 15 14:50:05 1998 Dave Brolley +Tue Jan 19 21:08:20 1999 Richard Henderson - * toplev.c (compile_file): Call init_parse using new interface. - (init_lex): Remove declaration. + * expr.c (emit_move_insn_1): Revert 17 Dec change. Don't emit + clobber during or after reload. - * c-lex.c (init_parse): Now returns char* containing filename. +Tue Jan 19 16:56:03 1999 Richard Henderson -Wed Apr 15 12:37:10 1998 Jeffrey A Law (law@cygnus.com) + * genoutput.c (name_for_index): New function. + (scan_operands, validate_insn_alternatives): Use it. + * genrecog.c (insn_name_ptr_size): New variable. + (make_insn_sequence): Fill in insn_name_ptr. + (merge_trees): Use it. - * pa.h (LEGITIMIZE_RELOAD_ADDRESS): Do nothing if not optimizing. +Tue Jan 19 16:37:36 1999 Richard Henderson -Wed Apr 15 12:10:18 1998 Michael Meissner + * i386/isc.h (TARGET_DEFAULT): Define symbolicly. + * i386/isccoff.h, i386/next.h, i386/sco.h, i386/sco5.h: Likewise. + * i386/scodbx.h, i386/sequent.h, i386.unix.h: Likewise. - * Makefile.in (gen{config,flags,codes,emit}): Link in host print-rtl.o. - (gen{extract,peep,opinit,output}): Ditto. +Tue Jan 19 15:00:10 1999 Jeffrey A Law (law@cygnus.com) - * gen{attr,codes,config,emit,output}.c (insn_attr_name): Provide a - global definition so print-rtl.o can be linked in. - * gen{peep,recog}.c (insn_attr_name): Ditto. + * loop.c (NUM_STORES): Delete. + (loop_store_mems): Turn into an EXPR_LIST of MEMs. + (prescan_loop): Properly initialize loop_mems_idx. + (note_addr_stored): Simplify using list structure instead of + fixed sized array. + (invariant_p, check_dbra_loop, load_mems): Similarly. -Tue Apr 14 07:30:57 1998 K. Richard Pixley + * flow.c (invalidate_from_autoinc): New function. + (mark_set_1, mark_used_regs): Use it. - * fixincludes: discard empty C++ comments, as found in sys/time.h - on hpux-11.0. + * Makefile.in (protoize.o, unprotoize.o): Depend on Makefile. -Wed Apr 15 10:47:21 1998 Andreas Schwab +1999-01-19 Vladimir N. Makarov - * config/m68k/m68k.md (adddi3, subdi3): Optimize for constant - operand. + * invoke.texi (-mlong-double-64): New option description. -Wed Apr 15 01:21:21 1998 Jeffrey A Law (law@cygnus.com) +1999-01-19 Jim Wilson - * emit-rtl.c (operand_subword): Rework slightly to avoid - bogus warning from previous change. + * libgcc2.c: Change all uses of LONG_DOUBLE_TYPE_SIZE to + LIBGCC2_LONG_DOUBLE_TYPE_SIZE. + (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): New. Set to LONG_DOUBLE_TYPE_SIZE + if not defined. + * i960/i960.h (MULTILIB_DEFAULTS): Define to mnumerics. + (CPP_SPECS): Add -mlong-double-64 support. + (TARGET_FLAG_LONG_DOUBLE_64, TARGET_LONG_DOUBLE_64): New. + (TARGET_SWITCHES): Add -mlong-double-64 support. + (LONG_DOUBLE_TYPE_SIZE): Likewise. + (LIBGCC2_LONG_DOUBLE_TYPE_SIZE): Define. + * i960/vx960-coff.h (MULTILIB_DEFAULTS): Define to msoft-float. + (CPP_SPECS): Add -mlong-double-64 support. + * i960/t-960bare (MULTILIB_OPTIONS): Add mlong-double-64. + (MULTILIB_DIRNAMES): Add ld64. + * i960/t-vxworks960 (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): Likewise. -Tue Apr 14 23:39:13 1998 Richard Henderson +Tue Jan 19 11:54:04 1999 Jason Merrill - * alpha.md: Revert Oct 27 change, as it is superceeded by Kenner's - Nov 8 find_replacement change. Move decls of get_unaligned_address - * alpha.h: ... here. + * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by + invisible reference. -Tue Apr 14 22:00:39 1998 John Carr +Tue Jan 19 14:51:36 1999 David Edelsohn - * function.c (assign_parms): Initialize unsignedp before passing - its pointer to promote_mode. + * rs6000.c (offsettable_addr_operand): Delete. + (offsettable_mem_operand): New function. + * rs6000.h (PREDICATE_CODES): Reflect function change. + (RS6000_SAVE_TOC): Represent address as MEM. + * win-nt.h (RS6000_SAVE_TOC): Same. + * rs6000.md (indirect calls): Change offsettable address parameter + to offsettable memory parameter. - * genattrtab.c (check_attr_test): Handle MATCH_INSN like MATCH_OPERAND. - (write_test_expr): Allow MATCH_INSN. +Tue Jan 19 10:24:53 1999 Mark Mitchell -Tue Apr 14 21:57:57 1998 Paul Eggert + * rtl.h (rtx_def): Update documentation. + (MEM_IN_STRUCT_P): Likewise. + (MEM_SCALAR_P): New macro. + (MEM_COPY_ATTRIBUTES): Likewise. + (MEM_SET_IN_STRUCT_P): Likewise. + * rtl.texi (MEM_SCALAR_P): Document. + * alias.c (canon_rtx): Use MEM_COPY_ATTRIBUTES. + (fixed_scalar_and_varying_struct_p): New function. Use + MEM_SCALAR_P rather than !MEM_IN_STRUCT_P. + (aliases_everything_p): Likewise. + (true_dependence): Use them. + (write_dependence_p): New function, containing code common to + anti_dependence and output_dependence. + (anti_dependence): Use it. + (output_dependence): Likewise. + * calls.c (save_fixed_argument_area): Don't clear + MEM_IN_STRUCT_P. + (expand_call): Use MEM_SET_IN_STRUCT_P. + (emit_library_call): Don't clear MEM_IN_STRUCT_P. + (emit_library_call_value): Likewise. + (store_one_arg): Use MEM_SET_IN_STRUCT_P. + * combine.c (simplify_rtx): Use MEM_COPY_ATTRIBUTES. + (make_extraction): Likewise. + (simplify_shift_const): Likewise. + (gen_lowpart_for_combine): Likewise. + * cse.c (gen_lowpart_if_possible): Use MEM_COPY_ATTRIBUTES. + * emit-rtl.c (operand_subword): Likewise. + (change_address): Likewise. + * explow.c (stabilize): Use MEM_COPY_ATTRIBUTES. + * expr.c (protect_from_queue): Use MEM_COPY_ATTRIBUTES. + (emit_group_store): Use MEM_SET_IN_STRUCT_P. + (copy_blkmode_from_reg): Likewise. + (store_field): Likewise. + (expand_expr): Remove bogus guesswork setting MEM_IN_STRUCT_P + heuristically. Use MEM_SET_IN_STRUCT_P. + (get_memory_rtx): Likewise. + * final.c (alter_subreg): Use MEM_COPY_ATTRIBUTES. + * function.c (assign_stack_temp): Clear MEM_SCALAR_P and + MEM_ALIAS_SET on newly returned MEMs. + (assign_temp): Use MEM_SET_IN_STRUCT_P. + (put_reg_into_stack): Likewise. + (fixup_var_refs1): Use MEM_COPY_ATTRIBUTES. + (gen_mem_addressof): Use MEM_SET_IN_STRUCT_P. + (assign_parms): Likewise. + (expand_function): Likewise. + * integrate.c (expand_inline_function): Likewise. + (copy_rtx_and_substitute): Use MEM_COPY_ATTRIBUTES. + * loop.c (note_addr_stored): Remove check on MEM_IN_STRUCT_P. + * optabs.c (gen_move_insn): Use MEM_COPY_ATTRIBUTES. + * print-rtl.c (print_rtx): Print /f for frame_related. + * recog.c (validate_replace_rtx_1): Use MEM_COPY_ATTRIBUTES. + * reload1.c (reload): Copy MEM_SCALAR_P as well. + * stmt.c (expand_decl): Use MEM_SET_IN_STRUCT_P. + (expand_anon_union_decl): Use MEM_COPY_ATTRIBUTES. + * varasm.c (make_decl_rtl): Use MEM_SET_IN_STRUCT_P. + (output_constant_def): Likewise. + * a29k.c (a29k_set_memflags_1): Take scalar_p. + Set MEM_SCALAR_P. + (a29k_set_memflags): Use it. + * alpha.c (get_aligned_mem): Use MEM_COPY_ATTRIBUTES. + * c4x.c (c4x_scan_for_ld): Likewise. + * h8300.c (fix_bit_operand): Likewise. + * m88k.c (legitimize_address): Likewise. + (block_move_loop): Likewise. + (block_move_no_loop): Likewise. + (block_move_sequence): Likewise. + (m88k_builtin_saveregs): Use MEM_SET_IN_STRUCT_P. + * mips/abi64.h (SETUP_INCOMING_VARARGS): Likewise. + * rs6000.c (expand_block_move_insn): Use MEM_COPY_ATTRIBUTES. + * sh.c (sh_builtin_saveregs): Use MEM_SET_IN_STRUCT_P. + * arm.h (arm_gen_load_multiple): Take scalar_p. + (arm_store_load_multiple): Likewise. + * arm.c (arm_gen_load_multiple): Likewise. + (arm_gen_store_multiple): Likewise. + (arm_gen_movstrqi): Treat MEM_SCALAR_P like MEM_IN_STRUCT_P. + +Tue Jan 19 12:30:37 1999 Andrew MacLeod + + * optabs.c (emit_libcall_block): Add a REG_EH_REGION reg note to all + calls within a libcall block to indicate no throws are possible. + * flow.c (find_basic_blocks, find_basic_blocks_1): Don't look for + libcall blocks. Don't add edges to exception handlers if we see + a REG_EH_REGION note with a value of 0. + (make_edges): Override active_eh_region vector if the call has a note + indicating the call does not throw. + +1999-01-19 Vladimir N. Makarov + + * config/rs6000/sysv4.h (CC1_SPEC): Fix correct numbers of {}. + +Tue Jan 19 06:26:30 1999 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (cccp.o, cpplib.o): Depend on Makefile. + +Mon Jan 18 09:56:41 1999 Jason Merrill + + * invoke.texi (C++ Dialect Options): Document -fno-rtti. + +1999-01-18 Vladimir N. Makarov + + * invoke.texi (-mcpu=740, -mcpu=750): New options. + (-m(no-)multiple, -m(no-)string): Describe cases for PPC740 & + PPC750. + +1999-01-18 Michael Meissner + + * rs6000.h ({ASM,CPP}_CPU_SPEC): Add support for all machines + supported with -mcpu=xxx. + (processor_type): Add PROCESSOR_PPC750. + (ADJUST_PRIORITY): Call rs6000_adjust_priority. + (RTX_COSTS): Supply costs for 750 multiply/divide operations. + (rs6000_adjust_priority): Add declaration. + + * rs6000.c (rs6000_override_options): -mcpu={750,740} now sets the + processor type as 750, not 603. Allow -mmultiple and -mstring on + little endian 750 systems. + (rs6000_adjust_priority): Stub for now. + (get_issue_rate): The PowerPC 750 can issue 2 instructions/cycle. + + * rs6000.md (function/cpu attributes): Add initial ppc750 support. + + * sysv4.h (STRICT_ALIGNMENT): Don't force strict alignment if + little endian. + (CC1_SPEC): Pass -mstrict-align if little endian, and not + overridden. + (CC1_ENDIAN_{LITTLE,BIG,DEFAULT}_SPEC): Endian specific configs. + (SUBTARGET_EXTRA_SPECS): Add cc1 endian specs. + + * {sysv4,eabi}le.h (CC1_ENDIAN_DEFAULT_SPEC): Override, default is + little endian. + + * t-ppcgas (MULTILIB_*): Delete obsolete Solaris multilibs. + +Mon Jan 18 12:03:08 1999 Gavin Romig-Koch + + * config/mips/mips.md (div_trap): Split div_trap_mips16 + from div_trap. + (div_trap_normal,div_trap_mips16): Correct the length attributes. + +Mon Jan 18 11:48:28 1999 Kaveh R. Ghazi + + * cpplib.c (special_symbol): Qualify a char* with the `const' keyword. + Instead of writing to const char *buf directly, use a non-const + variable `wbuf' to allocate and write a string, then set buf = wbuf. + + * cppulp.c (user_label_prefix): Qualify a char* with the `const' + keyword. + + * dyn-string.c (dyn_string_append): Likewise. - * install.texi: Update section on warnings that can be safely ignored. + * dyn-string.h (dyn_string_append): Likewise. -Tue Apr 14 14:55:16 1998 Jim Wilson + * final.c (end_final, output_operand_lossage, asm_fprintf): Likewise. - * mips.md (reload_outdi): Change the scratch mode from DImode to - TImode. New variable scratch, used instead of operand[2] in template. - Add code for MIPS16 HILO_REGNUM case where output reg is not M16_REG_P. + * output.h (end_final, output_operand_lossage, asm_fprintf, + named_section, decode_reg_name, make_decl_rtl, user_label_prefix): + Likewise. -Tue Apr 14 16:19:03 1998 Michael Meissner + * profile.c (init_branch_prob): Likewise. + + * toplev.c (set_target_switch, vmessage, + v_message_with_file_and_line, v_message_with_decl, + v_error_with_file_and_line, v_error_with_decl, v_error_for_asm, + verror, vfatal, v_warning_with_file_and_line, v_warning_with_decl, + v_warning_for_asm, vwarning, vpedwarn, v_pedwarn_with_decl, + v_pedwarn_with_file_and_line, vsorry, v_really_sorry, + open_dump_file, dump_rtl, clean_dump_file, + print_version, print_single_switch, print_switch_values, + dump_base_name, debug_args, lang_independent_options, + user_label_prefix, documented_lang_options, target_switches, + target_options, print_time, pfatal_with_name, fatal_io_error, + fatal_insn, default_print_error_function, print_error_function, + report_error_function, error_with_file_and_line, error_with_decl, + error_for_asm, error, fatal, warning_with_file_and_line, + warning_with_decl, warning_for_asm, warning, pedwarn, + pedwarn_with_decl, pedwarn_with_file_and_line, sorry, + really_sorry, botch, output_quoted_string, output_file_directive, + open_dump_file, rest_of_decl_compilation, display_help, main): + Likewise. - * expr.c (MOVE_RATIO): Set to 3 if optimizing for space. + * toplev.h (print_time, fatal, fatal_io_error, pfatal_with_name, + fatal_insn, warning, error, pedwarn, pedwarn_with_file_and_line, + warning_with_file_and_line, error_with_file_and_line, sorry, + really_sorry, default_print_error_function, report_error_function, + rest_of_decl_compilation, pedwarn_with_decl, warning_with_decl, + error_with_decl, error_for_asm, warning_for_asm, output_quoted_string, + output_file_directive, botch): Likewise. -Tue Apr 14 11:31:28 1998 Krister Walfridsson + * tree.h (make_decl_rtl): Likewise. - * i386/bsd386.h (ASM_OUTPUT_ALIGN): Redefine. + * varasm.c (strip_reg_name, named_section, decode_reg_name, + make_decl_rtl): Likewise. -Tue Apr 14 09:02:32 1998 Jeffrey A Law (law@cygnus.com) +Mon Jan 18 11:35:49 1999 Gavin Romig-Koch - * svr4.h (ASM_DECLARE_OBJECT_NAME): Use HOST_WIDE_INT_PRINT_DEC. - (ASM_FINISH_DECLARE_OBJECT): Likewise. + * Makefile.in (TCL_LIBRARY): Use 'cd' to find the library + directory logically rather than physically. - * Idea and part of the patch from HJ. - * Makefile.in: auto-host.h renamed from auto-config.h. All references - changed. - (distclean): Remove auto-build.h too. - * configure.in: Rename host autoconf generated file to auto-host.h. - If host != build, then run autoconf to generate auto-build.h for - the build machine and include it in build_xm_files. - Check for wait.h and sys/wait.h. +Mon Jan 18 09:05:37 1999 Kaveh R. Ghazi - * combine.c (simplify_rtx, case TRUNCATE): Respect value of - TRULY_NOOP_TRUNCATION. + * loop.c (insert_bct): Hide the definition of variables + `increment_direction', `compare_direction', `add_iteration' and + `loop_var_mode'. -Mon Apr 13 11:31:49 1998 Jason Merrill + * recog.c (mode_dependent_address_p): Mark parameter `addr' with + ATTRIBUTE_UNUSED. Mark label `win' with ATTRIBUTE_UNUSED_LABEL. + (mode_independent_operand): Mark label `lose' with + ATTRIBUTE_UNUSED_LABEL. - * tree.h (BINFO_OFFSET_ZEROP): Use integer_zerop. + * regclass.c (n_occurrences): Remove prototype and definition. -Sun Apr 12 20:55:32 1998 Catherine Moore + * reload.c (find_reloads_address_1): Mark variable `tem' with + ATTRIBUTE_UNUSED. - * invoke.texi (ld options) Include memset requirements - for options -nodstdlib and -nodefaultlibs. + * reload1.c (reload): Cast the first two arguments of `bcopy' to PTR. -1998-04-12 Paul Eggert + * sbitmap.c (sbitmap_copy): Likewise. - This change is from an idea suggested by Arthur David Olson. + * scan-decls.c (scan_decls): Hide label `handle_comma'. - * c-common.c (decl_attributes, record_function_format, - check_format_info, init_function_format_info): - Add support for strftime format checking. - (enum format_type): New type. - (record_function_format): Now static, and takes value of type - enum format_type instead of int. - (time_char_table): New constant. - (struct function_format_info): format_type member renamed from is_scan. - (check_format_info): Use `warning' rather than sprintf followed by - `warning', to avoid mishandling `%' in warnings. - Change `pedwarn' to `warning', since these warnings do not necessarily - mean the program does not conform to the C Standard, as the code - need not be executed. + * toplev.c (output_lang_identify): Mark prototype with + ATTRIBUTE_UNUSED. - * c-tree.h (record_function_format): Remove decl; no longer extern. + * tree.c (make_node): Cast the first argument of `bzero' to PTR. + (make_tree_vec): Likewise. + (build1): Likewise. - * extend.texi: Add documentation for strftime format checking. + * varasm.c (assemble_static_space): Mark variable `tem' with + ATTRIBUTE_UNUSED. -Sun Apr 12 20:23:03 1998 Jeffrey A Law (law@cygnus.com) +Mon Jan 18 04:28:36 1999 Nathan Sidwell - * mips/ecoffl.h: Do not include mips.h. - * mips/elf.h: Likewise. + * Makefile.in (GCOV_INSTALL_NAME): New macro. + (install-common): Use it. + (uninstall): Use it. + (uninstall): Use correct names for protoize and unprotoize. - * configure.in (mips-*-ecoff): Do not mention mips/mips.h in tm_files. - * mips/ecoff.h: Include "mips/mips.h". +Mon Jan 18 03:52:56 1999 Christian Bruel + Jeffrey A Law (law@cygnus.com) -Sat Apr 11 22:42:54 PDT 1998 Jeff Law (law@cygnus.com) + * flow.c (last_mem_set): Delete variable. References removed. + (mem_set_list): New variable. + (life_analysis): Initialize and finalize alias analysis. + (propagate_block); Initialize mem_set_list. Clear for CALL_INSNs. + (insn_dead_p): For a store to memory, search the entire mem_set_list + for a match. + (mark_set_1): Kill entries on the mem_set_list for aliased writes or + changes to their addresses. Add new entries to the mem_set_list for + memory writes writes. + (mark_used_regs): Kill entries on the mem_set_list which may be + referenced by a load operation. - * version.c: Bump for snapshot. +Mon Jan 18 01:01:02 1999 Jeffrey A Law (law@cygnus.com) -Sat Apr 11 01:24:28 1998 Jeffrey A Law (law@cygnus.com) + * alias.c (base_alias_check): Add missing return for differing + symbols case. - * cse.c (count_reg_usage): Correctly handle REG_NONNEG notes. - (delete_trivially_dead_insns): Renamed from delete_dead_from_cse. - * toplev.c (rest_of_compilation): Call delete_trivially_dead_insns instead of delete_dead_from_cse. Also call delete_trivially_dead_insns - between loop optimization passes. - * rtl.h: Updated appropriately. +Mon Jan 18 00:36:13 1999 Rainer Orth -Fri Apr 10 22:28:32 1998 Jeffrey A Law (law@cygnus.com) + * mips-tdump.c (print_file_desc): Handle unknown filenames and + missing local symbols. - Reinstall this patch from Jason. - * function.c (push_function_context_to): Don't call init_emit. +Sun Jan 17 21:04:31 1999 Richard Henderson -Fri Apr 10 13:40:20 1998 Nick Clifton + * jump.c (rtx_renumbered_equal_p): Special case CODE_LABEL. - * rtl.c (read_skip_spaces): Prevent infinite loops upon - encountering unterminated comments. + * system.h (bcopy): Implement with memmove not memcpy. -Fri Apr 10 10:43:41 1998 Jeffrey A Law (law@cygnus.com) +Sun Jan 17 19:23:20 1999 Jeffrey A Law (law@cygnus.com) - * emit-rtl.c (operand_subword): Properly handle CONST_INTs for - 64x32 cross builds. + * Makefile.in (cppulp.o): Add dependencies. - * configure.in: Handle --with-fast-fixincludes. - (fixincludes): If --with-fast-fixincludes, then use a different - fixincludes program by default. - * Makefile.in (fixinc.sh): New rule. + * i386.md (integer conditional moves): Add missing earlyclobbers. -Fri Apr 10 00:36:31 1998 H.J. Lu (hjl@gnu.org) + * regmove.c (optimize_reg_copy_1): Undo Aug 18 change. Update + REG_N_CALLS_CROSSED and REG_LIVE_LENGH if and only if we change + where a register is live. - * i386.md (movqi+1): Handle invalid QI register. - (movsf_push-1): Likewise. +Sun Jan 17 03:20:47 1999 H.J. Lu (hjl@gnu.org) -Thu Apr 9 16:53:59 1998 Nick Clifton + * reg-stack.c (subst_stack_regs_pat): Abort if the destination + of a FP conditional move is not on the FP register stack. - * config/m32r/m32r.c: call_address_operand(): Only accept symbolic - addresses. - symbolic_memort_operand(), call32_operand(), int8_operand(), - int16_operand(), uint24_operand(), reg_or_int8_operand(): Removed. - Not used. - uint16_operand(): Made static. +Sun Jan 17 01:15:04 1999 Jeff Law (law@cygnus.com) -Thu Apr 9 01:43:04 1998 Jeffrey A Law (law@cygnus.com) + * version.c: Bump for snapshot. - * calls.c (expand_call): Fix typo. +Sat Jan 16 23:40:33 1999 Jeffrey A Law (law@cygnus.com) -Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com) + * reload1.c (reload_cse_regs_1): Do not call + reload_cse_simplify_operands for an insn with asm operands. - * c-lex.c (finput): New global. - (init_parse): Always included. Handle !USE_CPPLIB using - code originally in compile_file. - (finish_parse): Update for CPPLIB. - * toplev.c (init_parse, finish_parse): Declare. - (finput): Delete variable. Now in front-ends. - (compile_file): Remove code which is now handled by init_parse - which is unconditionally called. Similarly for finish_parse. + * cccp.c (print_help): Fix typos. + * cpplib.c (print_help): Fix typos. + * toplev.c (f_optiosn): Fix typos. + (documented_lang_options): Fix typos. -Wed Apr 8 23:13:50 1998 Gavin Koch +Sat Jan 16 21:48:17 1999 Marc Espie (Marc.Espie@openbsd.org) - * config/mips/r3900.h (ASM_OUTPUT_DEF,SUPPORTS_WEAK, - ASM_WEAKEN_LABEL): Add. + * gcc.c (do_spec_1): Fix obvious typo. -Wed Apr 8 18:21:30 1998 Richard Henderson +Sat Jan 16 19:31:07 1999 Kaveh R. Ghazi - * alpha/crtbegin.asm, alpha/crtend.asm, alpha/t-crtb: New files. - * configure.in (alpha-*-linux*): Use them. + * c-decl.c (duplicate_decls): If `warn_traditional', warn when + a non-static function declaration follows a static one. -Fri Apr 3 17:02:13 1998 Alexandre Petit-Bianco + * invoke.texi (-Wtraditional): Document the extra check now done + by this flag. - * tree.def (EXPR_WITH_FILE_LOCATION): New tree node definition. - * tree.h (EXPR_WFL_{NODE,FILENAME,FILENAME_NODE,LINENO, - COLNO,LINECOL,SET_LINECOL,EMIT_LINE_NOTE}): New macros. - (build_expr_wfl): New prototype declaration. - * tree.c (build_expr_wfl): New function, to build - EXPR_WITH_FILE_LOCATION nodes. - (copy_node): Don't zero TREE_CHAIN if copying a - EXPR_WITH_FILE_LOCATION node. - * print-tree.c (print_node): Handle EXPR_WITH_FILE_LOCATION. - * expr.c (expand_expr): Handle EXPR_WITH_FILE_LOCATION. +Sat Jan 16 15:13:46 1999 Jeffrey A Law (law@cygnus.com) -Wed Apr 8 12:51:19 1998 Jeffrey A Law (law@cygnus.com) + * pa.md (shadd): Create shadd insns, even if the result of the shift is + needed without the addition. - * configure.in (v850): Use t-v850. - (ix86-wrs-vxworks): Recognize 786 just like other x86 configurations. +Sat Jan 16 10:48:16 1999 J"orn Rennecke - * protoize.c (creat, read, write): Do not declare. + * sh.md (movdf, movsf): Temporary workaround for no_new_pseudos lossage. - * jump.c (mark_jump_label): Record REG_LABEL notes for insns which - refer to the CODE_LABEL before a dispatch table. +Fri Jan 15 23:44:37 1999 Richard Henderson - * invoke.texi: Add ARC options. + * sparc.c (sparc_issue): Add hypersparc/sparclite86x entries. - * gcc.c (proces_command): Improve error message for -o with - either -c or -S. +Fri Jan 15 22:30:04 1999 David Edelsohn - * i386/x-cygwin32 (CLIB): Link in advapi32. + * rs6000.h (CONST_OK_FOR_LETTER_P): Do not assume 32-bit CONST_INT. + * rs6000.c (u_short_cint_operand, add_operand, logical_operand, + non_add_cint_operand, non_logical_cint_operand): Likewise. + (get_issue_rate): Add CPU_PPC604E case. + * rs6000.md (movdi, !TARGET_POWERPC64 splitters): Handle 64-bit hosts. - * alpha.h (ASM_IDENTIFY_GCC): Define to nothing. - (ASM_IDENTIFY_LANGUAGE): Likewise. +Fri Jan 15 18:42:12 1999 Richard Henderson - * i386.md (movqi recognizer): Don't perfom byte increment into - a NON_QI_REG_P. + * expr.c (queued_subexp_p): Make public. + * expr.h (queued_subexp_p): Declare it. + * recog.c (asm_operand_ok): New function. + (check_asm_operands): Use it. After reload, use constrain_operands + instead. + * recog.h (asm_operand_ok): Declare it. + * stmt.c (expand_asm_operands): Use it to try harder to make + asms initially satisfy their constraints. - * configure.in (x86-dg-dgux): Run fixinc.dgux. +Fri Jan 15 17:43:59 1999 Jeffrey A. Law - * i370.h: Fix typo in GEN_INT changes. + * sparc.h (LEGITIMIZE_RELOAD_ADDRESS): Do not create + (mem (lo_sum (...)) for TFmode unless TARGET_V9. - * bitmap.c (bitmap_element_allocate): Use "void" for arglist instead - of an empty arglist in prototype. +Sat Jan 16 12:47:15 1999 Michael Hayes - * Makefile.in: Remove bytecode crud that crept back in after the - gcc2 merge. + * config/c4x/c4x.md (not_repeat_reg): Allow ldp instruction + in delay slot of RPTBD. -1998-04-08 Brendan Kehoe +Sat Jan 16 12:26:40 1999 Michael Hayes - * c-lex.h (is_class_name): Fix arg type to be tree, not void. - (make_pointer_declarator, reinit_parse_for_function): Fix typo. + * config/c4x/libgcc.S (___divhi3, ___modhi3): Fix long long + divide and modulo sign problem. -Wed Apr 8 06:16:45 1998 Richard Earnshaw (rearnsha@arm.com) +Fri Jan 15 11:02:31 1999 Michael Hayes - * arm.h (LEGITIMIZE_RELOAD_ADDRESS): Define. + * unroll.c (loop_iterations): Return 0 if the last loop insn + is not a jump insn or if the loop has multiple back edges. -Wed Apr 8 00:44:18 1998 Bernd Schmidt (crux@pool.informatik.rwth-aachen.de> +1999-01-15 Manfred Hollstein - * c-lex.c (is_class_name): Delete declaration. - (whitespace_cr): Make static and add prototype. - * c-lex.h (make_pointer_declarator, reinit_parse_for_function, - yylex, get_directive_line): Turn declarations into prototypes. - (position_after_whitespace, check_newline, yyerror,, is_class_name, - forget_protocol_qualifiers, remember_protocol_qualifiers): Add - prototypes. - * genattr.c (extend_range, write_upcase, gen_attr, write_units): Add - prototypes. - * gencodes.c (gen_insn): Add prototype. - * genconfig.c (walk_insn, gen_insn, gen_expand, gen_split, - gen_peephole): Add prototypes. - * genflags.c (num_operands, gen_proto, gen_nonproto, gen_insn): Add - prototypes. - * gengenrtl.c (type_from_format, accessor_from_format, special_rtx, - special_format, find_formats, gendecl, genmacro, gendef, genlegend, - genheader, gencode): Add prototypes. - * genopinit.c (gen_insn): Add prototype. - * genoutput.c (output_prologue, output_epilogue, scan_operands, - process_template, validate_insn_alternatives, gen_insn, gen_peephole, - gen_expand, gen_split, n_occurrences): Add prototypes. - * genpeep.c (gen_peephole): Add prototype. - * loop.c (find_and_verify_loops, mark_loop_jump, prescan_loop, - reg_in_basic_block_p, consec_sets_invariant_p, libcall_other_reg, - labels_in_range_p, count_loop_regs_set, note_addr_stored, - loop_reg_used_before_p, scan_loop, replace_call_address, - skip_consec_insns, libcall_benefit, ignore_some_movables, - force_movables, combine_movables, rtx_equal_for_loop_p, move_movables, - strength_reduce, valid_initial_value_p, find_mem_givs, record_biv, - check_final_value, record_giv, update_giv_derive, basic_induction_var, - simplify_giv_expr, general_induction_var, consec_sets_giv, - check_dbra_loop, express_from, combine_givs_p, combine_givs, - product_cheap_p, maybe_eliminate_biv, maybe_eliminate_biv_1, - last_use_this_basic_block, record_initial, update_reg_last_use, - iteration_info, analyze_loop_iterations, insert_bct, - instrument_loop_bct, indirect_jump_in_function_p): Turn declarations - into prototypes. + * configure.in (fixinc_defs): Do not define for m[68]8k-motorola-sysv{,3}; + it's working properly now. Remove comment saying "see m68k-motorola-sysv + as an example". + * configure: Regenerate using autoconf. -Tue Apr 7 21:48:52 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/fixincl.c (main): Do not ignore SIGCHLD. - * pa.h (LEGITIMIZE_RELOAD_ADDRESS): Define. +Thu Jan 14 22:38:41 1999 Jeffrey A Law (law@cygnus.com) -1998-04-07 Ken Raeburn + * unroll.c (find_splittable_givs): For a DEST_ADDR giv, do not share + a register with another DEST_ADDR giv if the address is not valid. - * config/mips/mips.c (siginfo): Deleted. - (override_options): Don't install SIGINFO signal handler. + * pa.c (hppa_expand_epilogue): Save and restore the static chain + around the call to mcount. -Tue Apr 7 11:58:04 1998 Jim Wilson + * h8300.h (ASM_OUTPUT_LABELREF): Use asm_fprintf, not fprintf. - * loop.c (check_dbra_loop): When normalize comparison_val, add check - to verify it is non-negative. + * stmt.c (expand_end_case): Use emit_cmp_and_jump_insns to avoid + generating non-canonical rtl. -Tue Apr 7 02:01:47 1998 Richard Henderson +1999-01-14 Vladimir N. Makarov - * alpha.c (alpha_expand_block_move): Correctly collect block offsets. - (alpha_expand_block_clear): Likewise. + * config/i960/i960.c (i960_output_move_double_zero, + i960_output_move_quad_zero): New functions for moving zeros. + (i960_output_move_double, i960_output_move_quad): Additional code + for situation when moving unaligned register group. -Mon Apr 6 23:36:01 1998 Richard Henderson + * config/i960/i960.h (i960_output_move_double_zero, + i960_output_move_quad_zero): The function definitions. - * tree.h (sizetype_tab): Fix previous change for K&R. + * config/i960/i960.md (movdi+1, movti+1): Usage of the functions. -Mon Apr 6 22:23:29 PDT 1998 Jeff Law (law@cygnus.com) +1999-01-13 Vladimir N. Makarov - * version.c: Bump for snapshot. + * config/i960/i960.c (i960_function_prologue): New code (optimal + solution) for saving global registers in local registers. + (form_reg_groups, reg_group_compare, split_reg_group): New + functions used by the code. + (reg_group): New structure definition for the new code. -Mon Apr 6 23:16:10 1998 Richard Earnshaw (rearnsha@arm.com) +1999-01-13 Manfred Hollstein - * configure.in (sparc-*-solaris2*): Add xm-siglist.h to xm_file. - Add USG and POSIX to xm_defines. + * fixinc/fixincl.c (create_file): Pass file creation mask as + third parameter to "open". Use O_TRUNC flag to open instead of + explicitly unlink'ing the file. + (process): and forget about the "chmod" stuff. -Mon Apr 6 21:49:57 1998 Bob Manson +Wed Jan 13 20:12:37 1999 Richard Henderson - * gcc.c: Add linker spec. - (link_command_spec): Use %(linker) instead of ld. - (main): If collect2 is requested as the linker, see if it exists; - if not, use ld instead. + * integrate.c (expand_inline_function): Recognize (mem (addressof)) + and substitute. Copy the return value from there into a new pseudo. - * Makefile.in (USE_COLLECT2): It's named collect2 now, not ld. - (ld:) Deleted. - (install-collect2): Install as collect2, not ld. +Wed Jan 13 16:47:00 1999 Catherine Moore - * configure.in(will_use_collect2): It's named collect2 now. + * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN + before generating a call to abort for volatile functions. + * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define. + (TARGET_ABORT_NORETURN): Define. + (abort-on-noreturn): New option. - * collect2: Remove checks to see if we were invoked recursively. - (collect_execute): Use _spawnvp under cygwin32. +Thu Jan 14 13:52:42 1999 Michael Hayes -Mon Apr 6 17:23:41 1998 Jim Wilson + * config/c4x/c4x.md (in_annul_slot_3): Correctly allow unarycc + and binarycc operations in 3rd annulled delay slot! - * haifa-sched.c (build_control_flow): Set unreachable for block whose - only predecessor is itself. +Wed Jan 13 16:16:44 1999 Catherine Moore -Mon Apr 6 16:08:04 1998 Kaveh R. Ghazi + * config/arm.c (output_func_epilogue): Check TARGET_ABORT_NORETURN + before generating a call to abort for volatile functions. + * config/arm.h (ARM_FLAG_ABORT_NORETURN): Define. + (TARGET_ABORT_NORETURN): Define. + (abort-on-noreturn): New option. - * c-parse.in: Include system.h, and remove stuff now made redundant. - * cccp.c: Likewise. - * cexp.y: Likewise. - * protoize.c: Likewise. Properly check for cpp stringification. +Wed Jan 13 13:30:08 1999 Kaveh R. Ghazi - * Makefile.in (c-parse.o, cccp.o, cexp.o, protoize.o, unprotoize.o): - Depend on system.h. + * cccp.c (xstrdup): Renamed from `savestring'. All callers changed. + Remove prototype which we get from libiberty.h. - * objc/Make-lang.in (objc-parse.o): Likewise. + * collect2.c (xstrdup): Likewise. -Mon Apr 6 14:59:58 1998 Kaveh R. Ghazi + * genextract.c (xstrdup): Likewise for `copystr'. + (mybzero): Remove it and use `memset' instead. - * gansidecl.h: Check if compiler supports __attribute__. Provide - definitions for ATTRIBUTE_UNUSED and ATTRIBUTE_PRINTF using - __attribute__ when its available. Also provide definitions for - ATTRIBUTE_PRINTF_1, ATTRIBUTE_PRINTF_2 and ATTRIBUTE_PRINTF_3 in - terms of ATTRIBUTE_PRINTF. + * genoutput.c (mybcopy, mybzero): Remove these. All callers changed + to use `memcpy' and `memset' instead. - * genoutput.c (process_template): Use ATTRIBUTE_UNUSED in place - of __attribute__. + * genrecog.c (xstrdup): Renamed from `copystr'. All callers + changed. Remove prototype. + (mybcopy, mybzero): Remove these and use memcpy/memset. -Mon Apr 6 07:17:52 1998 Catherine Moore +Wed Jan 13 00:59:04 1999 Jeffrey A Law (law@cygnus.com) - * combine.c (can_combine_p): Include successor in volatile test. + * mips.h (LOAD_EXTEND_OP): Correct for SImode and CCmode moves when + generating code for TARGET_64BIT. -Mon Apr 6 14:16:33 1998 J"orn Rennecke +Tue Jan 12 14:05:37 1999 David Edelsohn - * sh.h (CASE_VECTOR_SHORTEN_MODE): Fix logic when to set - offset_unsigned. + * rs6000.c (print_operand, cases 'm' and 'M'): Do not depend on + HOST_WIDE_INT word-size. + (rs6000_stack_info): Remove redundant alignment of fpmem. -Mon Apr 6 02:03:29 1998 Jeffrey A Law (law@cygnus.com) +Tue Jan 12 14:05:37 1999 Richard Henderson - * objc/objc-act.c (encode_aggregate_within): Avoid GNU extensions - in prototype and definition. + * rs6000.c (short_cint_operand): Remove CONSTANT_P_RTX handling. + (u_short_cint_operand, reg_or_cint_operand, logical_operand): Likewise. + (input_operand): Adjust CONSTANT_P_RTX handling. + * rs6000.h (PREDICATE_CODES): Remove CONSTANT_P_RTX references. + * rs6000.md (movsi): Adjust CONSTANT_P_RTX handling. + (movhi, movqi): Remove CONSTANT_P_RTX handling. + (movdi): Adjust CONSTANT_P_RTX handling. -Mon Apr 6 00:48:56 PDT 1998 Jeff Law (law@cygnus.com) +1999-01-12 Manfred Hollstein - * version.c: Bump for snapshot. + * configure: Regenerate using autoconf. -Mon Apr 6 00:08:50 1998 Richard Henderson + * fixinc/Makefile.in (INCLUDES): Add -I$(srcdir)/../../include. + * fixinc/fixincl.c (SIGCHLD): Use SIGCLD on (very) old systems. + (process): "fchmod" isn't available on all systems, use "chmod" + instead. + * fixinc/server.c: Add #include . + (STDIN_FILENO): Add default definition if no include file defines + it already. + (STDOUT_FILENO): Likewise. - * alpha.c (alpha_expand_block_clear): Add missing offset arg to - alpha_expand_unaligned_store_words. +Tue Jan 12 10:23:24 1999 Stan Cox -Sun Apr 5 21:31:24 1998 John Wehle (john@feith.com) + * mips.md (call_value_internal3c): New pattern for -mips16 -mlong-calls. - * i386.md (movsf_push, movsf_mem): Remove. - (movsf_push): Rename from movsf_push_nomove and move in front of - movsf. Use nonmemory_operand predicate and don't bother checking - TARGET_MOVE. - (movsf_push_memory): New pattern. - (movsf): Don't bother checking for push_operand. If TARGET_MOVE and - both operands refer to memory then force operand[1] into a register. - (movsf_normal): Change to unnamed pattern. - Likewise for movdf, movxf, and friends. +1999-01-12 Manfred Hollstein -Sun Apr 5 18:45:51 PDT 1998 Jeff Law (law@cygnus.com) + * m68k/mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Define to + ensure all prototypes necessary for building libio will be available. + * m68k/xm-mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Remove + definitions here as they are not host specific. + * m88k/sysv3.h, m88k/xm-sysv3.h: Likewise. - * version.c: Bump for snapshot. +Tue Jan 12 02:53:46 1999 Richard Henderson -Sun Apr 5 16:31:10 1998 Richard Henderson + * cse.c (cse_insn): Never prefer (const (constant_p_rtx)). - * configure.in (alpha-dec-osf*): Match osf1.3 correctly. +Tue Jan 12 02:36:10 1999 Jeff Law (law@cygnus.com) -Sun Apr 5 16:53:37 1998 Don Bowman + * version.c: Bump for snapshot. - * configure.in (mips-wrs-vxworks): New target. +Tue Jan 12 01:30:19 1999 Richard Henderson -Sat Apr 4 23:34:32 PST 1998 Jeff Law (law@cygnus.com) + * rtl.c (rtx_alloc): Use memset instead of inline loop. - * expmed.c (synth_mult): The value -1, has no zeros, so it can - never have the form ...011. + * recog.h (recog_op_alt): Declare extern. - * version.c: Bump for snapshot. +Tue Jan 12 00:23:31 1999 Richard Henderson -Sat Apr 4 20:16:46 1998 Richard Henderson + * function.c (purge_addressof_1): If the note accesses a mem+addressof + in a wider mode than any replacement, adjust the cached replacement. + Cache trivial substitutions as well. - * i386.c (asm_output_function_prefix, load_pic_register): - Use ASM_GENERATE_INTERNAL_LABEL properly. - (output_pic_addr_const): Recognize %X to supress any PIC sym suffix. - (print_operand): Ignore it. - (load_pic_register): Use it for the got load call. - * i386.md (prologue_set_got, prologue_get_pc): Likewise. - (prologue_get_pc_and_set_got): Likewise. - * i386.h: Update print_operand docs. +Tue Jan 12 00:06:00 1999 Richard Henderson -Sat Apr 4 19:08:37 1998 Richard Henderson + * Makefile.in (OBJECTS): Add sbitmap.o. + (BASIC_BLOCK_H): Add sbitmap.h. + * basic-block.h: Move simple bitmap code to sbitmap.h. + * flow.c: Move simple bitmap code to sbitmap.c. + * sbitmap.h, sbitmap.c: New files. - * i386.md (ffssi, ffshi): Rewrite as define_expands. - (ffssi_1, ffshi_1): New (unspec [] 5) support patterns. - * i386.c (notice_update_cc): Recognize unspec 5. +Mon Jan 11 23:51:50 1999 Richard Henderson -Sat Apr 4 18:07:16 1998 David Mosberger-Tang (davidm@mostang.com) + * alpha.h (TARGET_SWITCHES): Document switches. + (TARGET_OPTIONS): Likewise. - * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Accept '(' for s/sv/svi. - * alpha.c (print_operand): Handle it. - * alpha.md (fix_truncsfdi2): Use it. Add earlyclobber pattern - for ALPHA_TP_INSN. - (fix_truncdfdi2): Likewise. + * alpha/elf.h (ASM_FINISH_DECLARE_OBJECT): Use HOST_WIDE_INT_PRINT_DEC. -Sat Apr 4 17:42:05 1998 Richard Henderson +Mon Jan 11 22:54:14 1999 Richard Henderson - * tree.h (sizetype_tab[2], sbitsizetype, ubitsizetype): Merge all - of these into a single struct, with additional [us]sizetype entries. - * stor-layout.c (set_sizetype): Initialize [us]sizetype. - * fold-const.c (size_int_wide): Don't rely on sizetype_tab being - an array. + * tree.c (new_alias_set): Return zero if !flag_strict_aliasing. -Sat Apr 4 17:04:41 1998 Richard Henderson +Mon Jan 11 22:36:01 1999 Richard Henderson - * configure.in (alpha-*-linux-*): Undo tm_file changes from gcc2 merge. + * basic-block.h (basic_block_head): Rename to x_basic_block_head. + (basic_block_end): Rename to x_basic_block_end. + (BLOCK_HEAD, BLOCK_END): Update. -Sat Apr 4 13:50:01 1998 Richard Henderson + * caller-save.c: Change basic_block_head/end references to + BLOCK_HEAD/END. + * combine.c, flow.c, function.c, gcse.c, global.c: Likewise. + * graph.c, haifa-sched.c, local-alloc.c, regclass.c: Likewise. + * regmove.c, reload1.c, reorg.c, sched.c: Likewise. - * haifa-sched.c (split_block_insns): Don't supress insn splitting - on subsequent passes. +Sat Jan 9 23:54:09 1999 Kaveh R. Ghazi - * alpha.c (hard_fp_register_operand): New function. - * alpha.h (PREDICATE_CODES): Add it. - * alpha.md (extendsidi2): Kill bogus f<-f cvtql+cvtlq case. Add an - f<-m case and accompanying define_split. - (trapb): Use a unique unspec_volatile number. + * gcc.c (xstrerror): Renamed from my_strerror. All callers + changed. Remove prototype since we get that from libiberty.h. -Sat Apr 4 13:32:08 1998 Richard Henderson + * protoize.c (xstrerror): Likewise. - * configure.in (alpha-*-linux-gnu*): Undo Feb 3 change brought in - from gcc2 merge. +Sat Jan 9 23:22:04 1999 Kaveh R. Ghazi -Sat Apr 4 10:23:41 1998 Jeffrey A Law (law@cygnus.com) + * gcc.c (read_specs): Ensure format specifiers match their arguments. - * Check in merge from gcc2. See ChangeLog.11 and ChangeLog.12 - for details. +Sat Jan 9 20:04:24 1999 Richard Henderson - * haifa-sched.c: Mirror recent changes from gcc2. + * tree.c (copy_node): Oops. That would be copy not zero + in that last change. -Fri Apr 3 00:17:01 1998 Jeffrey A Law (law@cygnus.com) +Sun Jan 10 15:35:41 1999 Michael Hayes - * Makefile.in (insn*.o): Depend on system.h. + * config/c4x/c4x.c: Include system.h. + (c4x_caller_save_map): Disable caller save for RC. + (c4x_optimization_options): Disable scheduling before reload. + (valid_parallel_load_store) : Define return type as int. + Remove unused variable regs. + * config/c4x/c4x.h (REGISTER_MOVE_COST): Make independent of register + class. + * config/c4x/c4x.md (rotlqi3, rotrqi3): Fix up emitted RTL to + handle rotations. + (*db, decrement_and_branch_until_zero): Fix up constraints + to keep reload happy. - * pa.c (output_global_address): Initialize base. - * pa.h (GO_IF_LEGITIMATE_ADDRESS): Initialize index. +Sat Jan 9 18:35:29 1999 Richard Henderson -1998-04-03 Mike Stump + * tree.c (make_node): Call bzero instead of inline clear. + (copy_node, make_tree_vec, build1): Likewise. + (get_identifier): Call strlen instead of inline count. + (maybe_get_identifier): Likewise. - * gthr.h: Support systems that don't have weak, but have threads. - * configure.in (*wrs-vxworks*): Use VxWorks threads by default. - * gthr-vxworks.h: New file. - * objc/thr-vxworks.h: Dummy file from thr-single.c for now. +Sun Jan 10 14:04:51 1999 Michael Hayes -Thu Apr 2 18:00:52 1998 Jim Wilson + * config/c4x/c4x.md (in_annul_slot_3): Allow unarycc and binarycc + operations in 3rd annulled delay slot. + (*lshrqi3_const_set): Disallow c constraint for operand0. + (modhi3+1, modhi3+2): Set attribute type to multi. + * config/c4x/c4x.c (c4x_S_constraint): Removed space in middle of + != operator. - * i386.md (movqi+1): Change alternative 1 from *r/r to *r/*rn. +Sat Jan 9 11:44:55 1999 Kaveh R. Ghazi -1998-04-02 Vladimir N. Makarov + * gansidecl.h: Allow attribute unused on labels only when we are + version 2.93 or higher. Not all versions of 2.92 have this feature. - * ginclude/va-i960.h (va_end): Change void * to void. + * version.c: Bump minor number to 93. -Thu Apr 2 13:51:10 1998 Kaveh R. Ghazi +Fri Jan 8 10:51:13 1999 Andreas Schwab - * Makefile.in (choose-temp.o): Depend on system.h. + * config/m68k/m68k.h: Declare output_function_epilogue. + * recog.h: Declare next_insn_tests_no_inequality. - * choose-temp.c: Include system.h when IN_GCC. +Fri Jan 8 01:43:53 1999 Jeffrey A Law (law@cygnus.com) -Thu Apr 2 02:37:07 1998 Joern Rennecke (amylaar@cygnus.co.uk) - Richard Henderson + * stmt.c (optimize_tail_recursion): New function, extracted from ... + (expand_return): Use optimize_tail_recursion. + * tree.h (optimize_tail_recursion): Declare. - * reload.c (find_reloads_address): Try LEGITIMIZE_RELOAD_ADDRESS. - (move_replacements): New function. - * reload.h: Prototype it. + * toplev.c (compile_file): Move call to output_func_start_profiler + to after the loop to emit deferred functions. - * alpha.h (LEGITIMIZE_RELOAD_ADDRESS): New definition. +Thu Jan 7 19:52:53 1999 Gerald Pfeifer -Thu Apr 2 01:01:34 1998 Richard Henderson + * system.h (abort): Supply more detailed information on how to + report an Internal Compiler Error. - * configure (alpha-*-linuxecoff, alpha-*-linux-gnulibc1): - Run fixincludes. +Thu Jan 7 09:25:58 1999 Bruce Korb (korb@datadesign.com) - * emit-rtl.c (gen_lowpart_common): Skip count by HARD_REGNO_NREGS. - (gen_highpart): Likewise. - * final.c (alter_subreg): Allow the target to hook by-mode subreg - hard register number changes. + * fixinc/fixincl.c (*): More decapitalization of variables + plus some explanatory comments. -Wed Apr 1 22:26:22 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/Makefile.in fixinc/mkfixinc.sh: + When the fixincl program does not work for a certain system, + we substitute a shell script. Added user commentary when + this happens. - * fold-const.c optimze_bit_field_compare): Initialize rnbitpos, - rnbitsize, rnmode and rinner. - (make_range): Initialize type. - (fold): Initialize arg0, arg1 and varop. +Thu Jan 7 11:26:17 1999 Mark Mitchell - * function.c (instantiate_virtual_regs_1): Initialize offset, regnoi - and regnor. - (expand_function_start): Initialize last_ptr. + * calls.c (store_unaligned_arguments_into_pseudos): Use xmalloc to + allocate memory that will live beyond this function. + (expand_call): Free it here. - * stor-layout.c (layout_record): Initialize desired_align. - (get_best_mode): Initialize unit. +Thu Jan 7 03:08:17 1999 Richard Henderson - * tree.c (copy_node): Initialize length. + * sparc.h (PREFERRED_RELOAD_CLASS): Select GENERAL_REGS for + integer data not destined for fp regs. + (LEGITIMIZE_RELOAD_ADDRESS): New. - * c-lex.c (yylex): Initialize traditional_type, ansi_type and type. +Thu Jan 7 03:03:42 1999 Stan Cox + Richard Henderson - * caller-save.c (insert_save_restore): Initialize pat, code and - numregs. + Support for Hypersparc and Sparclite86x: + * sparc.h (TARGET_CPU_hypersparc, TARGET_CPU_sparclite86x): New. + (CPP_CPU32_DEFAULT_SPEC): Fix up for the new targets. + (ASM_CPU32_DEFAULT_SPEC): Likewise. + (TARGET_CPU_DEFAULT): Likewise. + (enum processor_type): Likewise. + (CPP_ENDIAN_SPEC): Handle little endian data. + (LIBGCC2_WORDS_BIG_ENDIAN): Likewise. + (ADJUST_COST): Call sparc_adjust_cost. + * sparc.c (sparc_override_options): Fix up for the new targets. + (supersparc_adjust_cost): Make static. + (hypersparc_adjust_cost): New. + (ultrasparc_adjust_cost): Make static. + (sparc_adjust_cost): New. + * sparc.md (attr cpu): Add hypersparc and sparclite86x. + (function_unit): Add hypersparc scheduling rules. - * emit-rtl.c (push_to_sequence): Initialize top. - (push_topmost_sequence): Likewise. + * configure.in (with_cpu handler): Recognize hypersparc. - * genattrtab.c (simplify_by_exploding): Initialize defval. +Thu Jan 7 23:54:05 1999 Michael Hayes - * profile.c (branch_prob): Initialize dest. + * config/c4x/c4x.c: Added space after negation operator. + * config/c4x/c4x.h: Likewise. + * config/c4x/c4x.md: Likewise. - * rtl.h (note_stores): Remove duplicate prototype. - (GEN_INT): Re-instate cast of second arg to HOST_WIDE_INT. +Thu Jan 7 23:39:27 1999 Michael Hayes - * cplus-dem.c (gnu_special): Don't get confused by . - strings that are not actually lengths. + * config/c4x/c4x.c (c4x_preferred_reload_class): Always return class. - * genattrtab.c: Make generated file use system.h, instead of - including stdio.h, etc directly. - * genextract.c, genopinit.c, genoutput.c: Likewise. - * genpeep.c, genrecog.c: Likewise +Thu Jan 7 00:29:25 1999 Bernd Schmidt - * genoutput.c (process_template): Mark operands in the generated - function as potentially unused if compiling with GNU CC. + * combine.c (num_sign_bit_copies): In NEG, MULT, DIV and MOD cases, + when a test can't be performed due to limited width of + HOST_BITS_PER_WIDE_INT, use the more conservative approximation. + Fix UDIV case for cases where the first operand has the highest bit + set. - * i386/freebsd-elf.h (CPP_PREDEFINES): Update from FreeBSD folks. +Thu Jan 7 00:01:38 1999 Lutz Vieweg - * pa.md (reload peepholes): Remove unused variable "mode". + * pa.h (reg_class): Add FPUPPER_REGS. + (REG_CLASS_NAMES): Similarly. + (REG_CLASS_CONTENTS): Similarly. + (REGNO_REG_CLASS): Handle FPUPPER_REGS. + (FP_REG_CLASS_P): Likewise. + (REG_CLASS_FROM_LETTER): Similarly. + (CLASS_MAX_NREGS): Similarly. -Wed Apr 1 17:06:19 1998 Nick Clifton +1999-01-06 Brendan Kehoe - * config/arm/thumb.h: Add super interworking support. - * config/arm/thumb.c: Add super interworking support. - * config/arm/thumb.md: Add super interworking support. - * config/arm/lib1funcs.asm: Add interworking support. - * config/arm/lib1thumb.asm: Add super interworking support. - * config/arm/t-semi: Add interworking support. - * config/arm/t-thumb: Add interworking support. - * config/arm/README-interworking: New file. + * fixincludes: For HP/UX 10.20, also look in curses_colr/curses.h + for a typedef of bool. Make sure to have a copy of the file is + in place before we look to fix it. Fix typo in variable name to + FILE. -Wed Apr 1 14:38:10 1998 Jim Wilson +Wed Jan 6 07:51:05 1999 Richard Henderson - * config/mips/iris6.h (MD_EXEC_PREFIX): Set to /usr/bin/. - (MD_STARTFILE_PREFIX): Unset. + * expr.c (expand_builtin) [case BUILT_IN_CONSTANT_P]: Use + value_mode for the return mode. -1998-04-01 Mark Mitchell +Wed Jan 6 17:55:19 1999 Robert Lipe - * varasm.c (make_decl_rtl): Update the DECL_ASSEMBLER_NAME for a - entity in a local scope. + * configure.in: New flag --with-dwarf2. If set, enables DWARF-2 + debugging as default. - * fold-const.c (fold): Call truthvalue_conversion for values which - are folded to boolean type. + * config/tm-dwarf2.h: New file. -Wed Apr 1 06:09:53 1998 Jeffrey A Law (law@cygnus.com) +Wed Jan 6 16:08:54 1999 Jeffrey A Law (law@cygnus.com) - * 1750a.md, arm.c, clipper.c, clipper.md: Use GEN_INT consistently. - * convex.h, dsp16xx.c, fx80.md, gmicro.c, gmicro.md: Likewise. - * i370.h, i370.md, i860.c, i860.h, i860.md, i960.c: Likewise. - * i960.h, i960.md, m32r.md, m68k.md, m68kv4.h, m88k.c: Likewise. - * m88k.md, ns32k.c, ns32k.md, pdp11.c, pdp11.h, pdp11.md: Likewise. - * pyr.c, pyr.h, pyr.md, romp.c, romp.h, romp.md: Likewise. - * rs6000.md, sparc.c, sparc.h, sparc.md, spur.c, spur.md: Likewise. - * tahoe.md, vax.h, vax.md, we32k.c, we32k.h, we32k.md: Likewise. - * md.texi: Likewise. + * h8300.h (ASM_OUTPUT_LABELREF): Define. -Wed Apr 1 08:33:44 1998 Manfred Hollstein + * pa.h (DONT_RECORD_EQUIVALENCE): Kill. + * local-alloc.c (update_equiv_regs): Corresponding changes. + * tm.texi (DONT_RECORD_EQUIVALENCE): Kill. - * fixincludes (limits.h): Fix nested comments in Motorola's - limits.h and sys/limits.h. + * calls.c (special_function_p): Push alloca test inside the large + conditional which excludes functions not at file scope or not + extern. -Tue Mar 31 16:57:33 1998 Jim Wilson + * calls.c (special_function_p): New function broken out of + expand_call. + (precompute_register_parameters): Likewise. + (store_one_arg): Likewise. + (store_unaligned_argumetns_into_pseudos): Likewise. + (save_fixed_argument_area): Likewise. + (restore_fixed_argument_area): Likewise. + (expand_call): Corresponding changes. - * alpha.c (alpha_expand_unaligned_load): Use tgt instead of addr - as dest of expand_binop call. +Thu Jan 7 00:12:24 1999 Michael Hayes - * alpha.md (extzv): Correct check for valid operand[2] values. + * config/c4x/c4x.md (addqi3): If the destination operand is + a hard register other than an extended precision register, + emit addqi3_noclobber. + (*addqi3_noclobber_reload): New pattern added so that reload + will recognize a store of a pseudo, equivalent to the sum + of the frame pointer and a constant, as an add insn. - * profile.c (branch_prob): Add code to recognize HPPA tablejump entry - branch. +1999-01-06 Manfred Hollstein - * toplev.c (rest_of__compilation): Call init_recog_no_volatile at end. + * fixinc/fixincl.c: Re-indent according to the GNU standards. + fixinc/server.c: Likewise. + fixinc/server.h: Likewise. -Mon Mar 30 13:11:05 1998 Stan Cox +Wed Jan 6 10:43:29 1999 Andreas Schwab - * libgcc2.c: (__main, __do_global_dtors, __do_global_ctors): - For __CYGWIN32__ use the versions in winsup/dcrt0.cc. + * config/m68k/m68k.c (const_uint32_operand): Remove CONSTANT_P_RTX + handling. + (const_sint32_operand): Likewise. - * gcc.c, cccp.c, cpplib.c, collect2.c (GET_ENVIRONMENT): Added. - cygwin32 can override this to allow both unix and win32 style PATHs. +Wed Jan 6 09:44:51 1999 Kaveh R. Ghazi - * i386/xm-cygwin32.h (GET_ENVIRONMENT): Defined to allow win32 - style environment paths. + * toplev.h: In addition to checking _JBLEN, also check if `setjmp' + is a macro when deciding if we can use `jmp_buf' in prototypes. -Mon Mar 30 14:43:20 1998 Kaveh R. Ghazi +Wed Jan 6 03:18:53 1999 Mark Elbrecht - * Makefile.in (cppalloc.o, cpperror.o, cppexp.o, cpphash.o, - cpplib.o, cppmain.o, fix-header.o, gcov.o, gen-protos.o, - gengenrtl.o, halfpic.o, hash.o, scan-decls.o, scan.o): Depend on - system.h. + * configure.in (pc-msdosdjgpp): Set x_make to x-go32. + * configure: Rebuilt. + * i386/xm-go32.h: Define LIBSTDCXX. + * i386/x-go32: New. + * i386/go32.h (MD_EXEC_PREFIX): Define. + (FILE_NAME_ABSOLUTE_P): Define. + (LINK_COMMAND_SPEC): Define. - * cpphash.c: Include config.h. - * cppalloc.c: Include system.h. Add parameters to various - function prototypes. - * cpperror.c: Likewise. - * cppexp.c: Likewise. - * cpphash.c: Likewise. - * cpplib.c: Likewise. - * cppmain.c: Likewise. - * fix-header.c: Likewise. - * gcov.c: Likewise. - * gen-protos.c: Likewise. - * gengenrtl.c: Likewise. - * halfpic.c: Likewise. - * hash.c: Likewise. - * scan-decls.c: Likewise. - * scan.c: Likewise. +Wed Jan 6 02:23:36 1999 "Charles M. Hannum" -Mon Mar 30 11:06:45 1998 Jim Wilson + * expr.c (store_expr): If the lhs is a memory location pointed + to be a postincremented (or postdecremented) pointer, always + force the rhs to be evaluated into a pseudo. - * README.gnat: Add lang_print_xnode definition. +Wed Jan 6 00:54:21 1999 Geoff Keating -Mon Mar 30 11:12:24 1998 Andreas Schwab + * real.c (mtherr): Print more reasonable warning messages. - * config/m68k/m68k.c (standard_68881_constant_p): Don't use - fmovecr on the 68060. +Tue Jan 5 21:57:42 1999 Kaveh R. Ghazi -Mon Mar 30 00:21:03 1998 Jeffrey A Law (law@cygnus.com) + * Makefile.in (gcc.o, prefix.o, cccp.o, cpplib.o): Depend on prefix.h. - * genemit.c (DONE): Rework so that it works in the true arm if - an if-else conditional. - (FAIL): Likewise. + * cccp.c: Include prefix.h, don't prototype prefix.c functions. + (new_include_prefix): Constify char* parameters. -Sun Mar 29 12:45:23 1998 Jeffrey A Law (law@cygnus.com) + * cppfiles.c (read_name_map): Likewise. + (append_include_chain): Likewise. Also, use a writable char* copy + of parameter `dir' which we then modify, rather than using the + parameter itself to store the new writable string. + (remap_filename): Constify some variables. Also, use a writable + char* to store an allocated string which we will be modifying. - * rs6000.c: Do not include stdioh or ctype.h anymore. + * cpplib.c: Include prefix.h, don't prototype prefix.c functions. + (cpp_start_read): Constify variable `str'. - * Makefile.in (c-typeck.o): Delete on expr.h, insn-codes.h and - $(RTL_H). - (stor-layout.o): Likewise. - * c-typeck.c: Include rtl.h and expr.h. - * stor-layout.c: Likewise. + * cpplib.h (append_include_chain): Constify a char* parameter. - * cpplib.c (cpp_file_line_for_message): Delete unused parameter. - All callers changed. - (do_sccs): Wrap in an SCCS_DIRECTIVE ifdef. - * fix-header.c (cpp_file_line_for_message): Delete unused paramter. - All callers changed. + * gcc.c Include prefix.h, don't prototype prefix.c functions. + (add_prefix, save_string): Constify char* parameters. + (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes. - * collect2.c (is_in_list): Wrap inside COLLECT_EXPORT_LIST ifdef. + * prefix.c: Include prefix.h. + (get_key_value, translate_name, save_string, update_path, + set_std_prefix): Constify various char* parameters and variables. + (save_string): Use xmalloc, not malloc. + (translate_name): Use a writable temporary variable to create and + modify a string before setting it to a const char*. - * local-alloc.c (reg_classes_overlap_p): Delete dead function. + * prefix.h: New file to prototype functions exported from prefix.c. - * tree.h (lang_print_xnode): Provide prototype. +Tue Jan 5 08:52:18 1999 Bruce Korb (korb@datadesign.com) -Sat Mar 28 23:50:44 PST 1998 Jeff Law (law@cygnus.com) + * fixinc/fixincl.c (various): Added debug code so + Manfred can trace the processing. - * version.c: Bump for snapshot. + * fixinc/inclhack.def (sys/utsname.h): Provide forward declaration of + struct utsname on Ultrix V4.[35]. -Sun Mar 29 00:42:21 1998 Jeffrey A Law (law@cygnus.com) + * fixinc/{fixincl.x|fixincl.sh|inclhack.sh} : Regenerated. - * objc/sendmsg.c (__objc_block_forward): Add braces for return - value if INVISIBLE_STRUCT_RETURN. +Mon Jan 4 15:37:30 1999 Zack Weinberg - * pa.c (arith_double_operand): Fix parens. + * cpplib.c (skip_if_group): Split out the logic that handles + directive recognition to its own function. Don't use + parse markers; use a bare pointer into the buffer. Use + copy/skip_rest_of_line instead of doing it by hand. Remove + `return on any directive' mode which was never used, and take + only one argument. + (consider_directive_while_skipping): New function, subroutine + of skip_if_group. Logic streamlined a bit. + (conditional_skip, do_elif, do_else): Call skip_if_group with + only one argument. - * haifa-sched.c (print_pattern): Correct arg to sprintf. +Mon Jan 4 15:27:30 1999 Zack Weinberg - * Makefile.in (libgcc1.null): Make return type for __foo void. + * cpplib.c (do_undef): EOF immediately after '#undef FOO' is not an + error. -Sat Mar 28 14:37:20 1998 Jeffrey A Law (law@cygnus.com) +Mon Jan 4 11:55:51 1999 Jason Merrill - * pa.h: Add declarations for many functions defined in pa.c. + * extend.texi (Bound member functions): Document. - * genpeep.c (main): Remove unused variable 'i' from the generated - file. +Mon Jan 4 11:01:48 1999 Kaveh R. Ghazi - * genemit.c (gen_expand): Do not emit "_done" or "_fail" labels. - (gen_split): Likewise. - (main): Rework generated definitions of DONE and FAIL so that they - no longer use gotos. Avoids warnings about unused labels. + * mips-tdump.c (st_to_string, sc_to_string, glevel_to_string, + lang_to_string, type_to_string): Make return type const char*. + (print_symbol): Apply `const' keyword to a char*. + (print_file_desc): Cast structure member `crfd' to ulong when + comparing against one. - * integrate.c (copy_rtx_and_substitute): Rework to avoid need for - unused "junk" variable. + * mips-tfile.c (pfatal_with_name): Apply `const' keyword to char*. + (fatal, error): Add ATTRIBUTE_PRINTF_1 to prototypes. + (progname, input_name): Apply `const' keyword to a char*. + Don't redundantly include sys/stat.h. + (alloc_info): Apply `const' keyword to a char*. + (st_to_string, sc_to_string): Likewise. + (hash_string): Cast variable `hash_string' to a symint_t when + comparing against one. + (add_string): Cast PAGE_USIZE to Ptrdiff_t when comparing against one. + Likewise cast it to long when comparing against one. + (add_local_symbol): Apply `const' keyword to a char*. + (add_ext_symbol): Likewise. + (add_unknown_tag): Likewise. + (add_procedure): Cast a printf-style field width to an int. + (add_file): Cast PAGE_USIZE to long when comparing against one. + (parse_begin): Cast a printf-style field width to an int. + (parse_bend): Likewise. + (parse_def): Likewise. + (parse_end): Likewise. + (mark_stabs): Mark parameter `start' with ATTRIBUTE_UNUSED. + (parse_stabs_common): Fix format specifier. + (parse_input): Change type of variable `i' to Size_t. + (write_object): Fix arguments to match format specifiers. + Cast variable `num_write' to long when comparing against one. + (read_seek): Cast variable `sys_read' to symint_t when comparing + against one. Fix arguments to match format specifiers. Cast + variable `size' to long when comparing against one. + (copy_object): Cast result of `sizeof' to int when comparing + against one. Fix arguments to match format specifiers. Cast + variable `ifd' to long when comparing against a signed value. + Likewise, likewise. - * genattrtab.c (write_complex_function): Add a default case in - generated switch statement to keep -W -Wall quiet. +Mon Jan 4 10:30:33 1999 Kaveh R. Ghazi -Sat Mar 28 10:47:21 1998 Nick Clifton + * c-common.c (decl_attributes): Allow applying attribute `unused' + on a LABEL_DECL. - * invoke.texi: Document more ARM and Thumb command line options. + * c-parse.in (label): Parse attributes after a label, and call + `decl_attributes' to handle them. - * config/arm/xm-thumb.h: New file. + * gansidecl.h (ATTRIBUTE_UNUSED_LABEL): Define. -Sat Mar 28 01:37:33 1998 Craig Burley + * genrecog.c (OUTPUT_LABEL, write_tree_1, write_tree): When + generating labels, mark them with ATTRIBUTE_UNUSED_LABEL. - * stmt.c (expand_expr_stmt): Must generate code for - statements within an expression (gcc's `({ ... )}') - even if -fsyntax-only. + * invoke.texi: Note that labels can be marked `unused'. -Sat Mar 28 01:06:12 1998 Bernd Schmidt - Jeffrey A Law (law@cygnus.com) +Sun Jan 3 23:32:18 1999 Jeff Law (law@cygnus.com) - * basic-block.h (basic_block_computed_jump_target): Declare. - * flags.h: (current_function_has_computed_jump): Declare. - * flow.c: (basic_block_computed_jump_target): Define. - (flow_analysis): Allocate it. Set current_function_has_computed_jump - to 0. - (find_basic_blocks): Set current_function_has_computed_jump and - elements of basic_block_computed_jump_target to 1 as appropriate. - * function.c: (current_function_has_computed_jump): Define. - * global.c (global_conflicts): Don't allocate pseudos into stack regs - at the start of a block that is reachable by a computed jump. - * reg-stack.c (stack_reg_life_analysis): If must restart, do so - immediately. - (subst_stack_regs): Undo change from Sep 4 1997. - (uses_reg_or_mem): Now unused, deleted. - * stupid.c (stupid_life_analysis): Compute - current_function_has_computed_jump. - (stupid_find_reg): Don't allocate stack regs if the function has a - computed goto. - * haifa-sched.c (is_cfg_nonregular): Delete code to determine if - the current function has a computed jump. Use the global value - instead. + * version.c: Bump for snapshot. -Sat Mar 28 00:21:37 1998 Jeffrey A Law (law@cygnus.com) +Sun Jan 3 23:00:42 1999 Jeffrey A Law (law@cygnus.com) - * i386/freebsd.h (CPP_PREDEFINES): Remove __386BSD__. - (DWARF2_UNWIND_INFO): Define to zero. + * optabs.c (emit_cmp_and_jump_insns): Use CONSTANT_P canonicalizing + RTL for a compare/jump sequence. -Fri Mar 27 16:04:49 1998 Michael Meissner +Sun Jan 3 22:58:15 1999 Michael Hayes - * gcc.c (set_std_prefix): Add declaration. - (process_command): If GCC_EXEC_PREFIX is set, remove /lib/gcc-lib/ - suffix, and update the standard prefix prefix.c uses. + * optabs.c (emit_cmp_insn): Abort if asked to emit non-canonical RTL + for a target with HAVE_cc0 defined. + (emit_cmp_and_jump_insns): New function. + * expr.h (emit_cmp_and_jump_insns): Prototype it. + * loop.c (check_dbra_loop): Use it to replace calls + to emit_cmp_insn and emit_jump_insn and to canonicalize + the comparison if necessary. + * unroll.c (unroll_loop): Likewise. - * prefix.c (std_prefix): New global to hold default prefix value. - (get_key_value): Change to use std_prefix instead of PREFIX. - (translate_name): Ditto. - (update_path): Ditto. - (get_key_value): Release allocated scratch storage. - (set_std_prefix): New function to reset the standard prefix. +Sun Jan 3 21:01:04 1999 Rainer Orth -Fri Mar 27 18:08:21 1998 J"orn Rennecke + * fixincludes (sys/utsname.h): Provide forward declaration of + struct utsname on Ultrix V4.[35]. - * sh.c (find_barrier): Fix calculations for alignment increase. + * mips.md (div_trap): Use local labels instead of dot-relative + branches. -Fri Mar 27 08:56:52 1998 Manfred Hollstein +Sun Jan 3 20:40:34 1999 Jeffrey A Law (law@cygnus.com) - * Makefile.in (stmp-fixinc): If we're actually fixing include - files, copy gcc's assert.h into the fixed include dir. - * fixincludes (assert.h): Avoid any attempts to fix a probably - broken system specific assert.h file. - * fixproto (stdlib.h): Make sure, it'll contain a definition of - size_t. + * pa.md (branch, negated branch): Handle (const_int 0) as first + source operand. + * pa.c (output_cbranch): Likewise. -Fri Mar 27 00:49:46 1998 Jeffrey A Law (law@cygnus.com) +Sun Jan 3 03:20:38 1999 David Edelsohn - * regclass.c (reg_scan_mark_refs): Be more selective about - when we mark a register with REGNO_POINTER_FLAG. + * rs6000.c (rs6000_stack_info): Undo spurious part of last + change. -Thu Mar 26 23:00:11 1998 J"orn Rennecke +1999-01-01 Manfred Hollstein - reload inheritance improvement: - * reload1.c (reg_reloaded_contents, reg_reloaded_insn): - Change meaning: index is now hard reg number. - (reg_reloaded_valid, reg_reloaded_dead): New variables. - (reload_spill_index): Content is now a hard reg number. - (reload_as_needed): Change to fit new variable meaning. - (forget_old_reloads_1, allocate_reload_reg): Likewise. - (choose_reload_regs, emit_reload_insns): Likewise. + * extend.texi (__builtin_constant_p): Add missing @smallexample. -Thu Mar 26 18:34:13 1998 J"orn Rennecke +Fri Jan 1 11:48:20 1999 Jeffrey A Law (law@cygnus.com) - * regclass.c (record_reg_classes): '?' increases cost by two. + * i386.md (doubleword shifts): Fix dumb mistakes in previous change. - * reload.c (find_reloads): Double previous costs. Output - reloads cost one unit extra. +Wed Dec 30 23:38:55 1998 Jeffrey A Law (law@cygnus.com) - * reload1.c (eliminate_regs): Delete LOAD_EXTENDED_OP code that - boiled down to && ! 0. + * m68k.md (adddi_dilshr32): Allow all operands to be registers too. + (adddi_dishl32): Similarly. - * reload.c (find_equiv_reg): Also consider a goal offset from the - frame pointer to be constant. + * cse.c (invalidate_skipped_block): Call invalidate_from_clobbers + for each insn in the skipped block. -Thu Mar 26 17:34:46 1998 J"orn Rennecke + * reload1.c (reload_as_needed): Verify that the insn satisfies its + constraints after replacing a register address with an autoincrement + address for reload inheritance purposes. - * sh.h (OPTIMIZATION_OPTIONS): Define. + * i386.md (doubleword shifts): Avoid namespace pollution. -Thu Mar 26 00:19:47 1998 Richard Henderson +Wed Dec 30 23:00:28 1998 David O'Brien - * combine.c (make_compound_operation): Simplify (subreg (*_extend) 0). + * configure.in (FreeBSD ELF): Needs special crt files. -Wed Mar 25 23:53:11 1998 Jeffrey A Law (law@cygnus.com) +Wed Dec 30 22:50:13 1998 Geoffrey Noer - * pa.c (pa_adjust_cost): Avoid redundant calls to get_attr_type. + * i386/xm-cygwin.h: Change DIR_SEPARATOR to forward slash. -Wed Mar 25 13:40:48 1998 Jim Wilson +1998-12-30 Andreas Schwab - * c-common.c (check_format_info): Initialize type, is_type. New local - integral_format. Don't warn for 'L' when pedantic. Do warn for 'L' - when pedantic if used with integral format specifier. + * loop.c (check_dbra_loop): While reversing the loop, if the + comparison value has a VOID mode use the mode of the other operand + to compute the mask. -Wed Mar 25 16:09:01 1998 Michael Meissner +Wed Dec 30 22:24:00 1998 Michael Meissner - * rs6000.h (FUNCTION_ARG_PADDING): Cast result to be enum - direction. - (function_arg_padding): Declare. + * rs6000.md ({save,restore}_stack_function): Take 2 operands to + avoid warnings in compiling explow.c. - * rs6000.c: Include system.h. - (function_arg_padding): Change return type to int, cast enum's to - int. + (patch from Ken Raeburn, raeburn@cygnus.com) + * rs6000.c (rs6000_stack_info): Force 8-byte alignment of + fpmem_offset. Compute total size after that, and then + rs6000_fpmem_offset using both values. - (From Kaveh R. Ghazi ) - * collect2.c (scan_prog_file): Add explicit braces to avoid - ambiguous `else'. +Mon Dec 28 19:26:32 1998 Gerald Pfeifer - * dbxout.c (dbxout_type_fields): Add braces around empty body in - an if-statement. - (dbxout_type): Likewise. + * gcc.texi (Non-bugs): ``Empty'' loops will be optimized away in + the future; indeed that already happens in some cases. - * rs6000.c (rs6000_override_options): Change type of `i', `j' and - `ptt_size' from int to size_t. - (rs6000_file_start): Likewise for `i'. - (rs6000_replace_regno): Add default case in enumeration switch. - (output_epilog): Remove unused variable `i'. - (rs6000_longcall_ref): Remove unused variables `len', `p', `reg1' - and `reg2'. +Tue Dec 29 11:58:53 1998 Richard Henderson - * rs6000.h (ADDITIONAL_REGISTER_NAMES): Add missing braces around - initializer. - (get_issue_rate, non_logical_cint_operand): Add prototype. - (rs6000_output_load_toc_table): Ditto. + * sparc.c (input_operand): Recognize (const (constant_p_rtx)). + (arith_operand): Remove constant_p_rtx handling. + (const64_operand, const64_high_operand): Likewise. + (arith11_operand, arith10_operand, arith_double_operand): Likewise. + (arith11_double_operand, arith10_double_operand, small_int): Likewise. + (small_int_or_double, uns_small_int, zero_operand): Likewise. + * sparc.h (PREDICATE_CODES): Likewise. - * rs6000.md (udivmodsi4): Add explicit braces to avoid ambiguous - `else'. + * rtl.h (CONSTANT_P): Remove CONSTANT_P_RTX. -Wed Mar 25 10:05:19 1998 Nick Clifton +Tue Dec 29 11:32:54 1998 Richard Kenner - * config/arm/thumb.c: New File. Support for ARM's Thumb - instruction set. - * config/arm/thumb.h: New File. Thumb definitions. - * config/arm/thumb.md: New File. Thumb machine description. - * config/arm/tcoff.h: New File. Thumb COFF support. - * config/arm/t-thumb: New File. Thumb makefile fragment. - * config/arm/lib1thumb.asm: New File. Thumb libgcc support functions. + * rtl.def (CONSTANT_P_RTX): Clarify commentary. + * expr.c (expand_builtin, case BUILT_IN_CONSTANT_P): Rework to + consider constant CONSTRUCTOR constant and to defer some cases + to cse. + * cse.c (fold_rtx, case CONST): Add handling for CONSTANT_P_RTX. + * regclass.c (reg_scan_mark_refs, case CONST): Likewise. - * configure.in: Add Thumb-coff target. - * configure: Add Thumb-coff target. - * config.sub: Add Thumb-coff target. +Tue Dec 29 11:30:10 1998 Richard Henderson -Wed Mar 25 10:30:32 1998 Jim Wilson + * expr.c (init_expr_once): Kill can_handle_constant_p recognition. + * cse.c (fold_rtx, case 'x'): Remove standalone CONSTANT_P_RTX code. - * loop.c (scan_loop): Initialize move_insn_first to zero. + * alpha.c (reg_or_6bit_operand): Remove CONSTANT_P_RTX handling. + (reg_or_8bit_operand, cint8_operand, add_operand): Likewise. + (sext_add_operand, and_operand, or_operand): Likewise. + (reg_or_cint_operand, some_operand, input_operand): Likewise. + * alpha.h (PREDICATE_CODES): Likewise. -Wed Mar 25 01:06:49 1998 Joel Sherrill (joel@OARcorp.com) +Sat Dec 26 23:26:26 1998 Jeff Law (law@cygnus.com) - * config/i386/go32-rtems.h: Defined TARGET_MEM_FUNCTIONS. - * config/i386/rtems.h: Likewise. - * config/i960/rtems.h: Likewise. - * config/m68k/rtems.h: Likewise. - * config/mips/rtems64.h: Likewise. - * config/pa/rtems.h: Likewise. - * config/rs6000/rtems.h: Likewise. - * config/sh/rtems.h: Likewise. - * config/sparc/rtems.h: Likewise. + * version.c: Bump for snapshot. -Wed Mar 25 00:57:26 1998 Richard Kenner +Sat Dec 26 09:17:04 1998 Jeffrey A Law (law@cygnus.com) - * pa.c (emit_move_sequence): If in reload, call find_replacement. + * gengenrtl.c (gencode): Always use bzero to clear memory instead + of dangerous casts and stores. -Tue Mar 24 10:44:11 1998 Nick Clifton + * Makefile.in (compare, gnucompare): Add missing else true clauses. - * Makefile.in (gcov$(exeext)): Support .exe extension to gcov. +Fri Dec 25 23:00:56 1998 Jeffrey A Law (law@cygnus.com) - * collect2.c (find_a_file): Add debugging. - (find_a_file): Test for win32 style absolute paths if - DIR_SERPARATOR is defined. - (prefix_from_string): Add debugging. - (main): Test for debug command line switch at start of program - execution. - (main): Use GET_ENVIRONMENT rather than getenv(). - (prefix_from_env): Use GET_ENVIRONMENT. + * alpha.md (builtin_longjmp): Add missing "DONE". -1998-03-24 Mark Mitchell +Thu Dec 24 10:39:57 1998 Stan Cox - * cplus-dem.c (optable): Add sizeof. - (demangle_template_value_parm): New function containing code - previously found in demangle_template. - (demangle_integral_value): New function which handles complicated - integral expressions. - (demangle_template): Use them. + * gcc.c (execute): Enable -pipe with win32. -Tue Mar 24 12:13:18 1998 Kaveh R. Ghazi +Wed Dec 23 10:27:44 1998 Nick Clifton - * Makefile.in (genconfig.o, genflags.o, gencodes.o, genemit.o, - genopinit.o, genrecog.o, genextract.o, genpeep.o, genattr.o, - genattrtab.o, genoutput.o): Depend on system.h. + * config/arm/t-arm-elf: Add multiplib option for leading + underscores. - * genattr.c: Include system.h. Add arguments to various function - prototypes. Remove redundant prototype of read_rtx(). - * genattrtab.c: Likewise. - * gencodes.c: Likewise. - * genconfig.c: Likewise. - * genemit.c: Likewise. - * genextract.c: Likewise. - * genflags.c: Likewise. - * genopinit.c: Likewise. - * genoutput.c: Likewise. - * genpeep.c: Likewise. - * genrecog.c: Likewise. + * config/arm/thumb.h (ASM_OUTPUT_LABELREF): Use variable + 'user_label_prefix' rather than macro USER_LABEL_PREFIX. -1998-03-24 Martin von Loewis + (thumb_shiftable_const): Use macro 'BASE_REG_CLASS' rather + than variable 'reload_address_base_reg_class'. [Note this + change is unrelated to the others in this patch]. - * c-lang.c (lang_print_xnode): New function. - * objc/objc-act.c (lang_print_xnode): Likewise. - * print-tree.c (print_node): Call it + * config/arm/unknown-elf.h (USER_LABEL_PREFIX): Default to no + leading underscore. -Mon Mar 23 23:59:11 1998 H.J. Lu (hjl@gnu.org) +Wed Dec 23 09:51:32 1998 Kaveh R. Ghazi - * c-parse.in: Recognize protocol qualifiers in class - definitions for objc. - Include "output.h". - (yyerror): Remove redundant decl. - (yyprint): Fix prototype. + * alias.c (record_alias_subset): Remove ignored `&'. + (init_alias_once): Likewise. -Mon Mar 23 23:49:47 1998 Jeffrey A Law (law@cygnus.com) + * c-lex.c (UNGETC): Cast first argument of comma expression to void. - * cse.c (rtx_cost): Only call CONST_COSTS if it is defined. + * config/mips/mips.c (mips_asm_file_end): Cast the result of + fwrite to `int' when comparing against one. - * stmt.c (unroll_block_trees): Free block_vector if needed. + * config/mips/mips.h (CAN_ELIMINATE): Add parens around && within ||. + (INITIAL_ELIMINATION_OFFSET): Add braces to avoid ambiguous `else'. -Mon Mar 23 23:26:42 1998 Philippe De Muyter + * cse.c (rehash_using_reg): Change type of variable `i' to + unsigned int. - * m68k/m68k.md (zero_extendqidi2, zero_extendhidi2): New patterns. - (zero_extendsidi2): Avoid useless copy. - (iordi_zext): New pattern. - (iorsi_zexthi_ashl16): Pattern reworked to avoid "0" constraint for - operand 2. - (iorsi_zext): New name for old unnamed pattern; indentation fixes. + * dwarf2out.c (initial_return_save): Cast -1 to unsigned before + assigning it to one. - * m68k/m68k.md (ashldi_const): Allow shift count in range ]32,63]. - (ashldi3): Allow constant shift count in range ]32,63]. - (ashrdi_const, ashrid3, lshrdi_const, lshrdi3): Likewise. + * except.c (duplicate_eh_handlers): Remove unused variable `tmp'. -1998-03-22 Mark Mitchell + * final.c (final_scan_insn): Likewise for variable `i'. + (output_asm_insn): Cast a char to unsigned char when used as an + array index. - * tree.h (IS_EXPR_CODE_CLASS): New macro. + * gcse.c (compute_pre_ppinout): Cast -1 to SBITMAP_ELT_TYPE when + assigning it to one. -Mon Mar 23 23:18:48 1998 Jeffrey A Law (law@cygnus.com) + * loop.c (strength_reduce): Remove unused variables `count' and `temp'. - * h8300.h (CONST_COSTS): Remove definition. - (DEFAULT_RTX_COSTS): Define. + * recog.c (preprocess_constraints): Cast a char to unsigned char + when used as an array index. -Mon Mar 23 22:58:22 1998 Joel Sherrill (joel@OARcorp.com) + * regmove.c (find_matches): Likewise. - * config/sh/rtems.h: Switched from ELF to COFF. + * reload1.c (calculate_needs): Add default case in switch. + (eliminate_regs_in_insn): Initialize variable `offset'. + (set_offsets_for_label): Change type of variable `i' to unsigned. + (reload_as_needed): Wrap variable `i' in macro check on + AUTO_INC_DEC || INSN_CLOBBERS_REGNO_P. -Mon Mar 23 14:14:20 1998 J"orn Rennecke + * scan-decls.c (scan_decls): Mark parameters `argc' and `argv' + with ATTRIBUTE_UNUSED. Cast variable `start_written' to size_t + when comparing against one. - * freebsd.h (ASM_OUTPUT_ALIGN): Redefine. + * stor-layout.c (layout_decl): Cast maximum_field_alignment to + unsigned when comparing against one. Likewise for + GET_MODE_ALIGNMENT(). + (layout_record): Cast record_align to int when comparing against a + signed value. + (layout_type): Cast TYPE_ALIGN() to int when comparing against a + signed value. -Sat Mar 21 23:52:56 PST 1998 Jeff Law (law@cygnus.com) + * tree.c (get_identifier): Cast variable `len' to unsigned when + comparing against one. + (maybe_get_identifier): Likewise - * version.c: Bump for snapshot. +Wed Dec 23 00:10:01 1998 Jeffrey A Law (law@cygnus.com) -Sun Mar 22 00:50:42 1998 Nick Clifton - Geoff Noer + * toplev.c (rest_of_compilation): Do not set reload_completed. + * reload1.c (reload): Set reload_completed before calling + cleanup_subreg_operands. - * Makefile.in: Various fixes for building cygwin32 native toolchains. +Tue Dec 22 23:58:31 1998 Richard Henderson - * objc/Makefile.in: Various fixes for building cygwin32 native toolchains. - * objc/Make-lang.in: Likewise. + * reload1.c (emit_reload_insns): Check `set' not null before use. - * config/i386/xm-cygwin32.h (PATH_SEPARATOR): Set to a semi-colon. +Tue Dec 22 15:15:45 1998 Nick Clifton -Sun Mar 22 00:21:46 1998 R. Ganesan + * rtlanal.c (multiple_sets): Change type of 'found' from 'rtx' to + 'int'. - * configure.in: Handle with-PACKAGE=no correctly +Tue Dec 22 13:55:44 1998 Theodore Papadopoulo -Fri Mar 20 17:36:23 1998 Kaveh R. Ghazi + * halfpic.c (half_pic_encode): Delete redundant code. - * Makefile.in (alias.o, bitmap.o, c-aux-info.o, c-common.o, - c-decl.o, c-iterate.o, c-lang.o, c-lex.o, c-pragma.o, c-typeck.o, - caller-save.o, calls.o, collect2.o, combine.o, cse.o, dbxout.o, - dwarf2out.o, dwarfout.o, emit-rtl.o, except.o, explow.o, expmed.o, - expr.o, final.o, flow.o, function.o, getpwd.o, global.o, - integrate.o, jump.o, local-alloc.o, loop.o, optabs.o, pexecute.o, - prefix.o, print-rtl.o, print-tree.o, profile.o, real.o, recog.o, - reg-stack.o, regclass.o, regmove.o, reload.o, reload1.o, reorg.o, - rtl.o, rtlanal.o, sdbout.o, stmt.o, stor-layout.o, stupid.o, - tlink.o, toplev.o, tree.o, unroll.o, varasm.o, xcoffout.o): Depend - on system.h. +Tue Dec 22 13:02:22 1998 Michael Meissner - * alias.c, bitmap.c, c-aux-info.c, c-common.c, c-decl.c, - c-iterate.c, c-lang.c, c-lex.c, c-pragma.c, c-typeck.c, - caller-save.c, calls.c, collect2.c, combine.c, cse.c, dbxout.c, - dwarf2out.c, dwarfout.c, emit-rtl.c, except.c, explow.c, expmed.c, - expr.c, final.c, flow.c, function.c, gcc.c, getpwd.c, global.c, - integrate.c, jump.c, local-alloc.c, loop.c, optabs.c, pexecute.c, - prefix.c, print-rtl.c, print-tree.c, profile.c, real.c, recog.c, - reg-stack.c, regclass.c, regmove.c, reload.c, reload1.c, reorg.c, - rtl.c, rtlanal.c, sched.c, sdbout.c, stmt.c, stor-layout.c, - stupid.c, tlink.c, toplev.c, tree.c, unroll.c, varasm.c, - xcoffout.c: Include system.h. Organize include ordering so - that stdarg/varargs comes before other system headers. Remove - spurious casts of functions assured of a prototype in system.h. + * toplev.c (main): Delete handling of -dM as a preprocessor + option. -Fri Mar 20 11:19:40 1998 Stan Cox +Mon Dec 21 17:39:38 1998 Michael Meissner - * reg-stack.c (pop_stack): Define. Pops any register on the - regstack and adjusts regstack. - (compare_for_stack_reg): Use pop_stack. + * toplev.c (main): Don't emit any warnings when using -dD, -dM, or + -dI, which are handled by the preprocessor. -Thu Mar 19 23:51:01 1998 Jeffrey A Law (law@cygnus.com) +Sun Dec 20 16:13:44 1998 John F. Carr - * configure.in (hppa1.0-hp-hpux10): Handle threads for this - config too. + * configure.in: Handle Digital UNIX 5.x the same as 4.x. + * i386/sol2.h: Define LOCAL_LABEL_PREFIX as ".". -Thu Mar 19 20:30:31 1998 Philippe De Muyter +Sun Dec 20 07:39:52 1998 Jeff Law (law@cygnus.com) - * libgcc2.c (exit): Do not call __bb_exit_func if HAVE_ATEXIT. + * version.c: Bump for snapshot. - * fold-const.c (fold): Replace sign-extension of a zero extended - value by a single zero extension. +Sat Dec 19 22:24:22 1998 Jeff Law (law@cygnus.com) -Thu Mar 19 00:58:07 1998 Jason Merrill + * version.c: Bump for snapshot. - * except.c (init_eh): Do nothing. - (save_eh_status): Call init_eh_for_function, not init_eh. - * function.c (push_function_context_to): Don't call init_emit. +Sat Dec 19 21:41:32 1998 Jeff Law (law@cygnus.com) -Thu Mar 19 13:39:52 1998 Michael Meissner + * version.c: Bump for snapshot. - * rs6000/sysv4.h (RELATIVE_PREFIX_NOT_LINKDIR): Undef for System V - and EABI. +Sat Dec 19 09:52:27 1998 Kaveh R. Ghazi + + * genattr.c (fatal): Qualify a char* with the `const' keyword. + + * genattrtab.c (fatal, attr_printf, attr_string, write_attr_set, + write_unit_name, write_eligible_delay, expand_units, + make_length_attrs, write_attr_case, find_attr, + make_internal_attr): Likewise. + * gencheck.c (tree_codes): Likewise. + * gencodes.c (fatal): Likewise. + * genconfig.c (fatal): Likewise. + * genemit.c (fatal): Likewise. + * genextract.c (fatal, walk_rtx, copystr): Likewise. + * genflags.c (fatal): Likewise. + * genopinit.c (fatal, optabs, gen_insn): Likewise. + * genoutput.c (fatal, error, predicates): Likewise. + * genpeep.c (fatal): Likewise. + * genrecog.c (fatal, decision, pred_table, add_to_sequence, + write_tree_1, write_tree, change_state, copystr, indents): Likewise. + +Thu Dec 17 18:21:49 1998 Rainer Orth + + * configure.in (with-fast-fixincludes): Fix whitespace. + * configure: Rebuilt. -Thu Mar 19 10:10:36 1998 Kaveh R. Ghazi + * fixincludes (c_asm.h): Wrap Digital UNIX V4.0B DEC C specific + asm() etc. function declarations in __DECC. - * final.c (shorten_branches): Add parentheses around +/- in - operand of &. +Thu Dec 17 13:57:23 1998 Nick Clifton - * flow.c (life_analysis): Wrap variable `i' in macro ELIMINABLE_REGS. + * expr.c (emit_move_insn_1): Only emit a clobber if the target + is a pseudo register. -Thu Mar 19 09:15:17 1998 Manfred Hollstein +Thu Dec 17 13:50:29 1998 Nick Clifton - * regclass.c (memory_move_secondary_cost): Wrap uses of - SECONDARY_INPUT_RELOAD_CLASS and SECONDARY_OUTPUT_RELOAD_CLASS - with #ifdef tests. + * gcse.c: Include expr.h in order to get the prototype for + get_condition() which is used in delete_null_pointer_checks(). -Thu Mar 19 09:06:35 1998 Manfred Hollstein +Thu Dec 17 15:58:26 1998 Kaveh R. Ghazi - * config/m68k/m68k.md (addqi3): Fix typo gen_INT vs. GEN_INT. + * hwint.h: New file to consolidate HOST_WIDE_INT (etc) macros. - * flow.c (life_analysis): #include to make sure - size_t is defined. - * cplus-dem.c (demangle_function_name): Likewise. +Thu Dec 17 12:31:12 1998 Jim Wilson -Thu Mar 19 09:00:01 1998 Manfred Hollstein + * Makefile.in (INTERNAL_CFLAGS): Add SCHED_CFLAGS. + (ALL_CFLAGS): Delete SCHED_CFLAGS. - * final.c (insn_noperands): Change type to unsigned int. - (final_scan_insn): Likewise for noperands; - properly check operand number boundaries. +1998-12-17 Vladimir N. Makarov -Wed Mar 18 16:20:30 1998 Richard Henderson + * config/i60/i960.md (extendqihi2): Fix typo (usage ',' instead of + ';'). - * alpha.md (extzv): Don't reject register operands. Fix - mode of operand 1. +1998-12-17 Michael Tiemann -Wed Mar 18 16:14:23 1998 Richard Henderson + * i960.md (extend*, zero_extend*): Don't generate rtl that looks + like (subreg:SI (reg:SI N) 0), because it's wrong, and it hides + optimizations from the combiner. - * dbxout.c (dbxout_function_end): Fix last change. The correct - predicate is ASM_OUTPUT_SECTION_NAME. +Thu Dec 17 08:27:03 1998 J"orn Rennecke -Wed Mar 18 12:43:20 1998 Jim Wilson + * loop.c (combine_givs_used_by_other): Don't depend on n_times_set. - * sh.md (ashlsi_c-1): Delete 3rd argument to gen_ashlsi_c. - (ashlsi): Use match_dup 1 instead of match_operand 2. +Wed Dec 16 17:30:35 1998 Nick Clifton -Wed Mar 18 13:46:07 1998 Richard Kenner + * toplev.c (main): Disable optimize_size if a specific + optimization level is requested. Always set optimization + level to 2 if -Os is specified. - * fold-const.c (operand_equal_for_comparison_p): See if equal - when nop conversions are removed. +Wed Dec 16 16:33:04 1998 Dave Brolley -Wed Mar 18 13:42:01 1998 Richard Kenner + * objc/lang-specs.h: Pass -MD, -MMD and -MG to cc1obj if configured with + cpplib. + * cpplib.c (cpp_start_read): If in_fname is not initialized, try to + initialize it using fname. - * expr.c (expand_expr, case COND_EXPR): If have conditional move, - don't use ORIGINAL_TARGET unless REG. +1998-12-16 Zack Weinberg -Wed Mar 18 16:53:19 1998 J"orn Rennecke + * cpplib.c (do_include): Treat #include_next in the + primary source file as #include plus warning. Treat + #include_next in a file included by absolute path as an + error. fp == CPP_NULL_BUFFER is a fatal inconsistency. - * netbsd.h (ASM_OUTPUT_ALIGN): Redefine. +Wed Dec 16 12:28:54 1998 Kaveh R. Ghazi -Wed Mar 18 12:43:20 1998 Jim Wilson + * cccp.c: Don't define MIN/MAX anymore. + * cpplib.c: Likewise. + * machmode.h: Likewise. + * system.h: Provide definitions for MIN/MAX. + +Tue Dec 15 23:47:42 1998 Zack Weinberg + + * fix-header.c: Don't define xstrdup here. + +Wed Dec 16 05:11:04 1998 J"orn Rennecke + + * loop.c (consec_sets_giv): New argument last_consec_insn. + (strength_reduce): Provide / use it. + +Wed Dec 16 17:24:07 1998 Michael Hayes - * loop.c (struct movable): New field move_insn_first. - (scan_loop): In consec sets code, set it. Clear it otherwise. - (move_movables): In consec sets code, use it. Copy REG_NOTES from - p to i1 only if i1 does not have REG_NOTES. Delete obsolete ifdefed - out code. + * loop.h (loop_info): New field 'vtop'. + * loop.c (check_dbra_loop): Use loop_info->vtop rather than + scanning loop for vtop. + * unroll.c (subtract_reg_term, find_common_reg_term): New functions. + (loop_iterations): Use them to determine if loop has a constant + number of iterations. Set loop_info->vtop. Don't subtract + common reg term from initial_value and final_value if have a + do-while loop. + +Tue Dec 15 13:49:55 1998 Jeffrey A Law (law@cygnus.com) + + * mn10200.md (addsi3 expander): Use "nonmemory_operand" for operand 2. + + * mn10300.md (bset, bclr): Operand 0 is a read/write operand. + + * mn10200.md (abssf2, negsf2): New expanders. -Wed Mar 18 09:52:56 1998 Richard Henderson + * mn10300.md (absdf2, abssf2, negdf2, negsf2): New expanders. + +Tue Dec 15 11:55:30 1998 Nick Clifton - * rtl.c (read_rtx): Fall back on homebrew atoll if HOST_WIDE_INT - is large, and the system doesn't provide atoll or atoq. - (atoll): New. + * integrate.c (copy_rtx_and_substitute): If a SUBREG is + replaced by a CONCAT whose components do not have the same + mode as the original SUBREG, use a new SUBREG to restore the + mode. + + * emit-rtl.c (subreg_realpart_p): Cope with subregs containing + multiword complex values. - * alpha/xm-vms.h (HAVE_ATOLL): Define. - Reported by Klaus Kaempf . +1998-12-15 Zack Weinberg -Wed Mar 18 09:56:26 1998 Kaveh R. Ghazi + * cppalloc.c: Add xstrdup here. + * cpplib.h: Remove savestring prototype. + * cpplib.c: Remove savestring function. s/savestring/xstrdup/ + throughout. + * cppfiles.c: s/savestring/xstrdup/ throughout. - * c-lang.c (finish_file): Wrap variable `void_list_node' with macro - test !ASM_OUTPUT_CONSTRUCTOR || !ASM_OUTPUT_DESTRUCTOR. +1998-12-15 Zack Weinberg - * calls.c (emit_call_1): Wrap variable `already_popped' with macro - test !ACCUMULATE_OUTGOING_ARGS. + * cpplib.c: Make all directive handlers read their own + arguments. + (struct directive): Remove last two arguments from FUNC + member prototype. Remove `command_reads_line' member + entirely. + (directive_table): Remove initializations of + command_reads_line flag. Pretty-print. + (eval_if_expression, do_define, do_line, do_include, + do_undef, do_error, do_pragma, do_ident, do_if, do_xifdef, + do_else, do_elif, do_sccs, do_assert, do_unassert, + do_warning): Take only two args. - * collect2.c (write_c_file_glob): Wrap function definition in - macro test !LD_INIT_SWITCH. + (cpp_define): Call do_define with two args and the text to + define stuffed into a buffer. + (make_assertion): Call do_assert with two args. + (handle_directive): Call do_line with two args. Call + kt->func with two args. Remove command_reads_line + processing. + (do_define, do_undef, do_error, do_warning, do_pragma, + do_sccs): Read the rest of the line here. + (do_ident): Gobble rest of line, as cccp does. + (cpp_undef): New function. + (cpp_start_read): Call cpp_undef instead of do_undef. - * combine.c (try_combine): Wrap variables `cc_use' and - `compare_mode' in macro test EXTRA_CC_MODES. +1998-12-15 Zack Weinberg - * cpplib.c (do_ident): Remove unused variable `len'. - (skip_if_group): Remove unused variables `at_beg_of_line' and - `after_ident'. - (cpp_get_token): Remove unused variable `dummy'. + * cpphash.h (union hash_value): Remove `keydef' member, add a + `struct hashnode *aschain' member for #assert. - * dbxout.c (scope_labelno): Move static variable definition inside - the one function scope where it is used. - (dbxout_function_end): Wrap prototype and definition in - macro test !NO_DBX_FUNCTION_END. + * cpplib.c (struct tokenlist_list, struct + assertion_hashnode): Delete structure definitions. + (assertion_install, assertion_lookup, delete_assertion, + check_assertion, compare_token_lists, reverse_token_list, + read_token_list, free_token_list): Delete functions. + (parse_assertion): New function. + (cpp_cleanup): Don't destroy the assertion_hashtable. - * dwarf2out.c (add_subscript_info): Wrap variable `dimension_number' - in macro test !MIPS_DEBUGGING_INFO. + (do_assert): Gut and rewrite. #assert foo (bar) places + entries for `#foo' and `#foo(bar)' in the macro hash table, + type T_ASSERT. The value union's `aschain' member is used + to chain all answers for a given predicate together. + (do_unassert): Also rewritten. Take an un-asserted + answer off the chain from its predicate and call + delete_macro on the hashnode, or walk a predicate chain + calling delete_macro on all the entries. + (cpp_read_check_assertion): Simply call parse_assertion to + get the canonical assertion name, and look that up in the + hash table. - * expr.c (expand_builtin_setjmp): Move declaration of variable `i' - into the scope where it is used. Wrap empty else-statement body - in braces. + * cpplib.h (ASSERTION_HASHNODE,ASSERTION_HASHSIZE,assertion_hashtab): + Removed. - * fix-header.c: Fix typo in comment. - (inf_skip_spaces): Cast results of INF_UNGET to (void). - (check_protection, main): Likewise. + * cpphash.c (install): Use bcopy instead of an explicit loop + to copy the macro name. - * flow.c (find_basic_blocks_1): Remove dangling comment text. + * cppexp.c (cpp_lex): Convert the result of + cpp_read_check_assertion to a `struct operation' directly; + don't go through parse_number. - * function.c (contains): Wrap prototype and definition in macro - test HAVE_prologue || HAVE_epilogue. - (fixup_var_refs_1): Remove unused variable `width'. +Tue Dec 15 18:27:39 1998 J"orn Rennecke - * gen-protos.c (main): Remove unused variable `optr'. + * loop.h (struct induction): Delete times_used member. + * loop.c (n_times_set): Rename to set_in_loop. Changed all users. + (n_times_used): Rename to n_times_set. Changed all users. + (scan_loop): Free reg_single_usage before strength reduction. + (record_giv, combine_givs): Remove handling of times_used member. + (combine_givs_used_once): Rename to: + (combine_givs_used_by_other) . Changed all callers. - * haifa-sched.c (debug_control_flow): Remove unused variable `j'. +Tue Dec 15 01:45:26 1998 Jason Merrill - * libgcc2.c (__udiv_w_sdiv): Provide dummy return value of 0. - (__sjpopnthrow): Remove unused variable `jmpbuf'. - (__throw): Remove unused variable `val'. + * dwarf2out.c (gen_struct_or_union_type_die): Check AGGREGATE_TYPE_P + instead of TREE_CODE_CLASS == 't'. + (gen_type_die): Likewise. + (scope_die_for): Ignore FUNCTION_TYPE "scopes". - * protoize.c: Check for a previously existing definition before - defining *_OK macros. +Mon Dec 14 16:23:27 1998 Jim Wilson - * scan-decls.c (scan_decls): Remove unused variable `old_written'. + * real.c (endian): Disable last change unless + HOST_BITS_PER_WIDE_INT is greater than 32. + +Mon Dec 14 17:13:36 1998 Andrew MacLeod + + * output.h (force_data_section): New prototype. + * varasm.c (force_data_section): New function to force the + data section, regardless of what in_section thinks. + * dwarf2out.c (output_call_frame_info): Call force_data_section + since varasm may not realize we've changes sections. + +Mon Dec 14 14:09:34 1998 Nick Clifton + + * reload1.c (reload): Delete REG_RETVAL and REG_LIBCALL notes + after completing reload. + + * rtl.texi: Document that REG_RETVAL and REG_LIBCALL are + deleted after reload. + +Mon Dec 14 01:39:28 1998 Jeffrey A Law (law@cygnus.com) + + * rtl.h (multiple_sets): Fix prototype. + * rtlanal.c (multiple_sets): Fix return type. + +Sun Dec 13 12:43:58 1998 Jeff Law (law@cygnus.com) -Tue Mar 17 00:45:48 1998 J"orn Rennecke + * version.c: Bump for snapshot. - * vax.h (ADDR_VEC_ALIGN): Define. +Sun Dec 13 01:05:22 1998 Jeff Law (law@cygnus.com) -Mon Mar 16 15:57:17 1998 Michael Meissner + * version.c: Bump for snapshot. - * gcc.c (default_arg): Don't wander off the end of allocated - memory. +1998-12-13 Manfred Hollstein - (From Geoffrey Keating ) - * rs6000.c (small_data_operand): Ensure that any address - referenced relative to the small data area is inside the SDA. + * protoize.c (fputs): Wrap extern declaration in #ifndef fputs. -Mon Mar 16 12:55:15 1998 Jim Wilson +Sun Dec 13 00:24:14 1998 J"orn Rennecke - * config/m68k/netbsd.h (ASM_SPEC): Add %{m68060}. + * rtl.h (recompute_reg_usage): Add second argument. + * flow.c (recompute_reg_usage): Likewise. + * toplev.c (rest_of_compilation): Supply second argument to + recompute_reg_usage. -Mon Mar 16 15:50:20 EST 1998 Andrew MacLeod + * reload1.c (compute_use_by_pseudos): Allow reg_renumber[regno] < 0 + after reload. - * except.h (in_same_eh_region): New prototype. - (free_insn_eh_region, init_insn_eh_region): New prototypes. - * except.c (insn_eh_region, maximum_uid): New static variables. - (set_insn_eh_region): New static function to set region numbers. - (free_insn_eh_region): New function to free EH region table. - (init_insn_eh_region): New function to initialize EH region table. - (in_same_eh_region): New function used to determine if two rtl - instructions are in the same exception region or not. - * final.c (final): Initialize the table indicating which instructions - belong in which exception region. - * genpeep.c (main): Add "except.h" to include file list in generated - file insn-peep.c. - * config/sparc/sparc.md: Add calls to 'in_same_eh_region' in 4 - peepholes involving calls and unconditional branches. +Sat Dec 12 23:39:10 1998 Jeffrey A Law (law@cygnus.com) -Mon Mar 16 11:16:50 1998 Jim Wilson + * m68k/t-m68kelf (MULTILIB_OPTIONS): Add mcpu32. + (MULTILIB_MATCHES): -m68332 now uses mcpu32 libraries, not m68000. + (MULTILIB_EXCEPTIONS): Don't build 68881 libraries for m68000, + mcpu32 or m5200. - * README.gnat: New file. + * i386/next.h (ASM_OUTPUT_ALIGN): Use 0x90 for fill character. -Mon Mar 16 11:14:20 1998 Andreas Schwab + * rtlanal.c (multiple_sets): New function. + * rtl.h (multiple_sets): Declare it. + * local-alloc.c (wipe_dead_reg): Use it. + * global.c (global_conflicts): Likewise. - * config/m68k/m68k.c: Include for atoi. Include - "recog.h" for offsettable_memref_p. - (legitimize_pic_address): Remove unused variable `offset'. - (notice_update_cc): Change return type to void. Add default label - to switch. - (standard_68881_constant_p): Remove unused variable mode. - (print_operand): Define local variable i only if SUPPORT_SUN_FPA. - (const_int_cost): Explicitly declare as returning int. - (output_dbcc_and_branch): Change return type to void. +Sat Dec 12 22:13:02 1998 Mark Mitchell - * config/m68k/linux.h, config/m68k/m68k.md, config/m68k/m68k.c, - config/m68k/m68k.h: Replace gen_rtx (XXX, ...) with gen_rtx_XXX - (...). Use GEN_INT instead of gen_rtx_CONST_INT. + * global.c (record_conflicts): Don't use an array of shorts to + store an array of ints. + (global_conflicts): Likewise. -Sun Mar 15 22:30:44 PST 1998 Jeff Law (law@cygnus.com) +Sat Dec 12 16:49:24 1998 Richard Henderson - * version.c: Bump for snapshot. + * alpha.c (alpha_expand_block_move): mode_for_size expects + bits, not bytes. Infer extra alignment from addressof. -Fri Mar 13 11:30:12 1998 Andreas Schwab +1998-12-11 Michael Meissner - * config/m68k/m68k.h (CONST_OK_FOR_LETTER_P): Fix logic in range - check for 'M' constraint. + * rs6000/sysv4.h (ASM_OUTPUT_ALIGNED_LOCAL): Put small data in the + .sbss section, not .sdata. -Thu Mar 12 14:47:14 1998 Jim Wilson +1998-12-11 Manfred Hollstein - * cccp.c (create_definition): If pedantic, call pedwarn for macro - varargs feature. + * cccp.c: Do not #include here; this is already done + by "system.h". + * collect2.c: Likewise. + * cpplib.h: Likewise. + * gcc.c: Likewise. + * gcov.c: Likewise. + * getpwd.c: Likewise. + * protoize.c: Likewise. + * toplev.c: Likewise. -Thu Mar 12 13:43:25 1998 Bernd Schmidt + * cpplib.h (HOST_WIDE_INT): Get definition from "machmode.h" + and don't try to define it here. + * Makefile.in (cppmain.o): Depend on machmode.h. + (cpplib.o): Likewise. + (cpperror.o): Likewise. + (cppexp.o): Likewise. + (cppfiles.o): Likewise. + (cpphash.o): Likewise. + (cppalloc.o): Likewise. + (fix-header.o): Likewise. + (scan-decls.o): Likewise. - * i386.c (ix86_logical_operator): New function. - (split_di): Ensure that when a MEM is split, the resulting MEMs have - SImode. - * i386.md (anddi3, xordi3, iordi3): New patterns. Add a define_split - to implement them. +Fri Dec 11 11:02:49 1998 Stan Cox -Thu Mar 12 15:13:16 1998 Kaveh R. Ghazi - Richard Earnshaw - Nick Clifton + * sh.c (print_operand): Lookup interrupt_handler attribute instead + of relying on static variable. + * (calc_live_regs): Likewise. + * (sh_pragma_insert_attributes): Create interrupt_handler + attribute if a pragma was specified. + * (sh_valid_machine_decl_attribute): Don't set static flag. + * sh.h (PRAGMA_INSERT_ATTRIBUTES): New. - * tm.texi (DEFAULT_RTX_COSTS): Document new macro. +Fri Dec 11 12:56:07 1998 J"orn Rennecke - * arm.h (DEFAULT_RTX_COSTS): Define instead of RTX_COSTS. + * reload1.c (reload_combine): Use BASIC_BLOCK_LIVE_AT_START + to determine if a register is live at a jump destination. + Everything is dead at a BARRIER. - * cse.c (rtx_cost): Provide a default case in an enumeration - switch, and call DEFAULT_RTX_COSTS if it's defined. +Thu Dec 10 16:02:06 1998 Jim Wilson -Thu Mar 12 10:02:38 1998 Manfred Hollstein + * cse.c (simplify_unary_operation): Sign-extend constants when + they have the most significant bit set for the target. + * real.c (endian): Sign-extend 32 bit output values on a 64 bit + host. + * m32r/m32r.c (m32r_expand_prologue): Store pretend_size in + HOST_WIDE_INT temporary before negating it. + * m32r/m32r.md (movsi_insn+1): Use ~0xffff instead of 0xffff0000. - * basic-block.h (compute_preds_succs): Change return type in - prototype to void. - * flow.c (compute_preds_succs): Likewise in function definition. +Thu Dec 10 15:05:59 1998 Dave Brolley - * regmove.c (find_matches): Cast char used as array index to unsigned char - to supress warning. + * objc/objc-act.c (lang_init_options): Enclose cpplib related code in + #if USE_CPPLIB. -Thu Mar 12 09:39:40 1998 Manfred Hollstein +Thu Dec 10 13:39:46 1998 Kaveh R. Ghazi - * i386.h (RTX_COSTS): Insert braces around nested if. - (ADDITIONAL_REGISTER_NAMES): Insert braces around structured - elements. + * collect2.h: New header file for prototypes. - * gcc.c (default_compilers): Properly put brackets around array elements in - initializer. + * Makefile.in (collect2.o, tlink.o): Depend on collect2.h. - * getopt.c (_getopt_internal): Add explicit braces around nested if; - reformatted. + * collect2.c: Include collect2.h. + * tlink.c: Likewise. - * reg-stack.c (record_asm_reg_life): Add explicit braces around nested if's. - (record_reg_life_pat): Add explicit parens around && and || in expression. - (stack_reg_life_analysis): Add parens around assignment used as expression. - (convert_regs): Likewise. +Wed Dec 9 23:55:11 1998 Jeffrey A Law (law@cygnus.com) -Thu Mar 12 09:25:29 1998 Manfred Hollstein + * flow.c: Update some comments. - * bitmap.c (bitmap_element_allocate): Remove unused parameter; - change callers accordingly. +Wed Dec 9 15:29:26 1998 Dave Brolley - * cplus-dem.c (arm_special): Remove unused parameter work in prototype - and definition; change all callers accordingly. + * objc/objc-act.c (cpp_initialized): Removed. + (lang_init_options): Initialize cpplib. + (lang_decode_option): Move initialization of cpplib to + lang_init_options. + * c-lang.c (parse_options,parse_in): Added. + (lang_init_options): Initialized cpplib here. + * c-decl.c (parse_options,cpp_initialized): Removed. + (c_decode_option): Move initialization of cpplib to + lang_init_options. - * except.c (init_eh): Avoid assignment of unused return value of - build_pointer_type; cast it to void, instead, and remove unused - variable type. +Wed Dec 9 19:36:57 1998 J"orn Rennecke - * gcc.c (lang_specific_driver): Define prototype only #ifdef - LANG_SPECIFIC_DRIVER. - (temp_names): Define only #ifdef MKTEMP_EACH_FILE. + * reload1.c (reload_combine, reload_combine_note_store): + Make STORE_RUID always valid. + (reload_combine): Check if BASE is clobbered too early. - * genoutput.c (output_epilogue): Initialize next_name to 0. +Wed Dec 9 09:53:58 1998 Nick Clifton + + * reload.c (find_reloads): Display the insn that cannot be + reloaded. + +Wed Dec 9 12:15:26 1998 Dave Brolley + + * cccp.c (create_definition): Fix end of buffer logic. + +Wed Dec 9 10:15:45 1998 Kaveh R. Ghazi + + * except.c (duplicate_eh_handlers, rethrow_symbol_map): Function + pointer parameters changed to use the PARAMS() macro. + +Wed Dec 9 09:12:40 1998 Andrew MacLeod - * real.c (efrexp): #if 0 prototype and function definition. - (eremain): Likewise. - (uditoe): Likewise. - (ditoe): Likewise. - (etoudi): Likewise. - (etodi): Likewise. - (esqrt): Likewise. + * except.h (struct handler_info): Add handler_number field. + * except.c (gen_exception_label): EH labels no longer need to be + on the permanent obstack. + (get_new_handler): Set the label number field. + (output_exception_table_entry): Regenerate handler label reference + from the label number field. + (init_eh): Remove a blank line. + * integrate.c (get_label_from_map): Labels no longer need to be + on the permanent obstack. - * reload.c (push_secondary_reload): Define prototype only - #ifdef HAVE_SECONDARY_RELOADS. +Tue Dec 8 22:04:33 1998 Jim Wilson - * varasm.c (assemble_static_space): Define rounded only - #ifndef ASM_OUTPUT_ALIGNED_LOCAL. + * i960/i960.h (CONST_COSTS, case CONST_INT): Accept power2_operand + only when OUTER_CODE is SET. -Thu Mar 12 09:11:35 1998 Manfred Hollstein +Tue Dec 8 22:47:15 1998 J"orn Rennecke - * i386.md (andsi): Add default case in enumeration switch. - (iorsi3): Likewise. - (iorhi3): Likewise. - (xorsi3): Likewise. + * loop.c (strength_reduce): If scan_start points to the loop exit + test, be wary of subversive use of gotos inside expression statements. + Don't set maybe_multiple for a backward jump that does not + include the label under consideration into its range. + * unroll.c (biv_total_increment): Make use of maybe_multiple field. -Thu Mar 12 08:37:02 1998 Manfred Hollstein +Tue Dec 8 22:33:18 1998 J"orn Rennecke - * c-decl (finish_struct): Change type of min_align to unsigned. + * explow.c (plus_constant_wide): Don't immediately return with + result of recursive call. - * cplus-dem.c (demangle_function_name): Change type of variable i to size_t; - remove unused variable len. +Tue Dec 8 15:32:56 1998 Andrew MacLeod - * dwarf2out.c (reg_save): Add explicit cast of -1 to unsigned and a - comment indicating this is proper behaviour. - (reg_loc_descriptor): Remove redundant comparison of unsigned variable - reg >= 0. - (based_loc_descr): Likewise. + * eh-common.h (struct eh_context): Add table_index for rethrows. - * enquire.c (bitpattern): Change type of variable i to unsigned. + * rtl.h (enum reg_note): Add REG_EH_REGION and REG_EH_RETHROW reg notes. + (SYMBOL_REF_NEED_ADJUST): New flag indicating symbol needs to be + processed when inlined or unrolled (ie duplicated in some way). - * final.c (output_asm_insn): Don't cast insn_noperands to unsigned. + * rtl.c (reg_note_name): Add strings for new reg_note enums. - * flow.c (life_analysis): Change type of variable i to size_t; - remove unused variable insn. + * expr.h (rethrow_libfunc): New library decl. - * gcc.c (translate_options): Change type of variables optlen, arglen and - complen to size_t. - (input_filename_length): Change type to size_t. - (do_spec_1): Change type of variable bufsize to size_t. - (main): Change type of variables i and j to size_t; - remove subblock local definition of variable i. - (lookup_compiler): Change type of second argument to size_t; - change type of variable i to size_t. + * optabs.c (rethrow_libfunc): Initialize. - * genemit.c (output_init_mov_optab): Change type of variable i to size_t. + * except.h (struct eh_entry): Add new field 'rethrow_label'. + (new_eh_region_entry): No longer exported from except.c. + (duplicate_handlers): Renamed to duplicate_eh_handlers and + different prototype. + (rethrow_symbol_map, rethrow_used): New exported functions. + (eh_region_from_symbol): New exported function. - * genopinit.c (get_insn): Change type of variable pindex to size_t. + * except.c (create_rethrow_ref): New function to create a single + SYMBOL_REF for a rethrow region. + (push_eh_entry): Initialize a rethrow ref. + (func_eh_entry): Add a rethrow_label field. + (new_eh_region_entry): Make static, and initialize the rethrow entry. + (duplicate_eh_handlers): Create a new region, and remap labels/symbols. + (eh_region_from_symbol): Find an EH region based on its rethrow symbol. + (rethrow_symbol_map): Given a label map, maps a rethrow symbol for + a region into an appropriate new symbol. + (rethrow_used): Indicate whether a rethrow symbol has been referenced. + (expand_eh_region_end): Don't issue jump around code for new-exceptions. + (end_catch_handler): Emit a barrier for new-exceptions since + control can never drop through the end of a catch block. + (expand_end_all_catch): new-exceptions never fall through a catch + block. + (expand_rethrow): Use __rethrow routine for new exceptions. + (output_exception_table_entry): Generate rethrow labels, if needed. + (output_exception_table): Generate start and end rethrow labels. + (init_eh): Create rethrow symbols for beginning and end of table. + (scan_region): Don't eliminate EH regions which are the targets of + rethrows. - * genrecog.c (add_to_sequence): Change type of variable i to size_t. + * flow.c (make_edges): Add different edges for rethrow calls, + identified by having the REG_EH_RETHROW reg label. + (delete_unreachable_blocks): Don't delete regions markers which are + the target of a rethrow. - * global.c (global_alloc): Change type of variable i to size_t. + * integrate.c (save_for_inline_eh_labelmap): New callback routine to + allow save_for_inline_copying to call duplicate_eh_handlers. + (save_for_inline_copying): Call duplicate_eh_handlers instead of + exposing internal details of exception regions. + (copy_for_inline): Check if SYMBOL_REFs need adjustment. + (expand_inline_function_eh_labelmap): New callback routine to + allow expand_inline_function to call duplicate_eh_handlers. + (expand_inline_function): Call duplicate_eh_handlers instead of + exposing internal details of exception regions. + (copy_rtx_and_substitute): Adjust SYMBOL_REFS if SYMBOL_REF_NEED_ADJUST + flag is set. - * regclass.c (init_reg_sets): Change type of variables i and j to unsigned. + * libgcc2.c (find_exception_handler): Generalize to enable it to + pick up processing where it left off last time for a rethrow. + (__unwinding_cleanup): New function. debug hook which is called before + unwinding when __throw finds there is nothing but cleanups left. + (throw_helper): Common parts of __throw extracted out for reuse. + (__throw): Common parts moved to throw_helper. + (__rethrow): New function for performing rethrows. - * stmt.c (expand_end_bindings): Change type of variable i to size_t. - (expand_end_case): Change type of variable count to size_t. +Tue Dec 8 13:11:04 1998 Jeffrey A Law (law@cygnus.com) - * toplev.c (main): Change type of variable j to size_t. - (set_target_switch): Change type of variable j to size_t. - (print_switch_values): Change type of variable j to size_t; - remove unused variable flags. + * reload1.c (current_function_decl): Tweak declaration. - * varasm.c (assemble_variable): Change type of variable align to size_t. - (const_hash_rtx): Change type of variable i to size_t. +Tue Dec 8 10:23:52 1998 Richard Henderson + + * c-decl.c (flag_isoc9x): Default off. + (c_decode_option): Kill -std=gnu, add -std=gnu89 and -std=gnu9x. + * cccp.c (print_help, main): Likewise. + * gcc.c (default_compilers): Update for -std=gnu*. -1998-03-11 Mark Mitchell +Tue Dec 8 01:14:46 1998 Jeffrey A Law (law@cygnus.com) - * dbxout.c (dbxout_type_methods): Only treat TYPE_METHODS as a - TREE_VEC if that's what it really is. + * Makefile.in (DEMANGLE_H): Change location to shared demangle.h. + * demangle.h: Deleted. -Wed Mar 11 15:16:01 1998 Michael Meissner + * reload1.c (current_function_decl): Declare. - * {haifa-,}sched.c (rank_for_schedule): Only take void * arguments - as per ISO C spec. +Tue Dec 8 11:58:51 1998 Kaveh R. Ghazi -Wed Mar 11 12:05:20 1998 Teemu Torma + * cpplib.c (convert_string): Use `0x00ff', not `0x00ffU'. + +Tue Dec 8 09:28:36 1998 Kaveh R. Ghazi - * gthr.h: Changed the comment about return values. - * gthr-solaris.h (__gthread_once): Do not use errno; return the - error number instead of -1. - (__gthread_key_create): Any non-zero return value is an error. - * libgcc2.c (eh_context_initialize): Check for non-zero return - value from __gthread_once. - Check that the value of get_eh_context was really changed. + * dbxout.c: If USG is defined use gstab.h, even if HAVE_STAB_H is set. -Wed Mar 11 18:26:25 1998 J"orn Rennecke +1998-12-08 Ulrich Drepper - * sh.h (LOOP_ALIGN): Only align when optimizing. - * sh.c (find_barrier): Clear inc for CODE_LABELs. - When not optimizing, calculate alignment for BARRIERs directly. + * configure.in: Test for availability of putc_unlocked, fputc_unlocked, + and fputs_unlocked. + * configure: Rebuilt. + * system.h: If the *_unlocked functions are available use them + instead of the locked counterparts by defining macros. + * config.in: Regenerated. -Wed Mar 11 15:07:18 1998 J"orn Rennecke +Tue Dec 8 00:34:05 1998 Mike Stump - * final.c (shorten_branches): Remove conditionalizing on - SHORTEN_WITH_ADJUST_INSN_LENGTH - * sh.h, pa.h (SHORTEN_WITH_ADJUST_INSN_LENGTH): Remove. + * i386/bsd.h (ASM_FILE_START): Don't use dump_base_name, it is + wrong and should only be used for dump related things, not + debugging information, instead main_input_filename should be used. + Also, reuse output_file_directive if possible. + * i386/aix386ng.h (ASM_FILE_START): Likewise. + * i386/isc.h (ASM_FILE_START): Likewise. + * i386/win-nt.h (ASM_FILE_START): Likewise. + * i386/sun386.h (ASM_FILE_START): Likewise. -Wed Mar 11 02:37:41 1998 Jeffrey A Law (law@cygnus.com) +Mon Dec 7 23:56:28 1998 Robert Lipe - * flow.c (find_basic_blocks_1): Keep the cfg accurate when removing - an unconditional jump around deleted blocks. + * configure.in (mips*-*-linux*): Handle big and little endian + systems. + * configure: Rebuilt. -Mon Mar 9 12:02:23 1998 Jim Wilson +Mon Dec 7 23:14:51 1998 Mike Stump - * profile.c (branch_prob): If see computed goto, call fatal instead of - abort. + * emit-rtl.c: Fix typo. - * config/mips/sni-svr4.h (CPP_PREDEFINE): Add -DSNI and -Dsinix. +Mon Dec 7 23:07:38 1998 Nathan Sidwell - * configure.in (alpha-dec-osf): Add default case for osf* to switch. - Patch from Bruno Haible. + * reload1.c (eliminate_regs): Don't do anything, if we're not + generating code. - * function.c (put_reg_into_stack): Copy MEM_IN_STRUCT_P from new. - (assign_parms): Set aggregate if hide_last_arg and last_named. +Mon Dec 7 15:27:09 1998 DJ Delorie -Mon Mar 9 19:57:56 1998 J"orn Rennecke + * mips/mips.h (ENCODE_SECTION_INFO): Handle TARGET_EMBEDDED_DATA. + Add comment. + * mips/mips.c (mips_select_section): Add comment. - * final.c (shorten_branches): Initialize insn_addresses. +Mon Dec 7 17:55:06 1998 Mike Stump -Mon Mar 9 14:10:23 1998 J"orn Rennecke + * cccp.c (ignore_escape_flag): Add support for \ as `natural' + characters in file names in #line to be consistent with #include + handling. We support escape processing in the # 1 "..." version of + the command. See also support in cp/lex.c. + (handle_directive): Likewise. + (do_line): Likewise. - * sh.h (MUST_PASS_IN_STACK): Define. +1998-12-07 Zack Weinberg -Sun Mar 8 13:01:56 1998 Jeffrey A Law (law@cygnus.com) + * cpplib.c (initialize_char_syntax): Use ISALPHA and ISALNUM + so it'll work on non-ASCII platforms. Always consider $ an + identifier character. Take no arguments. + (cpp_reader_init): Call initialize_char_syntax with no + arguments. + (cpp_start_read): Don't call initialize_char_syntax again. + Clear is_idchar['$'] and is_idstart['$'] if not + opts->dollars_in_ident. - * final.c (shorten_branches): Fix minor logic error in - ADDR_DIFF_VEC shortening support. + * cpplib.h (struct cpp_reader): Replace void *data element by + cpp_options *opts. Rearrange elements to make gdb printout + less annoying (put buffer stack at end). + (CPP_OPTIONS): Get rid of now-unnecessary cast. -Sun Mar 8 02:17:42 PST 1998 Jeff Law (law@cygnus.com) + * cppmain.c: s/data/opts/ when initializing cpp_reader + structure. + * c-decl.c: Likewise. + * objc/objc-act.c: Likewise. + * fix-header.c: Likewise. - * version.c: Bump for snapshot. +1998-12-07 Zack Weinberg -Sat Mar 7 00:54:15 1998 Jeffrey A Law (law@cygnus.com) - - * haifa-sched.c (is_cfg_nonregular): Change return type to - an int. No longer compute "estimated" number of edges. Use - computed_jump_p instead of duplicating the code. Fixup/add - some comments. - (build_control_flow): Returns a value indicating an irregularity - in the cfg was detected. Count the number of edges in the cfg. - allocate various edge tables. - (find_rgns): No longer look for unreachable blocks. - (schedule_insns): Do not allocate memory for edge tables here. - Free memory for edge tables before returning. Do not perform - cross block scheduling if build_control_flow returns nonzero. - * flow.c (compute_preds_succs): More accurately determine when - a block drops in. - - * basic-block.h (free_basic_block_vargs): Provide prototype. - - * cccp.c (main): Fix dumb mistakes in last change. - -Fri Mar 6 21:28:45 1998 J"orn Rennecke - - * rtl.h (addr_diff_vec_flags): New typedef. - (union rtunion_def): New member rt_addr_diff_vec_flags. - (ADDR_DIFF_VEC_FLAGS): New macro. - - * sh.c (output_branch): Fix offset overflow problems. - - * final.c (shorten_branches): Implement CASE_VECTOR_SHORTEN_MODE. - (final_scan_insn): New argument BODY for ASM_OUTPUT_ADDR_DIFF_ELT. - * rtl.def (ADDR_DIFF_VEC): Three new fields (min, max and flags). - * stmt.c (expand_end_case): Supply new arguments to - gen_rtx_ADDR_DIFF_VEC. - * 1750a.h (ASM_OUTPUT_ADDR_DIFF_ELT): New argument BODY. - * alpha.h, arc.h, clipper.h, convex.h : Likewise. - * dsp16xx.h, elxsi.h, fx80.h, gmicro.h, h8300.h : Likewise. - * i370.h, i386.h, i860.h, i960.h, m32r.h, m68k.h, m88k.h : Likewise. - * mips.h, mn10200.h, mn10300.h, ns32k.h, pa.h, pyr.h : Likewise. - * rs6000.h, sh.h, sparc.h, spur.h, tahoe.h, v850.h : Likewise. - * vax.h, we32k.h, alpha/vms.h, arm/aof.h, arm/aout.h : Likewise. - * i386/386bsd.h, i386/freebsd-elf.h : Likewise. - * i386/freebsd.h, i386/linux.h : Likewise. - * i386/netbsd.h, i386/osfrose.h, i386/ptx4-i.h, i386/sco5.h : Likewise. - * i386/sysv4.h, m68k/3b1.h, m68k/dpx2.h, m68k/hp320.h : Likewise. - * m68k/mot3300.h, m68k/sgs.h : Likewise. - * m68k/tower-as.h, ns32k/encore.h, sparc/pbd.h : Likewise. - * sh.h (INSN_ALIGN, INSN_LENGTH_ALIGNMENT): Define. - (CASE_VECTOR_SHORTEN_MODE): Define. - (short_cbranch_p, align_length, addr_diff_vec_adjust): Don't declare. - (med_branch_p, braf_branch_p): Don't declare. - (mdep_reorg_phase, barrier_align): Declare. - (ADJUST_INSN_LENGTH): Remove alignment handling. - * sh.c (uid_align, uid_align_max): Deleted. - (max_uid_before_fixup_addr_diff_vecs, branch_offset): Deleted. - (short_cbranch_p, med_branch_p, braf_branch_p, align_length): Deleted. - (cache_align_p, fixup_aligns, addr_diff_vec_adjust): Deleted. - (output_far_jump): Don't use braf_branch_p. - (output_branchy_insn): Don't use branch_offset. - (find_barrier): Remove checks for max_uid_before_fixup_addr_diff_vecs. - Remove paired barrier stuff. - Don't use cache_align_p. - Take alignment insns into account. - (fixup_addr_diff_vecs): Reduce to only fixing up the base label of - the addr_diff_vec. - (barrier_align, branch_dest): New function. - (machine_dependent_reorg, split_branches): Remove infrastructure - for branch shortening that is now provided in the backend. - * sh.md (short_cbranch_p, med_branch_p, med_cbranch_p): New attributes. - (braf_branch_p, braf_cbranch_p): Likewise. - (attribute length): Use new attributes. - (casesi_worker): Get mode and unsignednedd from ADDR_DIFF_VEC. - (addr_diff_vec_adjust): Delete. - (align_2): Now a define_expand. - (align_log): Now length 0. - -Fri Mar 6 14:41:33 1998 Michael Meissner - - * m32r.md (right): Correctly check for length == 2, not 1. - -Fri Mar 6 14:00:04 1998 Kaveh R. Ghazi - - * mips/mips.h: Prototype `machine_dependent_reorg'. - (ASM_OUTPUT_ALIGN): Remove unused variable `mask'. - -Fri Mar 6 11:43:35 1998 Joern Rennecke (amylaar@cygnus.co.uk) - - * final.c (shorten_branches): Restore accidentally removed code. - -Fri Mar 6 11:00:49 1998 Andreas Schwab - - * configure.in: Remove duplicate uses of AC_PROG_CC and - AC_PROG_MAKE_SET. - -Fri Mar 6 00:59:30 1998 Richard Henderson - - * configure.in (target_cpu_default2): Correct typo for alphapca56. - -Thu Mar 5 23:24:50 1998 Jeffrey A Law (law@cygnus.com) - Doug Evans (devans@cygnus.com) - - * haifa-sched.c (build_jmp_edges): Delete dead function. - (build_control_flow): Use cfg routines from flow.c - (schedule_insns): Remove debugging code accidentally checked - in earlier today. - - * basic-block.h: Add external integer list structures, typdefs, - accessor macros and function declarations. Simlarly for - basic block pred/succ support and simple bitmap stuff. - * flow.c: Add functions for integer list, basic block pred/succ - support and simple bitmap support. - (compute_dominators): New function to compute dominators and - post dominators. - (find_basic_blocks): Split into two functions. - (life_analysis): Likewise. - (flow_analysis): Removed. Now handled by calling find_basic_blocks, - the life_analysis from toplev.c - * toplev.c (rest_of_compilation): Call find_basic_blocks, then - life_analysis instead of flow_analysis. - -Thu Mar 5 23:06:26 1998 J"orn Rennecke - - * jump.c (jump_optimize): Call mark_jump_label also for deleted - insns. - (mark_jump_label): Don't increment ref counts for deleted insns. - -Thu Mar 5 09:55:15 1998 Kaveh R. Ghazi - - * mips/iris6.h (TARGET_DEFAULT): Parenthesize macro definition. - - * mips/mips.c: Include stdlib.h and unistd.h. - (mips_asm_file_end): Add braces around empty body in an if-statement. - (function_prologue): Wrap variable `fnname' in - !FUNCTION_NAME_ALREADY_DECLARED. Correct format specifier in fprintf. - (mips_select_rtx_section, mips_select_section): Declare as void. + * cpplib.h (struct cpp_buffer): Replace dir and dlen members + with a struct file_name_list pointer. + (struct cpp_reader): Add pointer to chain of `actual + directory' include searchpath entries. + (struct file_name_list): Add *alloc pointer for the sake of + the actual-directory chain. - * mips/mips.h: Add prototypes for extern functions in mips.c. - (FUNCTION_ARG_REGNO_P): Add parentheses around && within ||. - (ENCODE_SECTION_INFO): Add braces around empty body in an - if-statement. + Move definition of HOST_WIDE_INT here. + (cpp_parse_escape): Change prototype to match changes in + cppexp.c. - * mips/mips.md (movdi): Add parentheses around && within ||. - (movsf, movdf): Likewise. - (branch_zero, branch_zero_di): Add default case in - enumeration switch. + * cppfiles.c (actual_directory): New function. + (finclude): Use it to initialize the buffer's actual_dir + entry. + (find_include_file): We don't need to fix up max_include_len + here. + * cpplib.c (do_include): Don't allocate a file_name_list on + the fly for current directory "" includes, use the one that's + been preallocated in pfile->buffer->actual_dir. Hoist out + duplicate code from the search_start selection logic. + (cpp_reader_init): Initialize pfile->actual_dirs. -Thu Mar 5 02:45:48 1998 Richard Henderson + Remove definition of HOST_WIDE_INT. Change calls + to cpp_parse_escape to match changes in cppexp.c (note + hardcoded MASK, which is safe since this is the source + character set). - * alpha/alpha.h (TARGET_WINDOWS_NT, TARGET_OPEN_VMS): Just make them - real constants, since they can't be changed. - (TARGET_AS_CAN_SUBTRACT_LABELS): New. - * alpha/alpha.md (builtin_setjmp_receiver): Use it. - * alpha/osf.h (TARGET_AS_CAN_SUBTRACT_LABELS): New. - * alpha/osf2or3.h (TARGET_AS_CAN_SUBTRACT_LABELS): New. - * alpha/vms.h (TARGET_OPEN_VMS): New. - * alpha/win-nt.h (TARGET_WINDOWS_NT): New. + * cppexp.c: Bring over changes to cpp_parse_escape from cccp.c + to handle wide character constants in #if directives. The + function now returns a HOST_WIDE_INT, and takes a third + argument which is a binary mask for all legal values (0x00ff + for 8-bit `char', 0xffff for 16-bit `wchar_t', etc.) Define + MAX_CHAR_TYPE_MASK and MAX_WCHAR_TYPE_MASK. Change callers of + cpp_parse_escape to match. [Fixes c-torture/execute/widechar-1.c] -Thu Mar 5 02:41:27 1998 Richard Henderson +Mon Dec 7 15:38:25 1998 Dave Brolley - * reload.c (find_reloads): Always force (subreg (mem)) to be - reloaded if WORD_REGISTER_OPERATIONS. + * gcc.c (default_compilers): Fix typo in USE_CPPLIB spec for cc1. -Thu Mar 5 02:14:44 1998 Richard Henderson +Mon Dec 7 15:38:25 1998 Kaveh R. Ghazi - * haifa-sched.c (free_list): Rename from free_pnd_lst. - (free_pending_lists): Rename free_pnd_lst uses. - (remove_dependence): Place expunged element on unused_insn_list. - (alloc_INSN_LIST, alloc_EXPR_LIST): New. Change all callers of - gen_rtx_*_LIST and alloc_rtx to use them. - (compute_block_backward_dependences): Free the reg_last_* lists. + * c-aux-info.c (concat): Wrap function definition in !USE_CPPLIB. + * cppalloc.c: Move function `xcalloc' from cpplib.c to here. + * cpplib.c: Move function `xcalloc' from here to cppalloc.c. -Thu Mar 5 00:05:40 1998 Jeffrey A Law (law@cygnus.com) +Mon Dec 7 11:30:49 1998 Nick Clifton - * cccp.c (main): Avoid undefined behavior when setting pend_includes - and pend_files. + * final.c (output_asm_name): Use tabs to separate comments from + assembly text. -Wed Mar 4 21:58:25 1998 Franz Sirl + Include instruction lengths (if defined) in output. - * rs6000/linux.h: don't define DEFAULT_VTABLE_THUNKS to 1 if - USE_GNULIBC_1 is defined - * configure.in: add a new case powerpc-*-linux-gnulibc1 which - includes the t-linux-gnulibc1 fragment +Mon Dec 7 10:53:38 1998 Michael Hayes -Wed Mar 4 12:11:36 1998 Jim Wilson + * loop.c (check_dbra_loop): Fix initial_value and initial_equiv_value + in the loop_info structure. - * mips.md (movdf_internal1a): Fix misplaced parenthesis in condition. +Mon Dec 7 11:04:40 1998 Catherine Moore -Wed Mar 4 18:47:48 1998 J"orn Rennecke + * configure.in (arm*-*-ecos-elf): New target. + * configure: Regenerated. + * config/arm/elf.h (ASM_WEAKEN_LABEL): Define. + * config/arm/ecos-elf.h: New file. + * config/arm/unknown-elf.h (TARGET_VERSION): Check + for redefinition. - * final.c (final_scan_insn, case CODE_LABEL: Cleanup. +Mon Dec 7 16:15:51 1998 J"orn Rennecke -Wed Mar 4 15:51:19 1998 J"orn Rennecke + * sh.c (output_far_jump): Emit braf only for TARGET_SH2. - * final.c (shorten_branches): Tag the loop alignment onto the - first label after NOTE_INSN_LOOP_BEG even if there is an - intervening insn. +Sun Dec 6 04:19:45 1998 Jeff Law (law@cygnus.com) -Tue Mar 3 21:48:35 1998 J"orn Rennecke + * version.c: Bump for snapshot. - * final.c (insn_current_reference_address): - Use SEQ instead of BRANCH as argument to align_fuzz, to get a - proper alignment chain. +Sun Dec 6 05:16:16 1998 Michael Hayes - * final.c (max_labelno): New static variable. - (final_scan_insn): Check max_labelno before outputting an - alignment for a label. - (shorten_branches): Remove unused variable length_align. + * loop.c (check_dbra_loop): New argument loop_info. Update fields + as needed. -Tue Mar 3 14:27:23 1998 Kaveh R. Ghazi +Sun Dec 6 03:40:13 1998 Jeff Law (law@cygnus.com) - * sparc.c (ultrasparc_adjust_cost): Add default case in - enumeration switch. + * version.c: Bump for snapshot. - * sparc.h: Add prototypes for extern functions defined in - sparc.c. +Sun Dec 6 07:49:29 1998 Alexandre Oliva -Tue Mar 3 10:00:11 1998 Nick Clifton + * gcc.texi (Bug Reporting): 40Kb is a soft limit, larger + compressed reports are ok and preferred over URLs. - * toplev.c: Only generate .dbr file when dumping RTL if - DEALY_SLOTS is defined. +Sun Dec 6 07:45:33 1998 Alexandre Oliva -Tue Mar 3 07:36:37 1998 Manfred Hollstein + * invoke.texi (Warning Options): Soften the tone of -pedantic. - * reorg.c (fill_eager_delay_slots): Add new argument delay_list - in call to fill_slots_from_thread. +Sun Dec 6 00:20:44 1998 H.J. Lu (hjl@gnu.org) -Mon Mar 2 13:45:03 1998 Richard Henderson + * print-rtl.c (print_rtx): Add prototype. - * alpha/linux.h (CPP_PREDEFINES): Correct connecting whitespace - to SUB_CPP_PREDEFINES. Reported by asun@saul4.u.washington.edu. + * unroll.c (iteration_info): Make it static. -Mon Mar 2 22:59:28 1998 J"orn Rennecke +Sun Dec 6 01:19:46 1998 Richard Henderson - * final.c (insn_last_address, insn_current_align, uid_align): - New variables. - (in_align_chain, align_fuzz, align_shrink_fuzz): New functions. - (insn_current_reference_address): Likewise. - (shorten_branches, final_scan_insn): Implement LABEL_ALIGN, - LABEL_ALIGN_AFTER_BARRIER and LOOP_ALIGN target macros. - (label_to_alignment): New function. - * genattrtab.c (write_test_expr): If one of LABEL_ALIGN, - LABEL_ALIGN_AFTER_BARRIER or LOOP_ALIGN is defined, call - insn_current_reference_address instead of insn_current_address. - (or_attr_value, write_length_unit_log): New functions. - (main): Call write_length_unit_log. - (write_const_num_delay_slots): Output extra '\n'. - * alpha.h (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): - replace with: - (LOOP_ALIGN, ALIGN_LABEL_AFTER_BARRIER). - * i386.h, i386/osfrose.h, i386/svr3dbx.h, m68k.h, sparc.h: Likewise. - * arc.h, m32r.h (ASM_OUTPUT_LOOP_ALIGN): replace with: - (LOOP_ALIGN). - * i960.h, m88k.h: (ASM_OUTPUT_ALIGN_CODE): Replace with: - (LABEL_ALIGN_AFTER_BARRIER). - * ns32k/encore.h, ns32k/merlin.h, ns32k.h, ns32k/sequent.h: Likewise. - * ns32k/tek6000.h: Likewise. - * i386/gas.h (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): Delete. - * i386.md (casesi+1): Use ASM_OUTPUT_ALIGN instead of - ASM_OUTPUT_ALIGN_CODE. - -Mon Mar 2 01:05:50 PST 1998 Jeff Law (law@cygnus.com) + * alias.c (memrefs_conflict_p): A second ANDed address + disables the aligned address optimization. - * version.c: Bump for snapshot. +Sat Dec 5 18:48:25 1998 Richard Henderson -Mon Mar 2 00:52:18 PST 1998 Jeff Law (law@cygnus.com) + * alpha.c (alpha_emit_set_const_1): Fix parenthesis error + in -c << n case. - * version.c: Bump for snapshot. +Sat Dec 5 15:14:52 1998 Jason Merrill -Sun Mar 1 18:25:49 1998 Michael P. Hayes + * i960.h (BOOL_TYPE_SIZE): Define. - * reorg.c (fill_slots_from_thread): Don't steal delay list from target - if condition code of jump conflicts with opposite_needed. +Sun Dec 6 00:28:16 1998 Michael Hayes - * reorg.c (fill_slots_from_thread): Mark resources referenced in - opposite_needed thread. Return delay_list even when cannot get - any more delay insns from end of subroutine. + * config/c4x/c4x.c (valid_parallel_load_store): Flog functionality + from old valid_parallel_operands_4. + (valid_parallel_operands_4): Check that operands for 4 operand + parallel insns are valid, excluding load/store insns. + * config/c4x/c4x.h (valid_parallel_load_store): Add prototype. + * config/c4x/c4x.md (*movqf_parallel, *movqi_parallel): Use + valid_parallel_load_store instead of valid_parallel_operands_4. + (*absqf2_movqf_clobber, *floatqiqf2_movqf_clobber, + *negqf2_movqf_clobber, *absqi2_movqi_clobber, + *fixqfqi2_movqi_clobber, *negqi2_movqi_clobber, + *notqi_movqi_clobber): Use valid_parallel_operands_4. + (*subqf3_movqf_clobber, *ashlqi3_movqi_clobber, + *ashrqi3_movqi_clobber, *lshrqi3_movqi_clobber, + *subqi3_movqi_clobber): Use valid_parallel_operands_5. -Sun Mar 1 18:26:21 1998 Ken Rose (rose@acm.org) +Sat Dec 5 23:52:01 1998 Michael Hayes - * reorg.c (fill_slots_from_thread): New parameter, delay_list. - All callers changed. + * config/c4x/c4x.c (iteration_info): Delete extern. -Sun Mar 1 18:25:37 1998 Bruno Haible +Fri Dec 4 20:15:57 1998 Bernd Schmidt - * frame.c (start_fde_sort, fde_split, heapsort, fde_merge, - end_fde_sort): New functions for fast sorting of an FDE array. - (fde_insert): Simplified. - (add_fdes): Change argument list. - (frame_init): Use the new functions. + * tm.texi (SMALL_REGISTER_CLASSES): Make description match reality. -Sun Mar 1 18:06:21 1998 Jeffrey A Law (law@cygnus.com) + * final.c (cleanup_subreg_operands): Delete some unused code. - * ginclude/va-ppc.h (va_arg): Fix typo in long long support. + * recog.h (MAX_RECOG_ALTERNATIVES): New macro. + (struct insn_alternative): New structure definition. + (recog_op_alt): Declare variable. + (preprocess_constraints): Declare function. + * recog.c (recog_op_alt): New variable. + (extract_insn): Verify number of alternatives is in range. + (preprocess_constraints): New function. + * reg-stack.c: Include recog.h. + (constrain_asm_operands): Delete. + (get_asm_operand_lengths): Delete. + (get_asm_operand_n_inputs): New function. + (record_asm_reg_life): Delete OPERANDS, CONSTRAINTS, N_INPUTS and + N_OUTPUTS args. All callers changed. + Compute number of inputs and outputs here by calling + get_asm_operand_n_inputs. + Instead of constrain_asm_operands, call extract_insn, + constrain_operands and preprocess_constraints. Use information + computed by these functions throughout. + (record_reg_life): Delete code that is unused due to changes in + record_asm_reg_life. + (subst_asm_stack_regs): Delete OPERANDS, OPERAND_LOC, CONSTRAINTS, + N_INPUTS and N_OUTPUTS args. All callers changed. + Similar changes as in record_asm_reg_life. + (subst_stack_regs): Move n_operands declaration into the if statement + where it's used. + Delete code that is unused due to changes in subst_asm_stack_regs. + * stmt.c (expand_asm_operands): Verify number of alternatives is in + range. + * Makefile.in (reg-stack.o): Depend on recog.h. - * i386.c (reg_mentioned_in_mem): Fix dangling else statement. +Fri Dec 4 02:23:24 1998 Jeffrey A Law (law@cygnus.com) - * fold-const.c (fold_range_test): Always return a value. + * except.c (set_exception_version_code): Argument is an "int". -Sun Mar 1 17:57:34 1998 Mumit Khan +Fri Dec 4 01:29:28 1998 Jeffrey A Law (law@cygnus.com) - * config/i386/winnt.c (i386_pe_unique_section): Put read-only - data in the text section unless READONLY_DATA_SECTION is defined. + * configure.in (hppa2*-*-*): Handle like hppa1.1-*-* for now. + * configure: Rebuilt. -Sun Mar 1 17:48:46 1998 Jeffrey A Law (law@cygnus.com) +Fri Dec 4 01:29:28 1998 Robert Lipe - * c-parse.in (undeclared variable error): Tweak error message to - be clearer. + * configure.in (mipsel-*-linux*): New target. + * mips/linux.h: New file, based on other Linux targets. -Sun Mar 1 10:22:36 PST 1998 Jeff Law (law@cygnus.com) +Thu Dec 3 11:19:50 1998 Mike Stump - * version.c: Bump for snapshot. + * gthr-vxworks.h (__ehdtor): Fix memory leak. The delete hook + runs in the context of the deleter, not the deletee, so we must + use taskVarGet to find the correct memory to free. + (__gthread_key_create): Initialize the task + variable subsystem so that the task variable is still active when + the delete hook is run. -1998-02-28 Mark Mitchell - - * final.c (final_scan_insn): Undo overzealous removal of `set'. - -Sat Feb 28 07:54:03 1998 Kaveh R. Ghazi +1998-12-03 Joseph S. Myers - * pa.h (CONST_COSTS): When checking the CONST_DOUBLE enumerated - case, add parentheses to specify the proper order of precedence in - the if-statement. + * pdp11.h: Use optimize_size for space optimizations. + * pdp11.c: Likewise. + * pdp11.md: Likewise. + * pdp11.h (TARGET_40_PLUS): Fix typo. - * c-aux-info.c: Include string.h/strings.h. - - * pa.c: Include stdlib.h. - (pa_combine_instructions): Prototype the function. - (pa_can_combine_p, forward_branch_p, shadd_constant_p): Likewise. - (reloc_needed): Add default case for enumeration switch. - (remove_useless_addtr_insns): Remove unused variable `all'. - (hppa_expand_prologue): Add explicit braces to avoid - ambiguous `else'. - (output_function_epilogue): Remove unused variable `i'. - (output_millicode_call): Remove unused variable `link'. - (shadd_constant_p, forward_branch_p): Make the function static. - (following_call): Explicitly declare to return int. - (pa_reorg): Declare as void. - (pa_combine_instructions): Declare as static void. Add - parentheses around && within ||. +Thu Dec 3 11:48:32 1998 Jeffrey A Law (law@cygnus.com) - * pa.h: Add prototypes for pa_reorg, symbolic_operand, - following_call, function_label_operand, lhs_lshift_cint_operand - and zdepi_cint_p. + * local-alloc.c (block_alloc): Slightly retune heuristic to widen + qty lifetimes. - * pa.md: Add parentheses around && within ||. +Thu Dec 3 22:30:18 1998 Michael Hayes - * cppalloc.c: Include stdlib.h. + * alias.c (addr_side_effect_eval): New function. + (memrefs_conflict_p): Use it. + * rtl.h (addr_side_effect_eval): Prototype it. - * cpperror.c (cpp_print_containing_files): Remove unused variable - `i'. Fix format specifier in fprintf. +1998-12-02 Joseph S. Myers - * cse.c (cse_around_loop): Add explicit braces to avoid - ambiguous `else'. - (delete_dead_from_cse): Wrap variable `tem' in macro HAVE_cc0. + * pdp11.md (extendsfdf2): Fix mode mismatch in SET. - * expr.c (expand_expr): Add parentheses around && within ||. +Wed Dec 2 11:23:07 1998 Jim Wilson - * final.c (app_enable): Replace fprintf with fputs where there are - no format specifiers and no trailing argument after the string. - Eg, when printing ASM_APP_ON/ASM_APP_OFF. - (app_disable): Likewise. - (final_end_function): Likewise. - (final_scan_insn): Likewise. Remove unused variable `set'. - (profile_function): Wrap empty if-statement body in {} brackets. + * reload.c (find_reloads): When force const to memory, put result + in substed_operand not *recog_operand_loc. - * function.c: Include stdlib.h. - (pad_below): Wrap prototype and definition in ARGS_GROW_DOWNWARD. - (reposition_prologue_and_epilogue_notes): Add parentheses - around assignment used as truth value. +1998-12-02 Ulrich Drepper - * integrate.c (expand_inline_function): Wrap variable - `cc0_insn' in macro HAVE_cc0. + * c-lex.c: Fix indentation from last patch. + Remove trailing whitespace. + * real.c: Likewise. - * jump.c (jump_optimize): Wrap variable `q' in macro - HAVE_cc0. Remove unused variable `prev1'. +Wed Dec 2 10:11:12 1998 Jeffrey A Law (law@cygnus.com) - * libgcc2.c (__bb_exit_trace_func): Add parentheses around && - within ||. Fix format specifier in fprintf. - (__bb_init_prg): Add parentheses around assignment used as - truth value. + * flow.c (delete_block): Call set_last_insn after we have reset + NEXT_INSN (kept_tail). - * local-alloc.c: Include stdlib.h. - (requires_inout): Add parentheses around assignment used - as truth value. +Wed Dec 2 00:47:31 1998 Jeffrey A Law (law@cygnus.com) - * loop.c (analyze_loop_iterations): Wrap prototype and definition - in macro HAVE_decrement_and_branch_on_count. - (insert_bct, instrument_loop_bct): Likewise. - (move_movables): Add parentheses around assignment used as - truth value. - (consec_sets_invariant_p): Likewise. - (maybe_eliminate_biv_1): Wrap variable `new' in macro HAVE_cc0. + * mips.md (trap_if): Use "$0" for the value zero. - * objc/objc-act.c: Include stdlib.h. - (lookup_method_in_protocol_list): Wrap empty else-statement body - in braces. - (lookup_protocol_in_reflist): Likewise. - (objc_add_static_instance): Remove unused variables `decl_expr' - and `decl_spec'. - (get_objc_string_decl): Remove unused variable `decl'. - (generate_static_references): Remove unused variables `idecl' and - `instance'. - (check_protocols): Wrap empty else-statement body in braces. +Tue Dec 1 20:49:49 1998 Ulrich Drepper + Stephen L Moshier + Richard Henderson - * protoize.c: Include stdlib.h. - (substr): Add parentheses around assignment used as truth value. - (abspath): Likewise. - (shortpath): Likewise. + * c-common.c (declare_function_name): Declare predefined variable + `__func__'. - * regmove.c (fixup_match_1): Add parentheses around assignment - used as truth value. + * c-decl.c (flag_isoc9x): Set to 1 by default. + (c_decode_option): Handle -std= option. Remove -flang-isoc9x. + (grokdeclarator): Always emit warning about implicit int for ISO C 9x. - * reload.c (push_secondary_reload): Remove unused variable `i'. - (find_reloads): Add parentheses around assignment used as truth - value. + * c-parse.in: Allow constructors in ISO C 9x. + Rewrite designator list handling. + Allow [*] parameters. + Don't warn about comma at end of enum definition for ISO C 9x. - * reload1.c: Include stdlib.h. + * cccp.c (c9x): New variable. + (rest_extension): New variable. + (print_help): Document new -std= option. + (main): Recognize -std= option. Set c9x appropriately. + (create_definition): Recognize ISO C 9x vararg macros. - * rtl.h: Correct typo in prototype of offsettable_memref_p. - - * stmt.c (add_case_node): Add parentheses around assignment used - as truth value. - (case_tree2list): Likewise. - - * tree.c (valid_machine_attribute): Wrap variable `decl_attr_list' - in macro VALID_MACHINE_DECL_ATTRIBUTE. Wrap variable - `type_attr_list' in macro VALID_MACHINE_TYPE_ATTRIBUTE. - (merge_attributes): Add explicit braces to avoid ambiguous - `else'. - - * unroll.c (copy_loop_body): Wrap variable `cc0_insn' in - macro HAVE_cc0. - - * varasm.c: Include stdlib.h. + * gcc.c (default_compilers): Adjust specs for -std options. + (option_map): Add --std. + (display_help): Document -std. + * toplev.c (documented_lang_options): Add -std and remove + -flang-isoc9x. - * system.h: Remove sys/stat.h. - * gcc.c: Add sys/stat.h. + * c-lex.c (yylex): Recognize hex FP constants and call REAL_VALUE_ATOF + or REAL_VALUE_HTOF based on base of the constants. + * fold-const.c (real_hex_to_f): New function. Replacement function + for hex FP conversion if REAL_ARITHMETIC is not defined. + * real.c (asctoeg): Add handling of hex FP constants. + * real.h: Define REAL_VALUE_HTOF if necessary using ereal_atof or + real_hex_to_f. - * genattr.c: Wrap prototype of `free' in NEED_DECLARATION_FREE. - * genattrtab.c: Likewise. - * genconfig.c: Likewise. - * genemit.c: Likewise. - * genextract.c: Likewise. - * genflags.c: Likewise. - * genopinit.c: Likewise. - * genoutput.c: Likewise. - * genpeep.c: Likewise. - * genrecog.c: Likewise. - * tlink.c: Likewise. Also wrap `getenv' in NEED_DECLARATION_GETENV. +Tue Dec 1 16:45:49 1998 Stan Cox -Fri Feb 27 11:02:47 1998 Andreas Schwab + * mips.md (divmodsi4*, divmoddi4*, udivmodsi4*, udivmoddi4): Add + -mcheck-range-division/-mcheck-zero-division checking. Avoid as macro + expansion. Use hi/lo as destination register. + (div_trap): New. + (divsi3*, divdi3*, modsi3*, moddi3*, udivsi3*, udivdi3*, umodsi3*, + umoddi3*): Add -mcheck-range-division/-mcheck-zero-division checking. + Avoid as macro expansion. Use hi/lo as destination register. - * invoke.texi: Use @itemx for a secondary item in a @table. + * mips.h (MASK_CHECK_RANGE_DIV): New. + (MASK_NO_CHECK_ZERO_DIV): New. + (ELIMINABLE_REGS): Added GP_REG_FIRST + 31. + (CAN_ELIMINATE, INITIAL_ELIMINATION_OFFSET): Allow for getting + return address for leaf functions out of r31 to support + builtin_return_address. - * config/m68k/m68k.md (movsf+1): Optimize moving a CONST_DOUBLE - zero. +Tue Dec 1 15:03:30 1998 Herman A.J. ten Brugge -Thu Feb 26 00:13:21 1998 Ian Lance Taylor + * jump.c (jump_optimize): Call regs_set_between_p with PREV_INSN(x), + NEXT_INSN(x) to check insn x. - * choose-temp.c: Fix handling of sys/file.h to work in libiberty. +Tue Dec 1 15:20:44 1998 Jeffrey A Law (law@cygnus.com) -Wed Feb 25 23:40:54 1998 Jeffrey A Law (law@cygnus.com) + * flow.c (delete_block): Call set_last_insn if we end up deleting the + last insn in the rtl chain. - * i386.c (struct machine_function): Add new fields for PIC stuff. - (save_386_machine_status): Fix argument to xmalloc. Save pic_label_rtx - and pic_label_name. - (restore_386_machine_status): Corresponding changes. - (clear_386_stack_locals): Also clear pic_label_rtx and pic_label_name. + * reload1.c (reload): Do not set reload_completed or split insns + here. Instead... + * toplev.c (rest_of_compilation): Set reload_completed after + reload returns. Split insns after reload_cse has run. -Wed Feb 25 01:31:40 1998 Jeffrey A Law (law@cygnus.com) +Tue Dec 1 11:55:04 1998 Richard Henderson - * c-parse.y (undeclared variable error): Tweak error message - to be clearer. + * final.c (final_scan_insn): Abort if block_depth falls below 0. -Tue Feb 24 23:54:07 1998 Richard Henderson +Tue Dec 1 10:23:16 1998 Nick Clifton - * flags.h (g_switch_value, g_switch_set): Declare. - * alpha.c (override_options): Set g_switch_value=8 if not set. - * alpha/elf.h (CC1_SPEC): New. - (ASM_SPEC): New. - (LINK_SPEC): Pass along the -G value we were given. - (LOCAL_ASM_OP): Remove. - (ASM_OUTPUT_ALIGNED_LOCAL): Output to .bss or .sbss by size. - (MAX_OFILE_ALIGNMENT): New. - (BSS_SECTION_ASM_OP, SBSS_SECTION_ASM_OP, SDATA_SECTION_ASM_OP): New. - (EXTRA_SECTIONS): Add sbss and sdata. - (SECTION_FUNCTION_TEMPLATE): New. - (EXTRA_SECTION_FUNCTIONS): Use it. - (CTORS_SECTION_FUNCTION, DTORS_SECTION_FUNCTION): Remove. - (SELECT_SECTION): Use sdata when small enough. - * alpha/linux.h (ASM_SPEC): Remove. + * config/arm/t-arm-elf (LIBGCC2_CFLAGS): Define inhibit_libc. +Tue Dec 1 10:22:18 1998 Nick Clifton -Mon Feb 23 15:09:18 1998 Bruno Haible - * config.sub (sco5): Fix typo. + * config/arm/unknown-elf.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Remove + use of user-label_prefix. -Mon Feb 23 18:19:31 1998 Manfred Hollstein +Tue Dec 1 17:58:26 1998 J"orn Rennecke - * config/t-linux (LIBGCC1, CROSS_LIBGCC1, LIBGCC1_TEST): Add macros and - set to empty. - * config/t-linux-aout (LIBGCC1, CROSS_LIBGCC1, LIBGCC1_TEST): Likewise. - * config/alpha/t-linux: Remove file. - * config/sparc/t-linux: Remove file. - * config/m68k/t-linux (LIBGCC1, CROSS_LIBGCC1): Remove. - * config/m68k/t-linux-aout (LIBGCC1, CROSS_LIBGCC1): Likewise. - * configure.in (alpha*-*-linux-gnulibc1*): Use t-linux instead of alpha/t-linux - for tmake_file. - (alpha*-*-linux-gnu*): Likewise. - (sparc-*-linux-gnulibc1*): Use t-linux instead of sparc/t-linux for tmake_file. - (sparc-*-linux-gnu*): Likewise. + * reload1.c (emit_reload_insns): Clear spill_reg_store + when doing a new non-inherited reload from the same pseudo. -Mon Feb 23 10:47:39 1998 Robert Lipe - * collect2.c (ldd_file_name): Bracket declaration with same - manifests as use. - (full_real_ld_suffix): Deleted. Variable was calloced and - written into, but never read. + * local-alloc.c (function_invariant_p): New function. + (update_equiv_regs): Use function_invariant_p instead of CONSTANT_P + to decide if an equivalence should be recorded. + * reload1.c (num_eliminable_invariants): New static variable. + (reload): Set it. Use function_invariant_p instead of CONSTANT_P + to decide if an equivalence should be recorded. + Unshare PLUS. + (calculate_needs_all_insns): Skip insns that only set an equivalence. + Take num_eliminable_invariants into account when deciding + if register elimination should be done. + (reload_as_needed): Take num_eliminable_invariants into account + when deciding if register elimination should be done. + (eliminate_regs): Handle non-constant reg_equiv_constant. + * rtl.h (function_invariant_p): Declare. -1998-02-23 Mike Stump +Mon Nov 30 02:00:08 1998 Jeff Law (law@cygnus.com) - * configure.in: Add support for i386-wrs-vxworks configuration. - * i386/vxi386.h: New file. + * version.c: Bump for snapshot. -Sun Feb 22 21:16:51 1998 Bruno Haible +Mon Nov 30 00:42:59 1998 Jeff Law (law@cygnus.com) - * tree.c (contains_placeholder_p): Ensure function always returns - a value. - * sparc.md (movdi_sp64_insn): Add default case in enumeration switch. - (movsf_const_insn, movdf_const_insn, movtf_const_insn): Likewise. + * version.c: Bump for snapshot. -Sun Feb 22 20:58:19 1998 Jeffrey A Law (law@cygnus.com) +Sun Nov 29 22:59:40 1998 Jason Merrill - * vms.h (SELECT_SECTION): Use TREE_CODE_CLASS correctly. + * except.c (add_new_handler): Complain about additional handlers + after one that catches everything. -1998-02-22 Paul Eggert +Sat Nov 28 10:56:32 1998 Jeffrey A Law (law@cygnus.com) - * config/sparc/sol2-sld.h (LINKER_DOES_NOT_WORK_WITH_DWARF2): - Define this new symbol. - (DWARF2_DEBUGGING_INFO, DWARF_DEBUGGING_INFO): Do not #undef. - * toplev.c (main): Do not default to DWARF2_DEBUG with -ggdb if - LINKER_DOES_NOT_WORK_WITH_DWARF2 is defined. + * configure.in (alpha*-*-netbsd): Fix typo. + * configure: Rebuilt. -Sun Feb 22 20:07:32 1998 Jim Wilson +Fri Nov 27 12:28:56 1998 Kaveh R. Ghazi - * iris5.h (DWARF2_UNWIND_INFO): Define to 0. - * iris5gas.h (DWARF2_UNWIND_INFO): Define to 1. + * system.h: Include libiberty.h. -Sun Feb 22 15:29:48 1998 Richard Henderson + * c-aux-info.c: Remove prototypes for concat/concat3. Change + function `concat' from fixed parameters to variable parameters, + as is done in libiberty. All callers of concat/concat3 + changed to use the new `concat' with variable args. - * objc/Object.m (-error): Call objc_verror with our va_list. + * cccp.c: Remove things made redundant by libiberty.h and/or + conform to libiberty standards. + * cexp.y: Likewise. + * collect2.c: Likewise. + * config/1750a/1750a.h: Likewise. + * cppalloc.c: Likewise. + * cppexp.c: Likewise. + * cppfiles.c: Likewise. + * cpphash.c: Likewise. + * cpplib.c: Likewise. + * dyn-string.c: Likewise. + * fix-header.c: Likewise. + * gcc.c: Likewise. + * gcov.c: Likewise. + * genattr.c: Likewise. + * genattrtab.c: Likewise. + * gencheck.c: Likewise. + * gencodes.c: Likewise. + * genconfig.c: Likewise. + * genemit.c: Likewise. + * genextract.c: Likewise. + * genflags.c: Likewise. + * gengenrtl.c: Likewise. + * genopinit.c: Likewise. + * genoutput.c: Likewise. + * genpeep.c: Likewise. + * genrecog.c: Likewise. + * getpwd.c: Likewise. + * halfpic.c: Likewise. + * hash.c: Likewise. + * mips-tdump.c: Likewise. Wrap malloc/realloc/calloc prototypes + in NEED_DECLARATION_* macros. -Sun Feb 22 09:45:39 1998 Kaveh R. Ghazi + * mips-tfile.c: Remove things made redundant by libiberty.h and/or + conform to libiberty standards. + (fatal): Fix const-ification of variable `format' in + !ANSI_PROTOTYPES case. - * collect2.c (scan_prog_file): Completely cover uses of variable - `exports' with macro COLLECT_EXPORT_LIST. + * prefix.c: Remove things made redundant by libiberty.h and/or + conform to libiberty standards. -Sat Feb 21 20:36:23 1998 Jeff Law (law@cygnus.com) + * print-rtl.c: Rename variable `spaces' to `xspaces' to avoid + conflicting with function `spaces' from libiberty. - * version.c: Bump for snapshot. + * profile.c: Remove things made redundant by libiberty.h and/or + conform to libiberty standards. + * protoize.c: Likewise. + * rtl.h: Likewise. + * scan.h: Likewise. + * tlink.c: Likewise. + * toplev.c: Likewise. + * toplev.h: Likewise. + * tree.h: Likewise. -Fri Feb 20 16:22:13 1998 Michael Meissner +Thu Nov 26 08:38:06 1998 Kaveh R. Ghazi - * sched.c (schedule_block): Remove code to get arguments from hard - regs into pseudos early. Same as Aug 25, 1997 change to - haifa-sched.c. + * cppfiles.c (simplify_pathname): Un-ANSI-fy function definition. -1998-02-20 Jason Merrill +Thu Nov 26 23:45:37 1998 Michael Hayes - * collect2.c (main): Still handle !do_collecting for non-AIX targets. + * README.C4X: Updated URLs. + * config/c4x/c4x.c (c4x_address_conflict): Fix typo. + (valid_parallel_operands_5): Remove unused variable. -1998-02-16 Mark Mitchell +Thu Nov 26 23:40:03 1998 Michael Hayes - * toplev.c (rest_of_compilation): Do not defer the output of a - nested function. + * config/c4x/c4x.h (TARGET_DEFAULT): Fix typo. -Fri Feb 20 10:39:47 1998 Michael Tiemann +1998-11-26 Manfred Hollstein - * ginclude/va-mips.h (va_arg): Remove trailing space after '\' - continuation character (line 243). + * Makefile.in (CONFIG_LANGUAGES): New macro taking all languages + which can be configured. + (LANGUAGES): Use $(CONFIG_LANGUAGES) instead of @all_languages@ + (Makefile): Pass actual LANGUAGES through the environment when + re-configuring. + (cstamp-h): Likewise. + (config.status): Likewise. -Fri Feb 20 12:10:26 1998 Andreas Schwab + * configure.in (enable_languages): Add new configuration parameter + "--enable-languages=lang1,lang2,...". + (${srcdir}/*/config-lang.in): Change handling to configure only + those directories, that the user might have enabled; default to + "all" existing languages. + * configure: Regenerate. - * genrecog.c (main): Remove duplicated sentence in emitted comment. +Thu Nov 26 00:19:19 1998 Richard Henderson + + * rtlanal.c (regs_set_between_p): New function. + * rtl.h (regs_set_between_p): Prototype it. + * jump.c (jump_optimize): Use it instead of modified_between_p + in the Sep 2 change. + +Wed Nov 25 23:32:02 1998 Ian Dall + Matthias Pfaller + + * invoke.texi (Option Summary, NS32K Options): Add description + of NS32K specific options. + + * ns32k.md (tstdf, cmpdf, movdf, truncdfsf2, fixdfqi2, fixdfhi2, + fixdfsi2, fixunsdfqi2, fixunsdfhi2, fixunsdfsi2, fix_truncdfqi2, + fix_truncdfhi2, fix_truncdfsi2, adddf3, subdf3, muldf3, divdf3, + negdf2, absdf2): Use l instead of f since the double class and + float class are no longer the same. + (cmpsi, truncsiqi2, truncsihi2, addsi3, subsi3, mulsi3, umulsidi3, + divsi3, modsi3, andsi3, iorsi3, xorsi3, negsi2, one_cmplsi2, + ashlsi3, ashlhi3, ashlqi3, rotlsi3, rotlhi3, rotlqi3, abssi2,...): + Use "g" instead of "rmn" since LEGITIMATE_PIC_OPERAND has been + fixed. + (cmpsi, cmphi, cmpqi): Use general_operand instead of + non_immediate_operand. Removes erroneous assumption that can't + compare constants. + (movsf, movsi, movhi, movqi,...): New register numbering scheme. + (movsi, addsi3): Use NS32K_DISPLACEMENT_P instead of hard coded + constants. + (movstrsi, movstrsi1, movstrsi2): Completely new block move + scheme. + (...): Patterns to exploit multiply-add instructions. + (udivmodsi4, udivmodsi_internal4, udivmodhi4, + udivmoddihi4_internal, udivmodqi4, udivmoddiqi4_internal): New + patterns to exploit extended divide insns. + (udivsi3, udivhi3, udivqi3): Remove since superseded by udivmodsi + etc patterns. + + * ns32k.h (FUNCTION_VALUE, LIBCALL_VALUE): Use f0 for complex + float return values as well as simple scalar floats. + (TARGET_32381, TARGET_MULT_ADD, TARGET_SWITCHES): + Support new flag to denote 32381 fpu. + (OVERRIDE_OPTIONS): 32381 is a strict superset of 32081. + (CONDITIONAL_REGISTER_USAGE): Disable extra 32381 registers if not + compiling for 32381. + (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS, CALL_USED_REGISTERS, + REGISTER_NAMES, ADDITIONAL_REGISTER_NAMES, OUTPUT_REGISTER_NAMES, + REG_ALLOC_ORDER, DBX_REGISTER_NUMBER, R0_REGNUM, F0_REGNUM, + L1_REGNUM, STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, + LONG_FP_REGS_P, ARG_POINTER_REGNUM, reg_class, REG_CLASS_NAMES, + REG_CLASS_CONTENTS, SUBSET_P,REGNO_REG_CLASS, + REG_CLASS_FROM_LETTER, FUNCTION_PROLOGUE, FUNCTION_EPILOGUE, + REGNO_OK_FOR_INDEX_P, FP_REG_P, REG_OK_FOR_INDEX_P, + REG_OK_FOR_BASE_P, MEM_REG): New register scheme to include 32381 + fpu registers and special register classes for new 32381 + instructions dotf and polyf. + (MODES_TIEABLE_P): Allow all integer modes, notably DI and SI, to + be tieable. + (INCOMING_RETURN_ADDR_RTX, RETURN_ADDR_RTX, + INCOMING_FRAME_SP_OFFSET): New macros in case DWARF support is + required. + (SMALL_REGISTER_CLASSES): Make dependent on -mmult-add option. + (MOVE_RATIO): Set to zero because of smart movstrsi implementation. + (REGISTER_MOVE_COST): Move code to register_move_cost function for + ease of coding and debugging. + (CLASS_LIKELY_SPILLED_P): Under new register scheme class + LONG_FLOAT_REGO is likely spilled but not caught by default + definition. + (CONSTANT_ADDRESS_P, CONSTANT_ADDRESS_NO_LABEL_P): Use macro + instead of hard coded numbers in range check. + (ASM_OUTPUT_LABELREF_AS_INT): Delete since unused. + (...): Add prototypes for functions in ns32k.c but disable because + of problems when ns32k.h is included in machine independent files. + + * ns32k.c: Include "system.h", "tree.h", "expr.h", "flags.h". + (ns32k_reg_class_contents, regcass_map, ns32k_out_reg_names, + hard_regno_mode_ok, secondary_reload_class, + print_operand, print_operand_address): New register scheme to + include 32381 fpu registers and special register classes for new + 32381 instructions dotf and polyf. + (gen_indexed_expr): Make static to keep namespace clean. + (check_reg): Remove since never called. + (move_tail, expand_block_move): Helper functions for "movstrsi" + block move insn. + (register_move_cost): Helper function for REGISTER_MOVE_COST macro. + Increase cost of moves which go via memory. + * netbsd.h (TARGET_DEFAULT): Set (new) 32381 fpu flag. + (CPP_PREDEFINES): No longer predefine "unix". + + * ns32k.md (movsi, movsi, adddi3, subdi3, subsi3, subhi3, subqi3,...): + Remove erroneous %$. print_operand() can work out from the rtx is + an immediate prefix is required. + + * ns32k.h (RETURN_POPS_ARGS, VALID_MACHINE_DECL_ATTRIBUTE, + VALID_MACHINE_TYPE_ATTRIBUTE, COMP_TYPE_ATTRIBUTES, + SET_DEFAULT_TYPE_ATTRIBUTES): Support for -mrtd calling + convention. + (LEGITIMATE_PIC_OPERAND_P, SYMBOLIC_CONST): Correct handling of + pic operands. + + * ns32k.c (symbolic_reference_mentioned_p, print_operand): + Correct handling of pic operands. + (ns32k_valid_decl_attribute_p, ns32k_valid_type_attribute_p, + ns32k_comp_type_attributes, ns32k_return_pops_args): Support for + -mrtd calling convention. + +Wed Nov 25 23:42:20 1998 Tom Tromey + + * gcc.c (option_map): Recognize --output-class-directory. + +Thu Nov 26 18:26:21 1998 Michael Hayes + + * loop.h (precondition_loop_p): Added new mode argument. + * unroll.c (precondition_loop_p): Likewise. + (approx_final_value): Function deleted and subsumed + into loop_iterations. + (loop_find_equiv_value): New function. + (loop_iterations): Use loop_find_equiv_value to find increments + too large to be immediate constants. Also use it to find terms + common to initial and final iteration values that can be removed. + +Thu Nov 26 18:05:04 1998 Michael Hayes + + * loop.h (struct loop_info): Define new structure. + (precondition_loop_p): Added prototype. + (unroll_loop): Added new argument loop_info to prototype. + (final_biv_value, final_giv_value): Added new argument n_iterations + to prototype. + * loop.c (strength_reduce): Declare new structure loop_iteration_info + and new pointer loop_info. + (loop_n_iterations): Replace global variable by element in + loop_info structure. + (check_final_value): New argument n_iterations. + (insert_bct): New argument loop_info. + (loop_unroll_factor): Replace global array by element in + loop_info structure. + (loop_optimize): Remove code to allocate and initialize + loop_unroll_factor_array. + * unroll.c (precondition_loop_p): No longer static since + used by branch on count optimization. + (precondition_loop_p, unroll_loop): New argument loop_info. + (final_biv_value, final_giv_value, find_splittable_regs): New + argument n_iterations. + (loop_iteration_var, loop_initial_value, loop_increment, + loop_final_value, loop_comparison_code, loop_unroll_factor): + Replaced global variables by loop_info structure. + (loop_unroll_factor): Replace global array by element in + loop_info structure. + +Thu Nov 26 17:49:29 1998 Michael Hayes + + * loop.c (check_dbra_loop): Update JUMP_LABEL field of jump insn + when loop reversed. + + * unroll.c (precondition_loop_p): Return loop_initial_value + for initial_value instead of loop_iteration_var. + +Thu Nov 26 17:15:38 1998 Michael Hayes + + * config/c4x/c4x.md: Fix minor formatting problems. Update docs. + (*b, *b_rev, *b_noov, *b_noov_rev, *db, + decrement_and_branch_until_zero, rptb_end): Use c4x_output_cbranch + to output the instruction sequences. + (rpts): Delete. + (rptb_top): Provide alternatives to use any register or memory + for loop counter. + (rptb_end): Emit use of operands rather than assigning them + explicitly to the RS and RE registers. + +Thu Nov 26 16:37:59 1998 Michael Hayes + + * config/c4x/c4x.c (c4x_modified_between_p, c4x_mem_set_p, + c4x_mem_set_p, c4x_mem_modified_between_p, c4x_insn_moveable_p, + c4x_parallel_pack, c4x_parallel_find, c4x_update_info_reg, + c4x_update_info_regs, c4x_copy_insn_after, c4x_copy_insns_after, + c4x_merge_notes, c4x_parallel_process, + c4x_combine_parallel_independent, c4x_combine_parallel_dependent, + c4x_combine_parallel): Delete. + +Thu Nov 26 15:16:05 1998 Michael Hayes + + * config/c4x/c4x.c (c4x_override_options): For compatibility + with old target options clear flag_branch_on_count_reg if + -mno-rptb specified and set flag_argument_alias is -mno-aliases + specified. + (c4x_output_cbranch): Handle a sequence of insns rather than a + single insn. + (c4x_rptb_insert): Do not emit a RPTB insn if the RC register + has not been allocated as the loop counter. + (c4x_address_conflict): Do not allow two volatile memory references. + (valid_parallel_operands_4, valid_parallel_operands_5, + valid_parallel_operands_6): Reject pattern if the register destination + of the first set is used as part of an address in the second set. + +Thu Nov 26 14:56:32 1998 Michael Hayes + + * config/c4x/c4x.h (TARGET_DEFAULT): Add PARALEL_MPY_FLAG. + (TARGET_SMALL_REG_CLASS): Set to 0 so that SMALL_REGISTER_CLASSES + is no longer enabled if PARALLEL_MPY_FLAG set. + (HARD_REGNO_CALL_CLOBBERED): Add parentheses to remove ambiguity. + (REG_CLASS_CONTENTS): Add braces around initializers. + (HAVE_MULTIPLE_PACK): Define. + (ASM_OUTPUT_BYTE_FLOAT): Use %lf format specifier with + REAL_VALUE_TO_DECIMAL. + (ASM_OUTPUT_SHORT_FLOAT): Use %lf format specifier with + REAL_VALUE_TO_DECIMAL. + (ar0_reg_operand): Add prototype. + (ar0_mem_operand): Likewise. + (ar1_reg_operand): Likewise. + (ar1_mem_operand): Likewise. + (ar2_reg_operand): Likewise. + (ar2_mem_operand): Likewise. + (ar3_reg_operand): Likewise. + (ar3_mem_operand): Likewise. + (ar4_reg_operand): Likewise. + (ar4_mem_operand): Likewise. + (ar5_reg_operand): Likewise. + (ar5_mem_operand): Likewise. + (ar6_reg_operand): Likewise. + (ar6_mem_operand): Likewise. + (ar7_reg_operand): Likewise. + (ar7_mem_operand): Likewise. + (ir0_reg_operand): Likewise. + (ir0_mem_operand): Likewise. + (ir1_reg_operand): Likewise. + (ir1_mem_operand): Likewise. + (group1_reg_operand): Likewise. + (group1_mem_operand): Likewise. + (ir1_reg_operand): Likewise. + (arx_reg_operand): Likewise. + (not_rc_reg): Likewise. + (not_modify_reg): Likewise. + (c4x_group1_reg_operand): Remove prototype. + (c4x_group1_mem_operand): Likewise. + (c4x_arx_reg_operand): Likewise. + +Wed Nov 25 19:02:55 1998 (Stephen L Moshier) + + * emit-rtl.c (gen_lowpart_common): Remove earlier change. + * real.c (make_nan): Make SIGN arg actually specify the sign bit. + +Thu Nov 26 14:12:05 1998 Michael Hayes + + * config/c4x/c4x.md (addqi3): Emit addqi3_noclobber pattern + during reload. -Thu Feb 19 22:36:53 1998 Andrey Slepuhin - David Edelsohn +Wed Nov 25 22:05:28 1998 J"orn Rennecke + + * config/sh/lib1funcs.asm (___udivsi3_i4): Don't switch to sz == 1 + unless FMOVD_WORKS is defined. + +Wed Nov 25 20:11:04 1998 J"orn Rennecke + + * regclass.c (init_reg_sets): Move code that calculates tables + dependent on reg_class_contents from here... + (init_reg_sets_1): To here. + +Wed Nov 25 14:54:46 1998 Zack Weinberg + + * cpplib.h: Delete struct import_file. Add ihash element to + struct cpp_buffer. Delete dont_repeat_files and + import_hash_table elements from cpp_reader; change + all_include_files to a hash table. Delete all foobar_include + / last_foobar_include elements from struct cpp_options; put + back four such: quote_include, bracket_include, + system_include, after_include. Redo struct file_name_list + completely. Add new structure type include_hash. Add + prototypes for merge_include_chains and include_hash. Change + prototypes for finclude, find_include_file, and + append_include_chain to match changes below. + + * cppfiles.c (simplify_pathname, include_hash, + remap_filename, merge_include_chains): New functions. + (add_import, lookup_import, open_include_file): Removed. + (INO_T_EQ): Define this (copied from cccp.c). + (hack_vms_include_specification): Remove all calls and #if 0 + out the definition. It was being called incorrectly and at + the wrong times. Until a VMSie can look at this, it's better + to not pretend to support it. + (append_include_chain): Change calling convention; now takes + only one directory at a time, and sets up the data structure + itself. + (redundant_include_p): Rewritten - this is now used for all + include redundancy, whether by #ifndef, #import, or #pragma + once. Looks up things in the include hash table. + (file_cleanup): Decrement pfile->system_include_depth here if + it's >0. + (find_include_file): Calling convention changed; now passes + around a struct include_hash instead of 3 separate parameters. + Guts ripped out and replaced with new include_hash mechanism. + (finclude): Calling convention changed as for + find_include_file. Error exits pulled out-of-line. Reformat. + (safe_read): Return a long, not an int. + (deps_output): Don't recurse. + + * cpplib.c (is_system_include): Deleted. + (path_include): Fix up call to append_include_chain. + (do_include): Fix up calls to find_include_file and finclude. + Clean up dependency output a bit. Shorten obnoxiously lengthy + #import warning message. Don't decrement + pfile->system_include_depth here. + (do_pragma): Understand the include_hash structure. Reformat. + (do_endif): Correct handling of control macros. Understand + the include_hash. + (cpp_start_read): Fix up calls to finclude. Call + merge_include_chains. + (cpp_handle_option): Fix up calls to append_include_chain. + Understand the four partial include chains. + (cpp_finish): Add debugging code (#if 0-ed out) for the + include_hash. + (cpp_cleanup): Free the include_hash, not the import hash and + the all_include and dont_repeat lists which no longer exist. + +Wed Nov 25 11:26:19 1998 Jeffrey A Law (law@cygnus.com) + + * toplev.c (no_new_pseudos): Define. + (rest_of_compilation): Set no_new_pseudos as needed. + * emit-rtl.c (gen_reg_rtx): Abort if we try to create a new pseudo + if no_new_pseudos is set. + * rtl.h (no_new_pseudos): Declare it. + * reload1.c (reload): Update comments. + * md.texi: Corresponding changes. + +Wed Nov 25 11:26:17 1998 Bernd Schmidt + + * reload1.c (reg_used_in_insn): Renamed from reg_used_by_pseudo. + (choose_reload_regs): Rename it here as well. When computing it, + also merge in used hardregs. + +1998-11-25 Zack Weinberg + + * gcc.c: Split out Objective-C specs to... + * objc/lang-specs.h: here. (New file.) Make the specs cpplib + aware. + + * c-lex.c (init_parse): Always initialize the filename global. + * objc/objc-act.c (lang_init): Always call check_newline at + beginning of file. + +Wed Nov 25 00:48:29 1998 Graham + + * reload1.c (reload): Remove unused variable. + (reload_reg_free_for_value_p): Add missing parameter definition. + + * jump.c (jump_optimize): Remove unused variable. + +Wed Nov 25 00:07:11 1998 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (graph.o): Depend on $(RTL_H), not rtl.h. + + * cse.c (fold_rtx): Make autoincrement addressing mode tests be + runtime selectable. + * expr.c (move_by_pieces): Similarly. + (move_by_pieces_1, clear_by_pieces, clear_by_pieces_1): Similarly. + * flow.c (find_auto_inc): Similarly. + (try_pre_increment): Similarly. + * loop.c (strength_reduce): Similarly. + * regclass.c (auto_inc_dec_reg_p): Similarly. + * regmove.c (try_auto_increment): Similarly. + (fixup_match_1): Similarly. + * rtl.h (HAVE_PRE_INCREMENT): Define if not already defined. + (HAVE_PRE_DECREMENT): Similarly. + (HAVE_POST_INCREMENT, HAVE_POST_DECREMENT): Similarly. + * Corresponding changes to all target header files. + * tm.texi: Update docs for autoinc addressing modes. + +Tue Nov 24 20:24:59 1998 Jim Wilson + + * configure.in (m68020-*-elf*, m68k-*-elf*): New targets. + * configure: Rebuild. + * config/elfos.h: New file. + * config/m68k/m68020-elf.h, config/m68k/m68kelf.h, + config/m68k/t-m68kelf: New file. - * collect2.c (XCOFF_SCAN_LIBS): Remove. - (export_flag): New variable. - (export_file): #ifdef COLLECT_EXPORT_LIST. - (import_file, exports, imports, undefined): New variables. - (libs, cmdline_lib_dirs, libpath_lib_dirs, libpath, libexts): Same. - (dump_list, dump_prefix_list, is_in_list): New functions. - (write_export_file): $ifdef COLLECT_EXPORT_LIST. - (write_import_file, resolve_lib_name): New functions. - (use_import_list, ignore_library): Same. - (collect_exit): maybe_unlink import_file and #ifdef. - (handler): Same. - (main): New variable importf, #ifdef exportf. Move parsing of - -shared before general argument parsing. Resolve AIX library - paths and import libgcc.a symbols. Treat .so shared libraries the - same as objects and .a libraries. Create alias for object_lst and - increment it instead of original pointer. Scan AIX libraries as - objects earlier instead of using scan_libraries. Perform AIX - tlink later to resolve templates instead of forking ld. - (GCC_OK_SYMBOL): Ensure symbol not in undef section. - (GCC_UNDEF_SYMBOL): New macro. - (scan_prog_file): Loop for members of AIX libraries. Handle - export/import of ctors/dtors. - (aix_std_libs): New variable. - (scan_libraries, XCOFF): Delete. +Tue Nov 24 13:40:06 1998 Jeffrey A Law (law@cygnus.com) -Thu Feb 19 22:36:52 1998 Robert Lipe + * Makefile.in (HOST_AR): Define. + (HOST_AR_FLAGS, HOST_RANLIB, HOST_RANLIB_TEST): Similarly. + (libcpp.a): Use the host tools explicitly. + (STAGESTUFF): Add libcpp.a. - * collect2.c (full_real_ld_suffix): #ifdef CROSS_COMPILE. +Tue Nov 24 09:33:49 1998 Nick Clifton -1998-02-19 Mike Stump + * config/m32r/m32r.md (movstrsi_internal): Describe changes made + to source and destination registers. - * Makefile.in: Use $tooldir for sys-include to match toplevel - configure. +Mon Nov 23 20:28:02 1998 Mike Stump -Thu Feb 19 01:32:37 1998 Jeffrey A Law (law@cygnus.com) - Richard Kenner + * libgcc2.c (top_elt): Remove top_elt, it isn't thread safe. + The strategy we now use is to pre allocate the top_elt along + with the EH context so that each thread has its own top_elt. + This is necessary as the dynamic cleanup chain is used on the + top element of the stack and each thread MUST have its own. + (eh_context_static): Likewise. + (new_eh_context): Likewise. + (__sjthrow): Likewise. - * emit-rtl.c (gen_lowpart_common): Suppress last change if __complex__. +Mon Nov 23 20:25:03 1998 Jason Merrill - * emit-rtl.c (hard-reg-set.h): Include. - (get_lowpart_common): Don't make new REG for hard reg in a - class that cannot change size. - * Makefile.in (emit-rtl.o): Depend on hard-reg-set.h. + * i386/linux.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Wrap in do...while. + * i386.md (prologue_get_pc): Remove unused variable. - * combine.c: Revert previous patch. +Mon Nov 23 17:05:40 1998 Geoffrey Noer -1998-02-19 Paul Eggert + * i386/xm-cygwin.h: Rename cygwin_ path funcs back to cygwin32_. - * config/sparc/sol2-sld.h: New file. - * configure.in (sparc-*-solaris2*): Use it when using the - system linker. +Mon Nov 23 16:40:00 1998 Ulrich Drepper -Thu Feb 19 00:46:59 1998 Jeffrey A Law (law@cygnus.com) + * Makefile.in (OBJS): Add graph.o. + (graph.o): New dependency list. + * flags.h: Declare dump_for_graph and define graph_dump_types type. + * print-rtl.c (dump_for_graph): Define new variable. + (print_rtx): Rewrite to allow use in graph dumping functions. + * toplev.c: Declare print_rtl_graph_with_bb, clean_graph_dump_file, + finish_graph_dump_file. + Define graph_dump_format. + (compile_file): If graph dumping is enabled also clear these files. + Finish graph dump files. + (rest_of_compilation): Also dump graph information if enabled. + (main): Recognize -dv to enabled VCG based graph dumping. + * graph.c: New file. Graph dumping functions. - * loop.c (force_movables): Fix typo. +Mon Nov 23 16:39:04 1998 Richard Henderson -Thu Feb 19 08:26:30 1998 Manfred Hollstein + * configure.in: Look for . + * system.h: Include it before substitute S_ISREG definitions. - * m88k.h: Change file pattern to match reality. +Mon Nov 23 17:40:37 1998 Gavin Romig-Koch -Wed Feb 18 23:19:52 1998 Jeffrey A Law (law@cygnus.com) + * config/mips/abi.h: Use ABI_O64, duplicating ABI_32 usage. + * config/mips/iris6.h: Same. + * config/mips/mips.md: Same. + * config/mips/mips.c: Same; also add "-mabi=o64" option. + * config/mips/mips.h: Same; also define ABI_O64. - * varasm.c (output_constant_pool): Fix dumb thinko in last - change. +Mon Nov 23 17:02:27 1998 Kaveh R. Ghazi - * pa.h (ASM_OUTPUT_FUNCTION_PREFIX): Correctly translate from - a function name to a section name. + * configure.in: Use AC_PREREQ(2.12.1). -1998-02-18 Doug Evans +Mon Nov 23 10:16:38 1998 Melissa O'Neill - * tree.h (merge_machine_{type,decl}_attributes): Declare. - (split_specs_attrs, strip_attrs): Add prototypes. - * tree.c (merge_machine_{type,decl}_attributes): New functions. - * c-decl.c (duplicate_decls): Call merge_machine_decl_attributes. - Update olddecl's attributes too. - * c-common.c (strip_attrs): New function. - * c-typeck.c (common_type): Call merge_machine_type_attributes. - * varasm.c (make_function_rtl): New target macro REDO_SECTION_INFO_P. - (make_decl_rtl): Likewise. + * cccp.c (S_ISREG, S_ISDIR): Delete defines. + * cpplib.c, gcc.c: Likewise. + * system.h (S_ISREG, S_ISDIR): Define if not already defined. -1998-02-18 Jim Wilson +Mon Nov 23 09:53:44 1998 Richard Henderson - * c-decl.c (shadow_tag_warned): Call split_specs_attrs. + * local-alloc.c (local_alloc): Use malloc not alloca for + reg_qty, reg_offset, ref_next_in_qty. -Wed Feb 18 09:09:50 1998 Jeffrey A Law (law@cygnus.com) +Mon Nov 23 16:46:46 1998 J"orn Rennecke + + * caller-save.c (insert_one_insn): Initialize the live_before and + live_after register sets. + + Add SH4 support: + + * config/sh/lib1funcs.asm (___movstr_i4_even, ___movstr_i4_odd): Define. + (___movstrSI12_i4, ___sdivsi3_i4, ___udivsi3_i4): Define. + * sh.c (reg_class_from_letter, regno_reg_class): Add DF_REGS. + (fp_reg_names, assembler_dialect): New variables. + (print_operand_address): Handle SUBREGs. + (print_operand): Added 'o' case. + Don't use adj_offsettable_operand on PRE_DEC / POST_INC. + Name of FP registers depends on mode. + (expand_block_move): Emit different code for SH4 hardware. + (prepare_scc_operands): Use emit_sf_insn / emit_df_insn as appropriate. + (from_compare): Likewise. + (add_constant): New argument last_value. Changed all callers. + (find_barrier): Don't try HImode load for FPUL_REG. + (machine_dependent_reorg): Likewise. + (sfunc_uses_reg): A CLOBBER cannot be the address register use. + (gen_far_branch): Emit a barrier after the new jump. + (barrier_align): Don't trust instruction lengths before + fixing up pcloads. + (machine_dependent_reorg): Add support for FIRST_XD_REG .. LAST_XD_REG. + Use auto-inc addressing for fp registers if doubles need to + be loaded in two steps. + Set sh_flag_remove_dead_before_cse. + (push): Support for TARGET_FMOVD. Use gen_push_fpul for fpul. + (pop): Support for TARGET_FMOVD. Use gen_pop_fpul for fpul. + (calc_live_regs): Support for TARGET_FMOVD. Don't save FPSCR. + Support for FIRST_XD_REG .. LAST_XD_REG. + (sh_expand_prologue): Support for FIRST_XD_REG .. LAST_XD_REG. + (sh_expand_epilogue): Likewise. + (sh_builtin_saveregs): Use DFmode moves for fp regs on SH4. + (initial_elimination_offset): Take TARGET_ALIGN_DOUBLE into account. + (arith_reg_operand): FPUL_REG is OK for SH4. + (fp_arith_reg_operand, fp_extended_operand): New functions. + (tertiary_reload_operand, fpscr_operand): Likewise. + (commutative_float_operator, noncommutative_float_operator): Likewise. + (binary_float_operator, get_fpscr_rtx, emit_sf_insn): Likewise. + (emit_df_insn, expand_sf_unop, expand_sf_binop): Likewise. + (expand_df_unop, expand_df_binop, expand_fp_branch): Likewise. + (emit_fpscr_use, mark_use, remove_dead_before_cse): Likewise. + * sh.h (CPP_SPEC): Add support for -m4, m4-single, m4-single-only. + (CONDITIONAL_REGISTER_USAGE): Likewise. + (HARD_SH4_BIT, FPU_SINGLE_BIT, SH4_BIT, FMOVD_BIT): Define. + (TARGET_CACHE32, TARGET_SUPERSCALAR, TARGET_HARWARD): Define. + (TARGET_HARD_SH4, TARGET_FPU_SINGLE, TARGET_SH4, TARGET_FMOVD): Define. + (target_flag): Add -m4, m4-single, m4-single-only, -mfmovd. + (OPTIMIZATION_OPTIONS): If optimizing, set flag_omit_frame_pointer + to -1 and sh_flag_remove_dead_before_cse to 1. + (ASSEMBLER_DIALECT): Define to assembler_dialect. + (assembler_dialect, fp_reg_names): Declare. + (OVERRIDE_OPTIONS): Add code for TARGET_SH4. + Hide names of registers that are not accessible. + (CACHE_LOG): Take TARGET_CACHE32 into account. + (LOOP_ALIGN): Take TARGET_HARWARD into account. + (FIRST_XD_REG, LAST_XD_REG, FPSCR_REG): Define. + (FIRST_PSEUDO_REGISTER: Now 49. + (FIXED_REGISTERS, CALL_USED_REGISTERS): Include values for registers. + (HARD_REGNO_NREGS): Special treatment of FIRST_XD_REG .. LAST_XD_REG. + (HARD_REGNO_MODE_OK): Update. + (enum reg_class): Add DF_REGS and FPSCR_REGS. + (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REG_ALLOC_ORDER): Likewise. + (SECONDARY_OUTPUT_RELOAD_CLASS, SECONDARY_INPUT_RELOAD_CLASS): Update. + (CLASS_CANNOT_CHANGE_SIZE, DEBUG_REGISTER_NAMES): Define. + (NPARM_REGS): Eight floating point parameter registers on SH4. + (BASE_RETURN_VALUE_REG): SH4 also passes double values + in floating point registers. + (GET_SH_ARG_CLASS): Likewise. + Complex float types are also returned in float registers. + (BASE_ARG_REG): Complex float types are also passes in float registers. + (FUNCTION_VALUE): Change mode like PROMOTE_MODE does. + (LIBCALL_VALUE): Remove trailing semicolon. + (ROUND_REG): Round when double precision value is passed in floating + point register(s). + (FUNCTION_ARG_ADVANCE): No change wanted for SH4 when things are + passed on the stack. + (FUNCTION_ARG): Little endian adjustment for SH4 SFmode. + (FUNCTION_ARG_PARTIAL_NREGS): Zero for SH4. + (TRAMPOLINE_ALIGNMENT): Take TARGET_HARWARD into account. + (INITIALIZE_TRAMPOLINE): Emit ic_invalidate_line for TARGET_HARWARD. + (MODE_DISP_OK_8): Not for SH4 DFmode. + (GO_IF_LEGITIMATE_ADDRESS): No base reg + index reg for SH4 DFmode. + Allow indexed addressing for PSImode after reload. + (LEGITIMIZE_ADDRESS): Not for SH4 DFmode. + (LEGITIMIZE_RELOAD_ADDRESS): Handle SH3E SFmode. + Don't change SH4 DFmode nor PSImode RELOAD_FOR_INPUT_ADDRESS. + (DOUBLE_TYPE_SIZE): 64 for SH4. + (RTX_COSTS): Add PLUS case. + Increase cost of ASHIFT, ASHIFTRT, LSHIFTRT case. + (REGISTER_MOVE_COST): Add handling of R0_REGS, FPUL_REGS, T_REGS, + MAC_REGS, PR_REGS, DF_REGS. + (REGISTER_NAMES): Use fp_reg_names. + (enum processor_type): Add PROCESSOR_SH4. + (sh_flag_remove_dead_before_cse): Declare. + (rtx_equal_function_value_matters, fpscr_rtx, get_fpscr_rtx): Declare. + (PREDICATE_CODES): Add binary_float_operator, + commutative_float_operator, fp_arith_reg_operand, fp_extended_operand, + fpscr_operand, noncommutative_float_operator. + (ADJUST_COST): Use different scale for TARGET_SUPERSCALAR. + (SH_DYNAMIC_SHIFT_COST): Cheaper for SH4. + * sh.md (attribute cpu): Add value sh4. + (attrbutes fmovd, issues): Define. + (attribute type): Add values dfp_arith, dfp_cmp, dfp_conv, dfdiv. + (function units memory, int, mpy, fp): Make dependent on issue rate. + (function units issue, single_issue, load_si, load): Define. + (function units load_store, fdiv, gp_fpul): Define. + (attribute hit_stack): Provide proper default. + (use_sfunc_addr+1, udivsi3): Predicated on ! TARGET_SH4. + (udivsi3_i4, udivsi3_i4_single, divsi3_i4, divsi3_i4_single): New insns. + (udivsi3, divsi3): Emit special patterns for SH4 hardware, + (mulsi3_call): Now uses match_operand for function address. + (mulsi3): Also emit code for SH1 case. Wrap result in REG_LIBCALL / + REG_RETVAL notes. + (push, pop, push_e, pop_e): Now define_expands. + (push_fpul, push_4, pop_fpul, pop_4, ic_invalidate_line): New expanders. + (movsi_ie): Added y/i alternative. + (ic_invalidate_line_i, movdf_i4): New insns. + (movdf_i4+[123], reload_outdf+[12345], movsi_y+[12]): New splitters. + (reload_indf, reload_outdf, reload_outsf, reload_insi): New expanders. + (movdf): Add special code for SH4. + (movsf_ie, movsf_ie+1, reload_insf, calli): Make use of fpscr visible. + (call_valuei, calli, call_value): Likewise. + (movsf): Emit no-op move. + (mov_nop, movsi_y): New insns. + (blt, sge): Generalize to handle DFmode. + (return predicate): Call emit_fpscr_use and remove_dead_before_cse. + (block_move_real, block_lump_real): Predicate on ! TARGET_HARD_SH4. + (block_move_real_i4, block_lump_real_i4, fpu_switch): New insns. + (fpu_switch0, fpu_switch1, movpsi): New expanders. + (fpu_switch+[12], fix_truncsfsi2_i4_2+1): New splitters. + (toggle_sz): New insn. + (addsf3, subsf3, mulsf3, divsf3): Now define_expands. + (addsf3_i, subsf3_i, mulsf3_i4, mulsf3_ie, divsf3_i): New insns. + (macsf3): Make use of fpscr visible. Disable for SH4. + (floatsisf2): Make use of fpscr visible. + (floatsisf2_i4): New insn. + (floatsisf2_ie, fixsfsi, cmpgtsf_t, cmpeqsf_t): Disable for SH4. + (ieee_ccmpeqsf_t): Likewise. + (fix_truncsfsi2): Emit different code for SH4. + (fix_truncsfsi2_i4, fix_truncsfsi2_i4_2, cmpgtsf_t_i4): New insns. + (cmpeqsf_t_i4, ieee_ccmpeqsf_t_4): New insns. + (negsf2, sqrtsf2, abssf2): Now expanders. + (adddf3, subdf3i, muldf2, divdf3, floatsidf2): New expanders. + (negsf2_i, sqrtsf2_i, abssf2_i, adddf3_i, subdf3_i): New insns. + (muldf3_i, divdf3_i, floatsidf2_i, fix_truncdfsi2_i): New insns. + (fix_truncdfsi2, cmpdf, negdf2, sqrtdf2, absdf2): New expanders. + (fix_truncdfsi2_i4, cmpgtdf_t, cmpeqdf_t, ieee_ccmpeqdf_t): New insns. + (fix_truncdfsi2_i4_2+1): New splitters. + (negdf2_i, sqrtdf2_i, absdf2_i, extendsfdf2_i4): New insns. + (extendsfdf2, truncdfsf2): New expanders. + (truncdfsf2_i4): New insn. + * t-sh (LIB1ASMFUNCS): Add _movstr_i4, _sdivsi3_i4, _udivsi3_i4. + (MULTILIB_OPTIONS): Add m4-single-only/m4-single/m4. + * float-sh.h: When testing for __SH3E__, also test for + __SH4_SINGLE_ONLY__ . + * va-sh.h (__va_freg): Define to float. + (__va_greg, __fa_freg, __gnuc_va_list, va_start): + Define for __SH4_SINGLE_ONLY__ like for __SH3E__ . + (__PASS_AS_FLOAT, __TARGET_SH4_P): Likewise. + (__PASS_AS_FLOAT): Use different definition for __SH4__ and + __SH4_SINGLE__. + (TARGET_SH4_P): Define. + (va_arg): Use it. - Remove this change until we can fix it correctly. - * collect2.c: Bracket declaration of 'exportf' and - 'full_real_ld_suffix'. + * sh.md (movdf_k, movsf_i): Tweak the condition so that + init_expr_once is satisfied about the existence of load / store insns. -Wed Feb 18 08:44:25 1998 Bernd Schmidt + * sh.md (movsi_i, movsi_ie, movsi_i_lowpart, movsf_i, movsf_ie): + Change m constraint in source operand to mr / mf. - * Makefile.in (STAGESTUFF): Add genrtl.c, genrtl.h and gengenrtl. + * va-sh.h (__va_arg_sh1): Use __asm instead of asm. -Tue Feb 17 23:30:20 1998 Bernd Schmidt + * (__VA_REEF): Define. + (__va_arg_sh1): Use it. - * c-common.c (c_expand_start_cond, c_expand_end_cond, - c_expand_start_else): Don't warn about non-ambiguous else even if - braces are missing. + * va-sh.h (va_start, va_arg, va_copy): Add parentheses. -Tue Feb 17 23:56:50 1998 Robert Lipe +Sun Nov 22 21:34:02 1998 Jeffrey A Law (law@cygnus.com) - * sco5.h (ASM_OUTPUT_DOUBLE, ASM_OUTPUT_FLOAT, - ASM_OUTPUT_LONG_DOUBLE): Delete. Use the ones from i386.h - instead. + * i386/dgux.c (struct option): Add new "description field". + * m88k/m88k.c (struct option): Likewise. -Tue Feb 17 22:56:14 1998 Richard Henderson +Sun Nov 22 16:07:57 1998 Jeff Law (law@cygnus.com) - * combine.c (simplify_rtx): Obey CLASS_CANNOT_CHANGE_SIZE when - simplifying a subreg of a hard reg. - (expand_compound_operation): Likewise. - (force_to_mode): Likewise. + * version.c: Bump for snapshot. -Tue Feb 17 22:37:22 1998 Kaveh R. Ghazi +Sun Nov 22 13:40:02 1998 Bernd Schmidt - * fold-const.c: Include "system.h" to get stdlib.h and stdio.h. - (lshift_double): Add parentheses around + or - inside shift. - (rshift_double): Likewise. - (size_int_wide): Explicitly set type of `bit_p' to `int'. + * regmove.c (regmove_profitable_p): Use return value of find_matches + properly. - * Makefile.in (fold-const.o): Depend on system.h. +Sun Nov 22 02:47:37 1998 Jeff Law (law@cygnus.com) - * Makefile.in (gcc.o): Depend on system.h, in accordance with last - change to gcc.c. + * version.c: Bump for snapshot. - * haifa-sched.c: Include "system.h" to get and . - (BLOCKAGE_RANGE): Add parentheses around arithmetic in operand of |. - (sched_note_set): Remove unused parameter `b', all callers changed. - (schedule_block): Likewise for `rgn'. - (split_hard_reg_notes): Likewise for `orig_insn'. - (check_live): Likewise for `trg'. - (update_live): Likewise. - (check_live_1): Explcitly declare variable `i' as int. - (update_live_1): Likewise. - (insn_issue_delay): Remove unused variable `link'. - (sched_analyze_2): Add default case in enumeration switch. - (schedule_insns): Remove unused variable `i'. +Sat Nov 21 22:12:09 1998 Jeffrey A Law (law@cygnus.com) + + * reload1.c (eliminate_regs): Do not lose if eliminate_regs is called + without reload having been called earlier. + + * v850.c (ep_memory_operand): Offsets < 0 are not valid for EP + addressing modes. + (v850_reorg): Similarly. + + * loop.c (check_dbra_loop): Avoid using gen_add2_insn. + +Sat Nov 21 02:18:38 1998 J"orn Rennecke + + * loop.c (move_movables): Start of libcall might be new loop start. + +Fri Nov 20 12:14:16 1998 Kaveh R. Ghazi + + * hash.c (hash_table_init_n): Wrap prototype arguments in PARAMS(). + +Fri Nov 20 08:34:00 1998 Bernd Schmidt + + * function.c (nonlocal_goto_handler_slots): Renamed from + nonlocal_goto_handler_slot; now an EXPR_LIST chain. + (push_function_context_to): Adjust for this change. + (pop_function_context_from): Likewise. + (init_function_start): Likewise. + (expand_function_end): Likewise. + * function.h (struct function): Likewise. + * calls.c (expand_call): Likewise. + * explow.c (allocate_dynamic_stack_space): Likewise. + * expr.h (nonlocal_goto_handler_slots): Rename its declaration. + * stmt.c (declare_nonlocal_label): Make a new handler slot for each + label. + (expand_goto): When doing a nonlocal goto, find corresponding handler + slot for it. Don't put the label address in the static chain register. + (expand_end_bindings): Break out nonlocal goto handling code into + three new functions. + (expand_nl_handler_label, expand_nl_goto_receiver, + expand_nl_goto_receivers): New static functions, broken out of + expand_end_bindings and adapted to create one handler per nonlocal + label. + * function.c (delete_handlers): Delete insn if it references any of + the nonlocal goto handler slots. + * i960.md (nonlocal_goto): Comment out code that modifies + static_chain_rtx. + * sparc.md (nonlocal_goto): Likewise. + (goto_handler_and_restore_v9): Comment out. + (goto_handler_and_restore_v9_sp64): Comment out. + +Thu Nov 19 23:44:38 1998 Bernd Schmidt + + * expr.c (STACK_BYTES): Delete unused macro. + * calls.c: Provide default for PREFERRED_STACK_BOUNDARY. + (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. + (expand_call): Likewise. + (emit_library_call): Likewise. + (emit_library_call_value): Likewise. + * function.c: Provide default for PREFERRED_STACK_BOUNDARY. + (STACK_BYTES): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. + * explow.c: Provide default for PREFERRED_STACK_BOUNDARY. + (round_push): Use PREFERRED_STACK_BOUNDARY, not STACK_BOUNDARY. + (allocate_dynamic_stack_space): Likewise. + * tm.texi (PREFERRED_STACK_BOUNDARY): Document new macro. + (STACK_BOUNDARY): Update description to reflect the new situation. - * Makefile.in ($(SCHED_PREFIX)sched.o): Depend on system.h. +Thu Nov 19 22:20:51 1998 Jeffrey A Law (law@cygnus.com) -Tue Feb 17 22:31:04 1998 Jeffrey A Law (law@cygnus.com) + * reorg.c (relax_delay_slots): When optimizing for code size, if a + return with a filled delay slot is followed by a return with an + unfilled delay slot, delete the first return and reemit the insn + that was previously in its delay slot. - * loop.c (rtx_equal_for_loop_p): Add some braces to disambiguate - a dangling else clause. + * i860.c (single_insn_src_p): Add missing parens. + * ginclude/math-3300.h: Likewise. -Tue Feb 17 21:28:12 1998 Gavin Koch +Thu Nov 19 20:55:59 1998 H.J. Lu (hjl@gnu.org) - * mips/mips.h (CAN_ELIMINATE): Don't eliminate the frame - pointer for the stack pointer in MIPS16 and 64BIT. + * regclass.c (init_reg_sets_1): Add prototype. + (init_reg_modes): Likewise. -Tue Feb 17 21:17:30 1997 J"orn Rennecke +1998-11-19 Zack Weinberg - * rtl.h (force_line_numbers, restore_line_number_status): Declare. - * emit-rtl.c (force_line_numbers, restore_line_number_status): - New functions. - * stmt.c (struct nesting): Replace seenlabel with line_number_status. - (expand_start_case): Adjust to this change. - (check_seenlabel): New function. - (pushcase, pushcase_range, expand_endcase): Use it. + * c-common.c: Change warning messages to say `comparison is + always true' or `comparison is always false' instead of the + confusing `is always 0', `is always 1'. -Tue Feb 17 10:14:32 1998 J"orn Rennecke +Thu Nov 19 19:05:49 1998 Per Bothner - * i386.md (adddi3): Add =!r,0,0,X alternative. + * print-tree.c (print_node): After printing BLOCK or BIND_EXPR, + break instead of return (which loses closing '>'). -Mon Feb 16 16:13:43 1998 David Edelsohn +Thu Nov 19 19:34:13 1998 Jeffrey A Law (law@cygnus.com) - * rs6000.h (MY_ISCOFF): Add numeric value of U803XTOCMAGIC. - * x-aix31 (INSTALL): Delete. + * i386.h (LEGITIMATE_CONSTANT_P): Reject CONST_DOUBLEs that are not + standard 387 constants. -Mon Feb 16 09:24:32 1998 Gavin Koch + * i386.md (jump): Explicitly set "memory" attribute. + (indirect_jump, prologue_set_stack_ptr): Likewise. + (prologue_get_pc_and_set_got, pop): Likewise. + (allocate_stack_worder, blockage, return_internal): Likewise. + (return_pop_internal, nop): Likewise. + (epilogue_set_stack_ptr, leave): Likewise. - * mips/mips.c (mips_expand_epilogue): Update tsize_rtx if - tsize changes to something other than zero. +Thu Nov 19 15:42:54 1998 Nick Clifton -Mon Feb 16 09:11:48 1998 Gavin Koch + * config/arm/coff.h: Set USER_LABEL_PREFIX to "_". - * ginclude/va-mips.h: Replace casts of pointers to int with - casts of pointers to __PTRDIFF_TYPE__. +Thu Nov 19 23:20:59 1998 J"orn Rennecke -Mon Feb 16 08:17:14 1998 John Carr + * reload1.c (reload_reg_free_for_value_p): + Early auto_inc reloads don't conflict with outputs. - * loop.c (strength_reduce, record_biv, record_giv): Use - HOST_WIDE_INT_PRINT_DEC to print CONST_INT values. +Thu Nov 19 12:58:55 1998 Kaveh R. Ghazi -1998-02-16 Jason Merrill + * configure.in: Don't do AC_CHECK_HEADERS(wait.h sys/wait.h). + Instead call AC_HEADER_SYS_WAIT. - * tree.c (first_rtl_op): New fn. - (unsave_expr_now): Use it. - * print-tree.c (print_node): Likewise. - * tree.c (has_cleanups): New fn. - * fold-const.c (fold, case CLEANUP_POINT_EXPR): Use it. Be more - conservative about pushing the cleanup point down. - * tree.h: Declare them. + * collect2.c: Don't provide defaults for sys/wait.h macros. + * gcc.c: Likewise. + * protoize.c: Likewise. Also, don't include sys/wait.h. -Sun Feb 15 23:28:44 1998 Jeffrey A Law (law@cygnus.com) + * system.h: Include sys/wait.h and provide macro defaults. - * toplev.c (flag_schedule_reverse_before_reload): Delete variable. - (flag_schedule_reverse_after_reload): Likewise. - (f_options): Remove reverse scheduling support. - * flags.h (flag_schedule_reverse_before_reload): Delete declaration. - (flag_schedule_reverse_after_reload): Likewise. - * haifa-sched.c (rank_for_schedule): Remove support for reverse - scheduling. +1998-11-19 Andreas Schwab -Sun Feb 15 21:33:55 1998 Kaveh R. Ghazi + * Makefile.in (mandir): Set to @mandir@. + (man1dir): New variable to hold the former value of $(mandir). + Replace all uses of $(mandir) by $(man1dir). - * gcc.c: Get system includes, prototypes and macros via "system.h" - instead of doing it manually. Change all calls of the ctype - macros to custom versions defined in "system.h". +Wed Nov 18 16:31:28 1998 Jim Wilson - * system.h: Fix return type of bcmp prototype from `void' to `int'. - Make bcopy, bcmp and bzero prototypes explicitly `extern'. - Add a prototype for getenv. + * reload.c (find_reloads_address_part): If have a CONST_INT, create + a new one before passing it to force_const_mem. -Sun Feb 15 17:05:41 1998 Jim Wilson + * reload.c (find_reloads_toplev): Pass &x instead of NULL_PTR in + find_reloads_address call. - * mips/mips.h (INITIAL_ELIMINATION_OFFSET): Readd Jun 6 change. +Wed Nov 18 22:13:00 1998 J"orn Rennecke -Sun Feb 15 15:23:15 1998 John Carr + * expr.c (store_expr): Don't generate load-store pair + if TEMP is identical (according to ==) with TARGET. - * alias.c: Include and . - (init_alias_analysis): Pass NULL_RTX instead of 0 to record_set. +Tue Nov 17 22:25:16 1998 J"orn Rennecke -Sat Feb 14 11:23:09 PST 1998 Jeff Law (law@cygnus.com) + * reload1.c (reload_reg_free_for_value_p): When considered reload + has an output, matching inputs are not sufficient to avoid conflict. - * version.c: Bump for snapshot. +Tue Nov 17 11:51:16 1998 Mark Mitchell -Sat Feb 14 05:08:21 1998 Richard Earnshaw (rearnsha@arm.com) - - * arm.md (movsfcc): Also validate operands[3] when compiling hard - float. - (movdfcc): Only accept fpu_add_operand for operands[3]. - - * arm/t-semi (STMP_FIXPROTO): Define to nothing. - * arm/t-semiaof (STMP_FIXPROTO): Likewise. - -Sat Feb 14 02:02:41 1998 Jeffrey A Law (law@cygnus.com) - - * varasm.c (output_constant_pool): Bring back 'done' label inside - an appropriate #ifdef. - - * bitmap.c (bitmap_element_allocate): Wrap variable 'i' in an - appropriate #ifdef. - (bitmap_copy, bitmap_operation): Likewise. - * combine.c (combinable_i3pat): Similarly for 'src'. - * function.c (fixup_var_refs_1): Similarly for 'outerdest'. - (locate_and_pad_parm): Similarly for 'reg_parm_stack_space'. - * regclass.c (copy_cost): Similarly for 'secondary_class'. - * reload.c (make_memloc): Simliarly for 'i'. - (find_reloads_address_1): Similarly for 'link'. - * reload1.c (reload): Similarly for 'previous_frame_pointer_needed'. - (emit_reload_insns): Similarly for 'second_reloadreg'. - * unroll.c (iteration_info): Similarly for 'v'. - - * caller-save.c (insert_save_restore): Remove unused variable 'i'. - * calls.c (expand_call): Similarly for 'i'. - (emit_library_call, emit_library_call_value): Similarly for 'mode'. - * fold-const.c (strip_compund_expr): Similarly for 'type'. - * function.c (fixup_var_refs_1): Similarly for 'width'. - (fixup_memory_subreg): Similarly for 'saved'. - (locate_and_pad_parm): Similarly for 'boundary_in_bytes.' - (setjmp_protect): Similarly for 'sub'. - (thread_prologue_and_epilogue_insns): Similarly for 'insn'. - * loop.c (record_giv): Similarly for 'p'. - (combine_givs): Similarly for 'temp_iv'. - (indirect_jump_in_function_p): Similarly for 'is_indirect_jump'. - * recog.c (validate_replace_rtx_1): Similarly for 'width'. - * tree.c (get_set_constructor_bytes): Similarly for 'vals'. - * unroll.c (unroll_loop): Similarly for 'copy'. - (iteration_info): Similarly for 'b'. - * varasm.c (assemble_string): Similarly for 'i'. - * i386.h (LEGITIMIZE_ADDRESS): Similarly for 'orig_x'. - -1998-02-13 Martin von Loewis - - * c-lang.c (lang_print_xnode): New function. - * objc/objc-act.c (lang_print_xnode): Likewise. - * print-tree.c (print_node): Call it - -Fri Feb 13 14:38:34 1998 Jim Wilson - - * dwarf2out.c (decl_scope_node): New type. - (decl_scope_table): Change type to use it. - (decl_scope_table_allocated, decl_scope_depth): Change type to int. - (push_decl_scope): Use new type. New locals containing_scope, i. - Add code to handle setting previous field. - (scope_die_for): Change type of local i to int. Add code to use - previous field. - (dwarf2out_init): Use new type. - -1998-02-13 Jason Merrill - - * except.c (emit_throw): Lose throw_used. - -Fri Feb 13 20:36:05 1998 J"orn Rennecke - - * sched.c (update_flow_info, REG_WAS_0): Ignore if setting insn - was deleted. - * haifa-sched.c (update_flow_info, REG_WAS_0): Likewise. - -Fri Feb 13 12:18:40 1998 Jeffrey A Law (law@cygnus.com) - - * genextract.c (main): Fix typo. - -Fri Feb 13 08:41:49 1998 Robert Lipe - - * c-lang.c (finish_file): Bracket declaration of static_ctors, - static_dtors. - - * calls.c (expand_call): Bracket declaration of 'rtx_before_call', - 'old_stack_arg_under_construction' - (emit_library_call): Bracket declaration of 'upper_bound', - 'lower_bound', 'i', 'reg_parm_stack_space' - (emit_library_call_value): Likewise. - (store_one_arg): + * hash.h (hash_table_key): New type. + (hash_entry): Change `string' field to generic `key'. + (hash_table): Add `comp' and `hash' functions. + (hash_table_init): Take them as input. + (hash_table_init_n): Likewise. + (hash_lookup): Modify for generic keys. + (hash_newfunc): Likewise. + (hash_traverse): Likewise. + (string_hash): New function. + (string_compare): Likewise. + (string_copy): Likewise. + * hash.c (hash_table_init_n): Modify for generic keys. + (hash_table_init): Likewise. + (hash_lookup): Likewise. + (hash_newfunc): Likewise. + (hash_traverse): Likewise. + (string_hash): Split out from hash_lookup. + (string_compare): New function. + (string_copy): Split out from hash_lookup. + * tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash + tables. + (symbol_hash_lookup): Likewise. + (file_hash_newfunc): Likewise. + (file_hash_lookup): Likewise. + (demangled_hash_newfunc): Likewise. + (demangled_hash_lookup): Likewise. + (tlink_int): Likewise. + (read_repo_file): Likewise. + (recompile_files): Likewise. + (demangle_new_symbols): Likewise. + (scan_linker_output): Likewise. - * collect2.c: include when appropriate. - Bracket declaration of 'exportf' and 'full_real_ld_suffix'. +Tue Nov 17 17:13:53 1998 J"orn Rennecke - * emit-rtl.c (prev_cc0_setter): Remove unused variable 'link'. + * flow.c (insn_dead_p): New argument NOTES. Changed all callers. - * explow.c (plus_constant_for_output_wide): Remove unused variable - 'code'. - (memory_address): Remove unused variable 'orig_x'. +Mon Nov 16 17:56:07 1998 David Edelsohn - * genattrtab.c (make_canonical): Remove unreferenced label 'cond:'. - (write_const_num_delay_slots): Remove unused variable 'i'. + * rs6000.c (output_mi_thunk): Improve test for local branch. - * genopinit.c (main): Remove unused variables 'dummy', 'insn_ptr'. - (gen_insn): Remove unused variable 'obstack_ptr'. +Mon Nov 16 17:56:07 1998 Franz Sirl - * libgcc2.c (__bb_exit_func): Remove unused variables 'ret', - 'j', 'tmp', 'i'. - (__bb_exit_trace_func): Remove unused variable 'e'. + * rs6000.c (output_mi_thunk): Correct test for aggregate values. - * optabs.c (expand_binop): remove unused variables 'lhs', 'rhs', - 'funexp'. - (expand_unop): Remove unused variable 'funexp'. - (expand_complex_abs): Remove unused variable 'funexp'. - (init_optabs): Bracket declaration of 'j'. - (init_complex_libfuncs): Deleted. Dead static function. +Mon Nov 16 21:02:52 1998 J"orn Rennecke - * profile.c (branch_prob): Remove unused variables 'insn', 'dest'. + * reload1.c (reload_reg_free_before_p): Delete. + Changed all callers to use reload_reg_free_for_value_p instead. + (reload_reg_free_for_value_p): Handle more reload types. + A RELOAD_FOR_INPUT doesn't conflict with its + RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS. + Add special case for OUT == const0_rtx. + Added ignore_address_reloads argument. Changed all callers. - * reg-stack.c: Fix typo in proto for 'get_asm_operand_lengths' - (reg_to_stack): 'initialized', 'before_function_beg' - explictly type as ints instead of defaulting. - (emit_swap_insn): Remove unused variable 'i2'. - (compare_for_stack_reg): Remove unused variable 'src_note'. +Mon Nov 16 02:22:29 1998 Jason Merrill - * rtlanal.c (computed_jump_p): Remove unused variable 'computed_jump'. + * toplev.c (compile_file): Don't pedwarn about undefined static + functions just because we passed -Wunused. - * sched.c (actual_hazard): Bracket declaration of 'this_cost'. +Mon Nov 16 04:41:41 1998 J"orn Rennecke - * stmt.c (add_case_node): Add parens for assignment used as truth. - (all_cases_count): Remove unused variable 'count_high'. - (mark_seen_cases): Remove unused variable 'i'. - (check_for_full_enumeration_handling): Remove unused variable 't'. - Bracket declaration of 'all_values', 'l'. + * function.c (purge_addressof_1): Unshare rtl created by + store_bit_field. - * tlink.c: Include , , /. +Mon Nov 16 04:23:06 1998 J"orn Rennecke - * varasm.c (assemble_string): Remove unused variable 'i'. - (immed_double_const): Remove unused variable 'in_current_obstack'. - (immed_real_const_1): Likewise. - (output_constant_pool): Remove unreferenced label 'done'. - (output_constant): Remove unused variable 'x'. + * regmove.c (regmove_optimize): Don't do anything but + optimize_reg_copy[123] when flag_regmove is not set. - * i386/i386.h (ENCODE_SECTION_INFO): TREE_PUBLIC is an int, not - a string. +Sat Nov 14 15:05:07 1998 Richard Henderson - * i386/sco5.h (ASM_OUTPUT_ASCII): Add parens for assignment used - as truth. + * alpha.md (addsi3, subsi3): Revise 5 Nov change to store DImode + value in paradoxical SImode result, rather than truncating midpoint. -Fri Feb 13 10:21:41 1998 J"orn Rennecke +Fri Nov 13 22:19:23 1998 Richard Henderson - * combine.c (can_combine_p): Handle USEs in PARALLELs. + * alpha.c (reg_not_elim_operand): New. + * alpha.h (PREDICATE_CODES): Add it. + * alpha.md (s48addq, s48subq patterns): Use it as the predicate + for the multiplicand. + +Fri Nov 13 22:50:37 1998 David Edelsohn + + * rs6000.md (movsf): Remove explicit secondary-reload-like + functionality. Only truncate SFmode store if in FPR. + (movsf splitters): Combine const_double splitters. + (movsf_hardfloat): Add GPR support. + +Fri Nov 13 11:02:11 1998 Stan Cox + + * splet.h (SUBTARGET_OVERRIDE_OPTIONS): New to + deprecate -mlive-g0 and -mbroken-saverestore. + * t-splet (MULTILIB_OPTIONS): Likewise. + + * sparc.c (sparc_flat_compute_frame_size): Correctly calc args_size + in a leaf function. Clarify total_size/extra_size relationship. + +Thu Nov 12 19:20:57 1998 Geoffrey Noer + + * i386/cygwin32.asm: Delete. + * i386/cygwin.asm: New file, renamed from cygwin32.asm. + * i386/cygwin32.h: Delete. + * i386/cygwin.h: New file, renamed from cygwin32.h. + * i386/t-cygwin32: Delete. + * i386/t-cygwin: New file, renamed from t-cygwin32. Include + cygwin.asm instead of cygwin32.asm. Remove "32" from comment. + * i386/x-cygwin32: Delete. + * i386/x-cygwin: New file, renamed from x-cygwin32. + * i386/xm-cygwin32: Delete. + * i386/xm-cygwin: New file, renamed from xm-cygwin32. Use newly + renamed cygwin_ funcs for path translations. + * i386/win32.h: Define __CYGWIN__ when -mcygwin given. + * i386/winnt.c: Remove "32" from comment about cygwin. + * i386/mingw32.h: Fix references to cygwin32.h in light of above. + * rs6000/cygwin32.h: Delete. + * rs6000/cygwin.h: New file, renamed from cygwin32.h. Add + -D__CYGWIN__ to CPP_PREDEFINES. + * rs6000/x-cygwin32: Delete. + * rs6000/x-cygwin: New file, renamed from x-cygwin32. + * rs6000/xm-cygwin32: Delete. + * rs6000/xm-cygwin: New file, renamed from xm-cygwin32. + + * configure.in: Check for cygwin* instead of cygwin32. Account + for the rename of cygwin-related config files to lose the "32"s. + * configure: Regenerate. -Fri Feb 13 01:34:14 1998 H.J. Lu (hjl@gnu.org) + * cccp.c, collect2.c, gcc.c, getpwd.c, libgcc2.c, protoize.c, + toplev.c: Change all refs to __CYGWIN32__ to __CYGWIN__. - * config/linux.h (LIB_SPEC): Add -lc for -shared if - USE_GNULIBC_1 is not defined. - * config/sparc/linux.h; Ditto. +Wed Nov 11 12:25:19 1998 Tom Tromey - * config/sparc/linux64.h (LIB_SPEC): Add -lc for -shared. + * Makefile.in (JAVAGC): New macro. + * configure: Rebuilt. + * configure.in: Recognize --enable-java-gc argument. Subst + `JAVAGC' variable. - * config/alpha/linux-elf.h (LIB_SPEC): New. Defined if - USE_GNULIBC_1 is not defined. +Thu Nov 12 03:32:16 1998 J"orn Rennecke -Fri Feb 13 01:29:29 1998 Franz Sirl + Handle equivalences that have been obscured by gcse: - * rs6000/sysv4.h (ENDFILE_SPEC): add missing %(endfile_linux) - for -mcall-linux + * reload1.c (reload): Handle equivalences set up in multiple places. + * local-alloc.c (reg_equiv_init_insns): New variable. + (no_equiv): New function. + (update_equiv_regs): Handle equivalences set up in multiple places. + Don't ignore an insn just because its destination is likely to be + spilled. -Fri Feb 13 01:23:46 1998 Kaveh R. Ghazi +Wed Nov 11 13:46:13 1998 Jim Wilson - * system.h: New file to get common systems includes and various - definitions and declarations based on autoconf macros. + * except.c (expand_eh_return): Readd force_operand call lost in + Sept 15 change. -Fri Feb 13 00:46:19 1998 Jeffrey A Law (law@cygnus.com) +Tue Nov 10 17:04:11 1998 David Edelsohn - * cccp.c (new_include_prefix): Correctly handle -I./. + * rs6000.h (LEGITIMIZE_ADDRESS): Add missing goto on last case. -Thu Feb 12 20:16:35 1998 Michael Meissner +1998-11-09 Andreas Schwab - * rs6000.md: Replace gen_rtx (CONST_INT,...) with GEN_INT. + * dbxout.c: Check HAVE_STAB_H instead of HAVE_STABS_H. -Thu Feb 12 16:45:17 1998 Robert Lipe +Mon Nov 9 20:15:19 1998 Bernd Schmidt - * expr.c (expand_assignment): Correct typo exposed by -Wall. - offset should have been a truth value, not an assignment. + * regmove.c (regmove_optimize): Fix error in last change. -Thu Feb 12 15:26:50 1998 Jeffrey A Law (law@cygnus.com) +Mon Nov 9 16:37:52 1998 Andrew Cagney - * cse.c (delete_dead_from_cse): If a libcall produces a constant - result and that result can be substituted into SET_SRC of the - insn with the REG_RETVAL note, then perform the substitution - and delete the libcall. + * mips.c (function_prologue): When TARGET_MIPS16, adjust the register + offset in the .mask pseudo to compensate for frame pointer adjustments. + (mips16_fp_args, build_mips16_call_stub): For little endian, do not + word swap arguments moved to/from FP registers. + * mips16.S (DFREVCMP): Reverse arguments to OPCODE. -Thu Feb 12 14:04:09 1998 Gavin Koch +Mon Nov 9 09:47:06 1998 Jeff Law (law@cygnus.com) - * mips.md (trucndihi2,truncdiqi2): Change these to support - mips16. + * version.c: Bump for snapshot. -Thu Feb 12 11:34:55 1998 Gavin Koch +Mon Nov 9 02:14:14 1998 Jeff Law (law@cygnus.com) - * mips/mips.c (movdi_operand): Direct referances to symbols - that arn't mips16 consts in mips16 mode arn't valid operands. + * version.c: Bump for snapshot. - * mips/mips.c (mips_move_2words): Add gprel handling. +Mon Nov 9 03:06:24 1998 Jeffrey A Law (law@cygnus.com) -Thu Feb 12 11:18:37 1998 Gavin Koch + * reload1.c (delete_output_reload_insn): If a pseudo is set multiple + times, then it can not be completely replaced. - * mips.md (extendsidi2): Allow extension to/from a non-mips16 - register. +Mon Nov 9 00:39:02 1998 Richard Henderson -Thu Feb 12 00:04:16 1998 Marc Lehmann + * alpha.md (call, call_value) [OSF]: Correct alt 3 insn length. - * i386.c: Conditionally include , , and - . +Sun Nov 8 17:50:30 1998 Kaveh R. Ghazi -Wed Feb 11 11:43:34 1998 Kaveh R. Ghazi + * gansidecl.h: Prepend a "G" to the macro wrapping this file + (to distinguish it from the macro wrapping ansidecl.h.) + Include libiberty's ansidecl.h. Remove all redundant definitions. + Define the PROTO() style macros in terms of the PARAMS() ones. - * Makefile.in (WARN_CFLAGS): New variable. - (bootstrap, bootstrap2, bootstrap3, bootstrap4): Use it. -1998-02-11 Mark Mitchell + * calls.c (emit_library_call): Switch on ANSI_PROTOTYPES, not + __STDC__, when deciding whether to use ANSI variable args. + (emit_library_call_value): Likewise. - * config/i386/i386.c (reg_mentioned_in_mem): Don't abort when - falling through default case in switch. - (i386_aligned_p): Likewise. + * cccp.c (error): Likewise. + (warning): Likewise. + (error_with_line): Likewise. + (warning_with_line): Likewise. + (pedwarn): Likewise. + (pedwarn_with_line): Likewise. + (pedwarn_with_file_and_line): Likewise. + (fatal): Likewise. -Wed Feb 11 12:59:56 1998 Lee Iverson + * cexp.y (error): Likewise. + (pedwarn): Likewise. + (warning): Likewise. - * mips/mips.h (mips_abi_string): Correct typo in comment. + * collect2.c (fatal_perror): Likewise. + (fatal): Likewise. + (error): Likewise. -Wed Feb 11 08:29:56 1998 Gavin Koch + * combine.c (gen_rtx_combine): Likewise. - * mips/mips.md (movdi): These PLUS's need to be Pmode. + * cpperror.c (cpp_message): Likewise. + (cpp_fatal): Likewise. -Wed Feb 11 01:47:54 1998 Kaveh R. Ghazi + * cpplib.c (cpp_error): Likewise. + (cpp_warning): Likewise. + (cpp_pedwarn): Likewise. + (cpp_error_with_line): Likewise. + (cpp_warning_with_line): Likewise. + (cpp_pedwarn_with_line): Likewise. + (cpp_pedwarn_with_file_and_line): Likewise. - * Makefile.in (dwarf2out.o, emit-rtl.o, jump.o, cse.o, unroll.o, - reorg.o, regmove.o): Depend on insn-codes.h, it gets included - indirectly via expr.h. + * cpplib.h: Don't define PARAMS() macro. -Wed Feb 11 01:44:13 1998 Richard Henderson + * demangle.h: Likewise. - * stor-layout.c (layout_type): Do upper - lower in the native type, - so as to properly handle negative indices. + * doprint.c (checkit): Switch on ANSI_PROTOTYPES, not __STDC__, + when deciding whether to use ANSI variable args. -Wed Feb 11 01:35:55 1998 Robert Lipe + * emit-rtl.c (gen_rtx): Likewise. + (gen_rtvec): Likewise. - * except.c (start_dynamic_cleanup): Remove unused variable 'dhc'. - (expand_eh_region_start_tree): Remove unused variable 'note'. - (exception_optimize): Remove unused variable 'regions'. - (expand_builtin_eh_stub): Remove unused variable 'temp'. - (copy_eh_entry): Deleted. Dead function. + * final.c (asm_fprintf): Likewise. - * expr.c (move_block_to_reg) Bracket declaration of 'pat' and - 'last' with same #if HAVE_load_multiple as use of it. - (move_block_from_reg): Likewise. - (emit_move_insn_1): Remove unused variable 'insns'. - (store_constructor): Bracket declaration of startb, endb with - #if TARGET_MEMFUNCTIONS. Remove unused variables 'set_word_size' - 'target', and 'xtarget'. - (expand_builtin_setjmp): Remove unused variables 'op0', - 'next_arg_reg', 'old_inhibit_defer_pop'. - (expand_builtin): Remove unused variable 'offset'. - (do_store_flag): Remove unused variables 'pattern', 'jump_pat'. - (emit_queue): Add parens for assignment used as conditional. - (expand_expr): case TARGET_EXPR: Remove unused variable 'temp'. + * fix-header.c (cpp_message): Likewise. + (fatal): Likewise. + (cpp_fatal): Likewise. -Wed Feb 11 01:30:49 1998 Marc Lehmann + * gcc.c (concat): Likewise. + (fatal): Likewise. + (error): Likewise. - * i386.c: Added include for recog.h. - (override_options): Removed unused variable p. Initialized regno to - avoid warning. - (order_regs_for_local_alloc): Initialized regno to avoid warning. - (legitimize_address): Likewise for 'other'. - (i386_aligned_reg_p): Added default case with abort (). - (print_operand): Likewise. - (reg_mentioned_in_mem): Likewise. - (ix86_expand_binary_operator): Removed unused variables i & insn. - (ix86_expand_unary_operator): Removed unused variable insn. - (output_fp_cc0_set): Removed unused variable unordered_label. + * genattr.c (fatal): Likewise. -Wed Feb 11 01:23:03 1998 John F. Carr + * genattrtab.c (attr_rtx): Likewise. + (attr_printf): Likewise. + (fatal): Likewise. - * i386.c, i386.h, i386.md: Change gen_rtx (X, ...) to gen_rtx_X (...). - Use GEN_INT instead of gen_rtx (CONST_INT). Make printf arguments - and format string match. + * gencodes.c (fatal): Likewise. -Wed Feb 11 01:17:39 1998 Jeffrey A Law (law@cygnus.com) + * genconfig.c (fatal): Likewise. - * flow.c (life_analysis): Do not conside the stack pointer live at - the end of a function if the fucntio ncalls alloca. - (mark_used_regs): Similarly. + * genemit.c (fatal): Likewise. -1998-02-10 John F Carr + * genextract.c (fatal): Likewise. - * config/sparc/sparc.md (movdi_v8plus): Output stx on alternative - 1, fzero on alternative 8. + * genflags.c (fatal): Likewise. -Tue Feb 10 09:02:19 1998 Richard Kenner + * genopinit.c (fatal): Likewise. - * rs6000.c (setup_incoming_varargs): Always set rs6000_sysv_varargs_p. + * genoutput.c (fatal): Likewise. + (error): Likewise. -Tue Feb 10 03:35:43 1998 J"orn Rennecke + * genpeep.c (fatal): Likewise. - * reload.c (find_reloads_toplev): Handle arbitrary non-paradoxical - SUBREGs of CONST_INTs. + * genrecog.c (fatal): Likewise. -Mon Feb 9 17:52:36 1998 John Carr + * halfpic.h: Switch on ANSI_PROTOTYPES, not __STDC__, when + deciding whether to declare `tree_node' and `rtx_def'. - * mips.c (print_operand, function_prologue): Make printf format - match argument type. + * hash.h: Don't define stuff we get from gansidecl.h. -Mon Feb 9 02:37:25 1998 Kaveh R. Ghazi + * mips-tfile.c: Likewise. Define __proto() in terms of PARAMS(). + (fatal): Switch on ANSI_PROTOTYPES, not __STDC__, when deciding + whether to use ANSI variable args. + (error): Likewise. - * alpha.c (alpha_return_addr): Remove unused variable `first'. - (alpha_ra_ever_killed): Remove unused variables `ra' and `i'. - (output_epilog): Remove unused variable `frame_size_from_reg_save'. + * prefix.c (concat): Likewise. -Sun Feb 8 14:56:03 1998 Richard Kenner + * scan.h: Likewise. - * loop.c (strength_reduce): When placing increment for auto-inc - case, do comparison in loop order. + * system.h: Likewise. -Sun Feb 8 13:21:38 1998 John Carr + * toplev.c (error_with_file_and_line): Likewise. + (error_with_decl): Likewise. + (error_for_asm): Likewise. + (error): Likewise. + (fatal): Likewise. + (warning_with_file_and_line): Likewise. + (warning_with_decl): Likewise. + (warning_for_asm): Likewise. + (warning): Likewise. + (pedwarn): Likewise. + (pedwarn_with_decl): Likewise. + (pedwarn_with_file_and_line): Likewise. + (sorry): Likewise. + (really_sorry): Likewise. - * bitmap.c (bitmap_debug_file): HOST_PTR_PRINTF converts a pointer, - not a HOST_WIDE_INT. + * toplev.h: Switch on ANSI_PROTOTYPES, not __STDC__, when deciding + whether to declare `tree_node' and `rtx_def'. - * calls.c (expand_call): Change test of expand_inline_function - return value to stop compiler warning. + * tree.c (build): Switch on ANSI_PROTOTYPES, not __STDC__, when + deciding whether to use ANSI variable args. + (build_nt): Likewise. + (build_parse_node): Likewise. - * genattrtab.c (RTL_HASH): Cast pointer to long, not HOST_WIDE_INT. +Sun Nov 8 13:10:55 1998 Jeff Law (law@cygnus.com) -Sun Feb 8 12:04:24 1998 Jim Wilson (wilson@cygnus.com) - Jeff Law (law@cygnus.com) + * version.c: Bump for snapshot. - * regmove.c: Fix various minor formatting problems. - (optimize_reg_copy_1): Stop search at CALL_INSNs if flag_exceptions - is true. Make end of basic block tests consistent through regmove.c. - (optimize_reg_copy_2, optimize_reg_copy_3): Likewise. - (fixup_match_2, fixup_match_1, regmove_optimize): Likewise. +Sat Nov 7 23:34:01 1998 Kaveh R. Ghazi -Sun Feb 8 01:49:18 1998 Kaveh R. Ghazi + * Makefile.in (libcpp.a): Check RANLIB_TEST before runing RANLIB. - * gansidecl.h: Check for a conflicting macro definition before - attempting to prototype bcopy, bcmp or bzero. +Sat Nov 7 22:26:19 1998 David Edelsohn -Sun Feb 8 00:09:59 1998 Jeffrey A Law (law@cygnus.com) + * collect2.c (main, case 'b'): Use else if. - * expr.c (clear_pending_stack_adjust): Handle case where a function - calls alloca, but the user has specified -fomit-fframe-pointer. +Sat Nov 7 15:35:25 1998 Kaveh R. Ghazi - * function.c (assign_parms): Fix typo in last change. + * configure.in (host_xm_file, build_xm_file, xm_file, tm_file): + Arrange to include gansidecl.h in {ht}config.h & tm.h just + before the config/ directory headers. + (tm_file_list, host_xm_file_list, build_xm_file_list): Handle + gansidecl.h in the list of dependencies. -Sat Feb 7 23:54:29 1998 Robert Lipe + * Makefile.in (RTL_BASE_H): Don't depend on gansidecl.h. + (TREE_H, DEMANGLE_H, RECOG_H, REGS_H, libgcc2.a, stmp-multilib, + mbchar.o, collect2.o, pexecute.o, vfprintf.o, splay-tree.o, gcc.o, + gencheck.o, choose-temp.o, mkstemp.o, mkstemp.o, prefix.o, + dyn-string.o, cexp.o, cccp.o, cppmain.o, cpplib.o, cpperror.o, + cppexp.o, cppfiles.o, cpphash.o, cppalloc.o, scan-decls.o): + Likewise. - * gcc.c: Include /, , , - . - (free_path_suffix): Remove unreferenced static function. - (process_command): Remove unused variable temp. - (default_arg): Remove unused variable i. - (do_spec_1): Add parens for assignment used as truth value. - (main): Likewise. - (validate_all_switches): Likewise. - (main): Remove unused variables i, first_time> + * cccp.c: Don't include gansidecl.h. + * cexp.y: Likewise. + * collect2.c: Likewise. + * config/c4x/c4x.c: Likewise. + * config/v850/v850.h: Likewise. + * cppalloc.c: Likewise. + * cpperror.c: Likewise. + * cppexp.c: Likewise. + * cppfiles.c: Likewise. + * cpphash.c: Likewise. + * cpplib.c: Likewise. + * cppmain.c: Likewise. + * cppulp.c: Likewise. + * demangle.h: Likewise. + * doprint.c: Likewise. + * dyn-string.c: Likewise. + * eh-common.h: Likewise. + * fix-header.c: Likewise. + * frame.c: Likewise. + * gcc.c: Likewise. + * gcov.c: Likewise. + * gen-protos.c: Likewise. + * gencheck.c: Likewise. + * halfpic.h: Likewise. + * hash.c: Likewise. + * machmode.h: Likewise. + * mbchar.c: Likewise. + * prefix.c: Likewise. + * protoize.c: Likewise. + * recog.h: Likewise. + * rtl.h: Likewise. + * scan-decls.c: Likewise. + * tree.h: Likewise. + * varray.h: Likewise. - * c-common.c: Include and /. +Sat Nov 7 11:37:53 1998 Richard Henderson - * calls.c (expand_call): Remove unused variables funtree, - n_regs, and tmpmode. + * i386.md (call_value_pop): If we're not popping anything, + defer to call_value. + (call_pop): Likewise defer to call. - * dbxout.c, except.c: Include /. +Sat Nov 7 02:49:56 1998 Richard Henderson - * explow.c: (plus_constant_for_output_wide) Removed unused - variable all_constant. + * function.c (purge_addressof): Clear purge_addressof_replacements + only after processing the whole function. - * c-decl.c, genattr.c, genattrtab.c, getconfig.c, genemit.c - genextract.c, genflags.c, genopinit.c genoutput.c, genpeep.c, - genrecog.c, global.c, integrate.c , stupid.c : Include - . +Sat Nov 7 00:54:55 1998 Jeffrey A Law (law@cygnus.com) - * genextract.c: (walk_rtx) Remove unused variable link. + * reload1.c (reload): If we can not perform a particular elimination + when we thought we could earlier, then we must always iterate through + the loop at least one more time. - * genrecog.c: (concat) Remove unreferenced static function. +Fri Nov 6 19:37:33 1998 Richard Henderson - * prefix.c: Include /, + * alpha.c (add_operand): Simplify the CONST_INT match. + (sext_add_operand): Correct typo in comparison by using + CONST_OK_FOR_LETTER_P. + * alpha.md (s?addq): Use sext_add_operand to allow the negative + constant alternatives to be generated. + (mulsi3, muldi3, umuldi3_highpart): Loosen constraints to allow + small constants, since the hw instructions do. - * stmt.c: Include . - (expand_asm_operands): Remove unused variable val1. - (expand_return): Remove unused variable block. - (pushcase): Remove unused variables l and n. - (pushcaserange): Likewise. +Fri Nov 6 20:15:19 1998 Bernd Schmidt - * unroll.c (unroll_loop): Remove unused variable temp. + * reload1.c (emit_reload_insns): When rewriting the SET_DEST of a + previous insn to store directly into our reload register, make sure + that if the source of the previous insn is a reload register, its + spill_reg_store and spill_reg_stored_to values are cleared. -Sat Feb 7 23:46:09 1998 Greg McGary +Fri Nov 6 16:35:10 1998 David Edelsohn - * c-decl.c (pushdecl): Set DECL_ORIGINAL_TYPE once only. + * rs6000.md (floatunssidf2_internal splitter): Use base register + operand, not hard-coded SP. -Sat Feb 7 15:11:28 1998 Kaveh R. Ghazi +Fri Nov 6 04:07:53 1998 David S. Miller - * aclocal.m4 (GCC_FUNC_PRINTF_PTR): New macro to test the printf - functions for whether they support the %p format specifier. - * acconfig.h (HOST_PTR_PRINTF): Insert stub for autoconf. - * configure.in (GCC_FUNC_PRINTF_PTR): Use it. - * configure, config.in: Rebuild. + * jump.c (calculate_can_reach_end): Fix thinko. -Fri Feb 6 14:20:16 1998 Jim Wilson +Fri Nov 6 00:16:04 1998 Jeffrey A Law (law@cygnus.com) - * function.c (assign_parms): New variable named_arg, with value - depending on STRICT_ARGUMENT_NAMING. Use instead of ! last_named. + * reorg.c (fill_simple_delay_slots): Fix typo. -Fri Feb 6 14:34:28 1998 Gavin Koch + * romp.h (LEGITIMIZE_ADDRESS): Fix typo. - * mips/t-r3900: New - same as t-ecoff but eliminate - multilibs: mips1 and mips3. - * configure.in (tx39*): Use new mips/t-r3900. - * configure: Rebuild. - * mips/r3900.h (MULTILIB_DEFAULTS): Eliminate mips1. +Fri Nov 6 00:10:00 1998 Jan Hubicka (hubicka@freesoft.cz) -1998-02-06 Jason Merrill + * i386.md (extendsidi2): Use # in the output template. + (extendsidi splitters): New splitters. - * dwarf2out.c: Add old_args_size. - (dwarf2out_args_size): Use it. - (dwarf2out_begin_prologue): Initialize it. - (dwarf2out_stack_adjust): If !asynchronous_exceptions, save up - pushed args until we see a call. - * final.c (final_scan_insn): Hand CALL_INSNs off to the dwarf2 code - before outputting them. +Thu Nov 5 11:13:27 1998 Nick Clifton -1998-02-06 Kriang Lerdsuwanakij + * configure.in: Use unknown-elf.h as tm_file for arm-elf + configurations. + * configure: Regenerate. - * cplus-dem.c (demangle_template_template_parm): New function. - (demangle_template): Handle template template parameters. +Thu Nov 5 07:59:05 1998 David S. Miller -1998-02-02 Mark Mitchell + * jump.c (init_label_info, delete_barrier_successors, + mark_all_labels, delete_unreferenced_labels, + delete_noop_moves, calculate_can_reach_end): New functions broken + out of jump_optimize. + (jump_optimize): Use them. - * calls.c (expand_call): Don't confuse member functions named - realloc, setjmp, and so forth with the standard library - functions of the same names. +Thu Nov 5 07:57:45 1998 Andrew MacLeod -Thu Feb 5 21:59:49 1998 Jeffrey A Law (law@cygnus.com) + * except.c (expand_fixup_region_end): Make sure outer context labels + are not issued in an inner context during cleanups. - * stmt.c (expand_asm_operands): Correctly identify asm statements - no output operands. +Thu Nov 5 04:03:06 1998 Richard Henderson -Thu Feb 5 21:56:06 1998 Mumit Khan + * alpha.md (addsi3, subsi3): No new temporaries once cse is + no longer expected. - * c-common.c (decl_attributes): Flag unrecognized attribute - functions as warnings instead of as errors. +Thu Nov 5 03:29:19 1998 Richard Henderson -1998-02-05 Marc Lehmann + * alpha.md (addsi3, subsi3): Expand to a DImode temporary so as + to expose this midpoint to CSE. - * integrate.c (INTEGRATE_THRESHOLD): Inline only small functions - when -Os is specified. - * toplev.c (main): Don't disable flag_inline_functions anymore when - -Os is in effect. +Thu Nov 5 03:42:54 1998 David S. Miller -Fri Feb 6 00:27:36 1998 J"orn Rennecke + * config/sparc/sparc.md (movdf_const_intreg_sp64): Enable again. - * regmove.c: Update. - * flags.h (flag_regmove): Declare. - * rtl.h (optimize_reg_copy_1, optimize_reg_copy_2): Don't declare. - * local-alloc.c (optimize_reg_copy_1, optimize_reg_copy_2): - Moved into regmove; changed caller. - * toplev.c (rest_of_compilation): Call regmove_optimize also for - expensive_optimizations. +Thu Nov 5 10:53:01 1998 Andreas Schwab -Thu Feb 5 13:38:42 PST 1998 Jeff Law (law@cygnus.com) + * configure.in: Bring over gcc2 change of Nov 19 1997. - * version.c: Bump for snapshot. +Wed Nov 4 23:43:08 1998 Graham -Thu Feb 5 01:45:19 1998 J"orn Rennecke - Undo this change (the problem was actually in reload): - Fri Jan 23 23:28:59 1998 J"orn Rennecke + * toplev.c (output_lang_identify): Make definition dependent on + ASM_IDENTIFY_LANGUAGE. - * sh.md (movqi_i+1): New peephole. + * print-rtl.c (spaces): Make static. -Tue Feb 3 01:11:12 1998 Jeffrey A Law (law@cygnus.com) +Wed Nov 4 22:16:36 1998 Hans-Peter Nilsson - * jump.c (jump_optimize): Lose calls to modified_in_p they are - not needed anymore due to changes elsewhere in jump.c. + * extend.texi: Clarify proper uses for register clobbers in asms. - * jump.c (jump_optimize): Fix first arg to modified_in_p in - previous change. +Wed Nov 4 22:16:36 1998 Bernd Schmidt -Mon Feb 2 19:18:14 1998 Richard Henderson + * recog.h (enum op_type): Define. + (constrain_operands): Adjust prototype. + (recog_op_type): Declare new variable. + * recog.c (recog_op_type): New variable. + (insn_invalid_p): Allow modifying an asm statement after reload. + (extract_insn): Set up recog_op_type. + (constrain_operands): Lose INSN_CODE_NUM arg. All callers changed. + Don't compute operand types, use recog_op_type. + Use the information computed by extract_insn instead of the previous + method of finding it by insn code number. + * caller-save.c (init_caller_save): Use extract_insn, not insn_extract. + * reorg.c (fill_slots_from_thread): Likewise. + * reload1.c (reload_as_needed): Likewise. + (gen_reload): Likewise. + (inc_for_reload): Likewise. + (reload_cse_simplify_operands): Likewise. + Use the information computed by extract_insn instead of the previous + method of finding it by insn code number. + * genattrtab.c (write_attr_case): Generate call to extract_insn, not + insn_extract. + * final.c (final_scan_insn): Use extract_insn, not insn_extract. + (cleanup_operand_subregs): Use extract_insn, not insn_extract. + Use the information computed by extract_insn instead of the previous + method of finding it by insn code number. + * regmove.c (find_matches): Likewise. Change meaning of the return + value to be nonzero if the optimization can be performed, zero if + not. All callers changed. + Shorten some variable names to fix formatting problems. + (regmove_optimize): Shorten some variable names to fix formatting + problems. + Use the information computed by extract_insn instead of the previous + method of finding it by insn code number. + * regclass.c (scan_one_insn): Likewise. + (record_reg_classes): Don't compute operand types, use recog_op_type. + * reload.c (find_reloads): Lose CONSTRAINTS1 variable; use + recog_constraints instead. - * expr.c (expand_builtin_setjmp): Accept two new arguments for - the labels to branch to on first and subsequent executions. Don't - play with __dummy. Rename `setjmp' insn to `builtin_setjmp_setup', - and provide it with the jmp_buf. Use only one of - `builtin_setjmp_receiver' or `nonlocal_goto_receiver', - and provide the former with the target label. - (expand_builtin) [BUILTIN_SETJMP]: Generate a label for use by setjmp. - (expand_builtin) [BUILTIN_LONGJMP]: Split out to ... - (expand_builtin_longjmp): ... here. Recognize a `builtin_longjmp' - insn to replace all of the normal nonlocal_goto code. Don't play - with __dummy. Correct arguments to nonlocal_goto. - * expr.h (expand_builtin_setjmp): Update prototype. - * except.c (start_dynamic_handler): When using builtin_setjmp, - generate more accurate flow information. +Wed Nov 4 21:37:46 1998 Jeffrey A Law (law@cygnus.com) - * alpha.md (nonlocal_goto_receiver_osf): Delete. - (nonlocal_goto_receiver_vms): Rename to nonlocal_goto_receiver. - (builtin_longjmp, builtin_setjmp_receiver): New. - * sparc.md (update_return): Disambiguate unspec number. - (nonlocal_goto): Rearrange arguments to match caller in except.c. - (builtin_setjmp_setup): Rename from setjmp. Match and ignore the - jmp_buf operand. - * mips.md (nonlocal_goto_receiver, builtin_setjmp_receiver): Remove. - (builtin_setjmp_setup*, builtin_longjmp): New. + * rtl.h (flow2_completed): Declare. + * flow.c (flow2_completed): Definition. + * toplev.c (rest_of_compilation): Set and clear flow2_completed + as necessary. -Mon Feb 2 16:43:10 1998 John Carr +Wed Nov 4 19:15:37 1998 Melissa O'Neill - * mips.md: Change gen_rtx (CONST_INT) to GEN_INT. + * Makefile.in (libcpp.a): Ranlib libcpp.a. -Mon Feb 2 13:06:47 1998 Jim Wilson + * cppulp.c (user_label_prefix): Initialize. - * vmsconfig.com: Remove bytecode references. +Wed Nov 4 19:07:08 1998 John Wehle (john@feith.com) -1998-01-30 Andreas Schwab + * flow.c (mark_regs_live_at_end): Mark the stack pointer as live + at a RETURN if current_function_sp_is_unchanging is set. - * dwarf2out.c (dwarf2out_frame_init): Undo last change, so that - -fno-sjlj-exceptions works for a target that defines - DWARF2_UNWIND_INFO as zero. +Wed Nov 4 18:16:29 1998 Herman A.J. ten Brugge - * regmove.c (fixup_match_1): Undo last change which removed some - "useless" code, and add a comment explaining this. + * emit-rtl.c (try_split): Fixed error in Oct 10 patch. -Mon Feb 2 10:47:14 1998 Gavin Koch (gavin@cygnus.com) +Wed Nov 4 15:11:15 1998 Geoffrey Noer - * mips.c (mips_expand_prologue): Change uses of TARGET_64BIT - to TARGET_LONG64. + * i386/cygwin32.h (MASK_WIN32, MASK_CYGWIN, MASK_WINDOWS, MASK_DLL, + TARGET_WIN32, TARGET_CYGWIN, TARGET_WINDOWS, TARGET_DLL): New. + (SUBTARGET_SWITCHES): Add -mno-cygwin, -mcygwin, and -mdll options. + (CPP_PREDEFINES): Don't define __CYGWIN32__ here. + (STARTFILE_SPEC): Handle -mdll, -mno-cygwin options. + (CPP_SPEC): Handle -mno-cygwin option. Define __CYWIN__ in addition + to __CYGWIN32__. + (LIB_SPEC): Handle -mno-cygwin option. + (LINK_SPEC): Handle -mdll. -Mon Feb 2 10:38:41 1998 Klaus Kaempf +Wed Nov 4 22:56:14 1998 J"orn Rennecke - * makefile.vms: Remove bytecode references. - Create genrtl files. + * reload.c (find_reloads): Fix test for usage by other reload + to handle secondary reloads properly. -Mon Feb 2 02:08:04 1998 Michael P. Hayes +Wed Nov 4 17:25:10 1998 Kaveh R. Ghazi - * jump.c (jump_optimize): Allow conditional loading of floating point - constants and constants from memory. Reinstalled modified_in_p tests. + * reload1.c (ELIMINABLE_REGS, NUM_ELIMINABLE_REGS): Introduce an + intermediate structure which has exactly the members provided by + ELIMINABLE_REGS. Define NUM_ELIMINABLE_REGS in terms of the + static intermediate structure. -Mon Feb 2 01:38:39 1998 J"orn Rennecke + (init_elim_table): Xmalloc() `reg_eliminate', and initialize it + from the intermediate structure. Do the same analogous fix in + the case where ELIMINABLE_REGS is not defined. - * loop.c (get_condition): Handle sign-extended constants. +Tue Nov 3 20:50:03 1998 Jeffrey A Law (law@cygnus.com) -Mon Feb 2 01:22:46 1998 Hans-Peter Nilsson + * pa.h (SELECT_SECTION): Fix thinko. - * expr.c (emit_push_insn): Add code to use movstrti if present. +Tue Nov 3 17:51:36 1998 Jim Wilson - * expr.c (emit_push_insn): Use same max-move-amount for movstrhi - and movstrqi as in emit_block_move (). + * dwarf2out.c (output_call_frame_info): Comments on last change. -Mon Feb 2 00:09:52 1998 Toon Moene +Tue Nov 3 07:51:43 1998 Richard Earnshaw (rearnsha@arm.com) - * config/m68k/x-next: Remove /NextDeveloper/Headers from - the directories to fixinclude - /usr/include is a link - to it and hence its contents are fixed by default. + * arm.c (add_constant): When taking the address of an item in the + pool, get the mode of the item addressed. -Sun Feb 1 14:15:33 1998 Franz Sirl + * arm.c (final_prescan_insn case INSN): If an insn doesn't + contain a SET or a PARALLEL, don't consider it for conditional + execution. - * rs6000/linux.h: define JUMP_TABLES_IN_TEXT_SECTION + Restore ABI compatibility for NetBSD. + * arm/netbsd.h (DEFAULT_PCC_STRUCT_RETURN): Override setting in + arm.h. + (RETURN_IN_MEMORY): Likewise. -Sun Feb 1 13:01:15 1998 Klaus Kaempf +Mon Nov 2 11:46:17 1998 Doug Evans - * cccp.c (main): Predefine __VMS_VER on VMS. + * m32r/m32r.c (m32r_expand_block_move): Fix byte count computations. + (m32r_output_block_move): Rewrite bytes < 4 handling. -Sun Feb 1 12:39:53 1998 J"orn Rennecke +Mon Nov 2 10:10:35 1998 Kaveh R. Ghazi - * expr.c (get_inner_reference): Use sbitsizetype for type sizes. - * fold-const.c (size_int): Replace with - (size_int_wide). - (make_bit_field_ref): Use bitsize_int for bit position. - * stor-layout.c (sizetype): Delete. - (sizetype_tab, sbitsizetype, ubitsizetype): Declare. - (layout_record, layout_union, layout_type): - Use bitsize_int for bit size. - (set_sizetype): New function. - (make_signed_type, make_unsigned_type): Use it. - * c-decl.c (init_decl_processing): Likewise. - * tree.h (size_int): Don't delcare, #define. - (size_int_wide, sizetype_tab, sbitsize, ubitsize): Declare. - (set_sizetype): Declare. - (bitsize_int, size_int_2, BITS_PER_UNIT_LOG, sizetype, bitsizetype): - Define. - * c-typeck.c (c_sizeof, c_sizeof_nowarn, c_size_in_bytes): - Convert result to sizetype. - (really_start_incremental_init, push_init_level): - Set type of constructor_bit_index to sbitsizetype. - (push_init_level): Use unsigned arithmetic to determine padding. - (output_init_element): Likewise. - -Sun Feb 1 03:32:07 1998 Jeffrey A Law (law@cygnus.com) - - * combine.c (simplify_shift_const): Fix typo in last change. - -Sun Feb 1 02:50:46 1998 John Carr - - * combine.c (simplify_shift_const): (lshiftrt (truncate (lshiftrt))) - is (truncate (lshiftrt)). - -Sun Feb 1 01:06:53 1998 Richard Henderson - - * alpha.c (alpha_expand_unaligned_load): Use expand_binop properly. - Make sure result winds up in TGT. - (alpha_expand_unaligned_store): Use expand_binop properly. Allow - src to be other than DImode. - (alpha_expand_unaligned_load_words): Tidy. Take an offset argument. - (alpha_expand_unaligned_store_words): Likewise. - (alpha_expand_block_move): Use REGNO_POINTER_ALIGN. Restructure so - that source and destination are separately optimized for alignment. - (alpha_expand_block_clear): Use REGNO_POINTER_ALIGN. - -Sun Feb 1 01:55:09 1998 Jeffrey A Law (law@cygnus.com) - - * mips.md (adddi3_internal_2): Be consistent with adddi3 expander - with handling of -32768. - -Sun Feb 1 01:48:18 1998 Kaveh R. Ghazi - - * aclocal.m4 (GCC_NEED_DECLARATION): Modify macro to accept a - shell variable argument instead of only hard coded functions. - (GCC_NEED_DECLARATIONS): New macro to accept multiple functions. - - * configure.in: Collapse multiple calls to AC_CHECK_FUNCS into one - call. Collapse multiple calls to GCC_NEED_DECLARATION into one - call to GCC_NEED_DECLARATIONS (new macro.) Check if we need - declarations for bcopy, bcmp and bzero. - - * acconfig.h: Add stubs for bcopy, bcmp and bzero declarations. - - * gansidecl.h: If we have bcopy but don't declare it, then do so. - Likewise for bcmp and bzero. Only define macros for bcopy, bcmp, - bzero, index and rindex if they aren't already present. - -Sat Jan 31 11:26:58 1998 Jeffrey A Law (law@cygnus.com) - - * toplev.c (close_dump_file): Wrap function prototype for - argument "func" in PROTO. - (dump_rtl): Likewise. - -Fri Jan 30 22:30:39 1998 John Carr - - * sparc.c (sparc_override_options): Make v8plus and ultrasparc set - MASK_V8PLUS. - (output_function_epilogue): Omit epilogue if nothing drops through. - (output_move_double): Supress int ldd usage on ultrasparc and v9. - (registers_ok_for_ldd_peep): Likewise. - (print_operand): Supress b,a on ultrasparc. Let Y accept a constant. - (ultrasparc_adjust_cost): New function. - (sparc_issue_rate): New function. - * sparc.h (MASK_VIS, TARGET_VIS): New - (MASK_V8PLUS, TARGET_V8PLUS): New. - (TARGET_HARD_MUL32, TARGET_HARD_MUL): New. - (TARGET_SWITCHES): Add vis and v8plus. - (REG_CLASS_FROM_LETTER): Accept d and b for VIS. - (REGISTER_MOVE_COST): FP<->INT move cost 12 for ultrasparc. - (RTX_COSTS): Use TARGET_HARD_MUL - (ADJUST_COST): Call ultrasparc_adjust_cost. - (ISSUE_RATE): New. - * sparc.md (attr type): Add sload, fpmove, fpcmove. Adjust users - of load & fp appropritely. - (supersparc function units): Adjust for Haifa. - (ultrasparc function units): Likewise. - (get_pc_via_rdpc): All v9, not just arch64. - (movdi_v8plus, movdi_v8plus+1): New. - (adddi3_sp32+1): New. - (subdi3_sp32+1): New. - (movsi_insn, movsf_const_insn, movdf_const_insn): Know VIS. - (addsi3, subsi3, anddi3_sp32, andsi3, and_not_di_sp32): Likewise. - (and_not_si, iordi3_sp32, iorsi3, or_not_di_sp32, or_not_si): Likewise. - (xorsi3_sp32, xorsi3, xor_not_di_sp32, xor_not_si): Likewise. - (one_cmpldi2_sp32, one_cmplsi2): Likewise. - (ldd peepholes): Suppress for v9. - (return_adddi): Kill redundant test. Arg1 may be arith_operand. - (return_subsi): Revmove. - -Fri Jan 30 18:30:03 1998 John F Carr - - * mips.c (save_restore_insns): Set RTX_UNCHANGING_P in register - save/restore MEM rtl. - -Fri Jan 30 09:08:16 1998 Jeffrey A Law (law@cygnus.com) - - * configure.in: Check for declaration of abort. - * acconfig.h: Corresponding changes. - * toplev.c: Use NEED_DECLARATION_ABORT to determine if abort should - be declared. - -Thu Jan 29 20:26:12 1998 Jeffrey A Law (law@cygnus.com) - - * genattrtab.c (optimize): Define in case PRESERVE_DEATH_INFO_REGNO_P - uses it. - -Thu Jan 29 09:27:56 PST 1998 Jeff Law (law@cygnus.com) + * configure.in: Call AC_FUNC_VFORK. - * version.c: Bump for snapshot. + * collect2.c: Define VFORK_STRING as a printable string for + error messages (either "vfork" or "fork".) If HAVE_VFORK_H is + defined, include vfork.h. If VMS is defined, define vfork() + appropriately. Remove vfork check on USG, we're using autoconf. + (collect_execute): Pass VFORK_STRING to fatal_perror instead of + checking locally what string to pass. + (scan_prog_file): Likewise. + (scan_libraries): Likewise. -Thu Jan 29 10:12:27 1998 Jeffrey A Law (law@cygnus.com) + * gcc.c: Remove vfork check on USG, we're using autoconf. + Besides, no calls to vfork/fork occur in this file. - * configure.in: Check for atoq and atoll. - * rtl.c (read_rtx): Use HAVE_ATOLL and HAVE_ATOQ to select the - proper routine for converting ascii into long long values. + * protoize.c: Likewise. -Thu Jan 29 01:28:14 1998 Klaus Kaempf +Mon Nov 2 07:52:28 1998 Alexandre Oliva - * cccp.c (SYS$SEARCH, SYS$PARSE): Write as upper-case. + * configure.in (DEFAULT_LINKER): Renamed from LD. + (DEFAULT_ASSEMBLER): Renamed from AS; reverted Schwab's patch. + (gcc_cv_as): Try $DEFAULT_ASSEMBLER before $AS. + * configure: Rebuilt. - * vmsconfig.com: Remove bytecode references. +Mon Nov 2 01:48:10 1998 Alexandre Oliva - * alpha/vms.h (PREFIX): Define. + * BUGS: Fix the regexp for `more' to find the appropriate node. + Reported by Joerg Pietschmann - * alpha/vms.h (ASM_OUTPUT_ALIGNED_COMMON): Remove. + * BUGS: Added link to the WWW FAQ. - * am-alpha.h: Don't include alloca for OPEN_VMS. +Sun Nov 1 18:27:15 1998 Jeff Law (law@cygnus.com) - * alpha/xm-vms.h (HAVE_CPP_STRINGIFY): Define. + * version.c: Bump for snapshot. - * alpha/xm-vms.h (INCLUDE_DEFAULTS): Define. - (GCC_INCLUDE_DIR): Define +Sun Nov 1 11:04:32 1998 Jeffrey A Law (law@cygnus.com) - * make-cc.com, make-cccp.com, make-cc1.com: Removed. - * makefile.vms: New file. + * From Christian Gafton: + * i386/linux.h (CPP_PREDEFINES): Add -D__i386__. + * sparc/linux.h (CPP_PREDEFINES): Add -D__sparc__. + * sparc/linux64.h (CPP_PREDEFINES): Add -D__sparc__. - * alpha/vms.h (CPP_PREDEFINES): Remove -Dalpha. +Sat Oct 31 21:42:39 1998 Mark Mitchell - * alpha.c (output_prolog): Output '.name' directive - for minimal traceback information. + * c-common.c (c_get_alias_set): Allow all type-punning through + unions. Don't get confused about the type of a bit-field, despite + the antics of build_modify_expr. - * alpha.c (output_prolog): Don't prepend entry point symbols - with '$' on OPEN_VMS. +Sat Oct 31 22:35:29 1998 Jean-Pierre Radley -Thu Jan 29 00:25:35 1998 David S. Miller - Jeffrey A Law (law@cygnus.com) + * fixinc.sco: Parameterize #include_next values. + * fixinc/fixinc.sco: Likewise. - * rtl.c (read_rtx): Use atol/atoq based upon disposition of - HOST_WIDE_INT. +Sat Oct 31 20:39:35 1998 Jeffrey A Law (law@cygnus.com) - * genattrtab.c (write_test_expr): Use HOST_WIDE_INT_PRINT_DEC - as needed. - * genemit.c (gen_exp): Likewise. - * genpeep.c (match_rtx): Likewise. - * genrecog.c (write_tree_1): Likewise. + * toplev.c (rest_of_compilation): No longer set reload_completed. + * reload1.c (reload): Set it here. Perform instruction splitting + after reload has completed if we will be running the scheduler + again. - * c-lex.c (yyprint): Use proper format string based upon - disposition of HOST_BITS_PER_WIDE_INT. - (yylex): Put casts in right place for args to build_int_2. +Sat Oct 31 12:30:02 1998 Jeffrey A Law (law@cygnus.com) -Thu Jan 29 00:24:29 1998 Jeffrey A Law (law@cygnus.com) + * jump.c (jump_optimize): Initialize mappings from INSN_UID to + EH region if exceptions are enabled and we're performing cross + jump optimizations. + (find_cross_jump): Exit loop if the insns are in different EH regions. - * combine.c: Fix typos in Jan27 changes. +Sat Oct 31 10:02:48 1998 Mark Mitchell -Thu Jan 29 00:07:49 1998 Ollivier Robert + * dwarf2out.c (output_call_frame_info): Use + ASM_OUTPUT_DWARF_DELTA4 for the CIE offset to match frame.c. - * i386/freebsd.h (LIB_SPEC): Correctly handle -shared, -p and friends. - (LINK_SPEC): Likewise. - (STARTFILE_SPEC): Likewise. +Sat Oct 31 10:23:14 1998 Kaveh R. Ghazi -1998-01-28 Mike Stump + Reinstall Apr 24th fix, lost during May 6th gcc2 merge: + * c-common.c (check_format_info): Don't check for the 'x' + format character twice, instead check for 'x' and 'X' - * rtlanal.c (dead_or_set_regno_p): Ignore REG_DEAD notes after - reload completes. - * genattrtab.c (reload_completed): Define. +Fri Oct 30 14:50:25 1998 Jeffrey A Law (law@cygnus.com) - * m32r.md, mips.md, mn10200.md, mn10300.md, pyr.md: Remove obsolete - comments. + * configure.in (assembler features): Also make gas is configured if + we find it in the source tree. -Wed Jan 28 20:11:06 1998 J"orn Rennecke - - * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the - SUBREG_REG if the word count is unchanged, also in the input reload - case. Disable non-applicable sanity checks. - -Wed Jan 28 20:08:26 1998 Jeffrey A Law (law@cygnus.com) - - * config/t-svr4 (TARGET_LIBGCC2_CFLAGS): Add -fPIC. - -Wed Jan 28 20:04:43 1998 Ian Lance Taylor - - * i386/t-cygwin32 (LIMITS_H_TEST, LIBGCC2_INCLUDES): Define. - -Wed Jan 28 11:45:27 1998 Per Bothner - - * dbxout.c (dbxout_type): For a RECORD_TYPE, check that TYPE_BINFO - is a TREE_VEC before trying to use it for baseclasses. - (Chill uses the same field for a different purpose.) - - * toplev.c (strip_off_ending): Generalize to endings up to 5 chars. - -Tue Jan 27 23:15:55 1998 Lassi A. Tuura - - * config.sub: More accurate determination of HP processor types. - -Tue Jan 27 23:11:11 1998 Kaveh R. Ghazi - - * c-lex.c: Include and /. Add - prototype for `handle_sysv_pragma', and make it static. Add - parentheses around assignment used as truth value. - - * combine.c (combine_instructions): Protect variable `prev' with - macro HAVE_cc0. - (can_combine_p): Protect variable `link' with AUTO_INC_DEC. - (extract_left_shift): Add parentheses around operand of &. - (merge_outer_ops): Avoid an empty body in an else-statement. - (gen_rtx_combine): Remove unused variable `i'. - - * sparc/gmon-sol2.c: Include . Make return type of - function monstartup `void'. Likewise for internal_mcount. Add - `static void' prototype for moncontrol. Reconcile sprintf format - vs. args. - - * sparc/sparc.c: Include and /. - Make return type of function_arg_slotno explicitly `int'. - (reg_unused_after): Add parentheses around assignment used as - truth value. - (save_regs): Add explicit braces to avoid ambiguous `else'. - (function_arg_slotno): Add parentheses around && within ||. - (function_arg_pass_by_reference): Likewise. - (sparc_flat_output_function_prologue): Reconcile fprintf format - vs. args. - - * svr4.h (ASM_OUTPUT_LIMITED_STRING): Add parentheses around - assignment used as truth value. - - * cplus-dem.c: Include . - (demangle_signature): Avoid an empty body in an else-statement. - (do_type): Remove unused variable `lvl'. - - * cppexp.c: Don't have depend on MULTIBYTE_CHARS. - Include /. - (cpp_lex): Remove unused variable `namelen'. - (cpp_lex): Explicitly declare `num_chars' as an int. - - * cpplib.c: Avoid duplicate inclusion of , include - instead. Explicitly declare is_system_include - returning int. - (make_assertion): Remove unused variable `kt'. - (cpp_expand_to_buffer): Hide variable `obuf'. - (output_line_command): Remove unused variables, `line_end', - `line_cmd_buf' and `len'. - (macarg): Remove unused variable `arg_start'. - (special_symbol): Remove unused variable `i'. Add parentheses - around assignment used as truth value. - (do_include): Remove unused variables `pcfname' and `retried', - hide `pcf' and `pcfbuflimit'. - (do_line): Remove unused variable `i'. - (finclude): Hide variable `missing_newline'. - (cpp_handle_options): Remove unused variable `j'. - (read_token_list): Remove unused variable `eofp'. - (cpp_error_with_line): Remove unused variable `i'. - (cpp_warning_with_line): Likewise. - (cpp_pedwarn_with_line): Explicitly declare `column' as int. - (cpp_error_from_errno): Remove unused variable `i'. - - * cse.c (invalidate): Add parentheses around assignment used as - truth value. - (find_best_addr): Move declaration of variable `our_cost' inside - the conditional macro where its used. - (fold_rtx): Avoid an empty body in an if-statement. - (cse_insn): Wrap variables `this_insn_cc0_mode' and - `this_insn_cc0' in macro HAVE_cc0. - - * dwarf2out.c: Include and /. - (ASM_OUTPUT_DWARF_DATA8): Reconcile format vs. args in fprintf's. - (output_uleb128): Likewise. - (output_sleb128): Likewise. - (output_cfi): Likewise. - (output_call_frame_info): Remove unused variables `j', `fde_size' - and `fde_pad'. - (comp_unit_has_inlines): Hide declaration as per rest of file. - (size_of_line_prolog): Correct typo in prototype. - (add_arange): Likewise. - (output_aranges): Likewise. - (add_name_and_src_coords_attributes): Likewise. - (gen_array_type_die): Likewise. - (gen_inlined_subroutine_die): Likewise. - (equate_decl_number_to_die): Remove unused variable `i'. - (print_die): Reconcile format vs. args in fprintf's. - (print_dwarf_line_table): Likewise. - (output_die): Likewise. - (output_line_info): Likewise. - (add_subscript_info): Avoid an empty body in an else-statement. - (gen_subprogram_die): Remove unused variable `fp_loc'. - - * dwarfout.c: Explicitly declare `next_pubname_number' as int. - Protect `ordering_attribute' prototype with USE_ORDERING_ATTRIBUTE - macro. Protect `src_coords_attribute' prototype with - DWARF_DECL_COORDINATES macro. Hide `output_entry_point_die' - prototype as in the rest of the file. Likewise for - `output_pointer_type_die' and `output_reference_type_die'. Remove - prototype for `type_of_for_scope'. - (output_unsigned_leb128): Reconcile format vs. args in fprintf. - (type_attribute): Add explicit braces to avoid ambiguous `else'. - - * final.c: Include and /. - (shorten_branches): Protect declaration of tmp_length with - SHORTEN_WITH_ADJUST_INSN_LENGTH and ADJUST_INSN_LENGTH macros. - (profile_function): Protect declaration of `sval' and `cxt' - variables with appropriate macros. - (final_scan_insn): Likewise for `note' variable. Add explicit - braces to avoid empty body in an if-statement. - (output_asm_insn): Move variable `i' inside macro conditional - where it is used. Add parentheses around assignment used as truth - value. - (asm_fprintf) Likewise, likewise. - - * fix-header.c (main): Remove unused variable `done'. Protect - declaration of `i' with FIXPROTO_IGNORE_LIST. - - * pexecute.c: Include . Prototype `my_strerror'. - - * print-rtl.c (print_inline_rtx): Explicitly declare the parameter - `ind'. - - * profile.c: Include /. - (instrument_arcs): Remove unused variables `note', `inverted', - `zero' and `neg_one'. - (branch_prob): Avoid empty body in an if-statement. - - * regclass.c: Include . - (reg_alternate_class): Explicitly declare parameter `regno'. - - * regmove.c (regmove_optimize): Remove unused variable `p'. Add - parentheses around assignment used as truth value. - (find_matches): Remove unused variables `output_operand' and - `matching_operand'. - (fixup_match_1): Remove statement with no effect: "if (0) ;". - - * scan.c (sstring_append): Explicitly declare `count' as int. - (scan_string): Explicitly declare parameter `init' as int. - - * sched.c: Include . - (BLOCKAGE_RANGE): Add parentheses around arithmetic in operand of |. - (rank_for_schedule): Add parentheses around assignment used as - truth value. - (schedule_block): Likewise. - (regno_use_in): Likewise. - (schedule_insns): Remove unused variable `i'. - - * toplev.c: Include and /. - (v_message_with_decl): Remove unused variable `n'. - (botch): Explicitly declare parameter `s' as char *. - (main): Add parentheses around assignment used as truth value. - - * tree.c (make_node): Protect the variable `kind' with the - GATHER_STATISTICS macro. - (real_value_from_int_cst): Move variable `e' inside conditional - macro area where it is used. - (tree_last): Add parentheses around assignment used as truth value. - (build1): Protect the variable `kind' with the GATHER_STATISTICS - macro. - (print_obstack_statistics): Reconcile format vs. args in fprintf. - Protect variables `i', `total_nodes', and `total_bytes' with the - GATHER_STATISTICS macro. - -Tue Jan 27 23:01:55 1998 Mike Stump (mrs@wrs.com) - - * m32r.md, mips.md, mn10200.md, mn10300.md, pyr.md: Add - some comments regarding use of dead_or_set_p. - -Tue Jan 27 22:14:48 1998 Todd Vierling - - * fixincludes: Tweak fix for struct exception in math.h - -Tue Jan 27 17:21:09 1998 Gavin Koch (gavin@cygnus.com) - - * mips/mips.c (mips_expand_prologue,mips_expand_epilogue): - Change mode of registers used to add/sub from - hard_frame_pointer_rtx from word_mode to Pmode. - -Tue Jan 27 11:02:04 1998 Nick Clifton - - * v850.h (ASM_OUTPUT_ALIGNED_BSS): Use - asm_output_aligned_bss() instead of asm_output_bss(). - - * toplev.c (rest_of_compilation): Replace references to - stack_reg_dump_file and dbr_sched_dump_file with references to - rtl_dump_file. - -Tue Jan 27 10:22:13 1998 Kamil Iskra - - * tlink.c (scan_linker_output): Call fclose() for opened files. - -Tue Jan 27 05:05:26 1998 Richard Henderson - - * alpha.c (output_epilog [!VMS]): Don't tag global functions if - compiling with -fpic -- we want to be able to override symbols - properly. - (alpha_expand_block_move): Fix thinko in last change. +Fri Oct 30 13:23:20 1998 Richard Henderson - * alpha.h (ASM_OUTPUT_MI_THUNK): New define. - * config/alpha/win-nt.h (ASM_OUTPUT_MI_THUNK): New define. - * config/alpha/vms.h (ASM_OUTPUT_MI_THUNK): New undef. + * i386.c (i386_comp_type_attributes): Compare whether the + attributes are defined, not their tree nodes. -Tue Jan 27 03:21:23 1998 Richard Henderson +Fri Oct 30 11:39:47 1998 Alexandre Oliva - * alpha.md (abssf, absdf): Revert last change. + * configure.in (gxx_include_dir): Bitten by autoconf quoting + characters. :-( + * configure: Rebuilt. -Tue Jan 27 00:26:50 1998 John Carr +Fri Oct 30 10:43:29 1998 Andreas Schwab - * dwarf2out.c (dwarf2out_frame_init): Test value of DWARF2_UNWIND_INFO. - * mips/sni-svr4.h: Define DWARF2_UNWIND_INFO as 0. + * configure.in: Ignore non-absolute value in $AS. -Tue Jan 27 00:07:02 1998 Jeffrey A Law (law@cygnus.com) +Fri Oct 30 00:54:25 1998 Peter Jakubek - * emit-rtl.c (gen_lowpart_common): Handle more case where converting - a CONST_INT into SFmode. + * m68k.h (INDIRECTABLE_1_ADDRESS_P): Fix thinko. -Tue Jan 20 16:01:03 1998 Anthony Green +Fri Oct 30 00:42:34 1998 Mark Elbrecht + + * configure.in (msdosdjgpp): Set exeext and target_alias. + +Thu Oct 29 23:55:43 1998 Bernd Schmidt + + * flow.c (XNMALLOC): New macro. + (flow_int_list_blocks, basic_block_succ, basic_block_pred): New + static variables. + (add_edge, add_edge_to_label): New static functions. + (free_bb_memory): New function. + (flow_delete_insn): Delete function. + (basic_block_drops_in): Delete variable. + (find_basic_blocks): Allocate and initialize basic_block_head, + basic_block_succ. Don't allocate basic_block_drops_in. + Call free_bb_memory at the beginning. + (find_basic_blocks_1): Don't do multiple passes. + Delete code to compute basic_block_drops_in. + After calling make_edges, mark blocks reached by current block live. + Update test for unreachable live blocks. + (mark_label_ref): Delete args X, CHECKDUP. Add PRED arg. All callers + changed. + Simplify to call add_edge_to_label when a LABEL_REF is found. + (make_edges): Simplify to call add_edge_to_label instead of + mark_label_ref most of the time. + Compute here whether control drops into the next block. + (delete_unreachable_blocks): Return void. All callers changed. + Delete unreachable blocks in reverse order. + After deleting all unreachable blocks, renumber the remaining ones + and update n_basic_blocks. + (delete_block): Speed up deletion a bit. + Don't set basic_block_drops_in for deleted blocks. + (free_basic_block_vars): Don't free basic_block_drops_in. + (life_analysis_1): Update to use new edge representation. + (dump_flow_info): Delete code to print basic block info; call + dump_bb_data instead. + (compute_preds_succs): Delete code to recompute basic_block_drops_in + and uid_block_number. + Simply copy the previously computed cfg. + (dump_bb_data): New arg LIVE_INFO. All callers changed. + Print register lifetime information if LIVE_INFO is nonzero. + * basic-block.h (dump_bb_data): Adjust prototype. + * gcse.c (gcse_main): Update call to dump_bb_data. + * rtl.h (free_bb_memory): Declare. + * toplev.c (rest_of_compilation): Call free_bb_memory. + + * reload1.c (struct elim_table): Delete MAX_OFFSET member. + (update_eliminable_offsets): Don't compute it. + (set_initial_elim_offsets): Don't initialize it. + Break out some code into set_initial_label_offsets so the rest of + this function can be called from reload_as_needed. + Assume that INITIAL_FRAME_POINTER_OFFSET is defined when + ELIMINABLE_REGS isn't. + (set_initial_label_offsets): New function, broken out of + set_initial_elim_offsets. + (set_offsets_for_label): New function, broken out of set_label_offsets + and reload_as_needed. + (reload): Call the two new functions. + (reload_as_needed): Call set_initial_elim_offsets instead of + duplicating the code. Likewise for set_offsets_for_label. + + * reload1.c (choose_reload_regs): Fix typo in Oct 17 change. + (emit_reload_insns): Ensure that when we set reg_reloaded_valid for + any hard reg, reg_reloaded_dead contains valid data. + +Thu Oct 29 22:30:54 1998 Marcus Meissner + + * i386.c (i386_comp_type_attributes): Return nonzero for mismatched + "stdcall" and "cdecl" attributes. + +Thu Oct 29 19:05:17 1998 Jim Wilson + + * sched.c (update_flow_info): Add code to ! found_orig_dest case to + handle deleted no-op moves of hard registers. + * haifa-sched.c (update_flow_info): Likewise. - * flags.h: New flag (optimize_size). - * toplev.c (main): Parse -Os option and set optimize_space - accordingly. - * gcc.c (default_compilers), cp/lang-specs.h, f/lang-specs.h: Define - __OPTIMIZE_SIZE__ when compiling with -Os. - * config/dsp16xx/dsp16xx.h, config/i386/i386.h, - config/i386/dgux.h, config/i960/i960.h, config/pdp11/pdp11.h, - config/v850/v850.h (OPTIMIZATION_OPTIONS): New SIZE argument - to macro. - * config/i386/i386.c (optimization_options): Accept new SIZE argument. +Thu Oct 29 18:07:47 1998 Jeffrey A Law (law@cygnus.com) -Mon Jan 26 23:57:39 1998 Manfred Hollstein + * mips.md (reload_{in,out}{si,di}): Emit a USE of HILO at the end + of the sequences to reload the HILO register which do not actually + reference HILO. - * libgcc2.c (__clear_insn_cache): On sysV68 enable the memctl - stuff only if MCT_TEXT is #define'd. +Thu Oct 29 12:39:35 1998 Jim Wilson -Mon Jan 26 23:52:51 1998 Markus F.X.J. Oberhumer + * c-common.c (c_get_alias_set): Handle ARRAY_REF of union field. - * configure.in (i*86-pc-msdosdjgpp): Treat like msdos & go32 - configurations. +Thu Oct 29 14:10:22 1998 Andrew MacLeod -Fri Jan 23 09:39:36 1998 Nick Clifton + * except.c (emit_eh_context): Make the EH context register stay alive + at -O0 so stupid.c doesn't get confused. - * toplev.c: Add -dM command line option to dump RTL after the - machine dependent reorganisation pass, if there is one. - Reorganise RTL dump code, so that only one file handle is - needed. +1998-10-29 Herman A.J. ten Brugge -Mon Jan 26 12:09:42 1998 Benjamin Kosnik + * emit-rtl.c (try_split): Do not try to split a BARRIER. - * except.c (check_exception_handler_labels): Disable warning when - flag_syntax_only. +Thu Oct 29 01:33:54 1998 Jan Hubicka + Jeffrey A Law (law@cygnus.com) -Mon Jan 26 18:17:32 1998 Jim Wilson + * i386.md: Change ix86_cpu == PROCESSOR_PENTIUM to TARGET_PENTIUM. + (zero_extendsidi2): Use # in output template and handle completely by + splits. + (zero_extend splitters): New define_splits. + (ashiftrt_32): New pattern. - * sparc.c (pic_setup_code): Don't set LABEL_PRESERVE_P. +Wed Oct 28 22:58:35 1998 Jason Merrill -Mon Jan 26 18:11:30 1998 J"orn Rennecke + * tree.c (append_random_chars): New fn. + (get_file_function_name_long): Use it. - * c-decl.c (grokdeclarator): Get parameter tags from - last_function_parm_tags. - * dwarfout.c (output_formal_types): Set TREE_ASM_WRITTEN before - traversing the parameter types. - (output_type): No early exit for FUNCTION_TYPE / METHOD_TYPE context. +Wed Oct 28 22:27:05 1998 Richard Henderson + + * Makefile.in (cc1): Put C_OBJS, and thence @extra_c_objs@ last. + (LIBCPP_OBJS): New. Add cppulp.o. + (cppmain, fix-header): Depend on and use libcpp.a. + * configure.in (extra_c_objs, extra_cxx_objs): Use libcpp.a instead + of the individual object files. + * objc/Make-lang.in (cc1obj): Put OBJC_OBJS, and thence @extra_c_objs@, + last. + + * cccp.c (user_label_prefix): New. + (main): Set it off -f*leading-underscore. + (special_symbol): Use it. + * cpplib.c (special_symbol): Likewise. + (cpp_handle_option): Handle -f*leading-underscore. + * cppulp.c: New file. -Mon Jan 26 01:44:12 1998 Jeffrey A Law (law@cygnus.com) + * output.h (user_label_prefix): Declare it. + * dwarf2out.c (ASM_NAME_TO_STRING): Prepend user_label_prefix. + * toplev.c (f_options, main): Handle -f*leading-underscore. + + * defaults.h (ASM_OUTPUT_LABELREF): Use asm_fprintf instead of + referencing USER_LABEL_PREFIX directly. + * config/nextstep.h (ASM_OUTPUT_LABELREF): Likewise. + * m32r/m32r.h (ASM_OUTPUT_LABELREF): Likewise. + * final.c (asm_fprintf): Use user_label_prefix instead. + * arm/thumb.c (thumb_print_operand): Likewise. + + * gcc.c (default_compilers): Pass -f*leading-underscore on to + cpp wherever appropriate. + +Wed Oct 28 23:09:25 1998 Robert Lipe - * h8300.c (print_operand): Handle CONST_DOUBLE for 'e', 'f', and - the default case. - (get_shift_alg): Fix typo. + * sco5.h (SUBTARGET_SWITCHES): Add documentation for OpenServer- + specific compiler switches. -Sun Jan 25 22:22:04 1998 Richard Henderson +Wed Oct 28 21:05:53 1998 Jeffrey A Law (law@cygnus.com) - * alpha.c (alpha_expand_block_move): Copy ADDRESSOF to reg. + * Makefile.in (c-common.o): Depend on c-pragma.h. Use $(RTL_H) instead + of rtl.h. -Sun Jan 25 22:14:28 1998 Richard Henderson +Wed Oct 28 20:52:47 1998 Kaveh R. Ghazi - * toplev.c (get_run_time): Make sure each case gets its variables. + * gcc.c (EXTRA_SPECS, extra_specs): Introduce an intermediate + structure which has exactly the members provided by EXTRA_SPECS. + Xmalloc() the real `extra_specs', and initialize it from this + intermediate structure. -Sun Jan 25 22:10:21 1998 Richard Henderson + * alpha.h (EXTRA_SPECS): Revert change for missing initializers. - * configure.in (build_xm_file): Add auto-config.h if host=build. - (host_xm_file_list): Don't add $(srcdir) to auto-config.h. - (build_xm_file_list): Likewise. - * configure: Rebuild. + * mips.h (EXTRA_SPECS): Likewise. -Sun Jan 25 22:00:25 1998 Alasdair Baird + * sparc.h (EXTRA_SPECS): Likewise. - * recog.c (validate_replace_rtx_1): Only perform substitutions - of arguments to commutative and comparison operators once. +Wed Oct 28 16:46:07 1998 Andreas Schwab -Sun Jan 25 12:30:18 1998 Kaveh R. Ghazi + * function.c (purge_addressof_1): Instead of aborting when a + bitfield insertion as a replacement for (MEM (ADDRESSOF)) does not + work just put the ADDRESSOF on stack. Otherwise remember all such + successful replacements, so that exactly the same replacements + can be made on the REG_NOTEs. Remove the special case for CALL + insns again. + (purge_addressof_replacements): New variable. + (purge_addressof): Clear it at end. - * sparc.c (output_cbranch): Add default case in - enumeration switch. +1998-10-28 Zack Weinberg - * reorg.c (insn_sets_resource_p): Correct typo in prototype. - (emit_delay_sequence): Eliminate unused parameter, all callers + * c-lang.c: Declare extern char *yy_cur if USE_CPPLIB. + (lang_init): Call check_newline always. + * c-lex.c (init_parse) [USE_CPPLIB=1]: After calling + cpp_start_read, set yy_cur and yy_lim to read from + parse_in.token_buffer, so that we'll see the first #line + directive. + * cpplib.c (cpp_start_read): finclude the main input file + before processing -include/-imacros. Process -imacros and + -include separately, and handle -include by stacking a + buffer for the file in question as if it'd been #included. + * toplev.c (documented_lang_options): Recognize -H when + USE_CPPLIB is on. + +1998-10-28 Zack Weinberg + + * cpplib.c: Merge do_once into do_pragma. Break file handling + code out of do_include. + Move append_include_chain, deps_output, + file_cleanup, redundant_include_p, import_hash, + lookup_import, add_import, read_filename_string, read_name_map, + open_include_file, finclude, safe_read to cppfiles.c. + Move prototypes for deps_output, append_include_chain, + finclude to cpplib.h. Move definition of struct + file_name_list there also. + + * cppfiles.c: New file. Contains all the above functions + broken out of cpplib.c; also hack_vms_include_specification + from cccp.c and find_include_file, a new function broken out of + do_include. + + * Makefile.in (cppmain): Depend on cppfiles.o. + (fix-header): Likewise. + (cppfiles.o): New target. + * configure.in (--enable-c-cpplib): Add cppfiles.o to + extra_c_objs. Add ../cppfiles.o to extra_cxx_objs. + +Wed Oct 28 14:06:49 1998 Jim Wilson + + * dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort + if pending_types is non-zero. + (dwarfout_finish): Verify pending_types is zero before finishing. + +Wed Oct 28 10:29:09 1998 Nick Clifton + + * expr.c (convert_move): Use shifts to perform the move if a + suitable extend pattern cannot be found. Code written by + Richard Henderson . + +Wed Oct 28 03:59:29 1998 Bernd Schmidt + + * regclass.c (renumber, regno_allocated): New static variables, moved + out of allocate_reg_info. + (allocate_reg_info): Move these two variables outside the function. + Move code to free memory into new function free_reg_info. + (free_reg_info): New function, broken out of allocate_reg_info. + * toplev.c (compile_file): Call free_reg_info, not allocate_reg_info. + * rtl.h (allocate_reg_info): Don't declare. + (free_reg_info): Declare. + + * final.c (cleanup_subreg_operands): ASM_INPUTs need no treatment. + +Wed Oct 28 02:38:12 1998 Jason Merrill + + * toplev.c (compile_file): Temporarily revert last change. + +Wed Oct 28 00:00:35 1998 Jason Merrill + + * c-typeck.c (convert_for_assignment): Parenthesize. + +1998-10-28 Andreas Schwab + + * reload1.c (delete_output_reload): Avoid ambigous else. + +Wed Oct 28 00:10:35 1998 Jeffrey A Law (law@cygnus.com) + + * toplev.c (compile_file): Call allocate_reg_info to free register + table memory. + * rtl.h (allocate_reg_info): Declare. + + * PROJECTS: Remove entry for local spilling. + + * final.c (cleanup_subreg_operands): New function. + (final_scan_insn): Use it. + (alter_subreg): Clear the "used" field when we turn a SUBREG into + a REG. + * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG + operands when reload has finished. + * reload.h (cleanup_subreg_operands): Declare.. + * flow.c (life_analysis_1): No longer delete CLOBBER insns after + reload. Handled in reload itself. + +Tue Oct 27 23:32:34 1998 Bernd Schmidt + + * reload1.c (verify_initial_offsets): New function. + (reload): Call it after reload_as_needed. Also verify that the frame + size stays constant during reload_as_needed. + * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Undo Jul 26 change. + + * reload.h (struct insn_chain): Add need_operand_change element. + * reload1.c (new_insn_chain): Clear it. + (calculate_needs_all_insns): Set it; don't overload need_reload. + (reload_as_needed): Use it. + + * reload.c (find_reloads_address): Use BASE_REG_CLASS instead of + reload_address_base_reg_class throughout. Similar for INDEX_REG_CLASS + and reload_address_index_reg_class. + (find_reloads_address_1): Likewise. + * reload.h (reload_address_base_reg_class, + reload_address_index_reg_class): Don't declare. + * reload1.c (reg_old_renumber, pseudo_previous_regs, + pseudo_forbidden_regs, bad_spill_regs_global): New static variables. + (used_spill_regs): Now static. + (reload_address_base_reg_class, reload_address_index_reg_class, + regs_explicitly_used, counted_for_groups, counted_for_nongroups, + basic_block_needs, max_needs, group_size, group_mode, max_groups, + max_nongroups, max_needs_insn, max_groups_insn, max_nongroups_insn, + forbidden_regs): + Deleted variables. + (init_reload): Delete code to compute base/index reg classes. + (reload): Delete variable J. + Delete code to manage basic_block_needs. + Don't compute regs_explicitly_used. + Allocate, initialize and free reg_old_renumber, pseudo_forbidden_regs, + pseudo_previous_regs. + Initialize bad_spill_regs_global. + Don't call order_regs_for_reload here. + Don't initialize spill_reg_order and n_spills. + Don't forbid explicitly used regs to be used for spill regs. + Change main loop to infinite loop, with explicit break statements. + Make SOMETHING_CHANGED variable local to that loop. + Don't initialize max_needs, max_groups, max_nongroups, max_needs_insn, + max_groups_insn, max_nongroups_insn, group_size, group_mode. + Make sure spilled_pseudos is cleared before calling spill_hard_reg or + new_spill_reg. + Don't call dump_needs. + Delete code to reset potential_reload_regs. + Delete code to terminate loop conditional on the global needs variables + showing no further needs. + (calculate_needs_all_insns): Return void. All callers changed. + Initialize something_needs_elimination here, not in reload. + Delete avoid_return_reg kludge. + (calculate_needs): Lose AVOID_RETURN_REG and GLOBAL args, return void. + All callers changed. + Initialize the group_mode and group_size elements of the arg CHAIN. + Delete code to manage basic_block_needs. + Operate on elements of CHAIN instead of global variables. + Delete avoid_return_reg kludge. + (find_tworeg_group): Lose GLOBAL arg, take CHAIN arg, return void. + All callers changed. + Operate on elements of CHAIN instead of global variables. + Delete special SMALL_REGISTER_CLASSES code. + Delete spill_failure code; now in new_spill_reg. + (find_group): Lose GLOBAL arg, take CHAIN arg, return void. + All callers changed. + Operate on elements of CHAIN instead of global variables. + (maybe_mark_pseudo_spilled): New static function. + (find_reload_regs): Lose GLOBAL arg, take CHAIN arg, return void. + All callers changed. + Operate on elements of CHAIN instead of global variables. + Call order_regs_for_reload here, not in reload. + Initialize spill_reg_order and n_spills. + Simplify test whether an asm insn is involved. + Delete spill_failure code; now in new_spill_reg. + Call maybe_mark_pseudo_spilled for everything marked as live in + CHAIN. Merge CHAIN's used_spill_regs into the global variable + used_spill_regs. + (dump_needs): Take CHAIN arg. No longer static, to prevent the + compiler from optimizing this function (now unused) away. + Operate on elements of CHAIN instead of global variables. + (possible_group_p): Lose MAX_GROUPS arg, take CHAIN arg. All callers changed. - (fill_simple_delay_slots): Likewise. - (fill_slots_from_thread): Likewise. - (fill_eager_delay_slots): Likewise. - (mark_referenced_resources): Add default case in enumeration switch. - (mark_set_resources): Likewise. - (rare_destination): Likewise. - (mostly_true_jump): Likewise. - (find_dead_or_set_registers): Likewise. - (redirect_with_delay_slots_safe_p): Remove unused variable `slots'. - (update_reg_unused_notes): Remove unused variable `p'. - (mark_target_live_regs): Remove unused variables `next' and - `jump_count'. - (fill_simple_delay_slots): Remove unused variable `j'. - (fill_slots_from_thread): Add parentheses around assignment used - as truth value. - (dbr_schedule): Likewise. + Operate on elements of CHAIN instead of global variables. + (count_possible_groups): Lose GROUP_SIZE, GROUP_MODE, MAX_GROUPS args, + take CHAIN arg. All callers changed. + Operate on elements of CHAIN instead of global variables. + (new_spill_reg): Lose MAX_NEEDS, MAX_NONGROUPS, GLOBAL args, take + CHAIN, NONGROUP args. Return void. All callers changed. + Verify caller isn't trying to spill a pseudo. + Simplify test for illegal reg, just use bad_spill_regs. + Generate better error messages. + Operate on elements of CHAIN instead of global variables. + Mark spilled register in CHAIN's used_spill_regs element. + Don't call spill_hard_reg. + (spill_hard_reg): Lose GLOBAL arg, return void. All callers changed. + Mark spilled hard regs in bad_spill_regs_global. + Mark affected pseudos in spilled_pseudos, but don't spill them. + (ior_hard_reg_set): New static function. + (finish_spills): Return int. All callers changed. + Compute spill_reg_order, n_spills and spill_regs here. Also update + regs_ever_live for regs used as spills. + For every pseudo in spilled_pseudos, spill it and mark the previous + hard reg it had in pseudo_previous_regs. Compute which hard regs + are used as spills in insns during which it is live, and retry global + register allocation. Update all life information in the + reload_insn_chain not to include pseudos without hard regs. + Call alter_reg for all affected speudos. + + (scan_paradoxical_subregs): Disable SMALL_REGISTER_CLASSES special + case, it's not clear what it's supposed to do. + + (hard_reg_use_compare): Take bad_spill_regs into account. + (pseudos_counted): New static variable. + (count_pseudo): New static function. + (order_regs_for_reload): Take CHAIN arg. All callers changed. + Initialize bad_spill_regs from bad_spill_regs_global, then merge any + hard registers explicitly used across the current insn into the set. + Compute hard_reg_n_uses taking only pseudos live across this insn + into account. + Tweak sorting of potential_reload_regs. + (compare_spill_regs): Delete function. + (reload_as_needed): Don't sort the spill_regs array, it's computed + in proper order in finish_spills. + Delete avoid_return_reg kludge. + Delete code to manage basic_block_needs. + (allocate_reload_reg): Minor speed/readability tweaks. + Operate on elements of CHAIN instead of global variables. + (choose_reload_regs): Lose AVOID_RETURN_REG arg. All callers changed. + Delete avoid_return_reg kludge. + Initialize reload_reg_used from CHAIN's used_spill_regs element. + Delete unused label FAIL. + (reload_combine): Replace reload_address_index_reg_class with + INDEX_REGS. + Don't use used_spill_regs to determine information about lifetime of + hard regs. + +Tue Oct 27 13:15:02 1998 Nick Clifton + + * toplev.c (display_help): Ignore empty target specific + options, and if -W is also specified on the command line then + display undocumented options. + + * config/arm/arm.c: Updated with changes in devo sources. + * config/arm/arm.h: Updated with changes in devo sources. + * config/arm/lib1funcs.asm: Updated with changes in devo sources. + * config/arm/lib1thumb.asm: Add ELF support. + +Tue Oct 27 16:11:43 1998 David Edelsohn + + * collect2.c (aix64_flag): New variable. + (main, case 'b'): Parse it. + (GCC_CHECK_HDR): Object magic number must match mode. + (scan_prog_file): Only check for shared object if valid header. + Print debugging if header/mode mismatch. - * objc/Make-lang.in (objc.stage1): Depend on stage1-start. - (objc.stage2, objc.stage3, objc.stage4): Likewise. +Tue Oct 27 10:15:02 1998 Nick Clifton -Sun Jan 25 12:13:47 1998 Michael Tiemann + Added support for arm-elf-linux configuration, submitted by Philip + Blundell , and integrated this with the arm-elf + code developed by Catherine Moore . The following + files are affected: - * cse.c (simplify_ternary_operation): Don't try to simplify - IF_THEN_ELSE expressions (created by combine) that don't use - relational operators. + * configure.in: Add arm-*-linux-gnu, armv2-*-linux and arm-*-elf + targets. -Fri Jan 23 22:48:24 1998 Jeffrey A Law (law@cygnus.com) + * configure: Regenerated. - * cse.c (simplify_ternary_operation): Handle more IF_THEN_ELSE - simplifications. + * config/arm/aout.h: Add default definitions of REGISTER_PREFIX, + USER_LABEL_PREFIX and LOCAL_LABEL_PREFIX. Make other macro + definitions conditional on their not having been already defined. - * crtstuff.c (init_dummy): Keep the epilogue in the init - section for non-ELF systems. + * config/arm/lin1funcs.asm: Add ELF only macros to generate .size + and .type directives, and add "(PLT)" qualification to function + calls. -Fri Jan 23 23:28:59 1998 J"orn Rennecke + * config/arm/linux.h: Deleted. This file is now superseded by + either linux-elf.h or linux-aout.h. - * sh.md (movqi_i+1): New peephole. + * config/arm/linux-gas.h: Define `inhibit_libc' if cross-compiling. + (CLEAR_INSN_CACHE): New macro, currently disabled (awaiting kernel + support). + Move definitions from old linux.h file here. -Fri Jan 23 15:39:42 1998 Jim Wilson + * config/arm/elf.h: New file. Generic ARM/ELF support. - * Makefile.in: Remove remaining bytecode stuff. - * emit-rtl.c, expr.c: Likewise. + * config/arm/linux-aout.h: New file. Support for Linux with a.out. -Fri Jan 23 12:41:10 1998 Nick Clifton (nickc@cygnus.com) + * config/arm/linux-elf.h: New file. Support for Linux with ELF. - * toplev.c (lang_options): Add unknown-pragma options. + * config/arm/linux-elf26.h: New file. Support for Linux with ELF + using the 26bit APCS. -Thu Jan 22 23:43:38 1998 Per Bothner + * config/arm/unknown-elf.h: New file. Support for OS'es other + than Linux with ELF. - * dwarfout.c (byte_size_attribute): Simplify and fix - don't need - special (and incomplete) handling for Chill arrays. + * config/arm/t-arm-elf: New file. makefile fragment for arm-elf + builds. -Fri Jan 23 00:27:23 1998 John Carr + * config/arm/coff.h: Include aout.h for basic assembler macros. + Add support for -mstructure_size_boundary= command line option. - * toplev.c (get_run_time): Call sysconf(_SC_CLK_TCK), when available, - to get clock rate. + * config/arm/arm.h: Add support for -mstructure_size_boundary= + command line option. Make macro definitions conditional on their + not having been already defined. -Fri Jan 23 00:19:36 1998 Gavin Koch (gavin@cygnus.com) + * config/arm/arm.c: Add support for -mstructure_size_boundary= + command line option. - * mips.md (muldi3_internal2): Reverse test for TARGET_MIPS16. -1998-01-22 scott snyder +Tue Oct 27 08:56:46 1998 Andrew MacLeod - * mips.c (function_prologue): Use HARD_FRAME_POINTER_REGNUM in - .frame directive instead of FRAME_POINTER_REGNUM. + * dwarfout.c (ASM_OUTPUT_DWARF_STRING_NEWLINE): ASM_OUTPUT_DWARF_STRING + has been changed to not include a newline. Use this macro instead. + (output_enumeral_list, const_value_attribute, name_attribute, + comp_dir_attribute, prototyped_attribute, producer_attribute, + inline_attribute, pure_or_virtual_attribute, output_inheritance_die, + dwarfout_file_scope_decl, generate_new_sfname_entry, + generate_macinfo_entry, dwarfout_init, dwarfout_finish): Use + ASM_OUTPUT_DWARF_STRING_NEWLINE macro. -Fri Jan 23 00:08:55 1998 Robin Kirkham +Mon Oct 26 13:35:02 1998 Richard Henderson - * m68k.h (TARGET_SWITCHES): -mcpu32 now clears MASK_68881. - (MACHINE_STATE_m68010_up): Replaced __mc68332__ with __mcpu32__. - * m68k/m68k-none.h(CPP_FPU_SPEC): Update relative to TARGET_SWITCHES. - (CPP_SPEC, ASM_SPEC, CC1_SPEC): Likewise. - (CPP_SPEC): -m68332 defines both __mc68332 and __mcpu32__. - * m68k/t-m68kbare (MULTILIB_OPTIONS): Add mcpu32. - (MULTILIB_MATCHES): -m68332 now uses mcpu32 libraries, not m68000. - (MULTILIB_EXCEPTIONS): Don't build 68881 libraries for m68000, - mcpu32 or m5200. - * longlong.h: Replace __mc68332__ with __mcpu32__. + * combine.c (subst): Process the inputs to a parallel asm_operands + only once. -Thu Jan 22 19:55:40 PST 1998 Jeff Law (law@cygnus.com) +Mon Oct 26 13:32:31 1998 Richard Henderson - * version.c: Bump for snapshot. + * stmt.c (expand_asm_operands): Accept `=' or `+' at any position. -Thu Jan 22 14:47:31 1998 Jim Wilson +Mon Oct 26 12:53:14 1998 Jeffrey A Law (law@cygnus.com) - * reload.c (push_reload): In WORD_REGISTER_OPERATIONS code, add test - to require the SUBREG mode to be smaller than the SUBREG_REG mode. - * reload1.c (eliminate_regs): Likewise. + * tm.texi (ASM_OUTPUT_MAX_SKIP_ALIGN): Document. -Thu Jan 22 14:49:14 1998 Jeffrey A Law (law@cygnus.com) +Mon Oct 26 00:36:58 1998 Jeff Law (law@cygnus.com) - * regmove.c (find_matches): Initialize matches->earlyclobber too. + * version.c: Bump for snapshot. -Thu Jan 22 01:40:52 1998 Richard Henderson +Sun Oct 25 23:36:52 1998 Jason Merrill - * alpha.md (abssf2, absdf2): Disable in IEEE mode. - (negsf2, negdf2): Use proper subtract in IEEE mode. + * stmt.c (expand_fixup): Set fixup->before_jump to a + NOTE_INSN_DELETED instead of a NOTE_INSN_BLOCK_BEG. -Tue Jan 20 09:29:09 1998 Jeffrey A Law (law@cygnus.com) +Sun Oct 25 15:49:57 1998 Kaveh R. Ghazi - * Makefile.in: Remove more bytecode stuff. - * expr.c, stmt.c, config/msdos/top.sed: Likewise. - * vax/xm-vms.h, winnt/config-nt.sed: Likewise. - * f/install.texi, objc/Make-lang.in: Likewise. + * Makefile.in (recog.o): Depend on toplev.h. + (insn-emit.o): Depend on recog.h. + (insn-peep.o): Depend on recog.h and insn-config.h. - * Makefile.in: Remove all bytecode support. - (OBJS): Make sure last entry is a real object file, not EXTRA_OBJS. - * emit-rtl.c: Remove all bytecode support. - * expr.c, expr.h function.c, integrate.c: Likewise. - * output.h, regclass.c, rtl.h, stmt.c, toplev.c: Likewise. - * tree.h, varasm.c: Likewise. - * config/m68k/m68k.h: Likewise. - * bi-*, bc-*, bytecode*: Delete bytecode related files. - * modemap.def: Likewise. + * combine.c (simplify_set): Remove unused variable `scratches'. -Tue Jan 20 09:02:31 1998 Gavin Koch (gavin@cygnus.com) + * final.c (final_scan_insn): Wrap declaration of variables `vlen' + and `idx' in macro conditional controlling their use. - * mips/mips.md (divsi3,divdi3,modsi3,moddi3,udivsi3,udivdi3, - umodsi3,umoddi3): Handle mips16 div/mod by a constant. + * genemit.c (main): Make the generated output file include + recog.h. Don't have it declare `insn_operand_constraint', since + we get it from recog.h. -Mon Jan 19 21:57:00 1998 Richard Henderson + * genpeep.c (main): Make the generated output file include + insn-config.h and recog.h. - * i386.md (push): Prohibit symbolic constants if flag_pic. - (movsi+1): Likewise for move to non-register. + * recog.c: Include toplev.h. + (extract_insn): Remove unused variable `p'. -Mon Jan 19 11:15:38 1998 Jim Wilson + * regclass.c (fix_register): Add missing braces around initializer + for `what_option'. + (allocate_reg_info): Move variable `i' into the scope where it is + used. Change its type to `size_t'. - * alpha.c (mode_mask_operand): Accept 0xffffffff on 32 bit host. - (print_operand): Handle 0xffffffff on 32 bit host. +Sun Oct 25 13:10:15 1998 Bernd Schmidt - * configure.in (thread_file): Rename uses before main loop to - target_thread_file. Initialize to empty in main loop. Set thread_file - to target_thread_file after main loop if not set. - * configure: Rebuild. + * reload.c (push_reload): When merging reloads, make sure + that reload_in_reg and reload_in are from the same reload in + all cases. - * genattrtab.c (find_and_mark_used_attributes): Handle CONST_INT. - (add_values_to_cover): Revert last change (which had no ChangeLog - entry). - (simplify_with_current_value_aux): Handle CONST_INT. +Sun Oct 25 12:07:00 1998 Mumit Khan -Mon Jan 19 10:14:55 1998 Andreas Schwab + * i386/crtdll.h (CPP_PREDEFINES): Fix typo. + * i386/mingw32.h (CPP_PREDEFINES): Likewise. - * unprotoize.c: Define UNPROTOIZE first, to actually take effect. +Fri Oct 23 23:42:03 1998 David Edelsohn -Mon Jan 19 10:11:52 1998 Richard Henderson + * loop.c (loop_has_tablejump): New variable. + (prescan_loop): Scan for it. + (insert_bct): Replace explicit scan with use of it. + * regclass.c (regclass): Restore loop variable j. + (record_reg_classes): Deterine op_types modifiers and initialize + classes[i] before matching constraints. Handle matching + constraints 5-9. - * configure.in: Add cpp stringify test. - * acconfig.h (HAVE_CPP_STRINGIFY): New tag. - * gengenrtl.c: Use it. - * configure, config.in: Rebuild. +Fri Oct 23 13:55:48 1998 Jim Wilson -Mon Jan 19 09:43:15 1998 Andreas Schwab + * m32r/m32r.c (gen_split_move_double): Call alter_subreg. Delete + subreg support. - * Makefile.in (genrtl.c genrtl.h): Add dummy command for GNU make. +Fri Oct 23 16:19:24 1998 Kaveh R. Ghazi -Mon Jan 19 09:38:18 1998 Richard Henderson + * mips.h (EXTRA_SPECS): Add missing initializers. - * configure.in: Find declaration for sbrk. - * acconfig.h (NEED_DECLARATION_SBRK): New tag. - * config.in, configure: Rebuild. - * mips-tfile.c: Properly protect declaration of sbrk and free. - * toplev.c: Properly protect declaration of sbrk. +Fri Oct 23 16:08:39 1998 Kaveh R. Ghazi -Sun Jan 18 20:18:01 1998 Richard Henderson + * sparc.h (EXTRA_SPECS): Add missing initializers. + (sparc_defer_case_vector): Provide a prototype. - * alpha.c (alpha_handle_trap_shadows): Ignore CLOBBERs. + * svr4.h (ASM_OUTPUT_ASCII): Cast STRING_LIMIT to (long) when + comparing it to the result of a pointer subtraction. -Sun Jan 18 01:54:27 1998 Jeffrey A Law (law@cygnus.com) +Fri Oct 23 15:34:14 1998 Kaveh R. Ghazi - * alpha/xm-winnt.h (HAS_INIT_SECTION): Undefine. + * alpha.c (override_options): Use ISDIGIT(), not isdigit(). Cast + the argument to (unsigned char). -Sun Jan 18 00:57:35 1998 Mike Stump (mrs@wrs.com) + * alpha.h (EXTRA_SPECS): Add missing initializers. + (ASM_GENERATE_INTERNAL_LABEL): Ensure the argument matches the + format specifier. - * configure.in (i960-wrs-vxworks): Default to latest vxworks release. +Fri Oct 23 13:12:35 1998 Jeffrey A Law (law@cygnus.com) -Sat Jan 17 23:41:36 1998 David S. Miller + * flow.c (life_analysis_1): Enable "rescan" code after reload. + (propagate_block): Delete dead code after reload. - * combine.c (force_to_mode, nonzero_bits): Correctly optimize - constant offset computations from objects with known alignment in - the presence of STACK_BIAS. + * sched.c (update_flow_info): Revert Oct 19, 1998 change. Brings + back Oct 15, 1998 change. + * haifa-sched.c (update_flow_info): Likewise. + * flow.c (life_analysis_1): Delete CLOBBER insns after reload. - * varasm.c (immed_double_const): Add casts to HOST_WIDE_INT where - necessary. - (const_hash): Hash val is unsigned long. - (SYMHASH): Likewise. + * mn10200.md (truncated shift): Accept constant inputs too. - * tree.c (TYPE_HASH): Type of hash val is unsigned long. +Fri Oct 23 04:06:57 1998 Richard Earnshaw (rearnsha@arm.com) - * print-tree.c (print_node_brief): HOST_PTR_PRINTF format wants a - char pointer, not HOST_WIDE_INT. - (print_node): Likewise. Also hash is unsigned long not - HOST_WIDE_INT. + * machmode.h (mode_mask_array): No longer const. + * rtl.c (init_rtl): Fully initialize it if EXTRA_CC_MODES defined. - * cse.c (canon_hash): Hash is unsigned long not HOST_WIDE_INT. +Fri Oct 23 11:19:06 1998 Martin v. Löwis - * explow.c (optimize_save_area_alloca): New function for targets - where SETJMP_VIA_SAVE_AREA is true. - (allocate_dynamic_stack_space): On SETJMP_VIA_SAVE_AREA targets, - compute the amount of stack space needed should we find later that - setjmp is never called by this function, stuff rtl for this inside - a REG_NOTE of the final SET of stack_pointer_rtx. - * toplev.c (rest_of_compilation): If SETJMP_VIA_SAVE_AREA and - current_function_calls_alloca, call optimize_save_area_alloca. + * frame.c: Somewhat explain `FDE'. + Suggested by Brendan Kehoe -Sat Jan 17 23:22:59 1998 John Wehle (john@feith.com) +Fri Oct 23 00:56:11 1998 Jason Merrill - * i386.md: Remove redundant integer push patterns. - Don't bother checking for TARGET_PUSH_MEMORY when - pushing constants or registers. + * expr.c (pending_chain): Move up. + (save_expr_status): Do save pending_chain. + (restore_expr_status): And restore it. + * function.h (struct function): Add pending_chain. -Sat Jan 17 22:35:39 1998 Mumit Khan - J.J VanderHeijden +1998-10-23 Herman A.J. ten Brugge + + * reorg.c (relax_delay_slots): Fixed test for mostly_true_jump. The + did not match the code. + +Fri Oct 23 00:07:01 1998 Bernd Schmidt + + * regclass.c (regclass): Break out some code into new function + scan_one_insn, and into regclass_init. + (init_cost): New static variable, moved out of regclass. + (regclass_init): Initialize it here, not in . + (scan_one_insn): New static function, broken out of regclass. + * recog.c (apply_change_group): Break out some code into new + function insn_invalid_p. + (insn_invalid_p): New static fn, broken out of apply_change_group. + +Thu Oct 22 22:34:42 1998 Jim Wilson + + * reload1.c (reload_as_needed): When rewrite POST_INC, verify + reg_reloaded_contents matches incremented pseudo. + + * v850/v850.c (v850_reorg): Call alter_subreg. Delete subreg support. + +Fri Oct 23 11:11:56 1998 Michael Hayes + + * rtl.def (POST_MODIFY, PRE_MODIFY): New generalized operators for + addressing modes with side effects. These are currently + placeholders for the C4x target. + +Thu Oct 22 16:46:35 1998 Bernd Schmidt + + * loop.c (express_from): Make sure that when generating a PLUS of + a PLUS, any constant expression appears on the outermost PLUS. + +Thu Oct 22 15:46:23 1998 Per Bothner (bothner@cygnus.com) + + * Makefile.in (distdir-cvs, distdir-start): Clean up so it + works if "$(srcdir)" != ".". + +Wed Oct 21 19:23:59 1998 Jim Wilson + + * expmed.c (store_bit_field): If need to add a SUBREG, then remove + existing SUBREG if we can, otherwise abort. + +Wed Oct 21 09:58:51 1998 Mark Mitchell + + * c-common.c (c_apply_type_quals_to_decl): Don't crash when + `restrict' is applied to a non-pointer variable. + +Wed Oct 21 09:18:58 1998 Mark Mitchell + + * invoke.texi: Document -flang-isoc9x. - * pexecute.c (pexecute): New function for mingw32. Supports pipes. - (pwait): New function for mingw32. + * Makefile.in (OBJS): Add splay-tree.o. + (c-common.o): Depend on rtl.h. + (splay-tree.o): List dependencies and provide build rule. + + * rtl.h (record_alias_subset): New function. + * alias.c: Include splay-tree.h. + (alias_set_entry): New type. + (CHECK_ALIAS_SETS_FOR_CONSISTENCY): Remove. + (DIFFERENT_ALIAS_SETS_P): Use mem_in_disjoint_alias_sets_p. + (mems_in_disjoin_alias_sets_p): New function. + (alias_set_compare): Likewise. + (insert_subset_children): Likewise. + (get_alias_set_entry): Likewise. + + * tree.h (TYPE_RESTRICT): New macro. + (TYPE_UNQUALIFIED): New manifest constant. + (TYPE_QUAL_CONST): Likewise. + (TYPE_QUAL_VOLATILE): Likewise. + (TYPE_QUAL_RESTRICT): Likewise. + (tree_type): Add restrict_flag. Reduce count of free bits. + (DECL_POINTER_ALIAS_SET): New macro. + (DECL_POINTER_ALIAS_SET_KNOWN_P): Likewise. + (tree_decl): Add pointer_alias_set. + (build_qualified_type): New function. + (build_type_variant): Define in terms of build_qualified_type. + * tree.c (set_type_quals): New function. + (make_node): Initialize DECL_POINTER_ALIAS_SET. + (build_type_attribute_variant): Use build_qualified_type and + set_type_quals. + (build_type_variant): Rename, and modify, to become... + (build_qualified_type): New function. + (build_complex_type): Use set_type_quals. - * gcc.c (execute): Mingw32 pexecute() supports pipes, but cygwin32 - pipe support is broken for now. + * c-tree.h (C_TYPE_OBJECT_P): New macro. + (C_TYPE_FUNCTION_P): Likewise. + (C_TYPE_INCOMPLETE_P): Likewise. + (C_TYPE_OBJECT_OR_INCOMPLETE_P): Likewise. + (c_apply_type_quals_to_decl): New function. + (c_build_qualified_type): New function. + (c_build_type_variant): Define in terms of c_build_qualified_type. + (flag_isoc9x): Declare. + * c-typeck.c (qualify_type): Use c_build_qualified_type. + (common_type): Change to use TYPE_QUALS. + (comptypes): Likewise. + (convert_for_assignment): Likewise. + * c-aux-info.c (gen_type): Likewise. Deal with `restrict'. + * c-decl.c (flag_isoc9x): Define. + (c_decode_option): Handle -flang-isoc9x. + (grokdeclarator): Update to handle restrict. Use TYPE_QUALS, + c_build_qualified_type, etc. Use c_apply_type_quals_to_decl. + * c-lex.c (init_lex): Deal with restrict. + (init_lex): Don't treat restrict as a reserved word in + -traditional mode, or without -flang-isoc9x. + * c-lex.h (rid): Add RID_RESTRICT. + * c-parse.gperf (restrict, __restrict, __restrict__): Make + equivalent to RID_RESTRICT. + * c-parse.in (TYPE_QUAL): Update comment. + * c-common.c: Include rtl.h. + (c_find_base_decl): New function. + (c_build_type_variant): Rename, and modify, to become ... + (c_build_qualified_type): New function. + (c_apply_type_quals_to_decl): Likewise. + (c_get_alias_set): For INDIRECT_REFs, check to see if we can find + a particular alias set for the reference. + * toplev.c (documented_lang_options): Add -flang-isoc9x. -1998-01-17 Lee Iverson +Wed Oct 21 09:15:06 1998 Nick Clifton - * emit_rtl.c (init_emit_once): Ensure that potential aliasing - between frame_pointer_rtx, hard_frame_pointer_rtx, and - arg_pointer_rtx is respected in initialization. - (init_emit_once): Use gen_rtx_raw_REG() to create - return_address_pointer_rtx. + * config/arm/arm.h (TARGET_SWITCHES): Document arm specific + command line switches. - * reorg.c: #include "expr.h" for rtx prototypes. - * Makefile.in (reorg.o): Depend on expr.h +Tue Oct 20 10:04:51 1998 Graham -Sat Jan 17 21:28:08 1998 Pieter Nagel + * reload.c (loc_mentioned_in_p): Add missing braces to bind + else to correct if. - * Makefile.in (FLAGS_TO_PASS): Pass down gcc_include_dir and - local_prefix to sub-make invocations. +Mon Oct 19 16:34:05 1998 Tom Tromey -Sat Jan 17 21:24:16 1998 David T. McWherter + * gcc.c (option_map): Added --classpath and --CLASSPATH. - * objc-parse.c: Recognize protocol qualifiers in class definitions. +Tue Oct 20 10:59:02 1998 Gavin Romig-Koch -Sat Jan 17 21:16:19 1998 Jeffrey A Law (law@cygnus.com) + * regclass.c (fix_register): Add error message. + * invoke.texi (-fcall-used-REG,-fcall-saved-REG): Note the + new error message. - * rtl.h: Fix typos. +Tue Oct 20 10:12:17 1998 Kaveh R. Ghazi - * acconfig.h (NEED_DECLARATION_ATOL): New declaration to check for. - * configure.in: Check for atol. - * rtl.c (atol): Only provide the declaration if NEED_DECLARATION_ATOL. + * c-decl.c (warn_missing_noreturn): New global variable. + (c_decode_option): Check for new flags -W{no-}missing-noreturn. + (finish_function): Implement missing noreturn warning. + + * c-tree.h (warn_missing_noreturn): Declare extern. + + * invoke.texi: Document new flags. + + * toplev.c (documented_lang_options): Add description. + +Tue Oct 20 22:16:11 1998 Michael Hayes + + * config/c4x/c4x.c (c4x_parallel_process): Disable until BCT + loop optimization stable for the C4x. + (c4x_rptb_info_t, c4x_dump, c4x_rptb_in_range, c4x_rptb_unjumped_loop, + c4x_rptb_find_comp_and_jump, c4x_rptb_loop_info_get, + c4x_rptb_emit_init, c4x_rptb_process): Deleted (superseded by BCT + loop optimization). + (c4x_address_conflict): Be more paranoid when packing a volatile + memref in a parallel load/store. + +Tue Oct 20 21:56:05 1998 Michael Hayes + + * config/c4x/c4x.md (repeat_block_top, repeat_block_end, + repeat_block_filler): Deleted. + (*ashlqi3_set, *ashrqi3_const_set, *ashrqi3_nonconst_clobber): + Condition code not set if destination register from 'c' class. + (*subbqi3_carry_clobber): Fix typo. + +1998-10-18 Herman A.J. ten Brugge + + * reorg.c (steal_delay_list_from_target): Check for insns that + modify the condition codes and effect the direction of the jump + in the sequence. - * rtl.c (read_rtx): Initialize list_rtx to NULL, not NULL_RTX. +Sat Oct 17 13:09:09 1998 Graham - * loop.c (find_and_verify_loops): When attempting to move insns from - inside the loop outside the loop, create a BARRIER if no suitable - one was found. + * function.c (purge_addressof_1): Replace call to + emit_insns_before() with emit_insn_before(). - * jump.c (jump_optimize): Remove Dec 17, 1997 chance in - favor of an equivalent change from gcc-2.8. +Mon Oct 19 19:34:03 1998 Mike Stump - * i386/x-sco5 (CC): Remove trailing whitespace. + * libgcc2.c (__pure_virtual): Call __terminate instead of _exit. -Sat Jan 17 21:09:46 1998 Kaveh R. Ghazi +Mon Oct 19 13:26:24 1998 Bernd Schmidt - * gengenrtl.c (type_from_format): De-ANSIfy function signature. - (accessor_from_format): Likewise. - (xmalloc): New function for use when linking with alloca.o. + * jump.c (sets_cc0_p): Compile only if HAVE_cc0. -Mon Jan 5 02:53:01 1998 Bruno Haible +Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com) - * frame.c (find_fde): Correct FDE's upper bound. + * gcse.c (compute_hash_table): Correctly identify hard regs which are + clobbered across calls. -Fri Jan 16 16:23:52 1998 Richard Henderson + * loop.c (scan_loop): Be more selective about what invariants are + moved out of a loop. - * gengenrtl.c (DEF_RTL_EXPR): Provide a K&R compliant version. +Mon Oct 19 10:46:58 1998 Jeff Law (law@cygnus.com) -Fri Jan 16 10:16:10 1998 Jeffrey A Law (law@cygnus.com) + * version.c: Bump for snapshot. - * calls.c (expand_call): Move #ifdef code out of macro argument - lists. - (emit_library_call, emit_library_call_value): Likewise. +Mon Oct 19 11:40:56 1998 Jeffrey A Law (law@cygnus.com) -Fri Jan 16 00:46:40 1998 Jeffrey A Law (law@cygnus.com) + * libgcc2.c (eh_context_static): Do not call malloc to allocate the + static eh_context structure. - * rtl.def (INLINE_HEADER): Fix bug exposed by gen_rtx_FOO changes. +Mon Oct 19 10:45:40 1998 Bernd Schmidt -Thu Jan 15 01:02:30 1998 Jeffrey A Law (law@cygnus.com) + * combine.c (recog_for_combine): Lose PADDED_SCRATCHES arg. All + callers changed. + (try_combine): Don't update max_scratch. + * flow.c (max_scratch, num_scratch): Delete variables. + (life_analysis_1): Don't initialize max_scratch. + (propagate_block): Don't update max_scratch. + (mark_set_1): Don't increment num_scratch. + * regs.h (max_scratch): Delete declaration. - * version.c: Bump for snapshot. +Mon Oct 19 10:28:15 1998 Jeffrey A Law (law@cygnus.com) -Wed Jan 14 22:49:17 1998 Richard Henderson + * reload1.c (reload_reg_free_before_p): Hack. Return 0 if EQUIV + is nonzero. This is temporary! - * alias.c: Change all uses of gen_rtx(FOO...) to gen_rtx_FOO; - change gen_rtx(expr...) to gen_rtx_fmt_foo(expr...). - * caller-save.c, calls.c, combine.c, cse.c: Likewise. - * dwarf2out.c, except.c, explow.c, expmed.c, expr.c: Likewise. - * final.c, flow.c, function.c, genpeep.c, haifa-sched.c: Likewise. - * halfpic.c, integrate.c, jump.c, local-alloc.c, loop.c: Likewise. - * profile.c, recog.c, reg-stack.c, regclass.c, regmove.c: Likewise. - * reload.c, reload1.c, reorg.c, sched.c, stmt.c, stupid.c: Likewise. - * unroll.c, varasm.c: Likewise. - * config/alpha/alpha.c, config/alpha/alpha.md: Likewise. + * sched.c (update_flow_info): Handle death notes made invalid by + instruction splitting. Partially reverts Oct 15, 1998 patch. + * haifa-sched.c (update_flow_info): Likewise. -Wed Jan 14 19:36:08 1998 Gavin Koch (gavin@cygnus.com) +Sun Oct 18 17:31:26 1998 Jeffrey A Law (law@cygnus.com) - * mips.h: Fix some type-o's from a previous change. + * function.c (uninitialized_vars_warning): Do not warn for a VAR_DECL + if it has a nonzero DECL_INITIAL. -Wed Jan 14 01:26:05 1998 Jeffrey A Law (law@cygnus.com) +Sat Oct 17 23:18:08 1998 Kaveh R. Ghazi - * loop.c (check_dbra_loop): Make sure initial value is a - CONST_INT before trying to normalize it. + * Makefile.in (flow.o): Depend on recog.h. -Tue Jan 13 23:27:54 1998 Robert Lipe (robertl@dgii.com) + * cpplib.h (directive_table): Add missing initializiers. + (finclude): Change type of variable `bsize' to size_t. - * sco5.h (ASM_OUTPUT_SECTION_NAME): Refresh from ../svr4.h. + * cse.c (rtx_cost): Mark parameter `outer_code' with ATTRIBUTE_UNUSED. -Tue Jan 13 22:47:02 1998 Herman ten Brugge + * dwarfout.h (dwarfout_label): Wrap prototype in macro RTX_CODE. - * cppexp.c: Include gansidecl.h + * fix-header.c (lookup_std_proto): Cast the result of `strlen' to + `int' when comparing against one. + (cpp_file_line_for_message): Mark parameter `pfile' with + ATTRIBUTE_UNUSED. + (cpp_fatal): Mark parameter `pfile' with ATTRIBUTE_UNUSED. -Tue Jan 13 22:43:35 1998 Ian Lance Taylor + * flow.c: Include recog.h. + (sbitmap_copy): Cast arguments 1 & 2 of `bcopy' to (PTR). - * svr4.h (LINK_SPEC): Never specify -h. - * ptx4.h (LINK_SPEC): Likewise. - * rs6000/sysv4.h (LINK_SPEC): Likewise. - * sparc/sol2.h (LINK_SPEC): Likewise. + * function.c (thread_prologue_and_epilogue_insns): Mark parameter + `f' with ATTRIBUTE_UNUSED. + (reposition_prologue_and_epilogue_notes): Likewise. -Tue Jan 13 22:39:40 1998 Richard Henderson (rth@cygnus.com) + * genopinit.c (gen_insn): Cast argument of ctype functions to + `unsigned char'. - * c-typeck.c (comptypes): Exit early on NULL input. + * haifa-sched.c: Include recog.h. + (blockage_range): Cast result of UNIT_BLOCKED macro to (int) when + comparing against one. - * haifa-sched.c (schedule_insns): Correctly remove inter-block - dependencies after reload. + * libgcc2.a (__throw): Revert ATTRIBUTE_UNUSED change for now. -Tue Jan 13 22:22:31 1998 Franz Sirl + * mips-tfile.c (parse_end): Cast the argument of ctype function to + `unsigned char'. + (parse_ent): Likewise. + (parse_input): Likewise. - * rs6000/linux.h (CPP_PREDEFINES): Add -D__ELF__. + * optabs.c (init_libfuncs): Likewise. -Tue Jan 13 22:14:57 1998 Klaus Kaempf + * protoize.c (find_rightmost_formals_list): Likewise. - * alpha/vms.h (DIR_SEPARATOR): define + * recog.h (const_double_operand): Fix typo in prototype. -Tue Jan 13 22:13:04 1998 Bruno Haible + * tlink.c (scan_linker_output): Cast the argument of ctype + function to `unsigned char'. - * Makefile.in (stamp-proto): Remove. - (protoize.o, unprotoize.o): Straightforward compile. - * unprotoize.c: Define UNPROTOIZE here, not in the Makefile. + * toplev.c (check_lang_option): Cast the result of `strlen' to + `int' when comparing against one. -Tue Jan 13 21:59:39 1998 Mumit Khan +Sat Oct 17 13:09:09 1998 Graham - * i386/cygwin32.h (STRIP_NAME_ENCODING): Define for Win32 to strip - off the trailing @[NUM] added by ENCODE_SECTION_INFO. + * gcse.c (dump_cuid_table): Correct typo. -Tue Jan 13 21:55:06 1998 Jeffrey A Law (law@cygnus.com) +Sat Oct 17 11:02:47 1998 Nick Clifton - * arm/netbsd.h (DWARF2_UNWIND_INFO): Define as zero for now. - * i386/netbsd.h, m68k/netbsd.h, ns32k/netbsd.h: Likewise. - * sparc/netbsd.h, vax/netbsd.h: Likewise. + * toplev.c (display_help): Prepend '-m' to target specific + options. + (check_lang_option): Ignore text after end of first word of a + language specific option. + +Sat Oct 17 02:26:03 1998 Bernd Schmidt + + * reload1.c (reg_used_by_pseudo): New static variable. + (choose_reload_regs): Initialize it. + Use it instead of testing spill_reg_order to determine whether a + pseudo is live in a hard register across the current insn. + Fix a typo in a reference to reload_reg_rtx. + + * flow.c (propagate_block): Replace code that computes and uses + regs_sometimes_live with simpler code that just walks the set of + currently live registers. + + * Makefile.in (insn-extract.o): Fix dependencies. + * genextract.c (main): Generate includes for insn-config.h and + recog.h. + Delete generation of declarations which are now in recog.h. + * genrecog.c (main): Delete generation of definitions which are + now in recog.c. + * local-alloc.c (block_alloc): Use extract_insn and the variables + it sets up instead of looking up values by insn_code. + * recog.c (recog_operand, recog_operand_loc, recog_dup_loc, + recog_dup_num): Define here instead of generating the definition in + genrecog.c. + (recog_n_operands, recog_n_dups, recog_n_alternatives, + recog_operand_mode, recog_constraints, recog_operand_address_p): + New variables. + (extract_insn): New function. + * recog.h (extract_insn): Declare function. + (which_alternative, recog_n_operands, recog_n_dups, + recog_n_alternatives, recog_operand_mode, recog_constraints, + recog_operand_address_p): Declare variables. + * regclass.c (n_occurrences): New static function. + * reload.c (n_occurrences): Delete function. + (find_reloads): Use extract_insn. + * reload.h (n_occurrences): Delete declaration. + +Sat Oct 17 01:17:51 1998 Jeffrey A Law (law@cygnus.com) + + * reload1.c (reload_as_needed): Fix test for when to call + update_eliminable_offsets. + +Fri Oct 16 20:40:50 1998 J"orn Rennecke + + Fix consistency problems with reg_equiv_{mem,address}; + Improve reload inheritance; + + * reload.c (reload_out_reg): New variable. + (loc_mentioned_in_p, remove_address_replacements): New functions. + (remove_replacements): Deleted. + (push_reload): Set reload_out_reg[i]. + When merging, also set reload_{in,out}_reg[i], and remove + duplicate address reloads. + (combine_reloads): Copy reload_out_reg[i]. + (find_reloads): Do make_memloc substitution also when + reg_equiv_memory_loc[regno] and num_not_at_initial_offset + are both nonzero. + Include *recog_operand_loc in commutativity operand changes. + Generate optional output reloads. + Delete reference to n_memlocs. Don't set *recog_operand_loc before + processing operands. Call make_memloc in reg_equiv_address code. + Set *recog_operand_loc only after processing operands, and only + if replace is true. Return a value. + When changing address reload types for operands that didn't get + reloaded, use RELOAD_FOR_OPADDR_ADDRESS for + RELOAD_FOR_INPADDR_ADDRESS / RELOAD_FOR_OUTADDR_ADDRESS reloads. + Don't emit USEs for pseudo SUBREGs when not replacing. + (find_reloads_address): Do make_memloc substitution also when + reg_equiv_memory_loc[regno] and num_not_at_initial_offset + are both nonzero. + (find_reloads_toplev): Likewise. + Call make_memloc in reg_equiv_address code. + (debug_reload_to_stream): Add code to output reload_out_reg. + (make_memloc): Delete local variable i, ifdefed out code, and + references to memlocs and n_memlocs. + (memlocs, n_memlocs): Delete. + (push_secondary_reload): Clear reload_out_reg. + (find_reloads_address_1): Provide memrefloc argument to all calls + to find_reloads_address. + In AUTO_INC code, handle non-directly addressable equivalences properly. + * reload.h (reload_out_reg, num_not_at_initial_offset): Declare. + (find_reloads): Add return type. + (remove_address_replacements, deallocate_reload_reg): Declare. + * reload1.c (num_not_at_initial_offset): No longer static. + (delete_address_reloads, delete_address_reloads_1): Likewise. + (deallocate_reload_reg): New function. + (spill_reg_stored_to): New array. + (eliminate_regs): Don't substitute from reg_equiv_memory_loc. + (eliminate_regs_in_insn): Move assignments of previous_offset and + max_offset fields, and recalculation of num_not_at_initial_offset + into new static function: + (update_eliminable_offsets) . + (reload_as_needed): Call update_eliminable_offsets after calling + find_reloads. + Call forget_old_reloads_1 with contents of reloaded auto_inc + expressions if the actual addressing can't be changed to match the + auto_inc. + (choose_reload_regs): For inheritance, replace + reload_reg_free_before_p test with reload_reg_used_at_all test, and + remove stand-alone reload_reg_used_at_all test. + Use reload_out_reg to determine which reload regs have output reloads. + Treat reload_override_in more similar to inherited reloads. + Handle (subreg (reg... for inheritance. + For flag_expensive_optimizations, add an extra pass to remove + unnecessary reloads from known working inheritance. + Delete obsolete code for pseudos replaced with MEMs. + Handle inheritance from auto_inc expressions. + (emit_reload_insns): If reload_in is a MEM, set OLD to + reload_in_reg[j]. + Don't reload directly from oldequiv; if it's a pseudo with a + stack slot, use reload_in[j]. + Check that reload_in_reg[j] is a MEM before replacing reload_in + from reg_reloaded_contents. + Include non-spill registers in reload inheritance processing. + Also try to use reload_out_reg to set spill_reg_store / + reg_last_reload_reg. + In code to set new_spill_reg_store, use single_set to find out if + there is a single set. + Add code that allows to delete optional output reloads. + Add code to allow deletion of output reloads that use no spill reg. + At the end, set reload_override_in to oldequiv. + Also call delete_output_reload if reload_out_reg is equal to old + in oldequiv code. + Add code to call delete_output_reload for stores with no matching load. + Set / use spill_reg_stored_to. + Handle case where secondary output reload uses a temporary, but + actual store isn't found. + When looking for a store of a value not loaded in order to call + delete_output_reload, count_occurrences should return 0 for no + loads; but discount inherited input reloadill_reg_stored_to. + Do checks for extra uses of REG. Changed all + callers. + Use delete_address_reloads. + (reload): Take return value of find_reloads into account. + If a no-op set needs more than one reload, delete it. + (reload_reg_free_before_p): RELOAD_FOR_INPUT + can ignore RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS + for the same operand. + (clear_reload_reg_in_use): Check for other reloads that keep a + register in use. + (reload_reg_free_for_value_p): Handle RELOAD_FOR_OPERAND_ADDRESS / + RELOAD_FOR_OPADDR_ADDR. + Take into account when an address address reload is only needed + for the address reload we are considering. + (count_occurrences): Use rtx_equal_p for MEMs. + (inc_for_reload): Return instruction that stores into RELOADREG. + New argument two, IN, and rtx. Changed all callers. + (calculate_needs_all_insns, reload_as_needed): + Don't clear after_call for a CLOBBER. + Keep track of how many hard registers need to be copied from + after_call, and don't clear after_call before we have seen + that much copies, or we see a different instruction. + +Fri Oct 16 10:58:23 1998 Jeffrey A Law (law@cygnus.com) + + * flow.c (find_basic_blocks_1): Do not delete unreachable blocks + after reload has completed. + +Fri Oct 16 17:26:10 1998 Dave Brolley + + * cpplib.c (cpp_get_token): Replace whitespace that occurs between + a macro name and the next token with a single blank if that whitespace + is in a macro buffer and the next token is not '('. + +Fri Oct 16 15:44:02 1998 Dave Brolley + + * cccp.c (rescan): Handle multibyte characters ending in backslash. + (rescan): Likewise. + (skip_if_group): Likewise. + (skip_to_end_of_comment): Likewise. + (macarg1): Likewise. + (discard_comments): Likewise. + (change_newlines): Likewise. + +Fri Oct 16 15:26:24 1998 Dave Brolley + + * c-lex.c (yylex): Fix unaligned access of wchar_t. + +Fri Oct 16 10:47:53 1998 Nick Clifton + + * config/arm/arm.h (TARGET_SWITCHES): Add --help documentation. + (TARGET_OPTIONS): Add --help documentation. + +Fri Oct 16 11:49:01 1998 Kaveh R. Ghazi + + * rtl.h (sets_cc0_p): Revert Oct 14 ATTRIBUTE_NORETURN change. + +Fri Oct 16 07:08:46 1998 Bruce Korb + + * fixinc/* Moved in from ../contrib directory in preparation + for integrating it into the normal build process. In particular, + fixinc/Makefile.in must be config-ed into the build directory + as fixinc/Makefile. Proposed patches to ./Makefile.in and + ./configure.in will be "in the mail" momentarily. + +Fri Oct 16 08:13:46 1998 David S. Miller + + * cse.c (cse_basic_block): Fixup hash flushing loop so we do not + accidently walk into the free list. Comment how that can happen. + (invalidate): Fix indentation. + +Thu Oct 15 23:53:29 1998 Bernd Schmidt + Jeffrey A Law (law@cygnus.com) -Tue Jan 13 21:37:07 1998 Shigeya Suzuki + * flow.c (life_analysis_1): Do not clobber regs_ever_live after + reload. Never perform rescans of the insn chain after reload. + (propagate_block): Do not delete insn or create new autoinc addressing + modes after reload. - * i386/bsd386.h (DWARF2_UNWIND_INFO): Define as zero for now. + * jump.c (jump_optimize): Unconditionally use the code that was + previously conditional on PRESERVE_DEATH_INFO_REGNO_P. + * reload1.c (reload): When reloading is finished, delete all + REG_DEAD and REG_UNUSED notes. + (emit_reload_insns): Delete all code that was conditional on + PRESERVE_DEATH_INFO_REGNO_P. + (no_longer_dead_regs): Delete variable. + (reload_cse_delete_death_notes): Delete function. + (reload_cse_no_longer_dead): Delete function. + (reload_cse_regs_1): Delete all code to handle deletion of death + notes. + (reload_cse_noop_set_p): Likewise. + (reload_cse_simplify_set): Likewise. + (reload_cse_simplify_operands): Likewise. + (reload_cse_move2add): Likewise. + * reorg.c (used_spill_regs): Delete declaration. + (max_label_num_after_reload): Delete declaration. + (find_dead_or_set_registers): Don't assume that spill regs are + dead at a CODE_LABEL. + * rtlanal.c (dead_or_set_regno_p): Death notes are always accurate, + even after reload. + * sched.c (sched_analyze_insn): Likewise. + (update_flow_info): Likewise. + * haifa-sched.c (sched_analyze_insn): Likewise. + (update_flow_info): Likewise. + * tm.texi (PRESERVE_DEATH_INFO_REGNO_P): Delete documentation. + * toplev.c (max_label_num_after_reload): Delete variable. + (rest_of_compilation): Don't set max_label_num_after_reload. + Call life_analysis after reload_cse_regs if optimizing. + * config/gmicro/gmicro.h: Delete comment referring to + PRESERVE_DEATH_INFO_REGNO_P. + * config/i386/i386.h: Likewise. + * config/m88k/m88k.h: Likewise. + * config/m32r/m32r.h (PRESERVE_DEATH_INFO_REGNO_P): Delete definition. + * config/sh/sh.h: Likewise. -Tue Jan 13 17:50:55 1998 Jim Wilson +Thu Oct 15 19:48:41 1998 David Edelsohn - * configure.in (target_cpu_default, target_cpu_default2): Use double - quotes around them when testing their value. - * configure: Rebuilt. + * loop.c (strength_reduce): Restore marking bct_p as + ATTRIBUTE_UNUSED. + * rs6000.c (optimization_options): Change #ifdef HAIFA to + HAVE_decrement_and_branch_on_count. + (small_data_operand): Remove TARGET_ELF condition for marking + parameters ATTRIBUTE_UNUSED. -Tue Jan 13 09:07:44 1998 John Carr +Thu Oct 15 11:45:51 1998 Robert Lipe - * gengenrtl.c (gencode): Emit new function obstack_alloc_rtx - to allocate rtx. - (gendef): Call obstack_alloc_rtx. + * config/i386/sco5.h (MAX_OFILE_ALIGNMENT): Define. + (SELECT_SECTION): Resync with svr4.h. -Tue Jan 13 01:16:36 1998 Robert Lipe (robertl@dgii.com) +Thu Oct 15 12:42:13 1998 David Edelsohn - * configure.in: (i[3456]86-UnixWare7-sysv5): Treat much like SVR4 - for now. + * loop.c (strength_reduce): Undo Oct 14 change marking bct_p + ATTRIBUTE_UNUSED. -Thu Dec 18 18:40:17 1997 Mumit Khan +Thu Oct 15 00:57:55 1998 Robert Lipe - * i386/mingw32.h (INCOMING_RETURN_ADDR_RTX): Delete. Use the value - of DWARF2_UNWIND_INFO, if any, from i386/cygwin32.h instead. - (STANDARD_INCLUDE_DIR): Change to /usr/local/i386-mingw32/include. + * c-pragma.c (handle_pragma_token): Test for null tree before + dereferencing TREE_CODE. -Tue Jan 13 00:44:02 1998 Jim Wilson +Thu Oct 15 17:36:48 1998 Michael Hayes - * mips.md (return_internal): Change mode from SImode to VOIDmode. + * config/c4x/c4x.c: Convert to use GEN_INT. + (c4x_parallel_process): Rework to handle new repeat loop structure. -Sat Jan 10 22:11:39 1998 J. Kean Johnston + * config/c4x/c4x.md: Convert to use GEN_INT. + (rptb_end): Convert to use GE test. Replace uses with clobbers. + (decrement_and_branch_on_count): Likewise. - * i386/sco5.h (STARTFILE_SPEC, ENDFILE_SPEC): Correctly handle - "-static". + * config/c4x/c4x.h (REPEAT_BLOCK_PROCESS): Deleted hook now that + loop.c has the desired functionality. + (rc_reg_operand): New prototype. -Sat Jan 10 22:04:15 1998 Stan Cox + * config/c4x/t-c4x: Can now build all front ends. - * i386.md: (movsicc_1, movhicc_1): For alternate 3 set the opcode - suffix from operand 3. +Wed Oct 14 23:27:08 1998 Didier FORT (didier.fort@fedex.com) -Sat Jan 10 21:50:16 1998 J"orn Rennecke - Jeffrey A Law (law@cygnus.com) + * fixincludes: Fix up rpc/{clnt,svr,xdr}.h for SunOS. - * regmove.c: New implementation of regmove pass. - * local-alloc.c (optimize_reg_copy_1, optimize_reg_copy_2): Remove - decls, make them have external linkage. Return a value from - optimize_reg_copy_1. - * reload.h (count_occurrences): Add decl. - * reload1.c (count_occurrences): Delete decl, make it have external - linkage. - * rtl.h (optimize_reg_copy_1, optimize_reg_copy_2): Declare. +Wed Oct 14 22:13:28 1998 Joel Sherrill (joel@OARcorp.com) -Sat Jan 10 20:30:12 1998 Jeffrey A Law (law@cygnus.com) + * Makefile.in (stmp-fixinc): Do not install assert.h if not desired. + * config/t-rtems: Do not install assert.h -- use newlib's. - * regclass.c (record_address_regs): Don't use REG_OK_FOR_BASE_P - if it is not defined. +Wed Oct 14 21:57:08 1998 J"orn Rennecke -Thu Jan 8 21:06:54 1998 Richard Henderson + * combine.c (combine_instructions): When finished, call init_recog. + * regmove.c (optimize_reg_copy_3): Reject volatile MEMs. - * Makefile.in (OBJ, GEN, RTL_H): Add genrtl.[oh] bits. - * emit-rtl.c (gen_rtx): Move special code to ... - (gen_rtx_CONST_INT): New function. - (gen_rtx_REG): New function. - (*): Update all calls to gen_rtx. - * genemit.c (gen_exp): Emit calls to gen_rtx_FOO for constant FOO. - * rtl.h: Include genrtl.h; prototype CONST_INT & REG generators. - (GEN_INT): Call gen_rtx_CONST_INT. - * gengenrtl.c: New file. +Wed Oct 14 16:10:22 1998 Per Bothner -Mon Jan 5 13:00:18 1998 John F. Carr + * toplev.c: If flag_syntax_only, don't open or write assembler file. - * alias.c (*_dependence): Call base_alias_check before canon_rtx. - (base_alias_check): If no base found for address call canon_rtx and - try again. +Wed Oct 14 13:26:05 1998 Kaveh R. Ghazi -Mon Jan 5 11:39:49 1998 Jeffrey A Law (law@cygnus.com) + * cppalloc.c (memory_full): Mark function prototype with + ATTRIBUTE_NORETURN. - * mips.c (mips_expand_prologue): Handle large frame with no outgoing - arguments for mips16. - (mips_expand_epilogue): Pass "orig_tsize" to save_restore_insns. - Don't lose if tsize is zero after handling large stack for mips16. - * mips.md (return): For trivial return, return address is in $31. + * demangle.h (collect_exit): Likewise. -Sun Jan 4 20:24:00 1998 Nigel Stephens + * fix-header.c (v_fatal, fatal): Likewise. - * mips/mips16.S: Various changes to make it work with -msingle-float - and -EL. + * gcc.c (pfatal_with_name, pfatal_pexecute, fatal, fancy_abort): + Likewise. -Sun Jan 4 14:25:18 1998 Gavin Koch - Ian Lance Taylor - Jeff Law + * gcov.c (print_usage): Likewise. - * mips.c, mips.h, mips.md: First cut at merging in mips16 - support. Major modifications throughout all three files. + * genattr.c (fatal, fancy_abort): Likewise. -Sun Jan 4 01:01:50 1998 scott snyder + * genattrtab.c (fatal, fancy_abort): Likewise. - * configure.in: Make gthr-default.h a forwarding header instead of - a symlink. + * gencodes.c (fatal, fancy_abort): Likewise. -Sat Jan 3 12:08:06 1998 Kaveh R. Ghazi + * genconfig.c (fatal, fancy_abort): Likewise. - * gcov-io.h: Include sys/types.h to ensure we get size_t. + * genemit.c (fatal, fancy_abort): Likewise. - * pa.h (ASM_OUTPUT_MI_THUNK): Add missing % in fprintf. + * genextract.c (fatal, fancy_abort): Likewise. -Fri Jan 2 23:40:09 1998 Jim Wilson (wilson@cygnus.com) - Jeffrey A Law (law@cygnus.com) + * genflags.c (fatal, fancy_abort): Likewise. - * crtstuff.c (__frame_dummy): New function for irix6. - (__do_global_ctors): Call __frame_dummy for irix6. - * iris6.h (LINK_SPEC): Hide __frame_dummy too. + * genopinit.c (fatal, fancy_abort): Likewise. -Fri Jan 2 04:57:57 1998 Weiwen Liu + * genoutput.c (fatal, fancy_abort): Likewise. - * alpha.c (vms_valid_decl_attribute_p): Move within #if OPEN_VMS. + * genpeep.c (fatal, fancy_abort): Likewise. -Fri Jan 2 04:34:14 1998 Richard Henderson + * genrecog.c (fatal, fancy_abort): Likewise. - * c-decl.c (init_decl_processing): Provide proper fallback symbol - for __builtin_memset. - * expr.c (expand_builtin) [MEMSET]: Arg 3 type code is INTEGER_TYPE - not INTEGER_CST. Assert arg 3 is a constant. + * libgcc2.c (__eprintf, __default_terminate, __sjthrow, + __sjpopnthrow, __throw): Likewise. - * alpha.c (mode_width_operand): Accept 64-bit modes. - (mode_mask_operand): Likewise. - (print_operand): Likewise for 'M' and 'U' codes. - (alpha_expand_unaligned_load): New function. - (alpha_expand_unaligned_store): Likewise. - (alpha_expand_unaligned_load_words): Likewise. - (alpha_expand_unaligned_store_words): Likewise. - (alpha_expand_block_move): Likewise. - (alpha_expand_block_clear): Likewise. - * alpha.h (MOVE_RATIO): New define. - * alpha.md (extxl, ext*h, ins*l, mskxl): Name them. - (insql, insxh, mskxh, extv, extzv, insv, movstrqi, clrstrqi): New. + * objc/objc-act.c (objc_fatal): Likewise. - * alpha.h (ASM_OUTPUT_LOOP_ALIGN, ASM_OUTPUT_ALIGN_CODE): Set to 3. - (CONSTANT_ALIGNMENT, DATA_ALIGNMENT): Disable. + * protoize.c (usage, aux_info_corrupted, + declare_source_confusing): Likewise. -Thu Jan 1 15:40:15 1998 Richard Henderson + * rtl.c (dump_and_abort): Likewise. - * configure.in: Put parenthesis around TARGET_CPU_DEFAULT's value. - * configure: Update. + * rtl.h (sets_cc0_p): Likewise. -Thu Jan 1 10:49:12 1998 Jeffrey A Law (law@cygnus.com) + * toplev.c (float_signal, pipe_closed): Likewise. - * emit-rtl.c (operand_subword): Correctly handle extracting a word - from a CONST_DOUBLE for 16bit targets with !WORDS_BIG_ENDIAN. +1998-10-14 Andreas Schwab - * mn10200.md (tstxx, cmpxx): Use "nonimmediate_operand" as predicate - for first argument. + * dwarf2out.c (expand_builtin_dwarf_reg_size): Look at all ranges + when generating the decision tree for the general case. -Wed Dec 31 14:42:18 1997 Ian Lance Taylor + * config/m68k/m68k.h (HARD_REGNO_MODE_OK): Don't accept modes + wider that 12 bytes in fpu regs or wider than 8 byte in fpa regs. - * configure.in: Set and subsitute host_exeext. Use it when creating - the assembler and linker symlinks. - * configure: Rebuild. - * Makefile.in (exeext): Set to @host_exeext@. - (build_exeext): New variable, set to @build_exeext@. - (FLAGS_TO_PASS): Pass down build_exeext. - (STAGESTUFF): Use build_exeext, not exeext, for gen* and bi* - programs. +Wed Oct 14 11:14:02 1998 Kaveh R. Ghazi -Wed Dec 31 10:05:44 1997 Jeffrey A Law (law@cygnus.com) + * Makefile.in (sched.o): Depend on recog.h. - * mn10200.md (addsi3, subsi3): Fix thinkos. + * alias.c (REG_BASE_VALUE): Cast the result of REGNO() macro to + (unsigned) when comparing against one. + (find_base_value): Likewise. + (record_base_value): Cast variable `regno' to (unsigned) when + comparing against one. Cast the result of REGNO() macro to + (unsigned) when comparing against one. + (memrefs_conflict_p): Change type of variables `r_x' and `r_y' to + unsigned. + (init_alias_analysis): Add unsigned variable `ui'. Use it as loop + variable where an unsigned index is needed. -Tue Dec 30 00:04:49 1997 Richard Henderson + * caller-save.c (init_caller_save): Cast `-1' to (enum insn_code) + before comparing against one. - * sparc.h (ASM_OUTPUT_MI_THUNK): Move %o7 through %g1 instead of - save+restore. Fix pic+big_offset delay slot. Use "pic" case for - unix always, since we want to be able to thunk to functions in a - shared library from an application. + * collect2.c: Add prototypes for functions `error', `fatal' and + `fatal_perror'. Make these functions take variable arguments + instead of faking it with a fixed number of args. + (write_c_file_stat): Cast the argument of ctype macro to (unsigned + char). -Mon Dec 29 14:37:31 1997 Ian Lance Taylor + * combine.c (can_combine_p): Mark parameter `pred' with + ATTRIBUTE_UNUSED. + (find_split_point): Cast variable `src' to (unsigned + HOST_WIDE_INT) when comparing against one. + (simplify_rtx): Cast 1 to (unsigned HOST_WIDE_INT) in shift. + (simplify_logical): Likewise. + (force_to_mode): Cast result of INTVAL() macro to (unsigned + HOST_WIDE_INT) when comparing against one. Cast 1 to (unsigned + HOST_WIDE_INT) in shift. + (simplify_and_const_int): Cast result of INTVAL() macro to + `unsigned HOST_WIDE_INT' when comparing against one. + (merge_outer_ops): Cast variable const0 to `unsigned + HOST_WIDE_INT' when comparing against the result of + GET_MODE_MASK() macro. + (simplify_comparison): Likewise for variable `c0'. Cast variable + `const_op' to `unsigned HOST_WIDE_INT' when comparing against + one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast the + result of `GET_MODE_MASK()/2' to `HOST_WIDE_INT' when comparing + against one. Cast `1' to `unsigned HOST_WIDE_INT' in shift. Cast + result of INTVAL() macro to `unsigned HOST_WIDE_INT' when + comparing against one. + (distribute_notes): Wrap variable `cc0_setter' in macro `HAVE_cc0'. + + config/mips/mips.c (gen_int_relational): Cast result of INTVAL() + macro to `unsigned HOST_WIDE_INT' when comparing against one. + (output_block_move): Cast `sizeof' expression to (int) when + comparing against one. + (function_arg): Cast BITS_PER_WORD to `unsigned' when comparing + against one. + (save_restore_insns): Cast `base_offset' to `long' to match format + specifier in fprintf. + + * config/mips/mips.h (Pmode): Cast the result of `Pmode' macro + to `enum machine_mode'. + + * flow.c (life_analysis_1): Remove unused variable `insn'. + + * gcc.c (translate_options): Move variables `j' and `k' into the + scope in which they are used. Change their types to `size_t'. + (set_spec): Cast the argument of ctype macro to `unsigned char'. + (read_specs): Likewise. + (process_command): Cast `sizeof' to (int) when comparing against one. + (do_spec_1): Cast the argument of ctype macro to `unsigned char'. + (handle_braces): Cast both sides of `==' expression to `long' to + ensure sign matching. + (main): Cast variable `i' to `int' when comparing against one. + + * gcov-io.h (__fetch_long): Change type of parameter `bytes' from + int to size_t. Cast variable `i' to size_t when comparing against + one. + + * genattrtab.c (convert_set_attr_alternative): Remove unused + parameter `insn_code'. All callers changed. + (convert_set_attr): Likewise. + + * genrecog.c (add_to_sequence): Cast result of XVECLEN() macro to + size_t when comparing against one. Likewise for variable `len'. + + * global.c (global_alloc): Cast variable `max_regno' to size_t + when comparing against one. Likewise for variable `max_allocno'. + + * jump.c (sets_cc0_p): Mark parameter `x' with ATTRIBUTE_UNUSED. + + * local-alloc.c (validate_equiv_mem_from_store): Mark parameter + `set' with ATTRIBUTE_UNUSED. + (find_free_reg): Cast `sizeof' expression to (int) when comparing + against one. + + * loop.c (count_loop_regs_set): Remove unused variable `dest'. + (strength_reduce): Mark parameter `bct_p' with ATTRIBUTE_UNUSED. + (get_condition): Cast variable `const_val' to `unsigned + HOST_WIDE_INT' when comparing against one. Cast unsigned + expression to HOST_WIDE_INT when comparing against one. + (insert_loop_mem): Mark parameter `data' with ATTRIBUTE_UNUSED. + (load_mems_and_recount_loop_regs_set): Cast variable `nregs' to + `unsigned' when comparing against one. + + * protoize.c (is_id_char): Change type of parameter `ch' to + unsigned char. + (munge_compile_params): Cast argument of ctype macro to (const + unsigned char). + (process_aux_info_file): Cast variable `aux_info_size' to int when + comparing against one. + (forward_to_next_token_char): Cast argument of ctype macro to + `const unsigned char'. + (edit_formals_lists): Likewise. + (find_rightmost_formals_list): Likewise. + (add_local_decl): Likewise. + (add_global_decls): Likewise. + (edit_fn_definition): Likewise. + (do_cleaning): Likewise. + (scan_for_missed_items): Likewise. + (edit_file): Cast variable `orig_size' to (int) when comparing + against one. + (main): Cast argument of ctype macro to `const unsigned char'. + + * recog.c (const_int_operand): Mark parameter `mode' with + ATTRIBUTE_UNUSED. - * mips/t-ecoff (CROSS_LIBGCC1): Define to libgcc1-asm.a. - (LIB1ASMSRC, LIB1ASMFUNCS): Define. + * regclass.c (record_reg_classes): Change type of variable `c' to + `unsigned char'. Cast `char' array index to `unsigned char'. + + * reload.c (push_secondary_reload): Cast argument to + REG_CLASS_FROM_LETTER() macro to `unsigned char'. + + * reload1.c (calculate_needs): Cast `char' array index to + `unsigned char'. + (set_label_offsets): Change type of variable `i' to unsigned int. + Cast result of XVECLEN() macro to unsigned when comparing against + one. + (mark_not_eliminable): Change type of variable `i' to unsigned. + (order_regs_for_reload): Likewise. Cast `max_regno' to unsigned + when comparing against one. + (reload_as_needed): Cast macro NUM_ELIMINABLE_REGS to (int) when + comparing against one. + (choose_reload_regs): Hide unused label `fail'. + (reload_cse_simplify_operands): Cast `char' array index to + `unsigned char'. + (reload_combine_note_store): Mark parameter `set' with + ATTRIBUTE_UNUSED. Cast UNITS_PER_WORD to unsigned when comparing + against one. + (reload_cse_move2add): Remove unused variable `src2'. + + * sched.c: Include recog.h. + (sched_note_set): Remove unused parameter `b'. All callers + changed. + (split_hard_reg_notes): Likewise for parameter `orig_insn'. + (blockage_range): Cast result of UNIT_BLOCKED() macro to (int) + when comparing against one. -Mon Dec 29 14:03:38 1997 Jeffrey A Law (law@cygnus.com) + * stupid.c (stupid_find_reg): Mark parameter `changes_size' with + ATTRIBUTE_UNUSED. Cast `sizeof' expression to (int) when + comparing against one. - * expr.c (expand_expr): For {BITFIELD,COMPONENT,ARRAY}_REF, if the - offset's mode is not ptr_mode, convert it. + * unroll.c (precondition_loop_p): Remove unused parameter + `loop_end'. All callers changed. -Mon Dec 29 15:58:18 1997 Michael Meissner +Tue Oct 13 22:12:11 1998 Bernd Schmidt - * libgcc2.c (inhibit_libc): Don't define inhibit_libc when cross - compiling if it was already defined. + * reload1.c (maybe_fix_stack_asms): New static function. + (reload): Call it. -Sun Dec 28 00:32:16 1997 Jeffrey A Law (law@cygnus.com) + * reload.h (compute_use_by_pseudos): Declare. - * flow.c (find_basic_blocks): Don't create a new basic block - for calls in a LIBCALL block. + * reload1.c (spilled_pseudos, insns_need_reload): New variables. + (something_needs_reloads): Delete variable. + (finish_spills): New function. + (compute_use_by_pseudos): New function. -Sun Dec 28 00:30:24 1997 David Edelsohn + (delete_caller_save_insns): Lose argument FIRST. All callers changed. + Use the reload_insn_chain instead of walking the rtl directly. - * config/fp-bit.c (L_df_to_sf): Fix typo in last change. + (reload): Allocate and free spilled_pseudos. + Ensure that all calls of spill_hard_reg are followed by a call to + finish_spills. + Use the insns_need_reload list instead of something_needs_reloads + to find out if reload_as_needed must be called. + Clear unused_insn_chains at the end. -Sat Dec 27 22:43:12 1997 Jeffrey A Law (law@cygnus.com) + (calculate_needs_all_insns): Lose FIRST parameter. All callers + changed. + Delete code to keep track of current basic block. + Walk reload_insn_chain instead of the rtl structure. Build the + insns_need_reload chain. + Remember which insns need reloading/elimination by setting the + appropriate fields in struct insn_chain, not by putting modes on the + insn. + + (calculate_needs): Lose THIS_BLOCK arg. Accept arg CHAIN instead of + arg INSN. All callers changed. + Delete declaration of struct needs. + Don't set something_needs_reloads. + Record insn needs in the CHAIN argument. + + (spill_hard_reg): Record the affected pseudos in spilled_pseudos. + + (reload_as_needed): Lose FIRST arg. All callers changed. + Walk the reload_insn_chain instead of the rtx structure. + Delete code to keep track of current basic block. + Rename one of the NEXT variables to OLD_NEXT. + + (allocate_reload_reg): Accept arg CHAIN instead of arg INSN. All + callers changed. + (choose_reload_regs): Likewise. - * cse.c (rtx_cost): Remove conflicting default case. + (emit_reload_insns): Replace INSN and BB args with arg CHAIN. All + callers changed. -Sat Dec 27 21:20:02 1997 Richard Henderson + * caller-save.c (MOVE_MAX_WORDS): New macro. Use it throughout + instead of (MOVE_MAX / UNITS_PER_WORD) computation. + (hard_regs_live, hard_regs_need_restore): Delete variables. + (n_regs_saved): Now static. + (referenced_regs, this_insn_sets): New variables. - * configure.in: Move default enabling of Haifa out of for loop. - * configure: Rebuild. + (setup_save_areas): Restructure the code a bit. -Thu Dec 25 01:02:54 1997 Jeffrey A Law (law@cygnus.com) + (restore_referenced_regs): Delete function. + (mark_referenced_regs): New function, similar to the old + restore_referenced_regs, but mark registers in referenced_regs. - * version.c: Bump for snapshot. + (clear_reg_live): Delete function. + (mark_set_regs): Renamed from set_reg_live. All callers changed. + Only mark registers in this_insn_sets. -1997-12-25 Teemu Torma + (save_call_clobbered_regs): Rework this function to walk the + reload_insn_chain instead of using the list of instructions directly. + Delete code to keep track of register lives, compute live regs on the + fly from information in the chain. + Instead of calling restore_referenced_regs, use mark_referenced_regs, + then walk the set it computes and call insert_restore as appropriate. - * Makefile.in (GTHREAD_FLAGS): New var. - (LIBGCC2_CFLAGS): Added $(GTHREAD_FLAGS). - (distclean): Remove gthr-default.h. + (insert_restore): Lose INSN and BLOCK args. Add CHAIN arg. All + callers changed. + Restructure the code a bit. Test hard_regs_saved instead of + hard_regs_need_restore. + (insert_save): Lose INSN and BLOCK args. Add CHAIN and TO_SAVE + args. All callers changed. + Restructure the code a bit. Use TO_SAVE to determine which regs to + save instead of more complicated test. + (insert_one_arg): Lose INSN and BLOCK args. Add CHAIN arg. All + callers changed. + Create a new insn_chain structure for the new insn and place it + into the chain. - * configure.in: Accept dce as a thread package. - Check for thread.h and pthread.h. - Link gthr-default.h to appropriate thread file and set - gthread_flags. - (hppa1.1-*-hpux10*): If --enable-threads, use dce threads and - include multilib definitions from pa/t-dce-thr. - (sparc-*-solaris2*): Enable threads by default, if thread.h or - pthread.h is found, preferring posix threads over solaris ones. + * rtl.texi: Update documentation to reflect that reload no longer + puts modes on the insns. - * config/pa/t-dce-thr: New file. - * config/pa/t-pa: Removed multilibs. - * config/sparc/t-sol2: Ditto. +1998-10-14 Andreas Schwab - * gthr.h: New file. - * gthr-single.h: New file. - * gthr-posix.h: New file. - * gthr-solaris.h: New file. - * gthr-dce.h: New file. - * libgcc-thr.h: Removed. - * objc/thr-dce.c: New file copied from thr-decosf1.c. + * function.c (purge_addressof_1): Force the first argument of a + CALL insn to memory. - * frame.c: Include gthr.h instead of libgcc-thr.h. - * libgcc2.c: Include gthr.h instead of libgcc-thr.h. - (eh_context_initialize): If __gthread_once fails, use static eh - context. - (eh_context_free): Call __gthread_key_dtor. +Wed Oct 14 00:38:40 1998 Jeffrey A Law (law@cygnus.com) -Wed Dec 24 23:33:17 1997 Jeffrey A Law (law@cygnus.com) + * rtl.h: Delete duplicate prototypes. Add some missing + prototypes. + * rtlanal.c (for_each_rtx): Formatting tweak. - * expr.h (MUST_PASS_IN_STACK): Allow target port to override. +1998-10-13 Herman A.J. ten Brugge -Wed Dec 24 23:12:14 1997 Jim Wilson + * real.c (emdnorm and etoasc): Disable round to even for c4x target + to be compatible with TI compiler. - * cse.c (max_insn_uid): New variable. - (cse_around_loop): Use max_insn_uid. - (cse_main): Set max_insn_uid. + * Makefile.in (USER_H): Add va-c4x.h to definition. - * abi64.h (LONG_MAX_SPEC): Check MIPS_ABI_DEFAULT and TARGET_DEFAULT, - and define __LONG_MAX__ appropriately. Add support for -mabi=X, - -mlong64, and -mgp{32,64} options. - * mips.c (mips_abi): Change type to int. - * mips.h (enum mips_abi_type): Delete. - (ABI_32, ABI_N32, ABI_64, ABI_EABI): Define as constants. - (mips_abi): Change type to int. +Tue Oct 13 23:03:37 1998 Richard Henderson -Wed Dec 24 22:38:34 1997 John Carr + * function.c (purge_addressof_1): Fix typo in inequality: do + bitfield optimization for equal mode sizes. + * expmed.c (store_bit_field): Don't take subregs of subregs in + the movstrict case. Tidy a potential problem in the multi-word case. + (extract_bit_field): Likewise. - * flags.h, toplev.c, calls.c, alias.c: Remove flag_alias_check; - optimization is now always enabled. +Tue Oct 13 22:12:11 1998 Bernd Schmidt - * calls.c (expand_call): Recognize C++ operator new as malloc-like + * flow.c (find_basic_blocks): Emit NOPs after normal calls in this function. + Compute max_uid_for_flow by calling get_max_uid after the scan. + (find_basic_blocks_1): Don't emit NOPs here. - * alias.c (memrefs_conflict_p): Eliminate tests now done by - base_alias_check. - (*_dependence): Call canon_rtx before base_alias_check. - (init_alias_once): New function to precompute set of registers which - can hold Pmode function arguments. - - * rtl.h: Declare init_alias_once. - - * toplev.c (compile_file): Call init_alias_once. - -Wed Dec 24 22:34:55 1997 Jeffrey A Law (law@cygnus.com) - - * tree.c (restore_tree_status): Do not dereference a null pointer. - -Tue Dec 23 12:56:46 1997 Paul Eggert : - - * genattrtab.c (main): Check HAVE_{G,S}ETRLIMIT in addition to - RLIMIT_STACK. This maintains consistency with the recent, similar - patch to cccp.c and toplev.c. - -Tue Dec 23 05:17:28 1997 Richard Henderson - - * genattrtab.c (expand_units): For large nr opclasses, expand - function_units_used with ORX to prevent blowups. Tag with FFS. - (num_unit_opclasses): New variable. - (gen_unit): Update it. - (enum operator): Add ORX_OP. - (operate_exp): Treat ORX as or, except don't expand across an if. - Reuse number rtx's after operating on them. - (check_attr_value): Accept IOR, AND, & FFS. - (write_test_expr): Transmute `in_comparison' to `flags'. Allow - for attribute value caching. Handle CONST_STRING, IF_THEN_ELSE. - (write_expr_attr_cache, write_toplevel_expr): New functions. - (write_attr_get): Handle FFS-tagged expressions. - (make_canonical): Don't expand const attributes. - (convert_const_symbol_ref): Dike out. - (evaluate_eq_attr): Handle SYMBOL_REF. - (main): Don't emit get_attr_foo for const attributes. - - * alpha.c (override_options): Reinstate PROCESSOR_EV6. - (alpha_adjust_cost): Add EV6 tuning; streamline EV5 tests. - * alpha.h (REGISTER_MOVE_COST): Increase ftoi/itof cost slightly. - * alpha.md: Redo all of the scheduling, adding EV6 support, and - combining function units where possible. - (attr "type"): Split loads, stores, cmov into int/fp. Combine - multiplies and divides. Add EV6 sqrt, ftoi, itof. - (attr "opsize"): New attribute. - (sqrtsf2-1, sqrtdf2-1): Provide proper TP_INSN patterns. - (movsf2-[12], movdf2-[12]): Provide CIX varients; don't allow CIX - to control register allocation. - (movsi2-1, movdi2-1): Likewise. - -Tue Dec 23 03:53:21 1997 Richard Henderson - - * alpha.h (CPP_PREDEFINES, LIB_SPEC, LINK_SPEC, STARTFILE_SPEC, - MD_STARTFILE_PREFIX, ASM_FILE_START, ASM_SPEC, ASM_FINAL_SPEC): - Move OSF/1 specific defines out. - * alpha/elf.h (TARGET_VERSION, CPP_PREDEFINES, DEFAULT_VTABLE_THUNKS): - Move Linux specific defines out. - (LINK_SPEC): Genericize. - (ASM_FILE_START): Emit .arch if using more than the base insn set. - (ASM_OUTPUT_SOURCE_LINE): Remove; identical to alpha.h version. - (SDB_DEBUGGING_INFO): Remove; gas can't handle it. - (HANDLE_SYSV_PRAGMA): Define. - * alpha/osf.h: New file. - * alpha/linux.h: Split. Retain file-format independant defines. - Import Linux bits from elf.h. - (CPP_PREDEFINES): Take a file-format specific SUB_CPP_PREDEFINES - (FUNCTION_PROFILER): _mcount takes its address in $28. - (MD_EXEC_PREFIX, MD_STARTFILE_PREFIX): Remove undef. - * alpha/linux-ecoff.h: New file. - * alpha/linux-elf.h: New file. - * alpha/vms.h (LIB_SPEC, LINK_SPEC): Copy from osf.h. - * alpha/win-nt.h (TARGET_DEFAULT): Define. - * configure.in (alpha*-*-osf*, alpha*-*-linux*) [tm_file]: - Add new headers as appropriate. - - * configure.in (alpha*): Enable Haifa by default. - (*-*-winnt3*): Change to winnt*, since we're not v3 specific. - * configure: Rebuild. +Tue Oct 13 22:05:49 1998 Richard Henderson -Tue Dec 23 03:14:54 1997 Richard Henderson + * alias.c (base_alias_check): Accept new args for the modes of the + two references. Use them to determine if an AND can overlap. Update + all callers. + (memrefs_conflict_p): Assume sizes are aligned, and uses them + to determine if an AND can overlap. - * Makefile.in (clean): Remove the stages with their objects here ... - (distclean): ... instead of here. +Tue Oct 13 17:51:04 1998 Jim Wilson -Mon Dec 22 11:24:01 1997 Kaveh R. Ghazi + * config/m68k/m68k.h (HARD_REGNO_MODE_OK): For FP regs, add REGNO >= 16 + check. Add comment to document problems with TARGET_SUN_FPA version + of this macro. + * config/m68k/m68k.md (movxf+1): Support 'r'/'r' moves. - * cse.c (rtx_cost): Add default case in enumeration switch. - * fix-header.c (recognized_macro): Likewise. - (recognized_extern): Likewise. - (write_rbrac): Likewise. - * objc/objc-act.c (encode_aggregate): Likewise. - (gen_declarator): Likewise. - (gen_declspecs): Likewise. +Tue Oct 13 17:46:18 1998 Kaveh R. Ghazi -Mon Dec 22 09:58:51 1997 Jeffrey A Law (law@cygnus.com) + * Makefile.in (gencheck.o): Depend on gansidecl.h. - * haifa-sched.c (create_reg_dead_note): Detect and handle another - case where we kill more regs after sched than were killed before - sched. - * sched.c (create_reg_dead_note): Similarly. + * c-common.c (print_char_table): Add missing initializers. + (scan_char_table): Likewise. + (time_char_table): Likewise. -Mon Dec 22 09:18:37 1997 Jeffrey A Law (law@cygnus.com) + * c-decl.c (c_decode_option): Mark parameter `argc' with + ATTRIBUTE_UNUSED. + (declare_parm_level): Mark parameter `definition_flag' with + ATTRIBUTE_UNUSED. - * c-pragma.c: Include flags.h. + * c-lex.c (readescape): Use `(unsigned)1' in shift. + (yylex): Likewise. Cast `sizeof' to an (int) when comparing + against one. -Sun Dec 21 22:10:59 1997 Mumit Khan + * calls.c (store_one_arg): Remove unused parameter `fndecl'. All + callers changed. + (emit_call_1): Mark parameters `fndecl' and `funtype' with + ATTRIBUTE_UNUSED. + (expand_call): Cast result of MIN() to (unsigned int) when + comparing against an unsigned value. - * i386/cygwin32.h (NO_IMPLICIT_EXTERN_C): Don't assume anything - about system headers. - (LIB_SPEC): Add -ladvapi32 -lshell32 to be consistent with mingw32 - and also to resolve symbols in prefix.c. + * cccp.c (pcfinclude): Remove unused parameter `limit'. All + callers changed. + (make_definition): Remove unused parameter `op'. All callers + changed. + (create_definition): Cast REST_EXTENSION_LENGTH to (long) when + comparing against the result of pointer arithmetic. + + * config/mips/mips.h (FUNCTION_ARG_BOUNDARY): Cast to (unsigned) + when comparing against one. + + * dwarf2out.c (dwarf2out_frame_debug): Cast REGNO() and + HARD_FRAME_POINTER_REGNUM to (unsigned) when comparing against + one. + (output_die): Move variable `i' into the scope in which it is + used. Change its type to `unsigned'. + (output_die): Cast the result of `strlen' to (int) when passing it + to ASM_OUTPUT_ASCII(). + (output_pubnames): Likewise. + (output_line_info): Likewise. - * i386/xm-cygwin32.h (HAVE_BCOPY): Define. This avoids a conflict - between gansidecl.h and newlib's _ansi.h when building libgcc2.a, - when the definitions in auto-config.h is not visible. - (HAVE_BZERO): Likewise. - (HAVE_BCMP): Likewise. - (HAVE_RINDEX): Likewise. - (HAVE_INDEX): Likewise. + * emit-rtl.c (global_rtl): Add missing initializers. -Sun Dec 21 21:54:22 1997 Jeffrey A Law (law@cygnus.com) + * explow.c (promote_mode): Mark parameter `for_call' with + ATTRIBUTE_UNUSED. - * pa.c (emit_move_sequence): Handle a function label source - operand. + * expmed.c (expand_shift): Cast the result of GET_MODE_BITSIZE to + `unsigned HOST_WIDE_INT' when comparing against one. + (synth_mult): Change type of variable `cost' to int. + (emit_store_flag): Use `(unsigned HOST_WIDE_INT) 1' in shift. + + * expr.c (copy_blkmode_from_reg): Cast BITS_PER_WORD to (unsigned) + when comparing against one. + (get_inner_reference): Change variable `alignment' to unsigned. + (expand_expr): Cast the result of GET_MODE_ALIGNMENT to (unsigned + int) when comparing against one. + (expand_builtin_setjmp): Change type of variable `i' to size_t. + + * fold-const.c (div_and_round_double): Cast BASE to + (HOST_WIDE_INT) when comparing against one. + + * gencheck.c: Include gansidecl.h. + (main): Mark parameter `argv' with ATTRIBUTE_UNUSED. + + * optabs.c (gen_cond_trap): Mark parameters `code', `op2' and + `tcode' with ATTRIBUTE_UNUSED. + + * real.c (edivm): Cast constant value to (unsigned long) in + expression compared against an unsigned value. + + * stmt.c (expand_return): Cast BITS_PER_WORD to (unsigned) when + comparing against one. + (expand_end_case): Cast CASE_VALUES_THRESHOLD to (unsigned int) + when comparing against one. + + * stor-layout.c (mode_for_size): Cast MAX_FIXED_MODE_SIZE to + (unsigned int) when comparing against one. Likewise for + GET_MODE_BITSIZE. + (smallest_mode_for_size): Likewise. + (save_storage_status): Mark parameter `p' with ATTRIBUTE_UNUSED. + (restore_storage_status): Likewise. + + * toplev.c (debug_args): Add missing initializer. + (f_options): Spelling correction. Add missing initializers. + (documented_lang_options): Likewise. + (debug_end_source_file): Mark parameter `lineno' with + ATTRIBUTE_UNUSED. -Sun Dec 21 16:13:55 1997 Nick Clifton -Sun Dec 21 15:51:10 1997 Manfred Hollstein + * config/v850/lib1funcs.asm (_udivsi3): Add .type declaration. + Replace use of r5 with use of r19. - * m68k/mot3300.h (ASM_BYTE_OP): Don't include '\t' in the - definition. - (ASM_OUTPUT_ASCII): Prefix ASM_BYTE_OP by one single '\t'. - -Sun Dec 21 13:58:39 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (FPBIT_FUNCS, DPBIT_FUNCS): Define. - (libgcc2.a): Depend on $(DPBIT) and $(FPBIT). Add rules to - generate more fine grained floating point emulation libraries. - * config/fp-bit.c: Add protecting #ifdef to all functions so - that they can be compiled separately. If !FINE_GRAINED_LIBRARIES, - then compile all suitable functions. - (pack_d, unpack_d, fpcmp_parts): Add declarations, define with two - underscores to avoid namespace pollution. - * t-mn10200 (LIB2FUNCS_EXTRA): Remove fp-bit.c - (FPBIT): Define. - * t-mn10300 (LIB2FUNCS_EXTRA): Remove fp-bit.c and dp-bit.c - (FPBIT): Define. - (DPBIT): Define. - -Sat Dec 20 11:26:47 1997 Kaveh R. Ghazi - Jeff Law + * config/v850/v850.h (LINK_POINTER_REGNUM): Define. - * bitmap.c (bitmap_clear): Ensure `inline' is at the beginning - of the declaration. - * c-decl.c (finish_decl): Use parentheses around && within ||. - * rtl.c: Include stdlib.h. - (read_skip_spaces): Add parentheses around assignments used as - truth values. - (read_rtx): Initialize list_rtx. - * cppexp.c (parse_number): Use || when operands are truth values. - * alias.c (find_base_value): Add default case. - (memrefs_conflict): Likewise. - * combine.c (sets_function_arg_p): Likewise. - * genemit.c (gen_exp): Likewise. - * local-alloc.c (contains_replace_regs): Likewise. - * rtlanal.c (jmp_uses_reg_or_mem): Likewise. - * fold-const.c (fold_convert): Use "&&" for truth values. - (fold): Add default case. - * sdbout.c (sdbout_field_types): Fix typo in declaration. - (sdbout_one_type): Add default case. - * alpha.c (alpha_sa_mask): Prototype only if OPEN_VMS. - (some_operand): Add default case. - (input_operand): Likewise. - (signed_comparison_operator): Likewise. - (divmod_operator): Likewise. - (alpha_set_memflags_1): Likewise. - * reload1.c (reload_cse_simplify_operands): Ensure function - always returns a value. - * scan-decls.c (scan_decls): Likewise. - * c-lex.c (skip_white_space): Fix typo in declaraion. - * c-typeck.c (comp_target_types): Add parentheses around assignment - used as truth value. - (print_spelling): Likewise. - (constructor_implicit, constructor_result): Remove unused variables. - * collect2.c (scan_library): Protect prototype with - #ifdef SCAN_LIBRARIES. - * emit-rtl.c (find_line_note): Fix typo in declaration. - * final.c (asm_insn_count): Protect prototype with - #ifdef HAVE_ATTR_length. - * flow.c (find_auto_inc): Protect prototype with #ifdef AUTO_INC_DEC. - (try_pre_increment_1, try_pre_increment): Likewise. - * regclass.c (auto_inc_dec_reg_p): Protect prototype with - #ifdef FORBIDDEN_INC_DEC_CLASSES. Make return type explicit. - * gcov-io.h (__store_long, __write_long, __read_long): Fix - unsigned/signed comparisons. - * gcov.c (read_files): Remove unused "first_type" variable. - (scan _for_source_files): Initialize s_ptr. - (function_summary): Eliminate "%lf" formatting, use %ld for - longs. - (output_data): Initialize branch_probs and last_line_num. - Eliminate "%lf" formatting, use "%ld" for longs. - -Fri Dec 19 17:31:11 1997 Ian Lance Taylor - - * mips16.S: New file. - - * libgcc2.c (varargs): Handle mips16. - - * expr.c (do_tablejump): Let CASE_VECTOR_PC_RELATIVE be an - expression. - * stmt.c (expand_end_case): Likewise. - * alpha.h (CASE_VECTOR_PC_RELATIVE): Update. - * fx80.h, gmicro.h, m68k.h, m88k.h, ns32k.h: Likewise. - * rs6000.h, sh.h, tahoe.h, v850.h, vax.h: Likewise. - -Tue Dec 16 15:14:09 1997 Andreas Schwab - - * objc/Make-lang.in: Create runtime-info.h and libobjc_entry.o in - the build directory. - (libobjc.a): Update dependency list. - (libobjc.dll): Likewise. Use libobjc_entry.o from the build - directory. - (objc/sendmsg.o): Add -Iobjc to find runtime-info.h. - (objc.mostlyclean): Remove runtime-info.h. + * config/v850/v850.c (compute_register_save_size): Allow for the + fact that helper functions save all registers, not just those used + by the function. -Fri Dec 19 00:19:42 1997 Richard Henderson + Replace constant 31 with macro LINK_POINTER_REGNUM. - * tree.c (build_range_type): Allow creation of ranges with no maximum. - * dbxout.c (dbxout_range_type): Handle missing TYPE_MAX_VALUE. - * dwarf2out.c (add_subscript_info): Likewise. - * dwarfout.c (subscript_data_attribute, byte_size_attribute): Likewise. - * sdbout.c (plain_type_1): Likewise. - * stmt.c (pushcase_range, all_cases_count, node_has_high_bound): - Likewise. - * fold-const.c (int_const_binop, fold_convert, make_range, fold): - Likewise. + * config/v850/v850.md: Use 'indirect_operand' rather than + 'memory_operand' for bit test/set/clear patterns. -Thu Dec 18 17:05:10 1997 Kaveh R. Ghazi +Tue Oct 13 11:49:14 1998 Jason Merrill - * mips.c (fatal): Remove declaration. + * mips/iris6.h (ASM_OUTPUT_WEAK_ALIAS): Call ASM_GLOBALIZE_LABEL. + * varasm.c (assemble_start_function et al): Don't call + ASM_GLOBALIZE_LABEL for weak symbols. -1997-12-18 Mark Mitchell +Tue Oct 13 11:37:45 1998 Nick Clifton - * integrate.c (get_label_from_map): New function. - (expand_inline_function): Use it. Initialize the label_map to - NULL_RTX instead of gen_label_rtx. - (copy_rtx_and_substitute): Use get_label_from_map. - * integrate.h (get_label_from_map): New function. - (set_label_from_map): New macro. - * unroll.c (unroll_loop): Use them. - (copy_loop_body): Ditto. + * cse.c (equiv_constant): Check for NULL return from + gen_lowpart_if_possible(). -Thu Dec 18 19:19:57 1997 Ian Lance Taylor +Tue Oct 13 11:24:51 1998 Jeffrey A Law (law@cygnus.com) - * mips/mips.h (INIT_SUBTARGET_OPTABS): Define if not defined. - (INIT_TARGET_OPTABS): Define. - * mips/ecoff.h: Include gofast.h before mips.h. - (INIT_SUBTARGET_OPTABS): Define instead of INIT_TARGET_OPTABS. - * mips/elf64.h: Likewise. - * mips/elf.h (ASM_OUTPUT_SECTION_NAME): Define. + * mn10200.md (addsi3, subsi3, negsi2): Only allow register operands. -Thu Dec 18 14:51:12 1997 Jason Merrill + * collect2.c (main): Pass -EL/-EB through to the compiler. - * except.c: Remove register_exception_table{,_p}. +1998-10-12 Herman A.J. ten Brugge -Thu Dec 18 14:57:29 1997 Gavin Koch + * expr.c (push_block): Handle targets where the stack grows + to higher addresses, but args grow to lower addresses and + ACCUMULATE_OUTGOING_ARGS is not defined. - * unroll.c (calculate_giv_inc): Handle constant increment found in - a MEM with an appropriate REG_EQUAL note. +Tue Oct 13 08:00:52 1998 Catherine Moore - * calls.c (expand_call): Implement LOAD_ARGS_REVERSED. + * config/v850/v850.c (print_operand): Extend meaning + of 'c' operands to support .vtinherit. - * dwarf2out.c (dwarf2out_frame_debug): Handle adjustments of the - frame pointer in the prologue. +Tue Oct 13 21:38:35 1998 Michael Hayes -Thu Dec 18 00:19:38 1997 Robert Lipe + * config/c4x/c4x.c: Convert to gen_rtx_FOO. + Added ATTRIBUTE_UNUSED to unused function arguments. + (rc_reg_operand): New predicate. + (c4x_rptb_insert): New function. + (c4x_rptb_nop_p): Recognize modified rptb_top pattern. + (c4x_optimization_options): New function. - * i386/x-sco5 (CLIB) Deleted. (ALLOCA) Added. - * i386/xm-sco5.h (USE_C_ALLOCA) Added. + * config/c4x/c4x.md: Convert to gen_rtx_FOO. + (decrement_and_branch_on_count): New pattern. + (rptb_top): Modified pattern to work with BCT optimization. -Tue Dec 16 18:51:00 1997 Bill Moyer + * config/c4x/c4x.h (RC_REG): New register class. + (rc_reg_operand): Define prototype. + (IS_RC_REG): New macro. + (IS_RC_OR_PSEUDO_REG): New macro. + (IS_RC_OR_PSEUDO_REGNO): New macro. + (OPTIMIZATION_OPTIONS): Define. - * config/m68k/m68k.c (output_function_prologue): Typecast - dwarf2out_cfi_label to (char *). - * config/m68k/m68kemb.h (STARTFILE_SPEC): Redefined to "". +Mon Oct 12 19:57:34 1998 Jason Merrill -Wed Dec 17 15:06:04 1997 Richard Henderson + * collect2.c (extract_init_priority): No priority is 65535. - * sparc.md (jump): Don't use the annul bit around an empty loop. - Patch from Kevin.Kelly@East.Sun.COM. +Mon Oct 12 12:10:37 1998 Alexandre Oliva -Wed Dec 17 00:51:36 1997 Stan Cox (scox@cygnus.com) + * Makefile.in (build_tooldir): New variable, same as old + $(tooldir), but without depending on $(libdir)/$(unlibsubdir). + (GCC_FOR_TARGET): Add -B$(build_tooldir)/bin/. + (bootstrap, bootstrap2, bootstrap3, bootstrap4): Likewise. - * jump.c: (jump_optimize): Don't use the return register as a - source1 of a conditional move. + * configure.in (gxx_include_dir): Set default based on unlibsubdir. + * Makefile.in (tooldir): Likewise. + (cccp.o, cpplib.o): Use unlibsubdir implicitly through + gxx_include_dir, includedir and tooldir. + (protoize.o, unprotoize.o): Likewise. -Tue Dec 16 23:45:40 1997 Richard Henderson +Mon Oct 12 10:50:44 1998 Nick Clifton - * sparc.c (DF_MODES): Or the mask not the bit number. - (function_arg) [ARCH64]: Send unprototyped arg to fp reg first. + * config/arm/arm.md: Replace (reg 24) with (reg:CC 24). -Wed Dec 17 00:13:48 1997 Christian Iseli + * config/arm/thumb.c (thumb_override_options): Add warning about + PIC code not being supported just yet. - * combine.c (force_to_mode): return immediately if operand is a CLOBBER. +Sun Oct 11 16:49:15 1998 John Wehle (john@feith.com) -Tue Dec 16 23:44:54 1997 Manfred Hollstein + * flow.c: Update comment. + (notice_stack_pointer_modification): New static function. + (record_volatile_insns): Use it. + (mark_regs_live_at_end): Mark the stack pointer as alive + at the end of the function if current_function_sp_is_unchanging + is set. + (life_analysis_1): Set current_function_sp_is_unchanging. + * function.c: Define it. + (init_function_start): Initialize it. + * output.h: Declare it. + * reorg.c (fill_simple_delay_slots, dbr_schedule): Mark + the stack pointer as alive at the end of the function if + current_function_sp_is_unchanging is set. + * i386.c (ix86_epilogue): Optimize the restoring + of the stack pointer. - * fixincludes (size_t): Add support for Motorola's stdlib.h - which fails to provide a definition for size_t. - (fabs/hypot): Provide a prototype for fabs on m88k-motorola-sysv3. - (strlen,strspn,strcspn return value): Handle different layout on sysV88. - (hypot): Provide a fake for hypot for m88k-motorola-sysv3. +Mon Oct 12 01:22:53 1998 Jeff Law (law@cygnus.com) - * m68k/xm-mot3300.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Define to - prevent unresolved externals in libio. - * m88k/xm-sysv3.h (ADD_MISSING_POSIX, ADD_MISSING_XOPEN): Likewise. + * version.c: Bump for snapshot. -Tue Dec 16 23:25:45 1997 H.J. Lu (hjl@gnu.org) +Sun Oct 11 23:04:30 1998 Robert Lipe + + * c-pragma.c (handle_pragma_token): If passed a token instead + of a tree, use that as the pack value. + +Sun Oct 11 14:21:14 1998 Mark Mitchell + + * flow.c (find_basic_blocks_1): Fix prototype. + +Sun Oct 11 05:03:41 1998 Ken Raeburn + + * tree.h (DECL_NO_CHECK_MEMORY_USAGE): New macros. + (struct tree_decl): New fields no_check_memory_usage. + * c-common.c (enum attrs): Add A_NO_CHECK_MEMORY_USAGE. + (init_attributes): Register it as a new attribute. + (decl_attributes): Set flags on functions given that attribute. + * c-decl.c (duplicate_decls): Merge new attribute. + * expr.h (current_function_check_memory_usage): Declare new var. + * calls.c, expr.c, function.c, stmt.c, alpha.c, clipper.c, m88k.c, + pa.c, sparc.c: Replace uses of flag_check_memory_usage with + current_function_check_memory_usage. + * function.h: Add field to struct function. + * function.c (current_function_check_memory_usage): Define it. + (push_function_context_to, pop_function_context_from): Save and + restore it. + (expand_function_start): Set it, based on global flag and function + attribute. + + * expr.c (expand_expr, case VAR_DECL): In memory-checking code, do + check non-automatic variables, to permit detection of writes to + read-only locations in embedded systems without memory management. + * calls.c (store_one_arg): Use ARGS_SIZE_RTX to get size of argument + when emitting chkr_set_right_libfunc call, even if the argument is + BLKmode or variable-sized; don't abort. + + * optabs.c (init_optabs): Create Checker and __cyg_profile_* + symbols in Pmode, not VOIDmode. - * config/sparc/linux64.h (LIBGCC_SPEC): Removed. - (CPP_SUBTARGET_SPEC): Add %{pthread:-D_REENTRANT}. - (LIB_SPEC): Updated for glibc 2. +Sun Oct 11 01:03:05 1998 Zack Weinberg -Tue Dec 16 20:11:36 1997 Jeffrey A Law (law@cygnus.com) + * cppexp.c: When forcing unsigned comparisons, cast both sides + of the operation. - * ginclude/stdarg.h: Undo BeOS changes, they break hpux. - * ginclude/varargs.h: Likewise. + * cpphash.h: Move static declaration of hashtab[]... + * cpphash.c: ...here. -Tue Dec 16 00:32:01 1997 Jeffrey A Law (law@cygnus.com) + * cpplib.c: Cast difference of two pointers to size_t before + comparing it to size_t. Cast signed to unsigned + before comparing to size_t. (FIXME: struct argdata should use + unsigned buffer sizes.) + * cpplib.h (struct cpp_reader): Declare token_buffer_size as + unsigned int. (CPP_WRITTEN): Cast return value to size_t. + (CPP_RESERVE): Parenthesize N for evaluation order, cast to + size_t before comparison. - * version.c: Bump for snapshot. +Sun Oct 11 00:15:29 1998 Jeffrey A Law (law@cygnus.com) -Tue Dec 16 00:14:29 1997 H.J. Lu (hjl@gnu.org) + * flow.c (find_basic_blocks): Delete "live_reachable_p" argument. + (find_basic_blocks_1): Similarly. + * output.h (find_basic_blocks): Fix prototype. + * gcse.c, toplev.c: Don't pass "live_reachable_p" argument to + find_basic_blocks anymore. - * frame.h (__register_frame, __register_frame_table, - __deregister_frame): New. - * frame.c (__register_frame, __register_frame_table, - __deregister_frame): New. - * frame.c (__deregister_frame_info): Return void *. - * frame.h (__deregister_frame_info): Ditto. - * collect2.c (__deregister_frame_info): Ditto. +Sat Oct 10 22:00:34 1998 Richard Henderson -Mon Dec 15 18:40:08 1997 Richard Henderson + * basic-block.h (EXECUTE_IF_SET_IN_SBITMAP): New macro. + (sbitmap_free, sbitmap_vector_free): New macros. + * output.h (rtl_dump_file): Declare. - * expmed.c (expand_shift): If SHIFT_COUNT_TRUNCATED, drop a SUBREG. +Sat Oct 10 17:01:42 1998 Jeffrey A Law (law@cygnus.com) -Mon Dec 15 18:31:43 1997 Richard Henderson + * regmove.c (optimize_reg_copy_3): Honor TRULY_NOOP_TRUNCATION. - * alpha.c (alpha_cpu_name): New variable. - (alpha_mlat_string): Likewise. - (alpha_memory_latency): Likewise. - (override_options): Handle -mmemory-latency. - (alpha_adjust_cost): Adjust load cost for latency. - * alpha.h (TARGET_OPTIONS): Add meory-latency. - (REGISTER_MOVE_COST): Define in terms of memory_latency. Take - TARGET_CIX into account. - (MEMORY_MOVE_COST): Define in terms of memory_latency. - * invoke.texi (DEC Alpha Options): Document -mmemory-latency. +Fri Oct 9 22:08:05 1998 Kaveh R. Ghazi - * alpha.h (ASM_COMMENT_START): New macro. + * fp-bit.c (SFtype): Don't implicitly use int in declaration. + (DFtype): Likewise. + (_fpdiv_parts): Remove unused parameter `tmp', all callers changed. + (divide): Remove unused variable `tmp'. + (si_to_float): Cast numeric constant to (SItype) before comparing + it against one. -Mon Dec 15 17:48:05 1997 Richard Henderson +Fri Oct 9 16:03:19 1998 Graham - * reload.h, reload1.c (eliminate_regs), caller-save.c, dbxout.c, - dwarfout.c, dwarf2out.c, reload.c, sdbout.c: Revert March 15 change. + * flow.c (print_rtl_with_bb): Changed type of in_bb_p to match use. + * gcc.c (add_preprocessor_option): Correct typo when allocating + memory, sizeof() argument had one too many `*'. + (add_assembler_option): Likewise. + (add_linker_option): Likewise. + * gcov.c (output_data): Likewise. + * local-alloc.c (memref_used_between_p): Likewise. + (update_equiv_regs): Likewise. + * loop.c (strength_reduce): Likewise. + * reg-stack.c (record_asm_reg_life): Likewise. + (subst_asm_stack_reg): Likewise. + * reorg.c (dbr_schedule): Likewise. - * reload.c (push_reload): If WORD_REGISTER_OPERATIONS, reload the - SUBREG_REG if the word count is unchanged. - * reload1.c (eliminate_regs) [case SET]: If W_R_O, preserve - subregs of identical word size for push_reload. +Fri Oct 9 15:57:51 1998 Bernd Schmidt -Mon Dec 15 Mark Mitchell 11:41:32 1997 + * flow.c (life_analysis_1): Break out some functions. + (find_basic_blocks_1): Likewise. Also move some variables out and + make them static. + Rename NONLOCAL_LABEL_LIST arg to NONLOCAL_LABELS and initialize + new static var nonlocal_label_list with it. + (active_eh_region, nested_eh_region, label_value_list, + nonlocal_label_list): New static variables. + (make_edges, delete_unreachable_blocks, delete_block): New static + functions, broken out of find_basic_blocks_1. + (record_volatile_insns, mark_regs_live_at_end, set_noop_p, + noop_move_p): New static functions, broken out of life_analysis_1. - * toplev.c (rest_of_compilation): Don't call save_for_inline_copy - if all we're doing is dealing with -Wreturn-type. +Fri Oct 9 15:49:29 1998 Richard Henderson -Mon Dec 15 09:44:39 1997 Richard Henderson + * expmed.c (store_bit_field): Pun non-integral str_rtx modes. + Take extra care for op0 now possibly being a subreg. + (extract_bit_field): Likewise. + * function.c (purge_addressof_1): Revert Oct 4 change. Drop + the reg to memory if there is no equal sized integral mode. + * stor-layout.c (int_mode_for_mode): New function. + * machmode.h: Prototype it. - * alpha.md (zero_extendqihi2, zero_extendqisi2, zero_extendqidi2): - Use and 255 instead of zapnot 1, since it schedules better. +Fri Oct 9 14:26:44 1998 Jeffrey A Law (law@cygnus.com) -Mon Dec 15 08:48:24 1997 Jeffrey A Law (law@cygnus.com) + * global.c (build_insn_chain): Verify no real insns exist past the + end of the last basic block, then exit the loop. - * stmt.c (expand_asm_operands): If an ASM has no outputs, then treat - it as volatile. +Fri Oct 9 11:44:47 1998 David Edelsohn -Mon Dec 15 00:04:48 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (insert_bct): Ensure loop_iteration_var non-zero before use. - * haifa-sched.c (remove_dependencies): Set RTX_INTEGRATED_P on - dependency we delete. Properly update prev for multiple consecutive - deletions. - (priority): Skip deleted dependence. +Thu Oct 8 21:59:47 1998 Dave Brolley -Fri Dec 12 18:54:23 1997 Per Bothner + * emit-rtl.c (init_emit_once): Call INIT_EXPANDERS. - * expr.c (expand_builtin): Support BUILT_IN_FMOD - just call fmod. +Thu Oct 8 22:03:45 1998 David Edelsohn -Fri Dec 12 01:19:48 1997 Jason Merrill + * rs6000.h (RTX_COSTS): Add PROCESSOR_PPC604e cases. - * flow.c (flow_analysis): Be consistent with find_basic_blocks in - determining when a new basic block starts. +Thu Oct 8 17:00:18 1998 Richard Henderson - * alpha/osf2or3.h (LIB_SPEC): Restore missing defn. + * flow.c (find_basic_blocks): Correctly determine when a call + is within an exception region. - * pa.h (TEXT_SPACE_P): Use TREE_CODE_CLASS. - * pa.md (iorsi3): Add missing args to *_operand calls. +Thu Oct 8 17:15:04 1998 Jeffrey A Law (law@cygnus.com) - * except.c (call_get_eh_context): Don't mess with sequences. - (emit_eh_context): Include the call in the sequence here. + * toplev.c (output_file_directive): Use DIR_SEPARATOR, not '/'. -1997-12-11 Paul Eggert + * cpplib.h: Protect from multiple inclusions. + * cpplib.c: Fix minor formatting problems. - * collect2.c (write_c_file_glob): Allocate initial frame object - in static storage and pass its address. + * i386/xm-cygwin32.h: Only define POSIX if it is not already defined. -Thu Dec 11 23:33:48 1997 Jason Merrill + * jump.c (jump_optimize): Revert accidental patch. - * except.c (call_get_eh_context): Don't take a parm. - Put the call at the top of the function. - (emit_eh_context): Adjust. - (get_eh_context): Replace with former use_eh_context. - (get_eh_context_once, get_saved_pc_ref): Remove. - (start_eh_unwinder, end_eh_unwinder, emit_unwinder): Remove. - * except.h: Adjust. - * integrate.c (expand_inline_function): Adjust. - * toplev.c (rest_of_compilation): Don't call emit_unwinder. + * Makefile.in (cpplib.o): Use unlibsubdir. -Fri Oct 10 17:58:31 CEST 1997 Marc Lehmann +Thu Oct 8 12:50:47 1998 Jim Wilson - * i386/xm-go32.h (EXECUTABLE_SUFFIX): Define. - (DIR_SEPARATOR, NO_SYS_SIGLIST): Likewise. + * loop.c (get_condition): Allow combine when either compare is + VOIDmode. -Thu Dec 11 23:55:17 1997 Manfred Hollstein +Thu Oct 8 11:31:01 1998 Jeff Law (law@cygnus.com) - * fixincludes (strlen,strspn,strcspn return value): Handle different - layout on sysV88. - (hypot): Provide a fake for hypot which is broken on - m88k-motorola-sysv3. + * version.c: Bump for snapshot. -Thu Dec 11 23:50:17 1997 John F. Carr +Thu Oct 8 12:21:14 1998 Richard Frith-Macdonald - * tree.c, tree.h: Change tree_code_type, tree_code_length, and - tree_code_name from pointers to arrays. - * tree.c: Remove standard_tree_code_* variables, no longer used. - * print-tree.c: Remove declaration of tree_code_name. + * c-lex.c (remember_protocol_qualifiers): Handle RID_BYREF. + (init_lex): Initialize ridpointers[RID_BYREF]. + * c-lex.h (enum rid): Add RID_BYREF. + * c-parse.gperf: Add RID_BYREF as a type qualifier. + * objc/objc-act.c (is_objc_type_qualifiers): Handle RID_BYREF. + (encode_type_qualifiers): Similarly. + * c-gperf.h: Rebuilt. - * cp/lex.c (init_lex): Update for tree_code_* changes. - * objc/objc-act.c (init_objc): Likewise. +Thu Oct 8 05:56:00 1998 Jeffrey A Law (law@cygnus.com) - * tree.def, cp/cp-tree.def, objc/objc-tree.def: Update for tree_code - changes. + * c-common.c (type_for_mode): Only return TItype nodes when + HOST_BITS_PER_WIDE_INT is >= 64 bits. + * c-decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare + when HOST_BITS_PER_WIDE_INT is >= 64 bits. + (init_decl_processing): Only create TItype nodes when + HOST_BITS_PER_WIDE_INT is >= 64 bits. + * c-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare + when HOST_BITS_PER_WIDE_INT is >= 64 bits. -Thu Dec 11 23:34:54 1997 Fred Fish +Thu Oct 8 05:05:34 1998 Bernd Schmidt - * config.sub: Add support for BeOS target. - * configure.in: Likewise. - * ginclude/stdarg.h: Likewise. - * ginclude/stddef.h: Likewise. - * ginclude/varargs.h: Likewise. - * rs6000/beos.h: New file for BeOS. - * rs6000/t-beos: Likewise. - * rs6000/x-beos: Likewise. - * rs6000/xm-beos.h: Likewise. - * toplev.c (get_run_time): Just return 0 on BeOS. + * stmt.c (n_occurrences): New static function. + (expand_asm_operands): Verify that all constrains match in the + number of alternatives. + Verify that '+' or '=' are at the beginning of an output constraint. + Don't allow '&' for input operands. + Verify that '%' isn't written for the last operand. + * reload.c (find_reloads): Abort if an asm is found with invalid + constraints; all possible problems ought to be checked for earlier. -Thu Dec 11 23:25:23 1997 Jeffrey A Law (law@cygnus.com) - Toon Moene (toon@moene.indiv.nluug.nl) +Thu Oct 8 04:26:20 1998 Michael Hayes - * m68k.h (GO_IF_LEGITIMATE_ADDRESS): No longer cater to horribly - old and broken Sun3 assemblers. Newer versions handle large - offsets correctly as does the GNU assembler. + * flags.h (flag_branch_on_count_reg): Always declare. + * toplev.c (flag_branch_on_count_reg): Likewise. + * toplev.c: Fix typos. -Thu Dec 11 23:06:48 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * real.c (c4xtoe): Remove unused variables. Add some missing parens. + (toc4x): Similarly. - * objc/objc-act.c (lang_report_error_function): Disable. - * objc/objc-parse.y: Include "output.h". - (yyerror): Remove redundant decl. - (yyprint): Fix prototype. - (apply_args_register_offset): Remove redundant decl. - (get_file_function_name): Likewise. +Thu Oct 8 01:25:22 1998 Richard Henderson -Thu Dec 11 22:02:10 1997 Jason Merrill + * flow.c (find_basic_blocks): Calc upper bound for extra nops in + max_uids_for_flow. + (find_basic_blocks_1): Add a nop to the end of a basic block when + a trailing call insn does not have abnormal control flow. + * gcse.c (pre_transpout): New variable. + (alloc_pre_mem, free_pre_mem, dump_pre_data): Bookkeeping for it. + (compute_pre_transpout): Calculate it. + (compute_pre_ppinout): Use it to eliminate impossible placements + due to abnormal control flow through calls. + (compute_pre_data): Call compute_pre_transpout. - * flow.c (find_basic_blocks): A CALL_INSN that can throw starts - a new basic block. - (find_basic_blocks_1): Likewise. +Wed Oct 7 21:40:24 1998 David S. Miller -Thu Dec 11 21:08:48 1997 Jason Merrill + * config/sparc/sol2-sld-64.h (ASM_CPU_SPEC): Fix typo. - * except.c (use_eh_context): Don't copy_rtx a REG. - (emit_throw): Lose old unwinder support. - (expand_internal_throw): Likewise. - * libgcc2.c (struct eh_context): Likewise. - (new_eh_context): Likewise. - (__get_eh_info): Lose redundant cast. - (__get_dynamic_handler_chain): Likewise. - (__get_saved_pc): Lose. - Lose all old unwinder support code. - -Thu Dec 11 20:42:18 1997 Teemu Torma - - Thread-safe EH support for pthreads, DCE threads and Solaris threads. - - * integrate.c (expand_inline_function): If the inline fn uses eh - context, make sure that the current fn has one. - * toplev.c (rest_of_compilation): Call emit_eh_context. - * except.c (use_eh_context): New fn. - (get_eh_context_once): New fn. - (call_get_eh_context): New fn. - (emit_eh_context): New fn. - (get_eh_context): Call either get_eh_context_once or - call_get_eh_context, depending on what we have. - (get_dynamic_handler_chain): Call get_eh_context_once. - * except.h: Prototypes for fns above. - * optabs.c (get_eh_context_libfunc): Removed. - (init_optabs): Don't initialize it. - * expr.h (get_eh_context_libfunc): Removed. - * rtl.h, rtl.c: New reg_note REG_EH_CONTEXT. - * config/pa/pa.h (CPP_SPEC): Support for -threads. - * config/pa/pa-hpux10.h (LIB_SPEC): Ditto. - * config/pa/t-pa (MULTILIB_OPTIONS, MULTILIB_DIRNAMES): - New multilib for -threads. - * config/sparc/t-sol2: Added multilibs for -threads and - made -pthreads alias to it. - * config/sparc/sol2.h (CPP_SPEC, LIB_SPEC): - Added -threads and -pthreads options. - * libgcc-thr.h: New file. - * libgcc2.c: (__get_cpp_eh_context): Removed. - (struct cpp_eh_context): Removed. - (struct eh_context): Replaced cpp_eh_context with generic language - specific pointer. - (__get_eh_info): New function. - (__throw): Check eh_context::info. - (__sjthrow): Ditto. - * libgcc2.c: Include libgcc-thr.h. - (new_eh_context, __get_eh_context, - eh_pthread_initialize, eh_context_initialize, eh_context_static, - eh_context_specific, eh_context_free): New functions. - (get_eh_context, eh_context_key): New variables. - (__sjthrow, __sjpopnthrow, __eh_pcnthrow, __throw): Use - get_eh_context to get the context. - (longjmp): Move the declaration inside - #ifdef DONT_USE_BUILTIN_SETJMP. - * frame.c: Include libgcc-thr.h. - (object_mutex): Mutex to protect the object list. - (find_fde, __register_frame, __register_frame_table, - __deregister_frame): Hold the lock while accessing objects. - * except.h (get_eh_context): Declare. - * except.c (current_function_ehc): Define. - (current_function_dhc, current_function_dcc): Removed. - (get_eh_context): New function. - (get_dynamic_handler_chain): Use get_eh_context. - (get_saved_pc_ref): Ditto. - (get_dynamic_cleanup_chain): Removed references to - current_function_dcc. - (save_eh_status, restore_eh_status): Save and restore - current_function_ehc instead. - * optabs.c (get_eh_context_libfunc): New variable. - (init_optabs): Initialize it. - * expr.h: Declare get_eh_context_libfunc. - * function.h (struct function): Replaced dhc and dcc with ehc. - * except.c (get_saved_pc_ref): New functions. - (eh_saved_pc_rtx, eh_saved_pc): Deleted. - (expand_internal_throw_indirect): Use get_saved_pc_ref() instead - of eh_saved_pc. - (end_eh_unwinder): Likewise. - (init_eh): Remove initialization of eh_saved_pc. - * optabs.c (get_saved_pc_libfunc): New variable. - (init_optabs): Initialize it. - * expr.h: Declare get_saved_pc_libfunc. - * except.h (eh_saved_pc_rtx): Deleted. - (get_saved_pc_ref): Declared. - - From Scott Snyder : - * libgcc2.c (__get_saved_pc): New. - (__eh_type, __eh_pc): Deleted. - (__eh_pcnthrow): Use __get_saved_pc() instead of __eh_pc. - (__get_dynamic_handler_chain): Move __dynamic_handler_chain inside - this fcn. - -Thu Dec 11 17:23:48 1997 John F. Carr - - * sparc/sol2.h: Use 64 bit multiply and divide functions in - Solaris libc. Define TARGET_LIVE_G0 and TARGET_BROKEN_SAVERESTORE - as 0. - - * rtl.h (global_rtl): New variable, replacing separate variables for - commonly used rtl. - (const_int_rtx): Now array of rtx_def, not rtx. - * emit-rtl.c: Update for new rtl data structures. - * genattrtab.c: Define global_rtl. - -Thu Dec 11 15:50:29 1997 David Edelsohn - - * configure.in ({rs6000,powerpc}-*-*): Enable Haifa scheduler by - default. - -Wed Dec 10 12:30:18 1997 Anthony Green - - * crtstuff.c (__do_global_ctors): Fix typo. - -Tue Dec 9 09:43:59 1997 Manfred Hollstein - - * toplev.c (main): Check HAVE_GETRLIMIT and HAVE_SETRLIMIT in addition - to RLIMIT_STACK to see if we can call getrlimit and setrlimit. - -Tue Dec 9 09:38:58 1997 David Edelsohn - - * rs6000.h (FUNCTION_ARG_PADDING): Define. - * rs6000.c (function_arg_padding): New function. - -Tue Dec 9 10:34:21 1997 Manfred Hollstein - - * m68k.c: Include tree.h only once. - -Tue Dec 9 09:32:33 1997 Richard Kenner - - * integrate.c (save_for_inline_copying): Make a new reg_parm_stack_loc. - -Tue Dec 9 01:16:06 1997 Jeffrey A Law (law@cygnus.com) - - * Partially cleaned up prototyping code from HJ. - * tree.h: Add many prototypes. - * haifa-sched.c (haifa_classify_insn): Renamed from classify_insn. - All references changed. - * rtl.h: Protect from multiple inclusions. Add many prototypes. +Wed Oct 7 21:19:46 1998 Ken Raeburn -Tue Dec 9 01:15:15 1997 Fred Fish + * config/mips/mips.md (tablejump_internal3, tablejump_internal4 + and matching define_insns): Tack on a `use' of the table label, so + flow analysis will recognize a tablejump. - * libgcc2.c (string.h): Hoist inclusion to occur before first use of - string functions like strlen. +Wed Oct 7 17:33:39 1998 Richard Henderson -Tue Dec 9 00:57:38 1997 Manfred Hollstein + * gcse.c (pre_insert_insn): Tweek to notice that calls do not + always end basic blocks for abnormal edge reasons. - * configure.in: Check for functions getrlimit and setrlimit. - * cccp.c (main): Check HAVE_GETRLIMIT and HAVE_SETRLIMIT in addition - to RLIMIT_STACK to see if we can call getrlimit and setrlimit. +Wed Oct 7 14:40:43 1998 Nick Clifton -Mon Dec 8 23:53:26 1997 Jay Sachs + * config/i386/i386.h: Remove definition of + HANDLE_PRAGMA_PACK_PUSH_POP. - * Makefile.in (compare*): Handle losing behavior from 4.4bsd make. + * config/i386/go32.h: Add definition of + HANDLE_PRAGMA_PACK_PUSH_POP. -Mon Dec 8 21:03:28 1997 Richard Henderson + * config/i386/win32.h: Add definition of + HANDLE_PRAGMA_PACK_PUSH_POP. - * alpha.c (REG_RA, alpha_return_addr, output_epilog): - Fix merge problems. + * config/i386/cygwin32.h: Add definition of + HANDLE_PRAGMA_PACK_PUSH_POP. - * alpha.c (override_options): Don't know about scheduling for EV6. - * alpha.md (ev5 function units): Don't overload as ev6. + * c-pragma.c (insert_pack_attributes): Do not insert + attributes unless #pragma pack(push,) is in effect. - * alpha.c (alpha_adjust_cost): Simplify. Fix typo in ev5 mult case. - * alpha.md (define_attr type): Add mvi. - (ev5_e0): Define sceduling parameters for it. - (TARGET_MAX insns): Type is mvi not shift. +Wed Oct 7 12:10:46 1998 Jim Wilson -Mon Dec 8 18:15:00 1997 Richard Henderson + * expr.c (emit_group_store): Handle a PARALLEL destination. - * alpha/win-nt.h (TRAMPOLINE_TEMPLATE): Fix backported gcc-2.8 bug. +Wed Oct 7 10:07:29 1998 Richard Henderson -Mon Dec 8 21:17:28 1997 J"orn Rennecke + * gcse.c (pre_insert_insn): When a call ends a bb, insert + the new insns before the argument regs are loaded. - * cstamp-h, auto-config.h: Delete. +Wed Oct 7 12:55:26 1998 Kaveh R. Ghazi -Sun Dec 7 19:19:03 1997 Jeffrey A Law (law@cygnus.com) + * Makefile.in (c-gperf.h): Add -L KR-C -F ', 0, 0' flags to gperf. + (c-parse.gperf): Update comments describing invocation flags. + (c-gperf.h): Regenerate using gperf 2.7.1 (19981006 egcs). - * version.c: Bump for snapshot. +1998-10-07 Manfred Hollstein -Sat Dec 6 22:22:22 1997 Jeffrey A Law (law@cygnus.com) + * reload1.c (reload): Call free before clobbering the memory + locations or constants pointers. - * cccp.c: Fix typo brought over in merge. +Wed Oct 7 02:05:20 1998 David S. Miller - * Merge in changes from gcc-2.8. + * config/sparc/sol2-sld-64.h (TRANSFER_FROM_TRAMPOLINE): Rework + for efficiency by checking whether we need to modify the current + stack permission at all. + (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Define. + * config/sparc/sparc.c (sparc_initialize_trampoline): Emit + __enable_execute_stack libcall here too if + TRANSFER_FROM_TRAMPOLINE is defined. + * config/sparc/sparc.h: Set TARGET_ARCH32 to a constant if + IN_LIBGCC2. -Mon Nov 3 05:45:32 1997 Philippe De Muyter +Wed Oct 7 02:27:52 1998 Jeffrey A Law (law@cygnus.com) - * m68k.c: Include tree.h for dwarf2out_cfi_label. + * Makefile.in (DRIVER_DEFINES): Remove last change. - * gcc.c (process_command): Do not take address of function fatal when - calling lang_specific_driver. +Wed Oct 7 01:08:43 1998 Bernd Schmidt -Sat Dec 6 01:02:38 1997 Mumit Khan + * jump.c (duplicate_loop_exit_test): Strip REG_WAS_0 notes off all + insns we're going to copy. + * regclass.c (reg_scan_mark_refs): Don't test X for NULL_RTX. - * config/i386/cygwin32.h (DWARF2_UNWIND): Exception handling - doesn't work with it yet, so set it to 0. - * config/i386/xm-cygwin32.h (NO_SYS_SIGLIST): Define. + * loop.c (count_one_set): Add prototype. -Sat Dec 6 01:01:02 1997 Christian Iseli + * caller-save.c (restore_referenced_regs): Lose mode argument. + (insert_save): Lose mode argument. + (insert_restore): Lose mode argument. + (insert_one_insn): Lose mode argument. + (save_call_clobbered_regs): Lose mode argument. + (setup_save_areas): Take no argument and return void. All callers + changed. + Don't verify validity of memory addresses. + * reload.h (setup_save_ares): Adjust prototype. + (save_call_clobbered_regs): Likewise. + * reload1.c (delete_caller_save_insns): New function. + (caller_save_spill_class): Delete variable. + (caller_save_group_size): Delete variable. + (reload): Call setup_save_areas and save_call_clobbered_regs + in the main loop, before calling calculate_needs_all_insns. + Don't call save_call_clobbered_regs after the loop. + Call delete_caller_save_insns at the end of an iteration if + something changed. + Delete code to manage caller_save_spill_class. + Emit the final note before setting reload_first_uid. + Simplify test that determines whether reload_as_needed gets run. + (calculate_needs): Delete code to manage caller_save_spill_class. + +Tue Oct 6 15:42:27 1998 Richard Henderson + + * collect2.c (main): Initialize ld_file_name. + +Tue Oct 6 15:45:15 1998 Catherine Moore + + * config/sparc/sysv4.h (ASM_OUTPUT_SECTION_NAME): Don't + check for flag_function_sections. + +Tue Oct 6 20:02:31 1998 J"orn Rennecke + + * cse.c (insert_regs): Fix bug in Sep 24 change. + +Tue Oct 6 17:00:42 1998 J"orn Rennecke + + * flags.h (flag_dump_unnumbered): Declare. + * toplev.c (flag_dump_unnumbered): Don't declare. + * print-rtl.c (flags.h): Include. + (print_rtl_single): Add return value. + * rtl.h (print_rtl_single): Update declaration. + * flow.c (flag_dump_unnumbered): Don't declare. + (print_rtl_with_bb): Use return value of print_rtl_single. + +Tue Oct 6 01:36:00 1998 Bernd Schmidt + + * loop.c (count_one_set): New static function, broken out of + count_loop_regs_set. + (count_loop_regs_set): Call it. + * global.c (mark_reg_store): Handle clobbers here by not calling + set_preference. + (mark_reg_clobber): Just call mark_reg_store after ensuring SETTER + is in fact a clobber. + * integrate.c (process_reg_param): New function, broken out of + expand_inline_function. + (expand_inline_function): Call it. + + * i386.md (addsidi3_1): Delete unused variable temp. + (addsidi3_2): Likewise. + (clstrstrsi): Delete unused variable addr1. + + * rtl.h: Don't declare any functions also declared in recog.h. + + * Makefile.in (stupid.o): Update dependencies. + (global.o): Likewise. + + * global.c: Include reload.h. + (reg_becomes_live): New function. + (reg_dies): New function. + (build_insn_chain): New function. + (global_alloc): Call build_insn_chain before calling reload. + + * reload.h (struct needs): New structure definition. + (struct insn_chain): Likewise. + (reload_insn_chain): Declare variable. + (new_insn_chain): Declare function. + + * reload1.c (reload_startobj): New variable. + (reload_insn_chain): New variable. + (unused_insn_chains): New variable. + (new_insn_chain): New function. + (init_reload): Initialize reload_startobj, not reload_firstobj. + (reload): Initialize reload_firstobj. + Before returning, free everything on the reload_obstack. + + * stupid.c: Include insn-config.h, reload.h and basic-block.h. + (reg_where_dead_chain, reg_where_born_exact, reg_where_born_clobber, + current_chain): New variables. + (reg_where_born): Delete variable. + (REG_WHERE_BORN): New macro. + (find_clobbered_regs): New function. + (stupid_life_analysis): Don't allocate/free reg_where_born. + Allocate and free reg_where_born_exact, reg_where_born_clobber, + reg_where_dead_chain. + Use REG_WHERE_BORN instead of reg_where_born. + While processing the insns, build the reload_insn_chain with + information about register lifetimes. + (stupid_reg_compare): Use REG_WHERE_BORN instead of reg_where_born. + (stupid_mark_refs): Replace arg INSN with arg CHAIN. All callers + changed. + Compute and information about birth and death of pseudo registers in + reg_where_dead_chain, reg_where_born_exact and reg_where_born_clobber. + Delete code to set elements of reg_where_born. + +Mon Oct 5 22:34:30 1998 Alexandre Petit-Bianco + + * tree.def (GOTO_EXPR): Modified documentation. + * expr.c (expand_expr): Expand GOTO_EXPR into a goto or a computed + goto. + +Mon Oct 5 22:43:36 1998 David Edelsohn + + * unroll.c (loop_iteration_var, loop_initial_value, loop_increment + loop_final_value, loop_comparison_code): No longer static. + (unroll_loop): Delete loop_start_value update. + * loop.h (loop_iteration_var, loop_initial_value, loop_increment, + loop_final_value, loop_comparison_code): Extern. + (loop_start_value): Delete extern. + * loop.c (loop_can_insert_bct, loop_increment, loop_start_value, + loop_comparison_value, loop_comparison_code): Delete. + (loop_optimize): Remove initialization for deleted variables. + (strength_reduce): Delete analyze_loop_iterations call. Only call + insert_bct if flag_branch_count_on_reg set. + (analyze_loop_iterations): Delete. + (insert_bct): Remove iteration count calculation. Move checks for + viable BCT optimization to here. Obtain iteration count from + loop_iterations and correct for unrolling. Check for enough + iteration to be beneficial. Comment out runtime iteration count + case. + (insert_bct): Print iteration count in dump file. Remove + loop_var_mode and use word_mode directly. - * cse.c (cse_insn): Check for invalid entries when taking references. + * rs6000.h (processor_type): Add PROCESSOR_PPC604e. + * rs6000.c (rs6000_override_options): Use it. + (optimization_options): Enable use of flag_branch_on_count_reg. + * rs6000.md (define_function_unit): Describe 604e. -Fri Dec 5 18:26:25 1997 J"orn Rennecke +1998-10-05 Herman A.J. ten Brugge - * loop.c (invariant_p): Don't test flag_rerun_loop_opt. - (loop_optimize, scan_loop, strength_reduce): New argument unroll_p. - * toplev.c (rest_of_compilation): Pass it. Remove code to - save / clear / restore flag_unroll_{,all_}loops. + * loop.c (move_movables): Corrected threshold calculation for + moved_once registers. -Fri Dec 5 16:26:03 1997 Bernd Schmidt +Mon Oct 5 21:18:45 1998 Bernd Schmidt - * i386.c (notice_update_cc): Remove bogus pentium GCC code. + * loop.c (combine_givs_p): Fix test for identical givs. -Fri Dec 5 16:25:14 1997 Jeffrey A Law (law@cygnus.com) +Mon Oct 5 10:11:28 1998 Nick Clifton - * stmt.c (warn_if_unused_value): Don't warn for TRY_CATCH_EXPR. + * dwarf2out.c (gen_subprogram_die): If errorcount nonzero, don't + call abort if the function is already defined. -Thu Dec 4 11:51:00 1997 Jason Merrill +Mon Oct 5 10:02:36 1998 Jeffrey A Law (law@cygnus.com) - * except.c (get_dynamic_handler_chain): Only make the call once per - function. + * combine.c (simplify_rtx): Do not replace TRUNCATE with a SUBREG if + truncation is not a no-op. - * except.c (expand_end_all_catch): Fix for sjlj exceptions. +Mon Oct 5 09:02:04 1998 Jeff Law (law@cygnus.com) -Thu Dec 4 12:30:40 1997 J"orn Rennecke + * version.c: Bump for snapshot. - * sh.c (final_prescan_insn): Use local label prefix - when emitting .uses pseudo-ops. +Mon Oct 5 08:19:55 1998 Jeff Law (law@cygnus.com) -Wed Dec 3 12:01:56 1997 Jason Merrill + * version.c: Bump for snapshot. - * libgcc2.c (__throw): Use __builtin_return_addr instead of __eh_pc. - * except.c: Lose outer_context_label_stack. - (expand_eh_region_end): Rethrow from outer_context here. - (expand_fixup_region_end): Let expand_eh_region_end do the rethrow. - (expand_internal_throw): Take no args. - (expand_internal_throw_indirect): Lose. - (expand_leftover_cleanups, expand_start_all_catch): Use expand_rethrow. - (expand_start_all_catch): Start a rethrow region. - (expand_end_all_catch): End it. - (expand_rethrow): New fn. - * except.h: Reflect above changes. - * flow.c: Revert change of Nov 27. +Mon Oct 5 01:07:23 1998 Torbjorn Granlund -Thu Dec 4 00:24:09 1997 Jeffrey A Law (law@cygnus.com) + * expmed.c (expand_divmod): Don't widen for computing remainder + if we seem to have a divmod pattern for needed mode. - * i386/t-sol2 (CRTSTUFF_T_CFLAGS): Turn on the optimizer. +Mon Oct 5 01:01:42 1998 Zack Weinberg -Wed Dec 3 12:01:56 1997 Jason Merrill + * cpplib.c (macroexpand): Correct off-by-one error in handling + of escapes. - * except.c (expand_fixup_region_end): New fn. - (expand_fixup_region_start): Likewise. - (expand_eh_region_start_tree): Store cleanup into finalization here. - * stmt.c (expand_cleanups): Use them to protect fixups. +Sun Oct 4 23:58:30 1998 Richard Henderson -Wed Dec 3 11:41:13 1997 Gavin Koch + * combine.c (expand_field_assignment): Don't do bitwise operations + on MODE_FLOAT; pun to MODE_INT if possible. - * mips/mips.md (muldi3_r4000): Broaden the output template - and attribute assignments to handle three operand dmult; - rename to muldi3_internal2. - (muldi3): Call the new muldi3_internal2 for R4000, and - any GENERATE_MULT3 chip. +Sun Oct 4 18:33:24 1998 Jason Merrill + scott snyder -Tue Dec 2 19:40:43 1997 Jason Merrill + * tlink.c (scan_linker_output): Recognize errors from irix 6.2 + linker. Recognize mangled names in quotes. - * stmt.c (expand_decl_cleanup): Update thisblock after eh_region_start. +Sun Oct 4 02:58:20 1998 Jakub Jelinek -Tue Dec 2 12:54:33 1997 Jim Wilson + * config/sparc/sparc.md (ashldi3+1): Name it ashldi3_sp64. + (ashlsi3_const1, ashldi3_const1): New combiner patterns. + (ashrsi3_extend, ashrsi3_extend2): New combiner patterns. + (lshrsi3_extend, lshrsi3_extend2): Likewise. - * unroll.c (find_splittable_givs): Remove last change. Handle givs - with a dest_reg that was created by loop. +Sun Oct 4 00:23:00 1998 David S. Miller -Sat Nov 29 12:44:57 1997 David Edelsohn + * function.c (purge_addressof_1): If trying to take a sub-word + integral piece of a floating point mode, put it on the stack. - * rs6000.c (function_arg_partial_nregs): Undo Nov. 26 patch. +Sat Oct 3 19:01:03 1998 Richard Henderson - * rs6000/aix41.h (ASM_CPU_SPEC): Define. + * alpha/linux.h (CPP_PREDEFINES): Define __alpha__ for imake. -Fri Nov 28 10:00:27 1997 Jeffrey A Law (law@cygnus.com) +Sat Oct 3 14:42:19 1998 Jason Merrill - * configure.in: Fix NCR entries. + * PROJECTS: Remove template friends. -Thu Nov 27 12:20:19 1997 Jeffrey A Law (law@cygnus.com) + * collect2.c (sort_ids): Remove unused variable. - * flow.c (find_basic_blocks): Handle cfg issues for rethrows and - nested exceptions correctly. + * tm.texi (MATH_LIBRARY): Document. + (NEED_MATH_LIBRARY): Remove. - * unroll.c (find_splittable_givs): Don't split givs with a dest_reg - that was created by loop. + * varasm.c (assemble_start_function, assemble_variable, weak_finish, + assemble_alias): Do ASM_GLOBALIZE_LABEL for weak symbols, too. -Thu Nov 27 09:34:58 1997 Jason Merrill +Sat Oct 3 16:14:44 1998 John Carr - * expr.c (preexpand_calls): Don't look past a TRY_CATCH_EXPR. + * dwarf2out.c (expand_builtin_dwarf_reg_size): Initialize + last_end to 0x7fffffff. - * except.c (expand_start_all_catch): One more do_pending_stack_adjust. +Fri Oct 2 19:14:20 1998 David S. Miller -Wed Nov 26 15:47:30 1997 Michael Meissner + * function.c (purge_addressof_1): Do not perform endianness + corrections on bitpos, who we call will do it for us. - * rs6000.c (SMALL_DATA_REG): Register to use for small data relocs. - (print_operand): Use SMALL_DATA_REG for the register involved in - small data relocations. - (print_operand_address): Ditto. +Fri Oct 2 11:52:35 1998 Jeffrey A Law (law@cygnus.com) - * rs6000/linux.h (LINK_SPEC): Pass -dynamic-linker /lib/ld.so.1 if - -dynamic linker is not used. + * h8300.c (WORD_REG_USED): Fix typo. + (initial_offset): Use WORD_REG_USED. - * rs6000.md (call insns): For local calls, use @local suffix under - System V. Don't use @plt under Solaris. + * h8300.c (handle_pragma): Fix typo. - * rs6000.c (output_function_profiler): Put label address in r0, and - store LR in 4(sp) for System V/eabi. +Fri Oct 2 10:51:35 1998 Bernd Schmidt - * rs6000.h (ASM_OUTPUT_REG_{PUSH,POP}): Keep stack aligned to 16 - byte boundary, and maintain stack backchain. + * caller-save.c (insert_save_restore): Break this function up + into new functions insert_restore, insert_save and insert_one_insn. + All callers changed. + (insert_restore): New function, mostly broken out of + insert_save_restore. + (insert_save): Likewise. + (insert_one_insn): Likewise. + (restore_referenced_regs): New argument BLOCK. All callers changed. + (save_call_clobbered_regs): Don't keep track of basic block boundaries + in this function, do it in insert_one_insn instead. + + * reload1.c (reload): Break out some more pieces into separate + functions. + (dump_needs): New function, broken out of reload. + (set_initial_elim_offsets): Likewise. + (init_elim_table): Likewise. + (update_eliminables): Likewise. + + * global.c (global_alloc): Delete code to manage the scratch_list. + * local-alloc.c (qty_scratch_rtx): Delete. + (scratch_block): Delete. + (scratch_list): Delete. + (scratch_list_length): Delete. + (scratch_index): Delete. + (alloc_qty_for_scratch): Delete. + (local-alloc): Update initialization of max_qty. + Delete code to manage the scratch list. + Delete code to allocate/initialize qty_scratch_rtx. + (block_alloc): Don't allocate quantities for scratches. + Delete code to manage the scratch list. + * regs.h (scratch_list): Delete declaration. + (scratch_block): Delete declaration. + (scratch_list_length): Delete declaration. + * reload1.c (reload): Delete code to manage the scratch list. + (spill_hard_reg): Likewise. + (mark_scratch_live): Delete. + + * recog.c (alter_subreg): Delete declaration. + +1998-10-02 Andreas Jaeger + + * Makefile.in (cccp.o): Fix typo in last patch. + +Fri Oct 2 16:13:12 1998 J"orn Rennecke + + * t-sh (LIB1ASMFUNCS): Add _set_fpscr . + * config/sh/lib1funcs.asm (___set_fpscr): Add. + +Fri Oct 2 02:01:59 1998 Jeffrey A Law (law@cygnus.com) -Tue Nov 25 14:08:12 1997 Jim Wilson + * regclass.c (reg_scan_mark_refs): Return immediately if passed a + NULL_RTX as an argument. - * mips.md (fix_truncdfsi2, fix_truncsfsi2, fix_truncdfdi2, - fix_truncsfdi2): Change *. + * Makefile.in (unlibsubdir): Define. + (DRIVER_DEFINES): Use unlibsubdir. + (cccp.o, cpplib.o, protoize.o, unprotoize.o): Similarly. + (stmp-fixinc): Similarly. -Wed Nov 26 11:12:26 1997 Jason Merrill +Thu Oct 1 19:58:30 1998 Bernd Schmidt - * toplev.c (main): Complain about -gdwarfn. + * regmove.c (regmove_optimize): Add variable old_max_uid. + At the end of the function, update basic_block_end. -Tue Nov 25 22:43:30 1997 Jason Merrill +Thu Oct 1 17:58:25 1998 David S. Miller - * dwarfout.c (output_type): If finalizing, write out nested types - of types we've already written. + * dwarf2out.c (expand_builtin_dwarf_reg_size): Use + FIRST_PSEUDO_REGISTER as upper bound for last_end, not an + arbitrary constant. -Tue Nov 25 20:32:24 1997 Michael Meissner +Thu Oct 1 17:57:14 1998 Nick Clifton - (patches originally from Geoffrey Keating) - * rs6000.c (function_arg): Excess floating point arguments don't - go into GPR registers after exhausting FP registers under the - System V.4 ABI. - (function_arg_partial_nregs): Ditto. + * config/arm/arm.c: Improve interworking support. - * rs6000.md (call insns): If -fPIC or -mrelocatable, add @plt - suffix to calls. +Thu Oct 1 18:43:35 1998 J"orn Rennecke -Tue Nov 25 23:37:27 1997 Jason Merrill + * reload1.c (choose_reload_regs): Fix test if reload_reg_rtx[r] was + copied from reload_out[r] . - * integrate.c (output_inline_function): Just unset DECL_INLINE. +Thu Oct 1 19:20:09 1998 John Carr -Tue Nov 25 23:33:29 1997 scott snyder + * dwarf2out.c (expand_builtin_dwarf_reg_size): Fix to work + with more than three size ranges. - * dwarf2out.c (outout_call_frame_info): Ensure that the info has - proper alignment. + * flow.c (sbitmap_copy): Use bcopy to copy bitmap. - * libgcc2.c (__throw): Initialize HANDLER. + * rtl.c (mode_name): Add a null string at the end of the array. + (mode_wider_mode): Change type to unsigned char. + (mode_mask_array): New variable. + (init_rtl): Update for mode_wider_mode type change. -Tue Nov 25 14:08:12 1997 Jim Wilson + * rtl.h (mode_wider_mode): Change type to unsigned char. + (mode_mask_array): Declare. + (GET_MODE_MASK): Use mode_mask_array. - * mips.md (fix_truncdfsi2, fix_truncsfsi2, fix_truncdfdi2, - fix_truncsfdi2): Change *X to ?*X. +Thu Oct 1 15:56:01 1998 Gavin Romig-Koch -Tue Nov 25 10:00:42 1997 Richard Henderson (rth@cygnus.com) + * calls.c (expand_call) : Encapsulate code into + copy_blkmode_from_reg. + * expr.c (copy_blkmode_from_reg): New function. + * expr.h (copy_blkmode_from_reg): New function. + * integrate.c (function_cannot_inline_p): We can inline + these now. + (expand_inline_function): Use copy_blkmode_from_reg + if needed. Avoid creating BLKmode REGs. + (copy_rtx_and_substitute): Don't try to SUBREG a BLKmode + object. - * alpha.h (CONST_OK_FOR_LETTER): Fix 'L' handling. +Thu Oct 1 10:42:27 1998 Nick Clifton -Tue Nov 25 10:00:42 1997 Jeffrey A Law (law@cygnus.com) + * config/v850/v850.c: Add function prototypes. + Add support for v850 special data areas. - * crtstuff.c (do_global_dtors_aux): Handle multiple calls better. + * config/v850/v850.h: Add support for v850 special data areas. -Tue Nov 25 01:26:55 1997 Bruno Haible : + * c-pragma.c: Add support for HANDLE_PRAGMA_PACK and + HANDLE_PRAGMA_PACK_PUSH_POP. + (push_alignment): New function: Cache an alignment requested + by a #pragma pack(push,). + (pop_alignment): New function: Pop an alignment from the + alignment stack. + (insert_pack_attributes): New function: Generate __packed__ + and __aligned__ attributes for new decls whilst a #pragma pack + is in effect. + (add_weak): New function: Cache a #pragma weak directive. + (handle_pragma_token): Document calling conventions. Add + support for #pragma pack(push,) and #pragma pack (pop). - * dwarf2out.c (ASM_OUTPUT_DWARF_DELTA1): Implement. + * c-pragma.h: If HANDLE_SYSV_PRAGMA or HANDLE_PRAGMA_PACK_PUSH_POP + are defined enable HANDLE_PRAGMA_PACK. + Move 'struct weak_syms' here (from varasm.c). + Add pragma states for push and pop pragmas. -Mon Nov 24 22:41:55 1997 Jason Merrill + * c-common.c (decl_attributes): Call PRAGMA_INSERT_ATTRIBUTES + if it is defined. - * except.c (get_dynamic_handler_chain): Build up a FUNCTION_DECL. - * optabs.c (init_optabs): Lose get_dynamic_handler_chain_libfunc. - * expr.h: Likewise. + * c-lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with + HANDLE_GENERIC_PRAGMAS. -Sat Nov 22 18:58:20 1997 Jeffrey A Law (law@cygnus.com) + * varasm.c: Move definition of 'struct weak_syms' into + c-pragma.h. + (handle_pragma_weak): Deleted. - * pa-hpux10.h (NEW_HP_ASSEMBLER): Define. - * pa.h (LEGITIMATE_CONSTANT_P): Reject LABEL_REFs if not using - gas and not using the new HP assembler. + * config/i386/i386.h: Define HANDLE_PRAGMA_PACK_PUSH_POP. -Fri Nov 21 15:20:05 1997 Jeffrey A Law (law@cygnus.com) + * config/winnt/win-nt.h: Define HANDLE_PRAGMA_PACK_PUSH_POP. - * Makefile.in (program_transform_cross_name): Clean up "-e" confusion. - (GCC_INSTALL_NAME, GCC_CROSS_NAME): Likewise. + * c-decl.c (start_function): Add invocation of + SET_DEFAULT_DECL_ATTRIBUTES, if defined. -Fri Nov 21 19:37:40 1997 Andrew Cagney + * tm.texi: Remove description of non-existent macro + SET_DEFAULT_SECTION_NAME. - * config/mips/elf64.h (MULTILIB_DEFAULTS): Test for - TARGET_ENDIAN_DEFAULT == zero instead of testing for macro - definition. + (HANDLE_SYSV_PRAGMA): Document. + (HANDLE_PRAGMA_PACK_PUSH_POP): Document. -Fri Nov 21 12:49:56 1997 Bruno Haible +Wed Sep 30 22:27:53 1998 Robert Lipe - * stmt.c (expand_end_bindings): Allow jump into block with cleanups. + * config.sub: Recognize i[34567]86-pc-udk as new target. + * configure.in: Likewise. + * config/i386/t-udk: New file. + * config/i386/udk.h: New file. -Fri Nov 21 12:18:51 1997 Jason Merrill +Wed Sep 30 19:33:07 1998 Jeffrey A Law (law@cygnus.com) - * except.h: Add outer_context_label_stack. - * except.c: Likewise. - (expand_start_all_catch): Push the outer_context for the try block - onto outer_context_label_stack. - (expand_end_all_catch): Use it and pop it. + * reorg.c (check_annul_list_true_false): Remove unused variables. + (steal_delay_list_from_target): Add missing "used_annul" variable. + (try_merge_delay_insns): Close out half formed comment. -Fri Nov 21 10:13:11 1997 Robert Lipe (robertl@dgii.com) +Wed Sep 30 19:13:20 1998 Zack Weinberg - * i386/sco5.h (HAVE_ATEXIT): Revert last change. + * cpplib.c (macroexpand): If arg->raw_before or + arg->raw_after, remove any no-reexpansion escape at the + beginning of the pasted token. Correct handling of whitespace + markers and no-reexpand markers at the end if arg->raw_after. -Thu Nov 20 16:11:50 1997 Richard Henderson + * toplev.c (documented_lang_options): Recognize -include, + -imacros, -iwithprefix, -iwithprefixbefore. + * cpplib.c (cpp_start_read): Process -imacros and -include + switches at the same time and in command-line order, after + initializing the dependency-output code. Emit properly nested + #line directives for them. Emit a #line for the main file + before processing these switches, and don't do it again + afterward. - * alpha.c (alpha_emit_set_const_1): Handle narrow hosts better. +Wed Sep 30 18:03:22 1998 Richard Henderson -Thu Nov 20 16:11:50 1997 Klaus Kaempf + * function.c (purge_addressof_1): Use bitfield manipulation + routines to handle mem mode < reg mode. - * alpha/vms.h (ASM_OUTPUT_ADDR_VEC_ELT): Add an L for the local label - to correspond with the change to ASM_GENERATE_INTERNAL_LABEL. +Wed Sep 30 18:43:32 1998 Herman ten Brugge -Thu Nov 20 14:42:15 1997 Jason Merrill + * reorg.c (try_merge_delay_insns): Account for resources referenced + in each instruction in INSN's delay list before trying to eliminate + useless instructions. Similarly when looking at a trial insn's delay + slots. - * Makefile.in (LIB2FUNCS): Remove C++ memory management support. - * libgcc2.c: Remove __builtin_new, __builtin_vec_new, set_new_handler, - __builtin_delete, and __builtin_vec_delete. + * reorg.c (check_annul_list_true_false): New function. + (steal_delay_list_from_{target,fallthrough}): Call it and also + refine tests for when we may annul if already filled a slot. + (fill_slots_from_thread): Likewise. + (delete_from_delay_slot): Return newly-created thread. + (try_merge_delay_isns): Use its new return value. - * except.c (output_exception_table): Don't bother with - __EXCEPTION_END__. +Wed Sep 30 18:29:26 1998 Jeffrey A Law (law@cygnus.com) -Thu Nov 20 16:11:50 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (check_dbra_loop): Use a vanilla loop reversal if the biv is + used to compute a giv or as some other non-counting use. - * pa.md (pre_stwm, post_stwm, pre_ldwm, post_ldwm): Base register - is an in/out operand. - (zero extended variants of stwm/stwm patterns): Similarly. +Wed Sep 30 18:19:27 1998 Michael Hayes - * mips/x-iris (FIXPROTO_DEFINES): Add -D_SGI_SOURCE. + * regs.h (HARD_REGNO_CALL_PART_CLOBBERED): New macro. + * local-alloc.c (find_free_reg): Use it. + * global.c (find_reg): Likewise. + * tm.texi: Document HARD_REGNO_CALL_PART_CLOBBERED. -Thu Nov 20 13:19:32 1997 Jason Merrill + * regs.h (HARD_REGNO_CALLER_SAVE_MODE): New macro. + * caller-save.c (init_caller_save): Use it. + * tm.texi: Document HARD_REGNO_CALLER_SAVE_MODE. - * dwarf2out.c (ASM_OUTPUT_DWARF_OFFSET4): Rename from VALUE4. - Use assemble_name. - (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Use assemble_name. - (output_call_frame_info): Emit a \n after using it. +Wed Sep 30 12:57:30 1998 Zack Weinberg -Thu Nov 20 00:38:46 1997 Dave Love + * configure.in: Add --enable-cpplib option which uses cpplib + for cpp, but doesn't link cpplib into cc1. Make help text + capitalization consistent. + * configure: Rebuilt. - * configure.in: Add AC_ARG_ENABLE for Haifa as documentation. +Wed Sep 30 10:09:39 1998 Mark Mitchell -Wed Nov 19 12:03:04 1997 Philippe De Muyter + * function.c (gen_mem_addressof): If the address REG is + REG_USERVAR_P make the new REG be so also. + * loop.c (scan_loop): Apply DeMorgan's laws and add documentation + in an attempt to clarify slightly. - * dwarf2out.c (CIE_LENGTH_LABEL, FDE_LENGTH_LABEL): New macros. - (ASM_OUTPUT_DWARF_VALUE4): New macro. - (ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL): Define if SET_ASM_OP is - defined. - (output_call_frame_info): Do not output forward label differences - if ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL is defined. - * m68k/mot3300.h (SET_ASM_OP): Define when not using gas. +Wed Sep 30 09:57:40 1998 Jeffrey A Law (law@cygnus.com) -Tue Nov 18 23:03:30 1997 J"orn Rennecke + * expr.c (expand_expr): Handle COMPONENT_REF, BIT_FIELD_REF ARRAY_REF + and INDIRECT_REF in code to check MAX_INTEGER_COMPUTATION_MODE. - * sh.md (attribute "type"): Add nil. - (movsi_ie): y/y alternative is type nil. - (movsf_ie): Replace ry/yr/X alternative by r/y/X , y/r/X and y/y/X - alternatives. - (movsf_ie+1): Delete. +Wed Sep 30 10:13:39 1998 Catherine Moore -Tue Nov 18 15:39:59 1997 Jim Wilson + * toplev.c: Fix last patch. - * mips/mips.c (save_restore_insns): If gp_offset or fp_offset are - large_int, emit two insns instead of one splitable insn. - * dwarf2out.c (dwarf2out_frame_debug): When set cfa_store_offset - from cfa_temp_value, use cfa_offset. Add assert checking that - cfa_reg is SP. +Tue Sep 29 20:03:18 1998 Jim Wilson -Mon Nov 17 15:35:38 1997 Tom Tromey + * loop.c (get_condition): Fix typo in May 9 change. - * cccp.c (deps_output): Properly quote file names for make. +Tue Sep 29 11:11:38 1998 Andrew MacLeod -Mon Nov 17 13:21:40 1997 Jeffrey A Law (law@cygnus.com) + * invoke.texi (-fexceptions): Merge 2 different descriptions. - * t-h8300 (MULTILIB_EXCEPTIONS): Define. +Mon Sep 28 22:08:52 1998 Kaveh R. Ghazi -Fri Nov 7 15:33:11 1997 Robert Lipe (robertl@dgii.com) + * toplev.c (documented_lang_options): Spelling corrections. - * i386/sco5.h (HAVE_ATEXIT): Delete definition. +Mon Sep 28 19:41:24 1998 Alexandre Oliva -Sun Nov 16 23:52:48 1997 Jeffrey A Law (law@cygnus.com) + * configure.in: New flags --with-ld and --with-as, equivalent + to setting LD and AS environment variables. Test whether + specified arguments are GNU commands, and report them with + checking messages. Use the specified AS for configure + tests too. + * configure: Likewise. + * acconfig.h: Add DEFAULT_ASSEMBLER and DEFAULT_LINKER. + * config.in: Likewise. + * gcc.c (find_a_file): When looking for `as' and `ld', return + the DEFAULT program if it exists. + * collect2.c (main): Use DEFAULT_LINKER if it exists. - * cse.c (cse_insn): Don't look at JUMP_LABEL field of a conditionl - return. - (cse_end_of_basic_block): Similarly. + * gcc.c (find_a_file): The test for existence of a full + pathname was reversed. -Sun Nov 16 23:01:40 1997 J. Kean Johnston +Mon Sep 28 17:34:35 1998 Michael Meissner - * i386/sco5.h (ASM_OUTPUT_ALIGNED_BSS): Define. - (SELECT_RTX_SECTION): Define. - (LIBGCC_SPEC, LIB_SPEC): Do the right thing for PIC. + * rs6000.h (ASM_OUTPUT_MI_THUNK): Only define on ELF systems. + * rs6000.c (output_mi_thunk): Always use a raw jump for now. -Sun Nov 16 22:47:03 1997 Manfred Hollstein +Mon Sep 28 14:24:03 1998 Mark Mitchell - * Makefile.in (compare, compare-lean): Define $stage for each - shell command. - (gnucompare, gnucompare-lean): Likewise. + * tree.h (TYPE_BINFO): Document. -Sun Nov 16 22:02:16 1997 Richard Henderson (rth@cygnus.com) +Mon Sep 28 12:55:49 1998 Stan Cox - * alpha/win-nt.h (TRAMPOLINE_TEMPLATE): Fix offsets. + * i386-coff.h (dbxcoff.h): Added. - * alpha.h (ASM_OUTPUT_ADDR_DIFF_ELT): Add an L for the local label - to correspond with the change to ASM_GENERATE_INTERNAL_LABEL. +Mon Sep 28 12:51:00 1998 Catherine Moore -Fri Nov 14 09:09:20 1997 Fred Fish (fnf@cygnus.com) + * toplev.c: Fix bad patch around flag_data_sections. - * dwarfout.c (byte_size_attribute): Add local var upper_bound - and add case to handle STRING_TYPE. - * dwarfout.c (output_string_type_die): Fix code to generate - correct string length attribute for fixed length strings. - Still needs support for varying length strings. +Mon Sep 28 10:32:28 1998 Nick Clifton -Fri Nov 14 08:46:56 1997 Jeffrey A Law (law@cygnus.com) + * reload1.c (reload): Use reload_address_index_reg_class and + reload_address_base_reg_class when setting + caller_save_spill_class. (Patch generated by Jim Wilson: + wilson@cygnus.com). - * toplev.c (get_run_time): Do something sensible for cygwin32. +Mon Sep 28 07:43:34 1998 Mark Mitchell -Fri Nov 14 07:24:20 1997 Richard Henderson + * c-common.c (c_get_alias_set): Tighten slightly for FUNCTION_TYPEs + and ARRAY_TYPEs. Tidy up. Improve support for type-punning. + * expr.c (store_field): Add alias_set parameter. Set the + MEM_ALIAS_SET accordingly, if the target is a MEM. + (expand_assignment): Use it. + (store_constructor_field): Pass 0. + (expand_expr): Likewise. - * expr.c (expand_builtin_setjmp): Set - current_function_has_nonlocal_label. - * stupid.c (stupid_life_analysis): If has_nonlocal_label, kill - call-saved registers across calls. +Mon Sep 28 07:54:03 1998 Catherine Moore - * alpha.md (exception_receiver): Remove. - (nonlocal_goto_receiver_osf): New - (nonlocal_goto_receiver_vms): Renamed from nonlocal_goto_receiver. - (nonlocal_goto_receiver): New, select _osf or _vms. + * flags.h: Add flag_data_sections. + * toplev.c: Add option -fdata-sections. Add flag_data_sections. + (compile_file): Error if flag_data_sections not supported. + * varasm.c (assemble_variable): Handle flag_data_sections. + * config/svr4.h: Modify prefixes for UNIQUE_SECTION_NAME. + * config/mips/elf.h: Likewise. + * config/mips/elf64.h: Likewise. + * invoke.texi: Describe -fdata-sections. - * alpha.c (output_prolog [*]): Prefix entry labels with '$' to - keep them from being propogated to the object file. - (alpha_write_linkage): Likewise. - * alpha.md (call_vms): Likewise. - (call_value_vms): Likewise. - (unnamed osf call insns): Likewise. +Mon Sep 28 04:15:44 1998 Craig Burley - * alpha.h (ASM_OUTPUT_INTERNAL_LABEL): Don't omit L from local label. - (ASM_GENERATE_INTERNAL_LABEL): Likewise. + * invoke.texi (-ffloat-store): Clarify that this option + does not affect intermediate results -- only variables. - * alpha.c (call_operand): Any reg is valid for WinNT. - * alpha.md (call_nt, call_value_nt): Don't force address into $27. - (anon nt calls): Add 'R' alternative. - * alpha/win-nt.h (TRAMPOLINE_TEMPLATE, TRAMPOLINE_SIZE, - INITIALIZE_TRAMPOLINE): Handle lack of original $27 and 32-bit ptrs. +Mon Sep 28 04:11:35 1998 Jeffrey A Law (law@cygnus.com) -Fri Nov 14 06:59:33 1997 Jeffrey A Law (law@cygnus.com) + * cpp.texi: Update for Fortran usage from Craig. - * calls.c (expand_call): Handle pcc_struct_value correctly for C++. +Fri Sep 25 22:09:47 1998 David Edelsohn - * i386/xm-cygwin32.h (HAVE_FILE_H, HAVE_RUSAGE): Delete defines. - * i386/xm-mingw32.h (HAVE_FILE_H, HAVE_RUSAGE): Likewise. - * rs6000/xm-cygwin32.h (HAVE_FILE_H, HAVE_RUSAGE): Likewise. + * rs6000.c (function_arg_boundary): Revert accidental change on + September 18. -Thu Nov 13 20:37:33 1997 Michael Meissner +Fri Sep 25 20:30:00 1998 Michael Meissner - * reload1.c (new_spill_reg): Improve fixed or forbidden register - spill error message. + * rs6000.h (ASM_OUTPUT_MI_THUNK): Declare, call output_mi_thunk. + (output_mi_thunk): Declare. -Thu Nov 13 20:29:08 1997 Kaveh R. Ghazi + * rs6000.c (output_mi_thunk): Function to create thunks for MI. + (output_function_profiler): Use r12 for temp, instead of r11 so + that we preserve the static chain register. - * prefix.c: Use stdarg.h only ifdef __STDC__. Otherwise, - use varargs.h. Wrap header with <>, not "". +Fri Sep 25 14:18:33 1998 Jim Wilson -Thu Nov 13 20:21:17 1997 Jeffrey A Law (law@cygnus.com) + * sdbout.c (sdbout_one_type): Don't look at TYPE_BINFO field of enums. - * integrate.c (save_for_inline_copying): Add return value from - savealloc. +Fri Sep 25 19:30:19 1998 J"orn Rennecke -Thu Nov 13 19:12:33 1997 Brendan Kehoe + * sh.c (gen_shl_sext): Fix case 5. - * fixincludes: Be a little more restrictive on what we will - substitute to replace definitions of MAXINT for HPUX. +Fri Sep 25 17:35:23 1998 J"orn Rennecke -Thu Nov 13 18:41:02 1997 Michael Meissner + * reload1.c (reload_combine): Re-add line that got accidentally lost. - * dbxout.c (dbxout_symbol_location): Don't assume that variables - whose address is the stack or argument pointers are indirect - pointers. +Fri Sep 25 10:43:47 1998 Kaveh R. Ghazi -1997-11-13 Paul Eggert + * cccp.c (pedwarn_with_file_and_line): For !__STDC__ case, avoid + accessing variables until they are initialized via va_arg(). - * cccp.c, cpplib.c (compare_defs): - Don't complain about arg name respellings unless pedantic. - * cpplib.c (compare_defs): Accept pfile as new arg. - All callers changed. +Thu Sep 24 22:12:16 1998 David S. Miller -Thu Nov 13 23:33:50 1997 J"orn Rennecke + * reload1.c (reload_combine): Initialize set before using. - * fold-const.c (fold_truthop): Fix bug in last change. +Thu Sep 24 18:53:20 1998 Jason Merrill -1997-11-13 Paul Eggert + * sdbout.c (sdbout_field_types): Don't emit the types of fields we + won't be emitting. - Fix some confusion with IEEE minus zero. +Thu Sep 24 17:05:30 1998 Nick Clifton - * real.h (REAL_VALUES_IDENTICAL): New macro. + * config/arm/arm.md (insv): Add comment. In CONST_INT case, and + operand3 with mask before using it. Patch provided by Jim Wilson. - * expr.c (is_zeros_p): Don't consider -0.0 to be all zeros. - * fold-const.c (operand_equal_p): Don't consider -0.0 to be - identical to 0.0. - * tree.c (simple_cst_equal): Don't consider -0.0 to have the - same tree structure as 0.0. +Thu Sep 24 15:08:08 1998 Jakub Jelinek - * varasm.c (immed_real_const_1): Use new REAL_VALUES_IDENTICAL - macro instead of doing it by hand. + * config/sparc/sparc.c (function_value): Perform the equivalent of + PROMOTE_MODE for ARCH64. + (eligible_for_epilogue_delay): Allow DImode operations in delay + slot of a return for ARCH64. -Thu Nov 13 16:56:14 1997 Jeffrey A Law (law@cygnus.com) +Thu Sep 24 22:17:54 1998 J"orn Rennecke - * v850/lib1funcs.asm: Minor whitespace changes. - * v850.c: Fix minor formatting problems in many places. - (construct_restore_jr, construct_save_jarl): Remove unwanted aborts. + * sh.md (sqrtsf2): Fix mode of sqrt. -Thu Nov 13 12:53:44 1997 Jim Wilson +Thu Sep 24 21:48:51 1998 J"orn Rennecke - * mips.h (GO_IF_LEGITIMATE_ADDRESS): Delete code swapping xplus0 and - xplus1 when xplus0 is not a register. + * reload1.c (choose_reload_regs): Also try inheritance when + reload_in is a stack slot of a pseudo, even if we already got a + reload reg. -Thu Nov 13 11:41:42 1997 Jeffrey A Law (law@cygnus.com) +Thu Sep 24 21:22:39 1998 J"orn Rennecke - * flow.c (find_basic_blocks): During marking phase, if we encounter - an insn with a REG_LABEL note, make the target block live and - create an edge from the insn to the target block. Do not make - edges from all blocks to the target block. + * reload1.c (reload_cse_regs_1): Renamed from reload_cse_regs. + (reload_cse_regs): New function body: call reload_cse_regs_1, + reload_combine, reload_cse_move2add. + When doing expensive_optimizations, call reload_cse_regs_1 a + second time after reload_cse_move2add. + (reload_combine, reload_combine_note_store): New functions. + (reload_combine_note_use): New function. + (reload_cse_move2add, move2add_note_store): New functions. - * m68k/x-next (OTHER_FIXINCLUDES_DIRS): Include /NextDeveloper/Headers. +Thu Sep 24 18:48:43 1998 J"orn Rennecke - * confiugre.in: Tweak NCR entries. - * configure: Rebuilt. + * reload.c (find_reloads): In code to promote RELOAD_FOR_X_ADDR_ADDR + reloads to RELOAD_FOR_X_ADDRESS reloads, test for reload sharing. -Thu Nov 13 11:07:41 1997 Michael Meissner + Properly keep track of first RELOAD_FOR_X_ADDRESS also for + more than 3 such reloads. - * rs6000.c (num_insns_constant): Use REAL_VALUE_FROM_CONST_DOUBLE to - pick apart floating point values, instead of using CONST_DOUBLE_LOW - and CONST_DOUBLE_HIGH. + If there is not more than one RELOAD_FOR_X_ADDRESS, don't change + RELOAD_FOR_X_ADDR_ADDR reload. - * rs6000.md (define_splits for DF constants): Use the appropriate - REAL_VALUE_* interface to pick apart DF floating point constants in - a machine independent fashion. +Thu Sep 24 17:45:55 1998 J"orn Rennecke -Thu Nov 13 00:06:58 1997 J"orn Rennecke + * expr.c (store_constructor): When initializing a field that is smaller + than a word, at the start of a word, try to widen it to a full word. - * fold-const.c (fold_truthop): When changing a one-bit comparison - against zero into a comparison against mask, do a proper sign - extension. + * cse.c (cse_insn): When we are about to change a register, + remove any invalid references to it. -Wed Nov 12 09:37:01 1997 Jeffrey A Law (law@cygnus.com) + (remove_invalid_subreg_refs): New function. + (mention_regs): Special treatment for SUBREGs. + (insert_regs): Don't strip SUBREG for call to mention_regs. + Check if reg_tick needs to be bumped up before that call. + (lookup_as_function): Try to match known word_mode constants when + looking for a norrower constant. + (canon_hash): Special treatment for SUBREGs. - * except.c: Do not include "assert.h". - (save_eh_status): Turn asserts into conditional aborts. - (restore_eh_status, scan_region): Likewise. - * dwarfout.c: Do not include "assert.h". - (bit_offset_attribute): Turn asserts into conditional aborts. - (bit_size_attribute, output_inlined_enumeration_type_die): Likewise. - (output_inlined_structure_type_die): Likewise. - (output_inlined_union_type_die): Likewise - (output_tagged_type_instantiation): Likewise. - (dwarfout_file_scope_decl): Likewise. - * dwarf2out.c: Do not include "assert.h" - (expand_builtin_dwarf_reg_size): Turn asserts into conditional aborts. - (reg_save, initial_return_save, dwarf2out_frame_debug): Likewise. - (add_child_die, modified_type_die, add_bit_offset_attribute): Likewise. - (add_bit_size_attribute, scope_die_for): Likewise. - (output_pending_types_for_scope): Likewise. - (get_inlined_enumeration_type_die): Likewise. - (get_inlined_structure_type_die): Likewise. - (get_inlined_union_type_die, gen_subprogram_die): Likewise. - (gen_tagged_type_instantiation_die): Likewise. +Thu Sep 24 01:35:34 1998 David S. Miller - * flow.c (find_basic_blocks): Refine further to get a more correct - cfg, especially in the presense of exception handling, computed - gotos, and other non-trivial cases. Call abort if an inaccuracy - is detected in the cfg. + * config/sparc/sol2-sld-64.h (TRANSFER_FROM_TRAMPOLINE): Define. + * config/sparc/sparc.c (sparc64_initialize_trampoline): If that is + defined, emit libcall to __enable_execute_stack. Also fix opcodes + and offsets in actual stack trampoline code so they match the + commentary and actually work. -Tue Nov 11 21:47:27 1997 J"orn Rennecke +Thu Sep 24 01:19:02 1998 Jakub Jelinek - * glimits.h (SHRT_MIN): Define in a way suitable for 16 bit hosts. + * configure.in (sparcv9-*-solaris): Use t-sol2 and t-sol2-64 for + tmake_file. + (sparc64-*-linux): Use t-linux and sparc/t-linux64 for + tmake_file. Set extra_parts to needed crt objects. + * configure: Rebuilt. + * config/sparc/linux64.h (SPARC_BI_ARCH): Define. + (TARGET_DEFAULT): Set if default is v9 or ultra. + (STARTFILE_SPEC32, STARTFILE_SPEC64): New macros. + (STARTFILE_SPEC): Set to those upon SPARC_BI_ARCH. + (ENDFILE_SPEC32, ENDFILE_SPEC64, ENDFILE_SPEC): Likewise. + (SUBTARGET_EXTRA_SPECS, LINK_ARCH32_SPEC, LINK_ARCH64_SPEC, + LINK_SPEC, LINK_ARCH_SPEC): Likewise. + (TARGET_VERSION): Define. + (MULTILIB_DEFAULT): Define. + * config/sparc/sparc.h (CPP_CPU_DEFAULT_SPEC): Rearrange so that + mixed 32/64 bit compilers based upon SPARC_BI_ARCH work. + (CPP_CPU64_DEFAULT_SPEC, CPP_CPU32_DEFAULT_SEC): Define + appropriately. + (TARGET_SWITCHES): Allow ptr32/ptr64 options once more. + * config/sparc/sparc.c (sparc_override_options): If arch and + pointer size disagree, emit diagnostic and fix it up. If + SPARC_BI_ARCH and TARGET_ARCH32, set cmodel to CM_32. Turn off + V8PLUS in 64-bit mode. + * config/sparc/t-linux64: New file. + * config/sparc/t-sol2-64: New file. + * config/sparc/t-sol2: Adjust build rules to use MULTILIB_CFLAGS. + * config/sparc/sol2-sld-64.h (SPARC_BI_ARCH): Define. + (ASM_CPU32_DEFAULT_SPEC, ASM_CPU64_DEFAULT_SPEC, + CPP_CPU32_DEFAULT_SPEC, CPP_CPU64_DEFAULT_SPEC): Define. + (ASM_SPEC, CPP_CPU_SPEC): Set appropriately based upon those. + (STARTFILE_SPEC32, STARTFILE_SPEC32, STARTFILE_ARCH_SPEC): + Define. + (STARTFILE_SPEC): Set appropriately based upon those. + (CPP_CPU_DEFAULT_SPEC, ASM_CPU_DEFAULT_SPEC): Set based upon + disposition of DEFAULT_ARCH32_P. + (LINK_ARCH32_SPEC, LINK_ARCH64_SPEC): Define. + (LINK_ARCH_SPEC, LINK_ARCH_DEFAULT_SPEC): Set based upon those. + (CC1_SPEC, MULTILIB_DEFAULTS): Set based upon DEFAULT_ARCH32_P. + (MD_STARTFILE_PREFIX): Set correctly based upon SPARC_BI_ARCH. + * config/sparc/xm-sysv4-64.h (HOST_BITS_PER_LONG): Only set on + arch64/v9. + * config/sparc/xm-sp64.h (HOST_BITS_PER_LONG): Likewise. - * c-lex.c (whitespace_cr, skip_white_space_on_line): New functions. - (skip_white_space): Use whitespace_cr. - (check_newline): Handle whitespace more consistently. +Wed Sep 23 22:32:31 1998 Mark Mitchell -Tue Nov 11 16:25:49 1997 Jim Wilson + * rtl.h (init_virtual_regs): New function. + * emit-rtl.c (init_virtual_regs): Define. + (insn_emit): Use it. + * integrate.c (save_for_inline_copying): Likewise. - * i386/cygwin32.h (CPP_PREDEFINES): Delete -DPOSIX. - * i386/xm-cygwin32.h (POSIX): Define. +Wed Sep 23 16:22:01 1998 Nick Clifton -Mon Nov 10 20:53:11 1997 Gavin Koch + * config/arm/thumb.h: The following patches were made by Jim Wilson: + (enum reg_class): Add NONARG_LO_REGS support. + (REG_CLASS_NAMES, REG_CLASS_CONTENTS, REGNO_REG_CLASS, + PREFERRED_RELOAD_CLASS, SECONDARY_RELOAD_CLASS): Likewise. + (GO_IF_LEGITIMATE_ADDRESS): Disable REG+REG addresses before reload + completes. Re-enable HImode REG+OFFSET addresses. + (LEGITIMIZE_RELOAD_ADDRESS): Define. - * config/mips/mips.h (MASK_DEBUG_H): Set to zero, so this bit - is available elsewhere. + * expmed.c (extract_bit_field): Add comment from Jim Wilson. -Mon Nov 10 16:21:58 1997 Doug Evans +Wed Sep 23 13:26:02 1998 Richard Henderson - * sparc/sparc.md (mov[sdt]f_const_insn): Fix condition to match - what the instruction can handle. + * alpha.c (get_aligned_mem): Revert Sep 20 change. + (alpha_set_memflags, alpha_set_memflags_1): Likewise. + (alpha_align_insns): Properly calculate initial offset wrt max_align. -Mon Nov 10 03:02:19 1997 Jason Merrill +Wed Sep 23 10:45:44 1998 Richard Earnshaw (rearnsha@arm.com) - * stmt.c (expand_decl_cleanup_no_eh): New fn. + * arm.c (find_barrier): Revert change of Apr 23. Handle table + jumps as a single entity, taking into account the size of the + table. - * except.c (expand_leftover_cleanups): do_pending_stack_adjust. +Tue Sep 22 15:13:34 1998 Alexandre Petit-Bianco -Mon Nov 10 00:05:56 1997 Jeffrey A Law (law@cygnus.com) + * tree.def (SWITCH_EXPR): New tree node definition. - * alias.c (MAX_ALIAS_LOOP_PASSES): Define. - (init_alias_analysis): Break out of loops after MAX_ALIAS_LOOP_PASSES. +Mon Sep 21 23:40:38 1998 Jeff Law (law@cygnus.com) -Sun Nov 9 14:34:47 1997 David Edelsohn + * version.c: Bump for snapshot. - * rs6000.md (lshrdi3_power): Delete '&' from first alternative and - swap instruction order. +Mon Sep 21 22:31:14 1998 Jeff Law (law@cygnus.com) -Sun Nov 9 02:07:16 1997 Jeffrey A Law (law@cygnus.com) + * version.c: Bump for snapshot. - * fixinc.svr4 (__STDC__): Add another case. +Mon Sep 21 22:48:09 1998 Jeffrey A Law (law@cygnus.com) -Sun Nov 9 02:00:29 1997 J"orn Rennecke + * configure.in: Recognize i[34567]86-*-openbsd* and handle it like + NetBSD. - * a29k.h (ELIGIBLE_FOR_EPILOGUE_DELAY): Avoid loads from varying - addresses in the epilogue delay slot. +Mon Sep 21 22:05:28 1998 Jeffrey A Law (law@cygnus.com) -Sun Nov 9 01:40:40 1997 Manfred Hollstein (manfred@s-direktnet.de) + * Revert this patch. + * reload.c (find_reloads): Do not replace a pseudo with + (MEM (reg_equiv_addr)) in the initializing insn for the + pseudo. - * m88k/dgux.h (ASM_CPU_SPEC): Reformatted to suppress wrong whitespace - in generated `specs' file. +Mon Sep 21 20:19:41 1998 John Carr -Sun Nov 9 01:37:11 1997 Jim Wilson (wilson@cygnus.com) + * final.c (final_scan_insn): Disable tracking CC across branches. - * flags.h (flag_rerun_loop_opt): Declare. - * loop.c (invariant_p, case LABEL_REF): Check flag_rerun_loop_opt. - * toplev.c (flag_rerum_loop_opt): Delete static. +Mon Sep 21 17:15:26 1998 Andrew MacLeod -Sat Nov 8 18:20:21 1997 J"orn Rennecke + * expr.h (eh_rtime_match_libfunc): New extern declaration. + * optabs.c (init_optabs): Set eh_rtime_match_libfunc. + * except.c (start_catch_handler): Use eh_rtime_match_libfunc. + * libgcc2.c (__eh_rtime_match): Always return 0 if the matcher is + NULL. Only include if inhibit_libc is not defined. - Bring over from FSF: +Mon Sep 21 14:10:51 1998 Jason Merrill - Thu Oct 30 12:21:06 1997 J"orn Rennecke + * toplev.c (rest_of_compilation): Skip compiling anything with + DECL_EXTERNAL set, not just if it has DECL_INLINE as well. - * va-sh.h (__va_arg_sh1): Define. - (va_arg): Use it. - SH3E doesn't use any integer registers for subsequent arguments - once a non-float value was passed in the stack. - * sh.c (machine_dependent_reorg): If optimizing, put explicit - alignment in front label for ADDR_DIFF_VEC. - * sh.h (PASS_IN_REG_P): Fix SH3E case. - (ADJUST_INSN_LENGTH): If not optimizing, add two extra bytes length. +Mon Sep 21 13:51:05 1998 Jim Wilson - Tue Oct 28 15:06:44 1997 J"orn Rennecke + * flow.c (find_basic_blocks): Delete check for in_libcall_block when + prev_code is a CALL_INSN. Change check for REG_RETVAL note to + use in_libcall_block. + (find_basic_blocks_1): Delete check for in_libcall_block when prev_code + is a CALL_INSN. If CALL_INSN and in_libcall_block, then change code + to INSN. - * sh/elf.h (PREFERRED_DEBUGGING_TYPE): Undefine before including - svr4.h. +Mon Sep 21 14:02:23 1998 Robert Lipe - Mon Oct 27 16:11:52 1997 J"orn Rennecke + * i386.h (TARGET_SWITCHES): Improve doc for align-double. Fix + typo in no-fancy-math-387 description. - * sh.c (machine_dependent_reorg): When -flag_delayed_branches, - put an use_sfunc_addr before each sfunc. - * sh.md (use_sfunc_addr, dummy_jump): New insns. - (casesi): For TARGET_SH2, emit a dummy_jump after LAB. +Mon Sep 21 09:27:18 1998 Jeff Law (law@cygnus.com) - Tue Oct 21 07:12:28 1997 J"orn Rennecke + * version.c: Bump for snapshot. - * sh/elf.h (PREFERRED_DEBUGGING_TYPE): Don't redefine. +Mon Sep 21 09:24:49 1998 Stan Cox -Fri Nov 7 10:22:24 1997 Jason Merrill + * i386-coff.h (DBX_DEBUGGING_INFO): Added. - * frame.c (add_fdes, count_fdes): Go back to checking pc_begin for - linked once FDEs. +Mon Sep 21 09:14:49 1998 Robert Lipe -Wed Nov 5 14:26:05 1997 Jeffrey A Law (law@cygnus.com) + * i386.h (TARGET_SWITCHES): Add description fields for flags + documented in install.texi. + (TARGET_OPTIONS): Likewise. - * alias.c (find_base_value): Only return the known base value for - pseudo registers. +Mon Sep 21 01:39:03 1998 Jeff Law (law@cygnus.com) -Wed Nov 5 11:27:14 1997 Jim Wilson + * version.c: Bump for snapshot. - * i386.c (load_pic_register): Call prologue_get_pc_and_set_got. - * i386.md (prologue_set_got, prologue_get_pc): Add UNSPEC_VOLATILE - to pattern. - (prologue_get_pc_and_set_got): New pattern. +Mon Sep 21 01:53:05 1998 Felix Lee -Tue Nov 4 20:36:50 1997 Richard Henderson (rth@cygnus.com) + * c-lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT (). + * cccp.c (main): Likewise. - * alpha.c (summarize_insn): Handle ASM_OPERANDS. Don't recurse - for SUBREG, just fall through. + * cccp.c, collect2.c, cpplib.c, gcc.c, config/i386/xm-cygwin32.h: + Rename GET_ENVIRONMENT to GET_ENV_PATH_LIST, and fix some + macro-use bugs. - * alpha.c (alpha_handle_trap_shadows): Init sum.defd to zero. +Mon Sep 21 00:52:12 1998 Per Bothner - * alpha.md (attr trap): Make TRAP_YES non-zero for sanity's sake. + * Makefile.in (LIBS): Link in libiberty.a. + * c-common.c, gcc.c, toplev.c: Replace (some) bcopy calls by memcpy. -Tue Nov 4 18:49:42 1997 Jeffrey A Law (law@cygnus.com) +Sun Sep 20 23:28:11 1998 Richard Henderson - * fixincludes: Fix "hypot" prototype in NeXT math.h. + * reload1.c (emit_reload_insns): Accept a new arg for the bb. Use + it to update bb boundaries. Update caller. + * function.c (reposition_prologue_and_epilogue_notes): Update + bb boundaries wrt the moved note. - * Makefile.in (USE_ALLOCA): Always include alloca.o. - (USE_HOST_ALLOCA): Likewise. +Sun Sep 20 20:57:02 1998 Robert Lipe - * rtl.def (CODE_LABEL): Use separate fields for LABEL_NUSES - and LABEL_REFS fields. - * rtl.h (LABEL_REFS): Update. + * configure.in (i*86-*-sysv5*): Use fixinc.svr4 to patch byteorder + problems. + * configure: Regenerate. -Tue Nov 4 16:55:11 1997 Jim Wilson +Sun Sep 20 19:01:51 1998 Richard Henderson - * combine.c (try_combine): When setting elim_i2, check whether newi2pat - sets i2dest. When calling distribute_notes for i3dest_killed, pass - elim_i2 and elim_i1. When setting elim_i1, check if newi2pat - sets i1dest. + * alpha.c (alpha_sr_alias_set): New variable. + (override_options): Set it. + (alpha_expand_prologue, alpha_expand_epilogue): Use it. + (mode_mask_operand): Fix signed-unsigned comparison warning. + (alpha_expand_block_move): Likewise. + (print_operand): Likewise. + (get_aligned_mem): Use change_address. + (alpha_set_memflags, alpha_set_memflags_1): Set the alias set. + (alphaev4_insn_pipe, alphaev4_next_group): New functions. + (alphaev4_next_nop, alphaev5_next_nop): New functions. + (alpha_align_insns): Remade from old alphaev5_align_insns + to handle multiple processors. + (alpha_reorg): Call alpha_align_insns for both ev4 and ev5. + * output.h (label_to_alignment): Prototype. - * mips.md (insv, extzv, extv): Add change_address call. - (movsi_ulw, movsi_usw): Change QImode to BLKmode in pattern. + * tree.c (new_alias_set): New function. + * tree.h (new_alias_set): Declare it. + * c-common.c (c_get_alias_set): Use it. - * integrate.c (save_for_inline_copying): Copy parm_reg_stack_loc. +Sun Sep 20 12:35:55 1998 Richard Henderson - * reload.c (find_reloads, case 'm' and 'o'): Reject HIGH constants. + * fold-const.c (fold): Yet another COND_EXPR bug: when folding + to an ABS expr, convert an unsigned input to signed. - * mips.c (mips_expand_epilogue): Emit blockage insn before call to - save_restore_insns if no FP and GP will be restored. +Sun Sep 20 12:14:45 1998 Jeffrey A Law (law@cygnus.com) - * dwarf2out.c (expand_builtin_dwarf_reg_size): New variable mode. - Convert CCmode to word_mode before calling GET_MODE_SIZE. + * fold-const.c (fold): Fix another type in COND_EXPR handling code. - * acconfig.h (HAVE_INTTYPES_H): Undef. - * configure.in (inttypes.h): Check for conflicts between sys/types.h - and inttypes.h, and verify that intmax_t is defined. - * config/mips/x-iris (CC, OPT, OLDCC): Comment out. - * config/mips/x-iris3: Likewise. +1998-09-20 Michael Hayes -Tue Nov 4 16:07:15 1997 Jeffrey A Law (law@cygnus.com) + * configure.in: Add support for c4x targets. + * configure: Rebuilt. - * alias.c (find_base_value): When copying arguments, return the - tenative value for a hard register. +Sun Sep 20 00:00:51 1998 Richard Henderson -Tue Nov 4 13:40:35 1997 Doug Evans + * combine.c (distribute_notes): If an insn is a cc0 user, only + delete it if we can also delete the cc0 setter. - * c-lex.c (MULTIBYTE_CHARS): #undef if cross compiling. - (yylex): Record wide strings using target endianness, not host. +Sun Sep 20 00:22:23 1998 Michael Tiemann -Tue Nov 4 13:13:12 1997 Jeffrey A Law (law@cygnus.com) + * fold-const.c (fold): Fix typo in COND_EXPR handling code. + (invert_truthvalue): Enable truthvalue inversion for + floating-point operands if -ffast-math. - * mn10200.h (ASM_OUTPUT_BSS): Delete. - (ASM_OUTPUT_ALIGNED_BSS): New macro - * mn10300.h (ASM_OUTPUT_BSS): Delete. - (ASM_OUTPUT_ALIGNED_BSS): New macro. - * v850.h (ASM_OUTPUT_BSS): Delete. - (ASM_OUTPUT_ALIGNED_BSS): New macro. +Sat Sep 19 23:58:07 1998 Melissa O'Neill -Tue Nov 4 00:55:48 1997 J"orn Rennecke + * configure.in: Disable collect2 for nextstep. Instead use + crtbegin/crtend. + * configure: Rebuilt. + * config/nextstep.h (STARTFILE_SPEC): Add crtbegin. + (ENDFILE_SPEC): Define. + (OBJECT_FORMAT_MACHO): Define. + (EH_FRAME_SECTION_ASM_OP): Define. + * crtstuff.c: Handle MACHO. - * profile.c (branch_prob): Insert an insn after a NOTE_INSN_SETJMP. +Sun Sep 20 00:24:24 1998 Robert Lipe -Mon Nov 3 14:36:50 1997 Jeffrey A Law (law@cygnus.com) + * config/i386/sco5.h (TARGET_MEM_FUNCTIONS): Define. - * configure.in (sco5): Use cpio to install header files. +1998-09-19 Torbjorn Granlund -Sun Nov 2 23:31:43 1997 Manfred Hollstein + * fp-bit.c (pack_d): Do not clear SIGN when fraction is 0. + (_fpadd_parts): Get sign right for 0. - * aclocal.m4 (conftestdata_from, conftestdata_to): Names shortened to - 14 char length. - * configure: Rebuild. +1998-09-19 Michael Hayes -Sun Nov 2 19:44:00 1997 Robert Lipe (robertl@dgii.com) + * ginclude/varargs.h: Add support for C4x target. + * ginclude/stdargs.h: Likewise. - * i386/sco5.h: enable -gstabs once again. +Sat Sep 19 12:05:09 1998 Richard Henderson -Sun Nov 2 19:27:21 1997 Jeffrey A Law (law@cygnus.com) + * alpha.c (alpha_return_addr): SET should be VOIDmode. + (alpha_emit_set_long_const): Rewrite to be callable from reload + and 32-bit hosts. + (alpha_expand_epilogue): Update for alpha_emit_set_long_const. + * alpha.md (movdi): Likewise. - * arm.c (output_move_double): Allocate 3 entries in otherops array. +Sat Sep 19 07:33:36 1998 Richard Earnshaw (rearnsha@arm.com) -Sat Nov 1 21:43:00 1997 Mike Stump (mrs@wrs.com) + * arm.c (add_constant): New parameter address_only, change caller. + Set it non-zero if taking the address of an item in the pool. + (arm_reorg): Handle cases where we need the address of an item in + the pool. - * except.c (expand_ex_region_start_for_decl): Emit EH_REGION_BEG - notes for sjlj exceptions too. - (expand_eh_region_end): Similarly for EH_REGION_END notes. - (exception_optimize): Optimize EH regions for sjlj exceptions too. - * final.c (final_scan_insn): Don't output labels for EH REGION - notes if doing sjlj exceptions. + * arm.c (bad_signed_byte_operand): Check both arms of a sum in + a memory address. + * arm.md (splits for *extendqihi_insn and *extendqisi_insn): Handle + memory addresses that are not in standard canonical form. -Sat Nov 1 19:15:28 1997 Jeffrey A Law (law@cygnus.com) +Sat Sep 19 01:00:32 1998 Michael Hayes (mph@elec.canterbury.ac.nz) - * alias.c (init_alias_analysis): Handle -fno-alias-check when - optimizing correctly. + * README.C4X: New file with information about the c4x ports. + * ginclude/va-c4x.h: New file for c4x varargs support. + * config/c4x: New directory with c4x port files. - * expr.c (expand_builtin_setjmp): Don't emit a SETJMP note - or set current_function_calls_setjmp anymore. +Fri Sep 18 22:52:05 1998 Jeffrey A Law (law@cygnus.com) - * flow.c (find_basic_blocks): If we delete the label for an - exception handler, remove it from the EH label list and remove - the EH_BEGIN/EH_END notes for that EH region. + * reload.c (find_reloads): Do not replace a pseudo with + (MEM (reg_equiv_addr)) in the initializing insn for the + pseudo. -Sat Nov 1 16:44:49 1997 Jason Merrill (jason@cygnus.com) +Fri Sep 18 23:50:56 1998 David Edelsohn - * flow.c (find_basic_blocks): Generate correct flow control - information when exception handling notes are present. + * toplev.c (rest_of_compilation): Set bct_p on second call to + loop_optimize. + * loop.c (loop_optimize, scan_loop, strength_reduce): New argument + bct_p. + (strength_reduce): Only call analyze_loop_iterations and + insert_bct if bct_p set. + (check_dbra_loop): Fix typo. + (insert_bct): Use word_mode instead of SImode. + (instrument_loop_bct): Likewise. Do not delete iteration count + condition code generation insn. Initialize iteration count before + loop start. + * rtl.h (loop_optimize): Update prototype. -Sat Nov 1 13:42:19 1997 Jeffrey A Law (law@cygnus.com) + * ginclude/va-ppc.h (va_arg): longlong types in overflow area are + not doubleword aligned. - * dwarf2out.c (output_call_frame_info): Fix length argument - to ASM_OUTPUT_ASCII. - (output_die, output_pubnames, output_line_info): Likewise. + * rs6000.c (optimization_options): New function. + (secondary_reload_class): Only call true_regnum for PSEUDO_REGs. + * rs6000.h (OPTIMIZATION_OPTIONS): Define. + (REG_ALLOC_ORDER): Allocate highest numbered condition regsiters + first; cr1 can be used for FP record condition insns. -Fri Oct 31 07:10:09 1997 Jeffrey A Law (law@cygnus.com) +Fri Sep 18 09:44:55 1998 Nick Clifton - * version.c: Bump for snapshot. + * config/m32r/m32r.h (m32r_block_immediate_operand): Add to + PREDICATE_CODES. - * dwarf2out.c (output_call_frame_info): Use ASM_OUTPUT_ASCII to - output ASCII by default. Only use ASM_OUTPUT_DWARF_STRING if - flag_debug_asm is on. - (output_die, output_pubnames, output_line_info): Likewise. + * config/m32r/m32r.md: Add "movstrsi" and "movstrsi_internal" + patterns. + + * config/m32r/m32r.c (m32r_print_operand): Add 's' and 'p' + operators. + (block_move_call): New function: Call a library routine to copy a + block of memory. + (m32r_expand_block_move): New function: Expand a "movstrsi" + pattern into a sequence of insns. + (m32r_output_block_move): New function: Expand a + "movstrsi_internal" pattern into a sequence of assembler opcodes. + (m32r_block_immediate_operand): New function: Return true if the + RTL is an integer constant, less than or equal to MAX_MOVE_BYTES. - * alias.c (init_alias_analysis): Add struct_value_incoming_rtx - and static_chain_rtx into the potential base values array if - they are registers. +Thu Sep 17 16:42:16 1998 Andrew MacLeod - * alias.c (new_reg_base_value): New array of potential base values. - (unique_id): Now file scoped static. - (find_base_value, case REG): Return the value in reg_base_value - array for the REG if it exists. Else, return the value from - new_reg_base_value if copying args and REG is a hard register. - (find_base_value, case PLUS): If either operand of the PLUS is - a REG, try to get its base value. Handle base + index and - index + base. - (record_set): Use new_reg_base_value instead of reg_base_value. - (init_alias_analysis): Allocate space for new_reg_base_value too. - Rework code to iterate over the insns propagating base value - information until nothing changes. + * except.c (start_catch_handler): Issue 'fatal' instead of 'error' and + re-align some code. + * libgcc2.c (__eh_rtime_match): fprintf a runtime error. Use . - * global.c (global_alloc): Free the conflict matrix after - reload has finished. +Thu Sep 17 12:24:33 1998 J"orn Rennecke -Fri Oct 31 01:45:31 1997 Jason Merrill + * regmove.c (copy_src_to_dest): Check that modes match. - * libgcc2.c (L_eh): Define __eh_pc. - Replace __eh_type with generic pointer __eh_info. +Wed Sep 16 22:10:42 1998 Robert Lipe -Fri Oct 31 00:34:55 1996 J"orn Rennecke + * config/i386/sco5.h (SUPPORTS_WEAK): True only if targeting ELF. - * expr.c (expand_increment): When enqueing a postincrement for a MEM, - use copy_to_reg if address is not a general_operand. +Wed Sep 16 15:24:54 1998 Richard Henderson -Fri Oct 31 00:16:55 1997 J"orn Rennecke + * i386.h (PREFERRED_RELOAD_CLASS): Respect an existing class + narrower than FLOAT_REGS. - * profile.c (output_func_start_profiler): Clear flag_inline_functions - for the duration of the call to rest_of_compilation. +Wed Sep 16 17:51:00 1998 Alexandre Oliva -Thu Oct 30 14:40:10 1997 Doug Evans + * cpplib.c: Removed OLD_GPLUSPLUS_INCLUDE_DIR. + * cccp.c: Likewise. + * Makefile.in (old_gxx_include_dir): Removed. - * configure.in (sparc-*-elf*): Use sparc/elf.h, sparc/t-elf. - Set extra_parts. - (sparc*-*-*): Recognize --with-cpu=v9. - * sparc/elf.h: New file. - * sparc/t-elf: New file. +Wed Sep 16 12:29:22 1998 Nick Clifton -Thu Oct 30 13:26:12 1997 Jeffrey A Law (law@cygnus.com) + * config/sh/sh.h: Update definition of HANDLE_PRAGMA to match + new specification. - * mn10300.c (const_8bit_operand): New function. - (mask_ok_for_mem_btst): New funtion. - * mn10300.md (btst patterns with mem operands): Use new functions - to avoid creating btst instructions with invalid operands. + * config/sh/sh.c (handle_pragma): Rename to sh_handle_pragma(). + (sh_handle_pragma): Change function arguments to match new + specification for HANDLE_PRAGMA. -Wed Oct 29 16:57:19 1997 Michael Meissner +Wed Sep 16 12:43:19 1998 Kaveh R. Ghazi - * rs6000/xm-sysv4.h: Include xm-linux.h instead of xm-svr4.h if we - are running on PowerPC Linux. + * gen-protos.c (parse_fn_proto): Cast argument of ISALNUM to + `unsigned char'. + (main): Mark parameter `argc' with ATTRIBUTE_UNUSED. + When generating output, initialize missing struct member to zero. -Wed Oct 29 13:10:11 1997 Gavin Koch +Wed Sep 16 14:47:43 1998 J"orn Rennecke - * config/mips/elf64.h (PREFERRED_DEBUGGING_TYPE): Only define - if not previously defined. + * regmove.c (copy_src_to_dest): Don't copy if that requires + (a) new register(s). -Tue Oct 28 23:55:27 1997 Doug Evans (devans@cygnus.com) +Wed Sep 16 01:29:12 1998 Bernd Schmidt - * function.c (assign_parms): Correct mode of stack_parm if - entry_parm underwent a mode conversion. + * global.c (reg_allocno): Now static. + * reload1.c (reg_allocno): Delete declaration. + (order_regs_for_reload): Take no arguments. Don't treat regs + allocated by global differently than those allocated by local-alloc. -1997-10-28 Brendan Kehoe +Wed Sep 16 01:09:01 1998 Kamil Iskra - * global.c (global_alloc): Use xmalloc instead of alloca for - CONFLICTS, since max_allocno * allocno_row_words alone can be more - than 2.5Mb sometimes. + * m68k/m68k.c (output_function_prologue): Reverse NO_ADDSUB_Q + condition, fix format strings. + (output_function_epilogue): Likewise. -Tue Oct 28 15:29:15 1997 Richard Henderson + * m68k/m68k.c: Don't include directly. - * reload1.c (eliminate_regs [SET]): If [SUBREG] widened the mode of - DEST for the spill, adjust mode of SRC to compensate. +Wed Sep 16 00:30:56 1998 Geoff Keating -Tue Oct 28 14:36:45 1997 Richard Henderson + * gcse.c: New definition NEVER_SET for reg_first_set, reg_last_set, + mem_first_set, mem_last_set; because 0 can be a CUID. + (oprs_unchanged_p): Use new definition. + (record_last_reg_set_info): Likewise. + (record_last_mem_set_info): Likewise. + (compute_hash_table): Likewise. - * alpha.md (reload_inqi): Check for MEM before strict_memory_address_p, - since any_memory_operand() allows pseudos during reload. - (reload_inhi, reload_outqi, reload_outhi): Likewise. +Tue Sep 15 22:59:52 1998 Jeffrey A Law (law@cygnus.com) -Tue Oct 28 11:53:14 1997 Jim Wilson + * rs6000.c (output_epilogue): Handle Chill. - * m68k.md (btst patterns): Add 5200 support. + * mn10200.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Define. + * mn10300.h (ASM_OUTPUT_DWARF2_ADDR_CONST): Define. -Tue Oct 28 11:58:40 1997 Toon Moene + * combine.c (make_extraction): If no mode is specified for + an operand of insv, extv, or extzv, default it to word_mode. + (simplify_comparison): Similarly. + * expmed.c (store_bit_field): Similarly. + (extract_bit_field): Similarly. + * function.c (fixup_var_regs_1): Similarly. + * recog.c (validate_replace_rtx_1): Similarly. + * mips.md (extv, extzv, insv expanders): Default modes for most + operands. Handle TARGET_64BIT. + (movdi_uld, movdi_usd): New patterns. - * fold-const.c (fold): For ((a * C1) / C3) or (((a * C1) + C2) / C3) - optimizations, look inside dividend to determine if the expression - can be simplified by using EXACT_DIV_EXPR. + * pa.c (emit_move_sequence): Do not replace a pseudo with its + equivalent memory location unless we have been provided a scratch + register. Similarly do not call find_replacement unless a + scratch register has been provided. -Tue Oct 28 10:19:01 1997 Jason Merrill +Tue Sep 15 19:23:01 1998 Bernd Schmidt - From Brendan: - * dwarf2out.c (output_call_frame_info): Use l1 instead of ".". + * i386.h (PREFERRED_RELOAD_CLASS): For standard 387 constants, + return FLOAT_REGS. -Tue Oct 28 00:32:14 1997 Richard Henderson +Tue Sep 15 19:09:06 1998 Richard Henderson - * alpha.c (summarize_insn [SUBREG]): Propogate SET. + * tree.h (BUILT_IN_CALLER_RETURN_ADDRESS): Unused. Kill. + (BUILT_IN_FP, BUILT_IN_SP, BUILT_IN_SET_RETURN_ADDR_REG): Kill. + (BUILT_IN_EH_STUB_OLD, BUILT_IN_EH_STUB, BUILT_IN_SET_EH_REGS): Kill. + (BUILT_IN_EH_RETURN, BUILT_IN_DWARF_CFA): New. + * c-decl.c (init_decl_processing): Update accordingly. + * expr.c (expand_builtin): Likewise. -Mon Oct 27 23:59:26 1997 Richard Henderson + * rtl.h (global_rtl): Add cfa entry. + (virtual_cfa_rtx, VIRTUAL_CFA_REGNUM): New. + (LAST_VIRTUAL_REGISTER): Update. + * emit-rtl.c (global_rtl): Add cfa entry. + (init_emit): Initialize it. + * function.c (cfa_offset): New. + (instantiate_virtual_regs): Initialize it. + (instantiate_virtual_regs_1): Instantiate virtual_cfa_rtx. + (expand_function_end): Call expand_eh_return. + * tm.texi (ARG_POINTER_CFA_OFFSET): New. + + * except.c (current_function_eh_stub_label): Kill. + (current_function_eh_old_stub_label): Likwise; update all references. + (expand_builtin_set_return_addr_reg): Kill. + (expand_builtin_eh_stub_old, expand_builtin_eh_stub): Kill. + (expand_builtin_set_eh_regs): Kill. + (eh_regs): Produce a third reg for the actual handler address. + (eh_return_context, eh_return_stack_adjust): New. + (eh_return_handler, eh_return_stub_label): New. + (init_eh_for_function): Initialize them. + (expand_builtin_eh_return, expand_eh_return): New. + * except.h: Update prototypes. + * flow.c (find_basic_blocks_1): Update references to the stub label. + * function.h (struct function): Kill stub label elements. + + * libgcc2.c (in_reg_window): For REG_SAVED_REG, check that the + register number is one that would be in the previous window. + Provide a dummy definition for non-windowed targets. + (get_reg_addr): New function. + (get_reg, put_reg, copy_reg): Use it. + (__throw): Rely on in_reg_window, not INCOMING_REGNO. Kill stub + generating code and use __builtin_eh_return. Use __builtin_dwarf_cfa. + + * alpha.c (alpha_eh_epilogue_sp_ofs): New. + (alpha_init_expanders): Initialize it. + (alpha_expand_epilogue): Use it. + * alpha.h: Declare it. + * alpha.md (eh_epilogue): New. + + * m68h.h (ARG_POINTER_CFA_OFFSET): New. + * sparc.h (ARG_POINTER_CFA_OFFSET): New. + +Tue Sep 15 19:31:58 1998 Michael Meissner + + * i960.h (CONST_COSTS): Fix thinko. Test flag, not the constant + flag bit mask. + +Tue Sep 15 14:10:54 1998 Andrew MacLeod + + * except.h (struct eh_entry): Add false_label field. + (end_catch_handler): Add prototype. + * except.c (push_eh_entry): Set false_label field to NULL_RTX. + (start_catch_handler): When using old style exceptions, issue + runtime typematch code before continuing with the handler. + (end_catch_handler): New function, generates label after handler + if needed by older style exceptions. + (expand_start_all_catch): No need to check for new style exceptions. + (output_exception_table_entry): Only output the first handler label + for old style exceptions. + * libgcc2.c (__eh_rtime_match): New routine to lump runtime matching + mechanism into one function, if a runtime matcher is provided. + +Tue Sep 15 13:53:59 1998 Andrew MacLeod + + * config/i960/i960.h (SLOW_BYTE_ACCESS): Change definition to 1. + +Tue Sep 15 09:59:01 1998 Mark Mitchell + + * integrate.c (copy_decl_list): Fix typo. + +Tue Sep 15 04:18:52 1998 David S. Miller + + * config/sparc/sparc.md (movdf_const_intreg_sp32): Fix length + attribute. + +Mon Sep 14 14:02:53 1998 Jeff Law (law@cygnus.com) - * alpha.c (alpha_handle_trap_shadows): Don't call get_attr_trap - on a CLOBBER. + * version.c: Bump for snapshot. -Mon Oct 27 21:25:20 1997 Richard Henderson +Mon Sep 14 10:33:56 1998 Jeff Law (law@cygnus.com) - * alpha.md (movqi, movhi): Make sure new insns created during reload - won't need reloading themselves. - (reload_inqi, reload_inhi, reload_outqi, reload_outhi): Likewise. + * version.c: Bump for snapshot. -Mon Oct 27 16:11:10 1997 Jeffrey A Law (law@cygnus.com) +Mon Sep 14 09:51:05 1998 Jeff Law (law@cygnus.com) - * mn10300.h (GO_IF_LEGITIMATE_ADDRESS): Disable reg+reg. + * version.c: Bump for snapshot. -Sun Oct 26 13:50:44 1997 Richard Henderson +Sun Sep 13 22:10:18 1998 David S. Miller - * alpha.c (alpha_sa_mask [VMS]): Don't include $26 in the mask. - Patch from Klaus Kaempf . + * invoke.texi (C Dialect Options): Put back missing @end itemize. -Sun Oct 26 13:31:47 1997 Jim Wilson (wilson@cygnus.com) +Mon Sep 14 02:33:46 1998 Alexandre Oliva - * expr.c (expand_expr, case INDIRECT_REF): Optimize a reference - to an element in a constant string. + * configure.in: Remove usage of `!' to negate the result of a + command; some common shells do not support it. -Sun Oct 26 11:41:49 1997 Jason Merrill +Sun Sep 13 19:17:35 1998 David S. Miller - * dwarf2out.c (output_call_frame_info): The CIE pointer is now a 32 - bit PC-relative offset. The exception range table pointer is now in - the CIE. - * frame.c (dwarf_cie, dwarf_fde): Rename CIE_pointer to CIE_delta. - (count_fdes, add_fdes, get_cie): Adjust. - (cie_info, extract_cie_info, __frame_state_for): Adjust eh_ptr uses. + * configure.in: In sparc9-sol2 config, use 'if test' not + brackets. + * configure: Rebuilt. - From H.J. Lu: - * frame.c (count_fdes, add_fdes): Skip linked once FDE entries. + * config/sparc/sol2-sld-64.h (SPARC_DEFAULT_CMODEL): Change to + CM_MEDANY. + (CPP_CPU_SPEC): Do not define _LP64, header files do this. + (CPP_CPU_DEFAULT_SPEC): Likewise. + * config/sparc/sol2.h (INIT_SUBTARGET_OPTABS): Get the names right + for arch64 libfuncs. -Sun Oct 26 11:52:01 1997 Richard Henderson + * config/sparc/sparc.md (goto_handler_and_restore): Allow any mode + for operand zero. - * alias.c (memrefs_conflict_p): Treat arg_pointer_rtx just - like stack_pointer_rtx. +Sun Sep 13 09:11:59 1998 Kaveh R. Ghazi -Sun Oct 26 11:32:16 1997 Manfred Hollstein + * acconfig.h (NEED_DECLARATION_STRSIGNAL): Provide a stub. - * Makefile.in (bootstrap-lean): Combined with `normal' bootstrap - targets using "$@" to provide support for similar but not identical - targets without having to duplicate code. - (bootstrap4): New goal. + * collect2.c: Don't declare `sys_siglist' here. + (my_strsignal): Prototype and define new function. Use it in + place of `sys_siglist' hacks. - * Makefile.in (compare, compare-lean, compare3): Combined to one - ruleset determining actions to be performed via $@. - (compare4, compare4-lean): New targets. - (gnucompare, gnucompare3): Combined to one ruleset determining - actions to be performed via $@. Also, note which files failed - the comparison test in .bad_compare. - (gnucompare-lean, gnucompare3-lean, gnucompare4-lean): New targets. + * mips_tfile.c: Likewise. -Sun Oct 26 10:06:11 1997 Toon Moene + * configure.in (AC_CHECK_FUNCS): Check for strsignal. + (GCC_NEED_DECLARATIONS): Likewise. - * fold-const (fold): Also simplify FLOOR_DIV_EXPR to EXACT_DIV_EXPR - if the dividend is a multiple of the divisor. + * system.h (strsignal): Prototype it, if necessary. + (sys_siglist): Declare it, if necessary. -Sun Oct 26 09:21:40 1997 Jeffrey A Law (law@cygnus.com) +Sun Sep 13 04:37:28 1998 David S. Miller - * Makefile.in (LIBGCC2_CFLAGS): Add -fexceptions. + * loop.c (move_movables): While removing insn sequences, preserve + the next pointer of the most recently deleted insn when we skip + over a NOTE. - * alias.c (find_base_term): Handle PRE_INC, PRE_DEC, POST_INC, - and POS_DEC. +Sun Sep 13 08:13:39 1998 Ben Elliston - * alias.c (true_dependence): Fix typo. + * objc/config-lang.in: Do not output the name of the selected + thread file when building the front-end. The Makefile for the + runtime library will do this. - * toplev.c (flag_rerun_loop_opt): New variable. - (f_options): Handle -frerun-loop-opt. - (rest_of_compilation): If -frerun-loop-opt, then run the loop - optimizer twice. - (main): Enable -frerun-loop-opt by default for -O2 or greater. + * objc/Make-lang.in: Do not build the runtime library or install + the Objective C header files. The Makefile for the runtime + library will do this. - * loop.c (simplify_giv_expr): Adding two invariants results - in an invariant. + * objc/Makefile.in (all.indirect): Only build the front-end. + (compiler): Rename to `frontend'. + (obj-runtime): Remove target. + (copy-headers): Likewise. + (clean): No need to remove `libobjc.a' any longer. -Sun Oct 26 09:15:15 1997 Richard Henderson +Sat Sep 12 11:37:19 1998 Michael Meissner - * expr.c (get_inner_reference): Remove the array bias after - converting the index to Pmode. + * rs6000.h ({ASM,CPP}_CPU_SPEC): Add support for all machines + supported with -mcpu=xxx. -Sat Oct 25 12:20:58 1997 Jeffrey A Law (law@cygnus.com) +Fri Sep 11 23:55:54 1998 David S. Miller - * mn10300.h (TARGET_SWITCHES): Add -mmult-bug and -mno-mult-bug. - (TARGET_MULT_BUG): Define. - (TARGET_DEFAULT): Default to TARGET_MULT_BUG. - * mn10300.md (mulsi3): Handle TARGET_MULT_BUG. + * flow.c (mark_set_1): Recognize multi-register structure return + values in CALL insns. + (mark_used_regs): Likewise. + (count_reg_sets_1): Likewise. + (count_reg_references): Likewise. + * rtlanal.c (note_stores): Likewise. + (reg_overlap_mentioned_p): Likewise. + * haifa-sched.c (check_live_1): Likewise. + (update_live_1): Likewise. + (sched_analyze_1): Likewise. + (sched_note_set): Likewise. + (birthing_insn_p): Likewise. + (attach_deaths): Likewise. -Fri Oct 24 17:40:34 1997 Jeffrey A Law (law@cygnus.com) + * config/sparc/sparc.md (movdf_const_intreg_sp64): Disable. - * mn10200.c (indirect_memory_operand): Delete unused function. - * mn10200.h (EXTRA_CONSTRAINT): Handle 'R'. - * mn10200.md (bset, bclr insns): Handle output in a reg too. +Fri Sep 11 22:57:55 1998 Eric Dumazet -Fri Oct 24 15:54:57 1997 Richard Henderson + * config/i386/sco5.h (ASM_WEAKEN_LABEL): Defined as in svr4.h. - * alpha.md (call patterns): Revert Oct 16 change; if we are to elide - the callee's ldgp, we must do it ourselves, and we use the jsr tag - for more than scheduling. +Thu Sep 10 22:02:04 1998 David S. Miller -Fri Oct 24 13:23:04 1997 Doug Evans + * glimits.h (__LONG_MAX__): Recognize __sparcv9 too. - * sparc/sparc.h (ASM_SPEC): Delete asm_arch. +Thu Sep 10 21:19:10 1998 Jakub Jelinek -Fri Oct 24 13:19:40 1997 Jeffrey A Law (law@cygnus.com) + * configure.in: Add check for GAS subsection -1 support. + * acconfig.h (HAVE_GAS_SUBSECTION_ORDERING): Add. + * configure config.in: Rebuilt. + * config/sparc/sparc.h (CASE_VECTOR_MODE): For V9 flag_pic, use + SImode is subsection -1 works, else use DImode. + (ASM_OUTPUT_ADDR_VEC_START, ASM_OUTPUT_ADDR_VEC_END): Define if + subsection -1 works. + * config/sparc/sparc.c (sparc_output_addr_vec, + sparc_output_addr_diff_vec): Use them if defined. - * mn10300.c (symbolic_operand, legitimize_address): New functions. - * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address. - (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic. +Thu Sep 10 10:46:01 1998 Mark Mitchell -Thu Oct 23 09:35:12 1997 Jeffrey A Law (law@cygnus.com) + * tree.h (DECL_ORIGIN): New macro. + * integrate.c (copy_and_set_decl_abstract_origin): New function. + (copy_decl_list): Use it. + (integrate_parm_decls): Likewise. + (integrate_decl_tree): Likewise. + * dwarf2out.c (decl_ultimate_origin): Simplify. + * dwarfout.c (decl_ultimate_origin): Likewise. + * c-decl.c (duplicate_decls): Use DECL_ORIGIN. + (pushdecl): Likewise. - * version.c: Bump for snapshot. +Thu Sep 10 08:01:31 1998 Anthony Green -Thu Oct 23 08:03:59 1997 J"orn Rennecke + * config/rs6000/rs6000.c (output_epilog): Add Java support. - * dbxout.c (dbxout_start_new_source_file): Use output_quoted_string - for FILENAME. +Thu Sep 10 14:48:59 1998 Martin von Löwis -Wed Oct 22 00:34:12 1997 Jeffrey A Law (law@cygnus.com) + * invoke.texi (C++ Dialect Options): Document -fhonor-std. - * toplev.c (flag_exceptions): Default value is 2. - (compile_file): If flag_exceptions still has the value 2, then - set it to 0. +Thu Sep 10 01:38:05 1998 Jeffrey A Law (law@cygnus.com) - * rs6000.c (struct machine_function): Add pic_offset_table_rtx. - (rs6000_save_machine_status): Save pic_offset_table_rtx. - (rs6000_restore_machine_status: Restore pic_offset_table_rtx. + * reg-stack.c (straighten_stack): Do nothing if the virtual stack is + empty or has a single entry. - * local-alloc.c (block_alloc): Don't lose if two SCRATCH expressions - are shared. + * toplev.c (rest_of_compilation): Open up the dump file for reg-stack + before calling reg_to_stack. - * rs6000.md (*movsi_got_internal_mem): New pattern. - (*movsi_got_internal_mem splitter): New define_split. - -Tue Oct 21 18:14:03 1997 Jim Wilson - - * obstack.h (obstack_empty_p): Fix spurious space after backslash. - -Tue Oct 21 18:34:01 1997 Geoffrey KEATING - - * rs6000.c: Avoid creating a stack frame under SYSV ABI if we - only need to save LR. - -Tue Oct 21 10:06:40 1997 Jeffrey A Law (law@cygnus.com) - - * mn10300.md (movqi, movhi): Avoid using address registers as - destinations unless absolutely necessary. - - * mn10200.c (expand_prologue): Fix typo. - - * mn10200.h (GO_IF_LEGITIMATE_ADDRESS): Do not allow indexed - addresses. - * mn10200.md (neghi2): Provide an alternative which works if - the input and output register are the same. - - * mn10300.c (print_operand): Handle 'S'. - * mn10300.md (ashlsi3, lshrsi3, ashrsi3): Use %S for - shift amount in last alternative - - * mn10300.c (expand_epilogue): Rework to handle register restores - in "ret" and "retf" instructions correctly. - -Mon Oct 20 16:47:08 1997 Jim Wilson - - * expmed.c (extract_bit_field): Don't make flag_force_mem disable - extzv for memory operands. - - * cse.c (simplify_ternary_operation, case IF_THEN_ELSE): Collapse - redundant conditional moves to single operand. - -Mon Oct 20 15:30:26 1997 Nick Clifton - - * v850.h: Move define of __v850__ from CPP_PREDEFINES - to CPP_SPEC. - - * xm-v850.h: Use __v850 rather than __v850__ to - identify v850 port. - -Mon Oct 20 14:15:02 1997 Jim Wilson - - * mips/mips.c (compute_frame_size): Not a leaf function if - profile_flag set. - -Mon Oct 20 14:16:38 1997 Geoffrey KEATING - - * rs6000/t-ppccomm: Use -msdata=none for crtstuff. - -Mon Oct 20 12:28:17 1997 Doug Evans - - * sparc/sparc.h (SPARC_V9,SPARC_ARCH64): Delete. - (DEFAULT_ARCH32_P): New macro. - (TARGET_ARCH{32,64}): Allow compile time or runtime selection. - (enum cmodel): Declare. - (sparc_cmodel_string,sparc_cmodel): Declare. - (SPARC_DEFAULT_CMODEL): Provide default. - (TARGET_{MEDLOW,MEDANY}): Renamed to TARGET_CM_{MEDLOW,MEDANY}. - (TARGET_FULLANY): Deleted. - (TARGET_CM_MEDMID): New macro. - (CPP_CPU_DEFAULT_SPEC): Renamed from CPP_DEFAULT_SPEC. - (ASM_CPU_DEFAULT_SPEC): Renamed from ASM_DEFAULT_SPEC. - (CPP_PREDEFINES): Take out stuff now handled by %(cpp_arch). - (CPP_SPEC): Rewrite. - (CPP_ARCH{,32,64,_DEFAULT}_SPEC): New macros. - (CPP_{ENDIAN,SUBTARGET}_SPEC): New macros. - (ASM_ARCH{,32,64,_DEFAULT}_SPEC): New macros. - (ASM_SPEC): Add %(asm_arch). - (EXTRA_SPECS): Rename cpp_default to cpp_cpu_default. - Rename asm_default to asm_cpu_default. - Add cpp_arch32, cpp_arch64, cpp_arch_default, cpp_arch, cpp_endian, - cpp_subtarget, asm_arch32, asm_arch64, asm_arch_default, asm_arch. - (NO_BUILTIN_{PTRDIFF,SIZE}_TYPE): Define ifdef SPARC_BI_ARCH. - ({PTRDIFF,SIZE}_TYPE): Provide 32 and 64 bit values. - (MASK_INT64,MASK_LONG64): Delete. - (MASK_ARCH64): Renamed to MASK_64BIT. - (MASK_{MEDLOW,MEDANY,FULLANY,CODE_MODEL}): Delete. - (EMBMEDANY_BASE_REG): Renamed from MEDANY_BASE_REG. - (TARGET_SWITCHES): Always provide 64 bit options. - (ARCH64_SWITCHES): Delete. - (TARGET_OPTIONS): New option -mcmodel=. - (INT_TYPE_SIZE): Always 32. - (MAX_LONG_TYPE_SIZE): Define ifdef SPARC_BI_ARCH. - (INIT_EXPANDERS): sparc64_init_expanders renamed to sparc_init_.... - (FUNCTION_{,BLOCK_}PROFILER): Delete TARGET_EMBMEDANY support. - (PRINT_OPERAND_PUNCT_VALID_P): Add '_'. - * sparc/linux-aout.h (CPP_PREDEFINES): Take out stuff handled by - CPP_SPEC. - (CPP_SUBTARGET_SPEC): Renamed from CPP_SPEC. - * sparc/linux.h: Likewise. - * sparc/linux64.h (SPARC_V9,SPARC_ARCH64): Delete. - (ASM_CPU_DEFAULT_SPEC): Renamed from ASM_DEFAULT_SPEC. - (TARGET_DEFAULT): Delete MASK_LONG64, MASK_MEDANY, add MASK_64BIT. - (SPARC_DEFAULT_CMODEL): Define. - (CPP_PREDEFINES): Take out stuff handled by CPP_SPEC. - (CPP_SUBTARGET_SPEC): Renamed from CPP_SPEC. - (LONG_DOUBLE_TYPE_SIZE): Define. - (ASM_SPEC): Add %(asm_arch). - * sparc/sol2.h (CPP_PREDEFINES): Take out stuff handled by CPP_SPEC. - (CPP_SUBTARGET_SPEC): Renamed from CPP_SPEC. - (TARGET_CPU_DEFAULT): Add ultrasparc case. - * sparc/sp64-aout.h (SPARC_V9,SPARC_ARCH64): Delete. - (TARGET_DEFAULT): MASK_ARCH64 renamed to MASK_64BIT. - (SPARC_DEFAULT_CMODEL): Define. - * sparc/sp64-elf.h (SPARC_V9,SPARC_ARCH64): Delete. - (TARGET_DEFAULT): MASK_ARCH64 renamed to MASK_64BIT. Delete - MASK_LONG64, MASK_MEDANY. - (SPARC_DEFAULT_CMODEL): Define. - (CPP_PREDEFINES): Delete. - (CPP_SUBTARGET_SPEC): Renamed from CPP_SPEC. - (ASM_SPEC): Add %(asm_arch). - (LONG_DOUBLE_TYPE_SIZE): Define. - (DWARF2_DEBUGGING_INFO): Define. - * sparc/splet.h (CPP_SPEC): Delete. - * sparc/sysv4.h (CPP_PREDEFINES): Take out stuff handled by CPP_SPEC. - (FUNCTION_BLOCK_PROFILER): Delete TARGET_EMBMEDANY support. - (BLOCK_PROFILER): Likewise. - * sparc/sparc.c (sparc_cmodel_string,sparc_cmodel): New globals. - (sparc_override_options): Handle code model selection. - (sparc_init_expanders): Renamed from sparc64_init_expanders. - * sparc/sparc.md: TARGET_ renamed to TARGET_CM_.... - TARGET_MEDANY renamed to TARGET_CM_EMBMEDANY. - (sethi_di_embmedany_{data,text}): Renamed from sethi_di_medany_.... - (sethi_di_fullany): Delete. - -Mon Oct 20 02:00:18 1997 Klaus Kaempf - Jeff Law - Richard Kenner +Thu Sep 10 00:03:34 1998 Richard Henderson - * alpha/vms.h (DIVSI3_LIBCALL): OTS$ functions are upper case. - (DIVDI3_LIBCALL, UDIVSI3_LIBCALL, UDIVDI3_LIBVALL): Likewise. - (MODSI3_LIBCALL, MODDI3_LIBCALL): Likewise. - (UMODSI3_LIBCALL, UMODDI3_LIBCALL): Likewise. - * alpha/alpha.md (arg_home): Likewise. + * alpha.c (alphaev5_insn_pipe): Abort on default case. + (alphaev5_next_group): Swallow CLOBBERs and USEs. - * alpha/alpha.c (vmskrunch): Delete - * alpha/vms.h (ENCODE_SECTION_INFO, ASM_DECLARE_FUNCTION_NAME): Delete. - * alpha.c (output_prolog, VMS): Use alloca for entry_label and don't - truncate to 64 characters. + * c-tree.h (warn_long_long): Declare it. - * make-l2.com: Support openVMS/Alpha. +Wed Sep 9 23:31:36 1998 (Stephen L Moshier) - * vmsconfig.com: Fix to work on openVMS/Alpha and openVMS/VAX. + * emit-rtl.c (gen_lowpart_common): Disable optimization of + initialized float-int union if the value is a NaN. -Sun Oct 19 19:00:35 1997 J"orn Rennecke +Wed Sep 9 23:00:48 1998 Nathan Sidwell - * longlong.h (count_leading_zeros): Add missing casts to USItype. + * c-lex.c (real_yylex): Don't warn about long long constants if + we're allowing long long -Sun Oct 19 18:44:06 1997 Jeffrey A Law (law@cygnus.com) +Wed Sep 9 21:58:41 1998 Bernd Schmidt - * i386/bsd386.h (ASM_COMMENT_START): Define. + * except.h (current_function_eh_stub_label): Declare. + (current_function_eh_old_stub_label): Declare. + * function.h (struct function): New members eh_stub_label and + eh_old_stub_label. + * except.c (current_function_eh_stub_label): New variable. + (current_function_eh_old_stub_label): New variable. + (init_eh_for_function): Clear them. + (save_eh_status): Save them. + (restore_eh_status): Restore them. + (expand_builtin_eh_stub): Set current_function_eh_stub_label. + (expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label. + * flow.c (find_basic_blocks_1): When handling a REG_LABEL note, don't + make an edge from the block that contains it to the block starting + with the label if this label is one of the eh stub labels. + If eh stub labels exist, show they are reachable from the last block + in the function. -Sat Oct 18 13:47:15 1997 Jason Merrill + * reload1.c (reload): Break out several subroutines and make some + variables global. + (calculate_needs_all_insns): New function, broken out of reload. + (calculate_needs): Likewise. + (find_reload_regs): Likewise. + (find_group): Likewise. + (find_tworeg_group): Likewise. + (something_needs_reloads): New global variable, formerly in reload. + (something_needs_elimination): Likewise. + (caller_save_spill_class): Likewise. + (caller_save_group_size): Likewise. + (max_needs): Likewise. + (group_size): Likewise. + (max_groups): Likewise. + (max_nongroups): Likewise. + (group_mode): Likewise. + (max_needs_insn): Likewise. + (max_groups_insn): Likewise. + (max_nongroups_insn): Likewise. + (failure): Likewise. - * tree.c (restore_tree_status): Also free up temporary storage - when we finish a toplevel function. - (dump_tree_statistics): Print stats for backend obstacks. + * print-rtl.c (print_rtx): For MEMs, print MEM_ALIAS_SET. -Sat Oct 18 12:47:31 1997 Doug Evans +Wed Sep 9 13:14:41 1998 Richard Henderson - * expr.c (use_group_regs): Don't call use_reg for MEMs. + * loop.c (load_mems): Copy rtx for output mem. -Sat Oct 18 09:49:46 1997 Jason Merrill - - * libgcc2.c (__throw): Don't copy the return address. - * dwarf2out.c (expand_builtin_dwarf_reg_size): Ignore return address. - - * except.c (exceptions_via_longjmp): Initialize to 2 (uninitialized). - * toplev.c (main): Initialize exceptions_via_longjmp. - - * tree.c: Add extra_inline_obstacks. - (save_tree_status): Use it. - (restore_tree_status): If this is a toplevel inline obstack and we - didn't want to save anything on it, recycle it. - (print_inline_obstack_statistics): New fn. - * function.c (pop_function_context_from): Pass context to - restore_tree_status. - * obstack.h (obstack_empty_p): New macro. - -Sat Oct 18 00:43:59 1997 Jeffrey A Law (law@cygnus.com) - - * i386/freebsd.h (ASM_COMMENT_START): Fix. - -Fri Oct 17 23:48:52 1997 Jim Wilson (wilson@cygnus.com) - - * v850.c (ep_memory_offset): New function. - (ep_memory_operand, substitute_ep_register, v850_reorg): Call it. - - * v850.h (CONST_OK_FOR_*): Add and correct comments. - (CONSTANT_ADDRESS_P): Add comment. - (EXTRA_CONSTRAINT): Define 'U'. - * v850.md: Add comments on bit field instructions. - (addsi3): Delete &r/r/r alternative. Add r/r/U alternative. - (lshrsi3): Use N not J constraint. - - * v850.md (v850_tst1+1): New define_split for tst1 instruction. - - * v850.c (reg_or_0_operand): Call register_operand. - (reg_or_int5_operand): Likewise. - * v850.h (MASK_BIG_SWITCH, TARGET_BIG_SWITCH): New macros. - (TARGET_SWITCHES): Add "big-switch". - (ASM_OUTPUT_ADDR_VEC_ELT, ASM_OUTPUT_ADDR_DIFF_ELT, CASE_VECTOR_MODE, - ASM_OUTPUT_BEFORE_BASE_LABEL): Add support for TARGET_BIG_SWITCH. - (CASE_DROPS_THROUGH): Comment out. - (CASE_VECTOR_PC_RELATIVE, JUMP_TABLES_IN_TEXT_SECTION): Define. - * v850.md (cmpsi): Delete compare mode. - (casesi): New pattern. - - * v850.h (CONST_OK_FOR_N): Delete redundant compare against zero. - * v850.md (ashlsi3): Use SImode not QImode for shift count. - (lshrsi3): Likewise. - - * v850.c (print_operand): Add 'c', 'C', and 'z' support. Delete - unreachable switch statement after 'b' support. Remove "b" from - strings for 'b' support. - * v850.md (branch_normal, branch_invert): Change %b to b%b. - -Fri Oct 17 23:33:20 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (LIBGCC2_CFLAGS): Avoid a backslash then an - empty line if @inhibit_libc@ is empty. - -Fri Oct 17 23:24:40 1997 Robert Lipe (robertl@dgii.com) - - * i386/sco5.h: Let ELF use dwarf2 unwinding. COFF uses sjlj. - (EH_FRAME_SECTION_ASM_OP, EH_FRAME_SECTION_ASM_OP_ELF): Defined. - (EH_FRAME_SECTION_ASM_OP_COFF): Likewise. - (DWARF2_UNWIND_INFO): Let this track object file format. - (EXTRA_SECTIONS): Add in_eh. - (EH_FRAME_SECTION_ASM_OP, EH_FRAME_SECTION_ASM_OP_ELF): Define. - (EH_FRAME_SECTION_ASM_OP_COFF): Likewise. - -Fri Oct 17 17:13:42 1997 David S. Miller - - * sparc/linux64.h (LINK_SPEC): Dynamic linker is ld-linux64.so.2. - * sparc/sparc.h (FUNCTION_PROFILER): Fix format string when - TARGET_MEDANY. - * sparc/sparc.c (dwarf2out_cfi_label): Extern no longer needed. - (output_double_int): Output DI mode values correctly when - HOST_BITS_PER_WIDE_INT is 64. - (output_fp_move_quad): If TARGET_V9 and not TARGET_HARD_QUAD, use - fmovd so it works if a quad float ends up in one of the upper 32 - float regs. - * sparc/sparc.md (pic_{lo_sum,sethi}_di): New patterns - necessary for PIC support on sparc64. - -Fri Oct 17 13:39:56 1997 Doug Evans - - * sparc/sp64-elf.h (TARGET_DEFAULT): Delete MASK_STACK_BIAS. - * sparc/sparc.h (PROMOTE_MODE): Promote small ints if arch64. - (PROMOTE_FUNCTION_ARGS,PROMOTE_FUNCTION_RETURN): Define. - (SPARC_FIRST_FP_REG, SPARC_FP_REG_P): New macros. - (SPARC_{OUTGOING,INCOMING}_INT_ARG_FIRST): New macros. - (SPARC_FP_ARG_FIRST): New macro. - (CONDITIONAL_REGISTER_USAGE): All v9 fp regs are volatile now. - (REG_ALLOC_ORDER,REG_LEAF_ALLOC_ORDER): Reorganize fp regs. - (NPARM_REGS): There are 32 fp argument registers now. - (FUNCTION_ARG_REGNO_P): Likewise. - (FIRST_PARM_OFFSET): Update to new v9 abi. - (REG_PARM_STACK_SPACE): Define for arch64. - (enum sparc_arg_class): Delete. - (sparc_arg_count,sparc_n_named_args): Delete. - (struct sparc_args): Redefine and use for arch32 as well as arch64. - (GET_SPARC_ARG_CLASS,ROUND_REG,ROUND_ADVANCE): Delete. - (FUNCTION_ARG_ADVANCE): Rewrite. - (FUNCTION_ARG,FUNCTION_INCOMING_ARG): Rewrite. - (FUNCTION_ARG_{PARTIAL_NREGS,PASS_BY_REFERENCE}): Rewrite. - (FUNCTION_ARG_CALLEE_COPIES): Delete. - (FUNCTION_ARG_{PADDING,BOUNDARY}): Define. - (STRICT_ARGUMENT_NAMING): Define. - (doublemove_string): Declare. - * sparc/sparc.c (sparc_arg_count,sparc_n_named_args): Delete. - (single_move_string): Use GEN_INT, and HOST_WIDE_INT. - (doublemove_string): New function. - (output_move_quad): Clean up some of the arch64 support. - (compute_frame_size): Add REG_PARM_STACK_SPACE if arch64. - Don't add 8 bytes of reserved space if arch64. - (sparc_builtin_saveregs): Combine arch32/arch64 versions. - (init_cumulative_args): New function. - (function_arg_slotno): New static function. - (function_arg,function_arg_partial_nregs): New functions. - (function_arg_{pass_by_reference,advance}): New functions. - (function_arg_padding): New function. - * ginclude/va-sparc.h: Rewrite v9 support. - -Fri Oct 17 12:29:48 1997 Christian Iseli - - * regclass.c (record_address_regs): Look at REG_OK_FOR_{BASE,INDEX}_P - for hard regs to determine base and index registers. - - * reload.c (debug_reload_to_stream): New function. Specify stream - into which to write debug info. - (debug_reload): Modify to call debug_reload_to_stream with stderr. - -Thu Oct 16 15:07:51 1997 Richard Henderson - - * combine.c (can_combine_p): Don't combine with an asm whose - output is a hard register. - -Thu Oct 16 15:43:26 1997 Mike Stump (mrs@wrs.com) - - * c-decl.c (start_struct): Ensure that structs with forward - declarations are in fact packed when -fpack-struct is given. - - * stor-layout.c (layout_record): Ignore STRUCTURE_SIZE_BOUNDARY if - we are packing a structure. This allows a structure with only - bytes to be aligned on a byte boundary and have no padding on a - m68k. - -Thu Oct 16 15:17:54 1997 Richard Kenner - - * rs6000.h (ROUND_TYPE_ALIGN): Don't blow up if no fields in record. - -Thu Oct 16 11:20:30 1997 Richard Henderson - - * alpha.c (alpha_return_addr_rtx): New variable. - (alpha_save_machine_status): New; save it. - (alpha_restore_machine_status): New; restore it. - (alpha_init_expanders): New; clear it. - (alpha_return_addr): New; set it. - (alpha_ra_ever_killed): New; if alpha_return_addr_rtx, regs_ever_live - is overly conservative, so search the insns explicitly. - (alpha_sa_mask [VMS]): Check alpha_ra_ever_killed. - (alpha_sa_size [VMS && !VMS]): Likewise. - * alpha.h (RETURN_ADDR_RTX): Call alpha_return_addr. - (INIT_EXPANDERS): New definition. - - * alpha.c: Move REG_PV, REG_RA somewhere more visible in the file. - (output_prolog [!VMS]): Use them. - - * alpha.c (output_prolog [!VMS]): Move gp detection to ... - (alpha_does_function_need_gp): ... a new function. Refine the - CALL_INSN test to just TYPE_JSR. - * alpha.md (most call insns): Fix some jsr/ibr type transpositions. - -Thu Oct 16 09:36:47 1997 Jeffrey A Law (law@cygnus.com) +Wed Sep 9 15:16:58 1998 Gavin Romig-Koch - * version.c: Bump for snapshot. + * mips/abi64.h (LONG_MAX_SPEC): Don't set LONG_MAX for + mips1 or mips2 either. -Wed Oct 15 21:38:18 1997 Richard Kenner +Wed Sep 9 12:31:35 1998 Jeffrey A Law (law@cygnus.com) - * pa.c (move_operand): Respect -mdisable-indexing. - * pa.h (GO_IF_LEGITIMATE_ADDRESS): Likewise. + * pa.c (pa_reorg): New marking scheme for jumps inside switch + tables. + (pa_adjust_insn_length): Update to work with new marking scheme + for jumps inside switch tables. + * pa.md (switch_jump): Remove pattern. + (jump): Handle jumps inside jump tables. -Wed Oct 15 21:34:45 1997 David Edelsohn + * Makefile.in (profile.o): Depend on insn-config.h - * rs6000.md (udivsi3, divsi3): Split into MQ and non-MQ cases for - PPC601. - (umulsidi3,umulsi3_highpart): Ditto. - (smulsi3_highpart_no_mq): Add !TARGET_POWER. +Wed Sep 9 09:36:51 1998 Jim Wilson -Wed Oct 15 18:21:46 1997 Richard Henderson + * iris6.h (DWARF2_UNWIND_INFO): Undef. - * alpha.c (final_prescan_insn): Gut, remove and transform to ... - (alpha_handle_trap_shadows): ... a new function. Handle the entire - function in one go. Emit RTL for trapb, instead of printf directly. - (alpha_reorg): New function. Call alpha_handle_trap_shadows. - (trap_pending): Kill global variable. - (output_epilog): Don't call final_prescan_insn. - (struct shadow_summary): Elide $31 and $f31; now it fits in a word. - * alpha.h (FINAL_PRESCAN_INSN): Remove. - (MACHINE_DEPENENT_REORG): Define. - * alpha.md (jsr patterns with trapb): Stupid and useless. Kill. - (trapb): New insn. +Wed Sep 9 01:32:01 1998 David S. Miller -Wed Oct 15 18:16:05 1997 Richard Henderson + Add preliminary native sparcv9 Solaris support. + * configure.in: Recognize sparv9-*-solaris2* + * configure: Rebuilt. + * config.sub: Recognize sparcv9 just like sparc64. + * config/sparc/sol2-c1.asm config/sparc/sol2-ci.asm + config/sparc/sol2-cn.asm: Macroize so it can be shared between + 32-bit and 64-bit Solaris systems. + * config/sparc/t-sol2: Assemble those with cpp. + * config/sparc/sparc.h (TARGET_CPU_sparcv9): New alias for v9. + (*TF*_LIBCALL): If ARCH64 use V9 names. + * config/sparc/{xm-sysv4-64,sol2-sld-64}.h: New files. + +Wed Sep 9 01:07:30 1998 Jakub Jelinek + + * config/sparc/sparc.h (TARGET_CM_MEDMID): Fix documentation. + (CASE_VECTOR_MODE): Set to SImode even if PTR64, when MEDLOW and + not doing pic. + (ASM_OUTPUT_ADDR_{VEC,DIFF}_ELT): Check CASE_VECTOR_MODE not + Pmode. + * config/sparc/sparc.md (tablejump): Likewise, and sign extend op0 + to Pmode if CASE_VECTOR_MODE is something else. + +Wed Sep 9 00:10:31 1998 Jeffrey A Law (law@cygnus.com) + + * prefix.c (update_path): Correctly handle cases where PATH is + a substring of the builtin prefix, but specifies a different + directory location. + +Tue Sep 8 23:46:04 1998 Hans-Peter Nilsson + + * expr.c: Corrected comment about what MOVE_RATIO does. + * config/alpha/alpha.h: Likewise. + * config/1750a/1750a.h: Likewise. + * config/clipper/clipper.h: Likewise. + * config/i386/i386.h: Likewise. + +Tue Sep 8 22:56:12 1998 Jeffrey A Law (law@cygnus.com) + + * configure.in (m68k-next-nextstep3*): Use collect2. + Similarly for x86 NeXT configurations. + * configure: Rebuilt. - Tune Haifa scheduler for Alpha: - * alpha.h (ISSUE_RATE): Define. - * alpha.c (alpha_adjust_cost): Handle EV5 mult delay; don't apply - EV4 adjustments to EV5. - * alpha.md: Remove all scaling from function unit delays. Rework - EV5 function units to match the CPU. - (umuldi3_highpart): EV5 added the IMULH insn class. +Tue Sep 8 01:38:57 1998 Nathan Sidwell -Wed Oct 15 17:42:41 1997 Jeffrey A Law (law@cygnus.com) + * configure.in: Don't assume srcdir is .../gcc. + * configure: Rebuilt. - * pa.c (following_call): Fail if the CALL_INSN is an indirect - call. +Sat Sep 5 16:34:34 1998 John Wehle (john@feith.com) -Tue Oct 14 12:01:00 1997 Mark Mitchell + * global.c: Update comments. + (global_alloc): Assign allocation-numbers + even for registers allocated by local_alloc in case + they are later spilled and retry_global_alloc is called. + (mark_reg_store, mark_reg_clobber, + mark_reg_conflicts, mark_reg_death): Always record a + conflict with a pseudo register even if it has been + assigned to a hard register. + (dump_conflicts): Don't list pseudo registers already assigned to + a hard register as needing to be allocated, but do list their + conflicts. + * local-alloc.c: Update comment. - * cplus-dem.c (demangle_signature): Don't look for return types on - constructors. Handle member template constructors. +Mon Sep 7 23:38:01 1998 Jeffrey A Law (law@cygnus.com) -Tue Oct 14 11:30:29 1997 Jason Merrill + * configure.in: Check for bogus GCC_EXEC_PREFIX and LIBRARY_PATH. + * configure: Rebuilt. - * tree.c (expr_tree_cons, build_expr_list, expralloc): New fns. - * tree.h: Declare them. +Mon Sep 7 22:41:46 1998 Michael Meissner -Fri Oct 10 13:46:56 1997 Doug Evans + * rs6000.c (rs6000_override_options): Fix name for ec603e, to add + missing 'c'. + * t-ppccomm (MULTILIB_MATCHES_FLOAT): Add support for -mcpu=xxx + for all targets that set -msoft-float. - * configure.in: Handle --with-newlib. - * Makefile.in (LIBGCC2_CFLAGS): Add @inhibit_libc@. +Mon Sep 7 23:30:07 1998 Kaveh R. Ghazi - * sparc/t-sp64 (LIBGCC2_CFLAGS): Delete. + * toplev.c (print_switch_values): Make static to match prototype. -Wed Oct 8 14:37:44 1997 Jeffrey A Law (law@cygnus.com) +Mon Sep 7 19:13:59 1998 Jeffrey A Law (law@cygnus.com) - * config/ptx4.h: Fix typo. + * configure.in: If we are unable to find the "gnatbind" program, + then do not configure the ada subdir. + * configure: Rebuilt. -Wed Oct 8 08:57:20 1997 Jeffrey A Law (law@cygnus.com) +Sun Sep 6 14:03:58 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. -Tue Oct 7 16:27:34 1997 Manfred Hollstein +Sun Sep 6 13:28:07 1998 Jeff Law (law@cygnus.com) + + * version.c: Bump for snapshot. - * aclocal.m4: Substitute INSTALL. - * configure: Re-built. +Sun Sep 6 08:54:14 1998 Kaveh R. Ghazi + + * Makefile.in (toplev.o): Depend on $(EXPR_H). + (insn-extract.o, insn-attrtab.o): Depend on toplev.h. + + * gansidecl.h: Define ATTRIBUTE_NORETURN. + + * genattrtab.c: Have insn-attrtab.c include toplev.h. + + * genextract.c: Have insn-extract.c include toplev.h. + + * rtl.h: Don't prototype `fatal_insn_not_found' and `fatal_insn'. + + * toplev.c: Include expr.h. + (really_sorry, fancy_abort): Remove prototypes. + (set_target_switch): Add argument in prototype. + (vfatal): Mark prototype with ATTRIBUTE_NORETURN. + (v_really_sorry): Likewise. + (print_version, print_single_switch, print_switch_values): Make + static and add prototype arguments. + (decl_printable_name): Add prototype arguments. + (lang_expand_expr_t): New typedef. + (lang_expand_expr): Declare as a lang_expand_expr_t. + (incomplete_decl_finalize_hook): Add prototype argument. + (decl_name): Mark variable `verbosity' with ATTRIBUTE_UNUSED. + (botch): Likewise for variable `s'. + (rest_of_type_compilation): Mark variables `type' and `toplev' + with ATTRIBUTE_UNUSED if none of DBX_DEBUGGING_INFO, + XCOFF_DEBUGGING_INFO or SDB_DEBUGGING_INFO are defined. + (display_help): Make variable `i' an `unsigned long'. + (main): Remove unused parameter `envp'. + Cast assignment to `lang_expand_expr' to a `lang_expand_expr_t'. + Cast -1 when comparing it with a `size_t'. + + * toplev.h (fatal, fatal_io_error, pfatal_with_name): Mark + prototype with ATTRIBUTE_NORETURN. + (fatal_insn_not_found, fatal_insn, really_sorry, + push_float_handler, pop_float_handler): Add prototypes. + (fancy_abort): Mark prototype with ATTRIBUTE_NORETURN. + (do_abort, botch): Add prototypes. + +Sat Sep 6 12:05:18 1998 John Carr + + * final.c (final): If a label is reached only from a single jump, + call NOTICE_UPDATE_CC on the jump and its predecessor before + emitting the insn after the label. + + * i386.h: Add AMD K6 support. + Change TARGET_* macros to use table lookup. + (INITIALIZE_TRAMPOLINE): Improve trampoline code. + (ADJUST_COST): Change definition to call function in i386.c. + (ISSUE_RATE): Define as 2 for anything newer than an 80486. + * i386.c: Add AMD K6 support. + Add constants for feature tests used by TARGET_* macros. + (split_di): If before reload, call gen_lowpart and gen_highpart. + (x86_adjust_cost): New function. + (put_jump_code): New function. + (print_operand): New codes 'D' and 'd'. + * i386.md: New insn types. New insn attribute "memory". + Redefine scheduling parameters to use new types and add AMD K6 + support. Explicitly set type of most insns. + (move insns): K6 prefers movl $0,reg to xorl reg,reg. Pentium + Pro and K6 prefer movl $1,reg to incl reg. + (adddi3, subdi3): Set cc_status. + (DImode shift patterns): Change label counters from HOST_WIDE_INT + to int; x86 can't have more than 2^31 DImode shifts per file. + (setcc): Combine all setcc patterns. Allow writing memory. + Combine all jump patterns using match_operator. + (*bzero): Name pattern. Emit multiple stos instructions when that + is faster than rep stos. + (xordi3, anddi3, iordi3): Simplify DImode logical patterns and + add define_split. + +Sun Sep 6 11:17:20 1998 Dave Love + + * config/m68k/x-next (BOOT_LDFLAGS): Define suitably for f771 + linking. + +Sat Sep 5 22:05:25 1998 Richard Henderson -Tue Oct 7 15:37:35 1997 Jeffrey A Law (law@cygnus.com) + * alpha.c (alpha_ra_ever_killed): Inspect the topmost sequence, + not whatever we're generating now. - * integrate.c (save_for_inline_copying): Avoid undefined pointer - operations. - (expand_inline_function): Likewise. + * alpha.c (set_frame_related_p, FRP): New. + (alpha_expand_prologue): Mark frame related insns. + (alpha_expand_epilogue): Likewise, but with a null FRP. + * alpha.h (INCOMING_RETURN_ADDR_RTX): New. + * alpha.md (exception_receiver): New. + * alpha/crtbegin.asm (.eh_frame): New beginning. + (__do_frame_setup, __do_frame_takedown): New. + * alpha/crtend.asm (.eh_frame): New ending. + * alpha/elf.h (DWARF2_DEBUGGING_INFO): Define. + (ASM_SPEC): Don't emit both dwarf2 and mdebug. + (ASM_FILE_START): Don't emit .file for dwarf2. - * dwarf2out.c (output_call_frame_info): Reinstate last change - using flag_debug_asm check instead of flag_verbose_asm. + * rtl.h (enum reg_note): Add REG_FRAME_RELATED_EXPR. + * rtl.c (reg_note_name): Likewise. + * rtl.texi (REG_NOTES): Likewise. + * dwarf2out.c (dwarf2out_frame_debug): Use it. Recognize a store + without an offset. -Tue Oct 7 12:57:26 1997 Jim Wilson +Sat Sep 5 14:47:17 1998 Richard Henderson - * dwarf2out.c (output_call_frame_info): Remove last change. + * i386.h (PREFERRED_RELOAD_CLASS): Standard fp constants load to TOS. + * i386.md (movsf, movdf, movxf): Validate memory address returned + from force_const_mem. Kill useless REG_EQUAL setting code. -1997-10-04 Andreas Schwab +Sat Sep 5 14:23:31 1998 Torbjorn Granlund - * frame.c (__frame_state_for): Execute the FDE insns until the - current pc value is strictly bigger than the target pc value. + * m68k.md (zero_extendsidi2): Fix typo. -Tue Oct 7 11:00:42 1997 Jason Merrill +Sat Sep 5 13:40:24 1998 Krister Walfridsson - * regclass.c (init_reg_modes): If we can't find a mode for the - register, use the previous one. + * configure.in: Removed references to the removed file. + * config/xm-netbsd.h: Use ${cpu_type}/xm-netbsd.h for + arm*-*-netbsd* and ns32k-*-netbsd*. + * config/i386/xm-netbsd.h: Removed unnecessary file. + * config/m68k/xm-netbsd.h: Likewise. + * config/sparc/xm-netbsd.h: Likewise. + * config/mips/xm-netbsd.h: Likewise. -Tue Oct 7 10:55:34 1997 Richard Henderson +Sat Aug 29 13:32:58 1998 Mumit Khan - * haifa-sched.c (print_block_visualization): Call fprintf directly, - don't sprintf through an alloca'ed buffer. + * i386/cygwin32.h (BIGGEST_ALIGNMENT): Define. + (PCC_BITFIELD_TYPE_MATTERS): Define to be 0. -Tue Oct 7 10:52:29 1997 Thomas Koenig (ig25@rz.uni-karlsruhe.de) + * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't check for + for exact section attributions. - * reload.c (decompose): Always initialize val.base. + * i386/mingw32.h (CPP_PREDEFINES): Add __MSVCRT__ for msvc + runtime. + * i386/crtdll.h (CPP_PREDEFINES): Define. -Tue Oct 7 10:19:26 1997 Manfred Hollstein (manfred@lts.sel.alcatel.de) +Sat Sep 5 03:23:05 1998 Jeffrey A Law (law@cygnus.com) - * m68k/mot3300.h (ASM_OUTPUT_ALIGN): Accept any alignment - instead of aborting. - * dwarf2out.c (output_call_frame_info): Call app_enable and - app_disable to let GNU as accept the generated comments. + * m68k.md (5200 movqi): Do not allow byte sized memory references + using address regs. + * m68k.c (output_move_qimode): Do not use byte sized operations on + address registers. -Tue Oct 7 11:41:21 1997 Michael Meissner + * Makefile.in (pexecute.o): Use pexecute.c from libiberty. Provide + explicit rules for building. Similarly for alloca, vfprintf, + choose-temp and mkstemp, getopt, getopt1, and obstack. + (INCLUDES): Add $(srcdir)/../include. + * pexecute.c, alloca.c, vfprintf.c, choose-temp.c, mkstemp.c: Delete. + * getopt.h, getopt.c getopt1.c, obstack.c, obstack.h: Likewise. - * tree.h (get_file_function_name): Add declaration. - * dwarf2out.c (output_call_frame_info): No need to cast - get_file_function_name call anymore. - * profile.c (toplevel): Remove get_file_function_name - declaration. - * c-lang.c (finish_file): Ditto. +Fri Sep 4 11:57:50 1998 Tom Tromey -Tue Oct 7 10:01:45 1997 Chip Salzenberg + * gcc.c (do_spec_1): [case 'o'] Account for + lang_specific_extra_outfiles. + (main): Correctly clear all slots in outfiles for + lang_specific_extra_outfiles. Set input_file_number before + calling lang_specific_pre_link. - * Makefile.in (program_transform_name): Let autoconf substitute - the correct value. +Fri Sep 4 10:37:07 1998 Jim Wilson -Tue Oct 7 09:54:35 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (load_mems): Fix JUMP_LABEL field after for_each_rtx call. - * haifa-sched.c (schedule_block): If the first real insn in a - block has any special notes attached to it, remove them. +Fri Sep 4 02:01:05 1998 David S. Miller -Tue Oct 7 09:48:51 1997 Richard Henderson + * config/sparc/sparc.c (output_double_int): In all V9 symbolic + cases, use xword. + (sparc_output_deferred_case_vectors): If no work to do, return. + Fix thinko in Sept 1 change. - * alpha.h (FLOAT_STORE_FLAG_VALUE): It's 2.0 not 0.5. +1998-09-03 SL Baur -Mon Oct 6 12:47:32 1997 Manfred Hollstein (manfred@lts.sel.alcatel.de) + * Makefile.in: Add semicolon in BISON definition for portability. - * m88k.c (m88k_begin_prologue): Remove superfluous backslash. +Thu Sep 3 13:34:41 1998 Toon Moene -Mon Oct 6 12:04:24 1997 Jeffrey A Law (law@cygnus.com) + * config/nextstep.c (handle_pragma): Correct name of third + argument. - * Makefile.in (check-g77): New test target. - (CHECK-TARGETS): Add check-g77. +Tue Sep 1 11:30:33 1998 Nick Clifton -Fri Oct 3 11:56:36 1997 Jason Merrill + * config/m32r/m32r.md: Change (reg:CC 17) to (reg:SI 17). + * config/m32r/m32r.h: Make register 17 be fixed. + * config/m32r/m32r.c: Use SImode for cc operations. - * toplev.c (rest_of_compilation): Defer all non-nested inlines. +Thu Sep 3 18:17:34 1998 Benjamin Kosnik -Fri Oct 3 15:49:27 1997 Michael Meissner + * invoke.texi (Warning Options): Add -Wnon-template-friend + documentation. - * flow.c (print_rtl_with_bb): Cast alloca return value for - in_bb_p. +Thu Sep 3 18:16:16 1998 Michael Meissner -Thu Oct 2 21:15:03 1997 Richard Henderson + * rs6000.c (rs6000_override_options): Add -mcpu={401,e603e}. - * i386.h (RETURN_ADDR_RTX): New definition that works for - __builtin_return_address(0) and -fomit-frame-pointer. +Thu Sep 3 18:05:16 1998 David Edelsohn -Wed Oct 1 13:43:53 1997 Jim Wilson + * rs6000.md (movsf): Disable explicit secondary-reload-like + functionality if TARGET_POWERPC64. + (movdf): Remove TARGET_POWERPC64 explicit secondary-reload-like + functionality. - Bring over from FSF. - Tue Aug 5 16:10:45 1997 Jason Merrill +Thu Sep 3 11:41:40 1998 Robert Lipe - * mips.c (function_arg): Handle passing a struct - containing a double in a DFmode register without the PARALLEL. + * fixinc.sco: Borrow code to wrap 'bool' typedefs from tinfo.h + and term.h from fixinc.wrap. -Wed Oct 1 11:13:25 1997 Ian Lance Taylor +Thu Sep 3 09:47:31 1998 Kaveh R. Ghazi - * pexecute.c: Use spawn if __CYGWIN32__. + * aclocal.m4 (GCC_HEADER_STRING): New macro to detect if it is + safe to include both string.h and strings.h together. + (GCC_NEED_DECLARATION): Test STRING_WITH_STRINGS when deciding + which headers to search for function declarations. Continue to + prefer string.h over strings.h when both are not acceptable. - * pexecute.c: Include "config.h" first, as per autoconf manual - (from Paul Eggert ). + * acconfig.h (STRING_WITH_STRINGS): Add stub. -Wed Oct 1 01:44:36 1997 Philippe De Muyter + * configure.in: Call GCC_HEADER_STRING. - * m68k/x-mot3300 (XCFLAGS): Disable as's long/short jump - optimisation for f/expr.o and f/stb.o. + * system.h: Test STRING_WITH_STRINGS when deciding which headers + to include. Continue to prefer string.h over strings.h when both + are not acceptable. -Tue Sep 30 23:48:57 1997 Jeffrey A Law (law@cygnus.com) +Wed Sep 2 23:56:29 1998 David S. Miller - * cse.c (this_insn_cc0_mode): Initialize. + * config/sparc/sparc.c (output_double_int): If V9 and MEDLOW, do + not assume top 32-bits of symbolic addresses are zero if + flag_pic. -Tue Sep 30 23:09:40 1997 Thomas Koenig +Thu Sep 3 00:23:21 1998 Richard Henderson - * cccp.c (expand_to_temp_buffer): Initialize all members of obuf. + * ginclude/va-alpha.h: Protect entire second portion of the + file against double inclusion. - * haifa-sched.c (get_block_head_tail): Remove unneeded initialization. +Thu Sep 3 00:37:55 1998 Ovidiu Predescu -Tue Sep 30 23:06:43 1997 Richard Henderson + Added support for the Boehm's garbage collector. + * configure.in: Handle --enable-objc-gc. + * configure: Rebuilt. + * Makefile.in (CHECK_TARGETS): Add check-objc. + (check-objc): New rule. + * objc/Make-lang.in: Build a different Objective-C library that + runs with the Boehm's collector. + * objc/encoding.c (objc_round_acc_size_for_types): New function. + * objc/encoding.c: Correctly compute the size of compound types in + the presence of bitfields. Skip the variable name of the type if + any. Added support for long long. + * objc/encoding.h (_C_GCINVISIBLE): New specifier. + (_F_GCINVISIBLE): New mask. + * objc/gc.c: New file. Compute the type memory mask associated with + a class based on the runtime information. + * objc/misc.c: Added the hooks that use the Boehm's collector + allocation functions. + * objc/objc-act.c (build_class_template): Generate a new class + member (gc_object_type) to hold the class' type memory mask. + (build_shared_structure_initializer): Initialize the new member to + NULL. + (encode_complete_bitfield): New function. Generate the new + encoding. + (encode_field_decl): Generate the new encoding only for the GNU + runtime. + * objc/objc-api.h (_C_LNG_LNG, _C_ULNG_LNG): New specifiers for the + long long types. + (class_get_gc_object_type): New function to mark a pointer instance + variable as a weak pointer. + * objc/objc-features.texi: New file. + * objc/objc.h (gc_object_type): New class member. + * objc/objects.c (class_create_instance): Create a typed memory + object when compiled with Boehm's collector support. + * objc/sendmsg.c (__objc_init_install_dtable): Call + __objc_send_initialize instead of setting the initialize flag. + (__objc_send_initialize): Call __objc_generate_gc_type_description + to generate the class type memory mask. Rewrite the code that + sends the +initialize so that it is called only once (bug report + and fix from Ronald Pijnacker ). + * testsuite/objc: New testsuite for Objective-C type encoding. + * testsuite/lib/objc-torture.exp: New file. + * testsuite/lib/objc.exp: New file. - * alpha.md (beq): For registers and ints 0-255, use cmpeq+bne, since - that pair will dual-issue on the 21164 and plus+beq won't. - (bne): Likewise for cmpeq+beq. +Wed Sep 2 14:47:36 1998 Jim Wilson -Tue Sep 30 16:07:58 1997 Jim Wilson + * jump.c (jump_optimize): In if/then/else transformations, add + another call to modified_between_p for the jump insn. - * except.c (find_exception_handler_labels): Correct argument to free. +Wed Sep 2 14:16:49 1998 Jeffrey A Law (law@cygnus.com) -Tue Sep 30 11:00:00 1997 Brendan Kehoe + * fix-header.c (symlink): Treat like readlink. - * except.c (find_exception_handler_labels): Free LABELS when we're - done. +Wed Sep 2 19:30:06 1998 J"orn Rennecke -Mon Sep 29 14:04:35 1997 Jeffrey A Law (law@cygnus.com) + * dwarfout.c (fundamental_type_code): Encode 32 bit floats/doubles + as FT_float. - * version.c: Bump for snapshot. +Wed Sep 2 10:06:07 1998 Nick Clifton -Mon Sep 29 10:51:53 1997 Jason Merrill + * config/nextstep.h: Update HANDLE_PRAGMA macro. + * config/h8300/h8300.h: Update HANDLE_PRAGMA macro. + * config/i960/i960.h: Update HANDLE_PRAGMA macro. - * flow.c (find_basic_blocks): Mark calls as potentially jumping - to the EH labels. + * config/nextstep.c (handle_pragma): Take three arguments, as per + the new HANDLE_PRAGMA macro specification. + * config/h8300/h8300.c (handle_pragma): Take three arguments, as + per the new HANDLE_PRAGMA macro specification. + * config/i960/i960.c (process_pragma): Take three arguments, as + per the new HANDLE_PRAGMA macro specification. -Mon Sep 29 09:58:06 1997 Jeffrey A Law (law@cygnus.com) +Wed Sep 2 09:25:29 1998 Nick Clifton - * configure.in: Substitute for "install" too. - * configure: Rebuilt. + * c-lex.c (check_newline): Call HANDLE_PRAGMA before + HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages + if unknown pragmas are encountered. + (handle_sysv_pragma): Interpret return code from + handle_pragma_token (). Return success/failure indication rather + than next unprocessed character. + (pragma_getc): New function: retrieves characters from the + input stream. Defined when HANDLE_PRAGMA is enabled. + (pragma_ungetc): New function: replaces characters back into the + input stream. Defined when HANDLE_PRAGMA is enabled. -Mon Sep 29 00:38:42 1997 Aaron Jackson + * c-pragma.c (handle_pragma_token): Return success/failure status + of the parse. - * Makefile.in (bootstrap-lean, compare-lean): New targets. + * c-pragma.h: Change prototype of handle_pragma_token(). -Mon Sep 29 00:18:16 1997 Richard Henderson (rth@cygnus.com) + * varasm.c (handle_pragma_weak): Only create this function if + HANDLE_PRAGMA_WEAK is defined. - * alias.c (base_alias_check): Two symbols can conflict if they - are accessed via AND. - (memrefs_conflict_p): Likewise. + * c-common,c (decl_attributes): If defined call the expression + contained within the INSERT_ATTRIBUTES macro before adding + attributes to a decl. - * alpha.h (SETUP_INCOMING_VARARGS): Emit a blockage insn - after flushing argument registers to the stack. + * tm.texi (HANDLE_PRAGMA): Document the new version of + HANDLE_PRAGMA, which takes three arguments. + (INSERT_ATTRIBUTES): Document this new macro. - * Makefile.in (mostlyclean): Remove .regmove files. + * LANGUAGES: Document the new version of HANDLE_PRAGMA and the + new INSERT_ATTRIBUTES macro. -Sun Sep 28 18:59:58 1997 Jason Merrill +Wed Sep 2 02:03:23 1998 David S. Miller - * libgcc2.c (__throw): Fix thinko. + * config/sparc/sparc.md (movdf): Only generate special RTL for + LABEL_REFs when PIC. + (move_label_di): Remove. + (movdi_pic_label_ref, movdi_high_pic_label_ref, + movdi_lo_sum_pic_label_ref): New patterns for 64-bit label + references when PIC. + * config/sparc/sparc.h (ASM_OUTPUT_ADDR_VEC_ELT, + ASM_OUTPUT_ADDR_DIFF_ELT): Don't do anything special for MEDLOW, + output an .xword for all 64-bit cases. -Sun Sep 28 12:00:52 1997 Mark Mitchell +Tue Sep 1 15:55:17 1998 David S. Miller - * cplus-dem.c (demangle_template): Add new parameter. Handle new - template-function mangling. - (consume_count_with_underscores): New function. - (demangle_signature): Handle new name-mangling scheme. + * config/sparc/sparc.c (finalize_pic): Don't output arbitrary + alignment, use FUNCTION_BOUNDARY instead. + (sparc_output_deferred_case_vectors): Likewise. -Sun Sep 28 01:55:04 1997 Philippe De Muyter +Mon Aug 31 17:25:41 1998 David S. Miller - * flow.c (print_rtl_with_bb): Cast alloca return values for variables - start and end. + * config/sparc/sparc.md (movsf_const_intreg): Kill warning. + (movtf_insn_sp64, movtf_no_e_insn_sp64): Reorder alternatives. -Sun Sep 28 01:05:16 1997 Jeffrey A Law (law@cygnus.com) +Mon Aug 31 13:57:55 1998 Richard Henderson - * frame.c: Remove last change. - * dwarf2.h: Remove last change. - * tree.h: Add declarations of DWARF2 unwind info support - functions. + * alpha/va_list.h: New file. + * alpha/x-alpha (EXTRA_HEADERS): New. Add va_list.h. -Sat Sep 27 11:02:38 1997 Jason Merrill +Mon Aug 31 14:55:02 1998 Jeffrey A Law (law@cygnus.com) - * c-decl.c (init_decl_processing): Add __builtin_dwarf_reg_size. - * tree.h (built_in_function): Likewise. - * expr.c (expand_builtin): Likewise. - * except.h: Likewise. - * dwarf2out.c (expand_builtin_dwarf_reg_size): New fn. - * libgcc2.c (copy_reg): New fn. - (__throw): Use it. + * NEWS: Add SCO Openserver and Unixware 7 notes. -Fri Sep 26 08:54:59 1997 Paul Eggert + * NEWS: Fix typos. - * c-typeck.c (build_binary_op): Warn about comparing signed vs - unsigned if -W is specified and -Wno-sign-compare is not. - * c-decl.c (warn_sign_compare): Initialize to -1. - (c_decode_option): -Wall no longer implies -Wsign-compare. +Mon Aug 31 15:42:18 1998 Dave Brolley -Fri Sep 26 09:00:13 1997 Andreas Schwab + * varasm.c (compare_constant_1): Handle RANGE_EXPR. + (record_constant_1): Handle RANGE_EXPR. - * frame.c: Include gansidecl.h for PROTO. - * dwarf2out.c: Move inclusion of dwarf2.h down so that PROTO is - defined. Don't declare dwarf2out_cfi_label here. - * dwarf2.h: Add declarations of DWARF2 unwind info support - functions. - * m68k.c: Include dwarf2.h. - (output_function_prologue): Add dwarf2 support. - * m68k.h (INCOMING_RETURN_ADDR_RTX, DWARF_FRAME_REGNUM): New macros. - (INCOMING_FRAME_SP_OFFSET): Likewise. +Mon Aug 31 10:54:03 1998 Richard Henderson - * integrate.c (expand_inline_function): Make sure there is at - least one insn that can be used as an insertion point. + * print-rtl.c (print_rtx): NOTE_INSN_LIVE has an rtx not a bitmap. + * haifa-sched.c (sched_analyze): Handle NOTE_INSN_RANGE_START + and NOTE_INSN_RANGE_END specially. + (reemit_notes): Likewise. -Wed Sep 24 21:34:06 1997 Jason Merrill +Mon Aug 31 10:18:52 1998 Kaveh R. Ghazi - * dwarf2out.c: s/flag_verbose_asm/flag_debug_asm/ + * sparc.c (TMASK, UMASK): Use `(unsigned)1' not `1U'. + (ultrasparc_sched_init): Remove unneeded &. -Wed Sep 24 22:05:30 1997 Jeffrey A Law (law@cygnus.com) +Mon Aug 31 10:47:16 1998 Andreas Schwab - * version.c: Bump for snapshot. + * config/m68k/m68k.h (TARGET_SWITCHES): Don't remove MASK_68040 + for m68020-60, to prevent the use of fintrz. -Wed Sep 24 17:36:23 1997 Doug Evans - - Bring over from FSF. - - Wed Sep 24 19:17:08 1997 Doug Evans - - * sparc/sparc.md (get_pc_via_call): Renamed from get_pc_sp32. - (get_pc_via_rdpc): Renamed from get_pc_sp64. - * sparc/sparc.c (finalize_pic): Update call to gen_get_pc_via_call. - - Wed Sep 24 18:38:22 1997 David S. Miller - - * sparc/sparc.h (ASM_CPU_SPEC): Pass -Av9a for v8plus, ultrasparc. - (TARGET_OPTIONS): Add -malign-loops=, -malign-jumps=, - -malign-functions=. - (sparc_align_{loops,jumps,funcs}_string): Declare. - (sparc_align_{loops,jumps,funcs}): Declare. - (DEFAULT_SPARC_ALIGN_FUNCS): New macro. - (FUNCTION_BOUNDARY): Use sparc_align_funcs. - (STACK_BIAS): Define. - (SPARC_SIMM*_P): Cast to unsigned HOST_WIDE_INT first, then perform - test. - (SPARC_SETHI_P): New macro. - (CONST_OK_FOR_LETTER_P): Use it. - (ASM_OUTPUT_ALIGN_CODE): Define. - (ASM_OUTPUT_LOOP_ALIGN): Define. - * sparc/sparc.c (sparc_align_{loops,jumps,funcs}_string): New globals. - (sparc_align_{loops,jumps,funcs}): New globals. - (sparc_override_options): Handle -malign-loops=, -malign-jumps=, - -malign-functions=. - (move_operand): Use SPARC_SETHI_P. - (arith_double_operand): Cast to unsigned HOST_WIDE_INT first, then - perform test. - (arith11_double_operand): Likewise. - (arith10_double_operand): Likewise. - (finalize_pic): Finish sparc64 support. - (emit_move_sequence): Use SPARC_SETHI_P. Simplify low part of - 64 bit constants if able. - (output_fp_move_quad): Don't use fmovq unless TARGET_HARD_QUAD. - (sparc_builtin_saveregs, sparc64 case): Don't save fp regs if - ! TARGET_FPU. - * sparc/sparc.md (*): Use GEN_INT instead of gen_rtx. - (get_pc_sp32): Use for sparc64 as well. - (lo_sum_di_sp{32,64}): Fix handling on 64 bit hosts. - (sethi_di_sp64_const): Likewise. - (movtf_cc_sp64): Check TARGET_HARD_QUAD. - (cmp_zero_extract_sp64): Use unsigned HOST_WIDE_INT in cast. - (ashlsi3, ashldi3, ashrsi3, ashrdi3, lshrsi3, lshrdi3): Likewise. +Sun Aug 30 22:17:20 1998 Mark Mitchell - Tue Sep 23 19:02:46 1997 Doug Evans + * configure.in: If the native compiler is GCC use $(WARN_CFLAGS) + even in stage1. + * Makefile.in: Likewise. + * configure: Regenerated. - * sparc/linux-aout.h (COMMENT_BEGIN): Delete. - * sparc/linux.h (COMMENT_BEGIN): Likewise. - * sparc/linux64.h (COMMENT_BEGIN): Likewise. +Sun Aug 30 22:15:41 1998 H.J. Lu (hjl@gnu.org) - Tue Sep 23 14:48:18 1997 David S. Miller + * configure.in (gxx_include_dir): Changed to + '${prefix}/include/g++'-${libstdcxx_interface}. + * configure: Rebuilt. - Add sparc64 linux support. - * configure.in (sparc64-*-linux*): Recognize. Add sparc/xm-sparc.h - to xm_file list on 32-bit sparc-linux. - * sparc/xm-sp64.h: New file. - * sparc/linux64.h: New file. - * sparc/xm-linux.h: Include some standard headers if not inhibit_libc. - Don't include xm-sparc.h. - * config/xm-linux.h (HAVE_PUTENV, HAVE_ATEXIT): Define. - * glimits.h (LONG_MAX): Handle sparc64. +Sun Aug 30 20:19:43 1998 Hans-Peter Nilsson - Sat Sep 20 03:07:54 1997 Doug Evans + * expr.c (expand_expr): Change ">" to ">=" making MOVE_RATIO use + consistent. + * tm.texi (Costs): Say MOVE_RATIO is number of mem-mem move + *sequences* *below* which scalar moves will be used. - * sparc/sysv4.h (ASM_COMMENT_START): Delete. - * sparc.h (ASM_COMMENT_START): Define. - * sparc.c (output_function_prologue): Use it. - (sparc_flat_output_function_{epi,pro}logue): Likewise. +Sun Aug 30 17:18:43 1998 Jeffrey A Law (law@cygnus.com) - Wed Sep 17 15:04:19 1997 Doug Evans - - * sparc/sysv4.h (ASM_OUTPUT_{FLOAT,DOUBLE,LONG_DOUBLE}): Delete, - use sparc.h's copies. - * sparc/sparc.h (ASM_OUTPUT_{FLOAT,DOUBLE,LONG_DOUBLE}): Print - ascii form as well. + * collect2.c (mktemp): Delete unused declaration. - Mon Sep 8 08:45:19 1997 Richard Kenner + * config/xm-netbsd.h: Remove unnecessary file. + * config/*/xm-netbsd.h: Do not include the generic xm-netbsd.h + file anymore, it is not needed. - * sparc.c (dwarf2out_cfi_label): Add declaration. - (save_regs, output_function_prologue): Remove cast for it. - (sparc_flat_{save_restore,output_function_prologue): Likewise. - ({save,restore}_regs): No longer inline. +Sun Aug 30 16:05:45 1998 Mark Mitchell -Tue Sep 23 12:34:51 1997 Richard Kenner + * convert.c (convert_to_integer): Issue an error on conversions to + incomplete types. - * fold-const.c (make_range): Correctly handle cases of converting - from unsigned to signed type. +Sun Aug 30 16:47:20 1998 Martin von Lvwis -Tue Sep 23 12:34:51 1997 Bernd Schmidt + * Makefile.in: Add lang_tree_files and gencheck.h. + * configure.in: Generate them. + * gencheck.c: Include gencheck.h. - * fold-const.c (merge_ranges): Make sure that if one range is subset - of another, it will always be the second range. Correct (+,-) case to - account for this. +Sat Aug 29 21:38:24 1998 David S. Miller -Tue Sep 23 08:32:51 1997 Jason Merrill - - * final.c (final_end_function): Also do dwarf2 thing if - DWARF2_DEBUGGING_INFO. - (final_start_function): Likewise. - -Tue Sep 23 01:15:50 1997 David S. Miller - - * expmed.c (expand_divmod): If compute_mode is not the same as - mode, handle the case where convert_modes() causes op1 to no - longer be a CONST_INT. - - * reorg.c (dbr_schedule): At end of this pass, add REG_BR_PRED - note holding get_jump_flags() calculation to all JUMP_INSNs. - * rtl.h (enum reg_note): New note types REG_BR_PRED and REG_SAVE_AREA. - * rtl.c (reg_note_name): Add new note types. - -Tue Sep 23 00:59:54 1997 Jeffrey A Law (law@cygnus.com) - - * rtlanal.c (computed_jump_p): Fix typo in last change. - -Tue Sep 23 00:42:44 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * config/sparc/sparc.md (pic_lo_sum_di, pic_sethi_di): Rename to + movdi_lo_sum_pic and movdi_high_pic and make visible. + * config/sparc/sparc.c (legitimize_pic_address): For -fPIC, + emit these when Pmode is not SImode. + * config/sparc/linux64.h (SPARC_DEFAULT_CMODEL): Make CM_MEDLOW. - * loop.c (indirect_jump_in_function_p): Return 0 - by default. +Sat Aug 29 14:59:32 1998 Mumit Khan -Tue Sep 23 00:33:55 1997 Jeffrey A Law (law@cygnus.com) + * i386/cygwin32.h (ASM_OUTPUT_SECTION_NAME): Don't emit + .linkonce directive after the first time. - * rs6000/xm-rs6000.h: Fix thinko in last change. - * rs6000/xm-sysv4.h: Likewise. +Sat Aug 29 12:39:56 1998 Jeffrey A Law (law@cygnus.com) -Mon Sep 22 19:33:53 1997 Jim Wilson + * m68k.md (beq0_di): Generate correct (and more efficient) code when + the clobbered operand overlaps with an input. + (bne0_di): Similarly. - * mips.c (save_restore_insns): Only set RTX_FRAME_RELATED_P if store_p. + * Makefile.in (INSTALL): Remove "--no-header" argument. -Mon Sep 22 14:41:00 1997 Jeffrey A Law (law@cygnus.com) + * NEWS: Various updates. - * reg-stack.c (find_blocks): Fix thinko in last change. +Fri Aug 28 19:00:44 1998 David S. Miller -1997-09-21 Andreas Schwab + * config/sparc/sparc.c (arith_operand, const64_operand, + const64_high_operand, arith_double_4096_operand): Mark mode as + unused. + (create_simple_focus_bits): Remove unused arg highest_bit_set, all + callers changed. + (sparc_emit_set_const64): Remove unused variable i. + (sparc_splitdi_legitimate): Likewise for addr_part. + (ultra_code_from_mask): Likewise for mask. + (ultra_cmove_results_ready_p): Fixup entry modulo calc. and + reverse return values so it matches usage and comments. + (ultra_flush_pipeline): Likewise. + (ultra_fpmode_conflict_exists): Likewise, remove unused variable + this_type, and allow loads and stores of differing FP modes as + they do not create a conflict. + (ultra_find_type): Initialize fpmode to SFmode, fix + parenthesization thinkos in large conditional. + (ultrasparc_sched_init): Mark dump and sched_verbose as unused. + Init free_slot_mask after ultra_cur_hist is reset, not before. + (ultrasparc_rescan_pipeline_state): Remove unused variable ucode. + (ultrasparc_sched_reorder): Don't bzero current pipeline state, + use ultra_flush_pipeline instead, then re-init group pointer. + Fix statement with no effect. If no progress made in, and no + instructions scheduled at all, advance to new pipeline cycle else + we get into an endless loop. + (ultrasparc_adjust_cost): Remove previous arg. + * config/sparc/sparc.h (ADJUST_COST): Update to reflect that. - * m68k.c (output_function_prologue): Add dwarf2 support. +Fri Aug 28 13:52:35 1998 Jim Wilson - * m68k.h (INCOMING_RETURN_ADDR_RTX, DWARF_FRAME_REGNUM, - INCOMING_FRAME_SP_OFFSET): New definitions. + * sparc.md (DImode, DFmode, TFmode splits): Delete self_reference + code. Use reg_overlap_mentioned_p to detect when source and + destination overlap. + (negtf2_notv9+1): Use DFmode instead of SFmode in last two operands. -Mon Sep 22 11:36:42 1997 David S. Miller +1998-08-28 Brendan Kehoe - * combine.c (try_combine): Use NULL_RTX instead of '0' where - appropriate in calls to gen_rtx(). - * cse.c (cse_main): Likewise. - * emit-rtl.c (gen_label_rtx): Likewise. - * expr.c (init_expr_once): Likewise. - * haifa-sched.c (flush_pending_lists, sched_analyze_insn, - sched_analyze, init_rgn_data_dependences, - compute_block_backward_dependences): Likewise. - * sched.c (schedule_insns): Likewise. - * varasm.c (immed_double_const): Likewise. + * loop.c (check_dbra_loop): Pass COMPARISON_VALUE, not + COMPARISON_VAL, into invariant_p. - * sparc.h (INCOMING_FRAME_SP_OFFSET): Define to - SPARC_STACK_BIAS for sake of dwarf2 on sparc64. +Fri Aug 28 15:13:25 1998 J"orn Rennecke -Mon Sep 22 11:21:33 1997 J. Kean Johnston + * regmove.c (regclass_compatible_p): New function. + (regmove_optimize): Use it. - * i386/sco5.h: Make ELF default file format and add -mcoff/-melf.. - (MULTILIB_DEFAULTS): Define. - (ASM_SPEC, CPP_SPEC): Handle -mcoff. - (STARTFILE_SPEC, ENDFILE_SPEC, LINK_SPEC): Likewise. - (LIBGCC_SPEC): Likewise. - (MASK_COFF, TARGET_COFF, TARGET_ELF): Define. - (SUBTARGET_SWITCHES): Add -mcoff and -melf. - * i386/t-sco5 (CRTSTUFF_T_CFLAGS): Add -fPIC. - (CRTSTUFF_T_CFLAGS_S): Tweak for COFF. - (EXTRA_PARTS, TAROUTOPTS): Delete. - (libgcc1-elf, libgcc2-elf, libgcc-elf targets): Delete. - (MULTILIB_OPTIONS): Define. - (MULTILIB_DIRNAMES, MULTILIB_EXCEPTIONS): Likewise. - (MULTILIB_MATCHE, MULTILIB_EXTRA_OPTS): Likewise. + Use NREGS parameter instead of calling max_reg_num. -Mon Sep 22 02:10:43 1997 Jeffrey A Law (law@cygnus.com) + (fixup_match_1): Don't use code = MINUS when later tieing with + a hard register is likely. - * version.c: Bump for snapshot. +Fri Aug 28 14:54:07 1998 J"orn Rennecke -Sun Sep 21 17:45:45 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (check_dbra_loop): Fix calculation of FINAL_VALUE when + COMPARISON_VAL was normalized. - * loop.c (loop_number): Delete function. Change all references - to use uid_loop_num array. - * loop.h (loop_number): Delete declaration. - * unroll.c (unroll_loop): Change "loop_number" references to - use uid_loop_num instead. +Thu Aug 27 20:10:46 1998 Jeffrey A Law (law@cygnus.com) - * loop.c (loop_unroll_factor): Move outside #ifdef HAIFA - conditional. - (loop_unroll_iter): Remove unused variable and all references. - (loop_optimize): Always allocate and clear space for loop_unroll_factor. - (insert_bct): Fix minor formatting problems. - * loop.h (loop_unroll_factor): Move decl outside #ifdef HAIFA. - (loop_unroll_iter): Removed unused decl. - * unroll.c (unroll_loop): Remove code to set loop_unroll_iter. - Always record the unrolling factor. + * loop.c (check_dbra_loop): The loop ending comparison value + must be an invariant or we can not reverse the loop. - * cse.c (simplify_relational_operation): Set h0u just like h0s. - Similarly for h1u and h1s. + * loop.c (scan_loop): Count down from max_reg_num - 1 to + FIRST_PSEUDO_REGISTER to avoid calling max_reg_num each iteration + of the loop. + (load_mems_and_recount_loop_regs_set): Likewise. - * flow.c (jmp_uses_reg_or_mem): Deleted unused function. - (find_basic_blocks): Use computed_jump_p to determine if a - particular JUMP_INSN is a computed jump. - * reg-stack.c (find_blocks): Use computed_jump_p to determine - if a particular JUMP_INSN is a computed jump. - * rtlanal.c (jmp_uses_reg_or_mem): New function. - (computed_jump_p): Likewise. - * rtl.h (computed_jump_p): Declare. - * genattrtab.c (pc_rtx): Define and initialize. - * loop.c (loop_optimize): Always determine if the current - function has a computed jump. - (indirect_jump_in_function_p): Use computed_jump_p to determine - if a particular JUMP_INSN is a computed jump. + * i386.c (print_operand): Remove obsolete 'c' docs. - * loop.c (fix_bct_param): Delete unused function. - (check_bct_param): Likewise. +Wed Aug 26 17:13:37 1998 Tom Tromey -Sat Sep 20 16:22:06 1997 Jason Merrill + * gthr.h: Document __GTHREAD_MUTEX_INIT_FUNCTION. + * frame.c (init_object_mutex): New function. + (init_object_mutex_once): Likewise. + (find_fde): Call it. + (__register_frame_info): Likewise. + (__register_frame_info_table): Likewise. + (__deregister_frame_info): Likewise. - * frame.c (__deregister_frame): Check properly for initialized object. +Thu Aug 27 15:14:18 1998 Jeffrey A Law (law@cygnus.com) -Fri Sep 19 20:51:03 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * haifa-sched.c (sched_analyze_insn): Fix thinko in last change. - * alpha/linux.h (HANDLE_SYSV_PRAGMA): Defined. +Thu Aug 27 16:34:51 1998 J"orn Rennecke -Fri Sep 19 18:53:50 1997 J"orn Rennecke + * loop.c (check_dbra_loop): Enable code for reversal + of some loops without a known constant loop end. - * jump.c (thread_jumps): check can_reverse_comparison_p before - threading a reversed-condition jump. +Wed Aug 26 18:38:15 1998 Richard Henderson - * sched.c (update_flow_info): Don't pass SCRATCH to dead_or_set_p. - * haifa-sched.c (update_flow_info): Likewise. + * haifa-sched.c (last_clock_var): New. + (schedule_block): Initialize it. + (schedule_insn): Use it to fill insn modes with issue information. -Thu Sep 18 21:13:40 1997 Jeffrey A Law (law@cygnus.com) + * alpha.c (alpha_handle_trap_shadows): Remove do-nothing exit. + Tag trapb and next insn with TImode. + (alphaev5_insn_pipe, alphaev5_next_group, alphaev5_align_insns): New. + (alpha_reorg): Add conditional for alpha_handle_trap_shadows. + Invoke alphaev5_align_insns as appropriate. + * alpha.h (LABEL_ALIGN_AFTER_BARRIER): Was ALIGN_LABEL_AFTER_BARRIER. + (MD_SCHED_VARIABLE_ISSUE): New. + * alpha.md (attr type): Add multi. + (define_asm_attributes): New. + (prologue_stack_probe_loop, builtin_setjmp_receiver): Set type multi. + (arg_home): Likewise. + (fnop, unop, realign): New. - * Makefile.in (BOOT_CFLAGS): Use -O2. +Wed Aug 26 15:55:41 1998 Jim Wilson - * configure.in (strtoul, bsearch): Have autoconf check for these - functions. - * configure, config.in: Rebuilt. + * iris5.h (PREFERRED_DEBUGGING_TYPE): Undef. + * iris5gas.h (PREFERRED_DEBUGGING_TYPE): Define. - * m68k/xm-mot3300.h (alloca): Properly declare if __STDC__. - * mips/mips.h (alloca): Likewise. - * rs6000/xm-rs6000.h (alloca): Likewise. - * rs6000/xm-sysv4.h: Likewise. + * configure.in (powerpc-ibm-aix4.[12]*): Change from 4.[12].*. + (rs6000-ibm-aix4.[12]*): Likewise. + * configure: Regenerate. -Thu Sep 18 14:22:22 1997 Jason Merrill +Wed Aug 26 09:30:59 1998 Nick Clifton - * final.c (final_scan_insn): Hand BARRIERs off to the dwarf2 code. - * dwarf2out.c (dwarf2out_frame_debug): Pass the whole insn along. - (dwarf2out_stack_adjust): A BARRIER resets the args space to 0. + * config/arm/thumb.c (thumb_exit): Do not move a4 into lr if it + already contains the return address. - * except.c (end_eh_unwinder): Subtract 1 from return address. - * libgcc2.c (__throw): Likewise. - (find_exception_handler): Don't change PC here. Compare end with >. +Wed Aug 26 12:57:09 1998 Jeffrey A Law (law@cygnus.com) -Thu Sep 18 10:43:07 1997 Nick Clifton + * calls.c (expand_call): Use bitfield instructions to extract/deposit + word sized hunks when loading unaligned args into registers. - * v850.c (compute_register_save_size): Correct register - number. - * v850.md (save_interrupt, return_interrupt): Correct - register number. - * v850/lib1funcs.asm (save_interrupt): Correct register number. - (return_interrupt): Use stack pointer, not element pointer. + * haifa-sched.c (sched_analyze_insn): Only create scheduling + barriers for LOOP, EH and SETJMP notes on the loop_notes list. -1997-09-18 Brendan Kehoe + * mn10300.h (RTX_COSTS): Handle UDIV and UMOD too. - * configure.in, configure: Make sure to create the stage* and include - symbolic links in each subdirectory. +Wed Aug 26 16:35:37 1998 J"orn Rennecke -Thu Sep 18 01:47:06 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (check_dbra_loop): Add some code that would allow reversal + of some loops without a known constant loop end if it were enabled. - * pa.md (reload_peepholes): Don't allow addresses with side - effects for the memory operand. +Wed Aug 26 11:08:44 1998 Gavin Romig-Koch -Wed Sep 17 18:19:53 1997 Jason Merrill + * mips.md (lshrsi3_internal2+2): Fix type-o. - * libgcc2.c (find_exception_handler): Subtract one from our PC when - looking for a handler, to avoid hitting the beginning of the next - region. +Wed Aug 26 10:53:03 1998 Kaveh R. Ghazi - * except.c (expand_builtin_set_return_addr_reg): Use force_operand. + * system.h: Include stdarg.h/varargs.h, make sure they are ordered + correctly with regards to stdio.h. -Wed Sep 17 18:33:59 1997 Jeffrey A Law (law@cygnus.com) + * calls.c: Remove stdarg.h/varargs.h. + * cccp.c: Likewise. + * cexp.y: Likewise. + * combine.c: Likewise. + * cpperror.c: Likewise. + * cpplib.c: Likewise. + * cpplib.h: Likewise. + * doprint.c: Likewise. + * emit-rtl.c: Likewise. + * final.c: Likewise. + * fix-header.c: Likewise. + * gcc.c: Likewise. + * genattr.c: Likewise. + * genattrtab.c: Likewise. + * gencodes.c: Likewise. + * genconfig.c: Likewise. + * genemit.c: Likewise. + * genextract.c: Likewise. + * genflags.c: Likewise. + * genopinit.c: Likewise. + * genoutput.c: Likewise. + * genpeep.c: Likewise. + * genrecog.c: Likewise. + * mips-tfile.c: Likewise. + * prefix.c: Likewise. + * protoize.c: Likewise. + * regmove.c: Likewise. + * toplev.c: Likewise. + * tree.c: Likewise. + +Wed Aug 26 05:09:27 1998 Jakub Jelinek + + * config/sparc/sparc.c (sparc_override_options): If not + TARGET_FPU, turn off TARGET_VIS. + * config/sparc/sparc.h (TARGET_SWITCHES): Add no-vis. + (LEGITIMATE_CONSTANT_P): Allow SF/DF mode zero when TARGET_VIS. + * config/sparc/sparc.md (movsi_insn): Use fzeros not fzero. + (movdi_insn_sp64): Add VIS fzero alternative. + (clear_sf, clear_df): New VIS patterns. + (movsf, movdf expanders): Allow fp_zero_operand flat out when + TARGET_VIS. + (one_cmpldi2_sp64): Provide new fnot1 VIS alternative. + +Tue Aug 25 10:57:41 1998 Mark Mitchell + + * loop.c (n_times_set, n_times_used, may_not_optimize, + reg_single_usage): Convert to varrays. All uses changed. + (insert_loop_mem): Return a value. + (scan_loop): Tweak AVOID_CC_MODE_COPIES code. + (load_mems_and_recount_loop_regs_set): Likewise. Grow the arrays, if + necessary. - * mips/abi64.h (LONG_MAX_SPEC): Define. - * mips.h (LONG_MAX_SPEC): Define. - (CPP_SPEC): Include long_max_spec. - (EXTRA_SPECS): Include long_max_spec. +Tue Aug 25 23:57:12 1998 Jeffrey A Law (law@cygnus.com) -Wed Sep 17 14:11:38 1997 Jeffrey A Law (law@cygnus.com) + * From Alexandre: + * configure.in: Do not set thread_file to "irix" since no such + support exists yet. - * v850.c (construct_save_jarl): Fix thinko in last change. + * sparc.md (float abs/neg splits): Check reload_completed before + calling alter_subreg. -Wed Sep 17 09:53:07 1997 Jeffrey A Law (law@cygnus.com) +Tue Aug 25 19:17:59 1998 David S. Miller - * version.c: Bump for snapshot. + * config/sparc/sparc.c (sparc_absnegfloat_split_legitimate): New + function. + * config/sparc/sparc.h: Declare it. + * config/sparc/sparc.md (float abs/neg splits): Use it. + (all other splits): Handle SUBREGs properly where necessary. + (unnamed (1< +Tue Aug 25 19:48:46 1998 Jeffrey A Law (law@cygnus.com) - * libgcc2.c (find_exception_handler): Not found is -1. + * reorg.c (fill_simple_delay_slots): Do not abort if we encounter + an insn on the unfilled_slots_list that has no delay slots. + (fill_eager_delay_slots): Similarly. - * integrate.c (expand_inline_function): Move expand_start_bindings - after expanding the arguments. +Tue Aug 25 13:35:20 1998 Nick Clifton -Tue Sep 16 11:13:46 1997 Jim Wilson + * config/v850/v850.c (movsi_source_operand): Treat CONSTANT_P_RTX + as an ordinary operand. - * expr.c (expand_expr): Remove previous incorrect change. - If target and slot has no DECL_RTL, then call mark_addressable - again for the slot after we give it RTL. +Tue Aug 25 12:54:57 1998 Jason Merrill -Tue Sep 16 09:18:52 1997 Jason Merrill (jason@cygnus.com) + * tree.c (valid_machine_attribute): Don't apply attributes to both + decl and type. - * expr.c (expand_expr, case TARGET_EXPR): Call mark_addressable - again for the slot after we give it RTL. +Tue Aug 25 12:23:20 1998 Richard Henderson -Tue Sep 16 00:13:20 1997 Nick Clifton + * reload.c (operands_match_p): Handle rtvecs. - * v850.c (register_is_ok_for_epilogue, - pattern_is_ok_for_epilogue, construct_restore_jr, - pattern_is_ok_for_prologue, construct_save_jarl): New functions. + * i386.c (legitimate_pic_address_disp_p): New. + (legitimate_address_p): Use it. + (legitimize_pic_address): Use unspecs to represent @GOT and @GOTOFF. + Handle constant pool symbols just like statics. + (emit_pic_move): Use Pmode not SImode for clarity. + (output_pic_addr_const) [SYMBOL_REF]: Remove @GOT and @GOTOFF hacks. + [UNSPEC]: New, handling what we killed above. + [PLUS]: Detect and abort on invalid symbol arithmetic. + * i386.h (CONSTANT_ADDRESS_P): Remove HIGH. - * v850.h (pattern_is_ok_for_prologue, - pattern_is_ok_for_epilogue, register_is_ok_for_epilogue): New - predicates. +Tue Aug 25 12:02:23 1998 Mark Mitchell - * v850.md: Replace prologue and epilogue patterns with a - match_parallel pattern. + * alias.c: Include output.h. + (DIFFERENT_ALIAS_SETS_P): Don't treat alias sets as + different if we're in a varargs function. + * Makefile.in (alias.o): Depend on output.h -Mon Sep 15 22:53:01 1997 Jeffrey A Law (law@cygnus.com) +Tue Aug 25 19:20:12 1998 J"orn Rennecke - * aclocal.m4: Add replacement for AC_PROG_INSTALL. - * configure.in: Use EGCS_PROG_INSTALL. + * sh.h (GIV_SORT_CRITERION): Delete. -Mon Sep 15 22:40:55 1997 Jim Wilson (wilson@cygnus.com) +Tue Aug 25 13:19:46 1998 Dave Brolley - * dwarf2out.c (gen_subprogram_die): Handle redefinition of an - extern inline function. + * regclass.c (regclass): Use xmalloc/free instead of alloca. + * stupid.c (stupid_life_analysis): Likewise. + * reload1.c (reload): Likewise. -Mon Sep 15 22:40:55 1997 Richard Henderson (rth@cygnus.com) +Tue Aug 25 05:48:18 1998 Jakub Jelinek - * dwarf2out.c (reg_loc_descriptor): Fix prototype. - (concat_loc_descriptor): New function. - (loc_descriptor): Call it. - (add_AT_location_description): Also elide the descriptor if both - halves of a CONCAT are pseudos. - (add_location_or_const_value_attribute): Recognize CONCAT too. + * config/sparc/sparc.c (arith_4096_operand, arith_add_operand, + arith_double_4096_operand, arith_double_add_operand): New + predicates. + * config/sparc/sparc.h (PREDICATE_CODES): Add them, declare them. + * config/sparc/sparc.md (adddi3, addsi3, subdi3, subsi3): Use + them to transform add/sub 4096 into add/sub -4096. -Mon Sep 15 15:24:00 1997 Richard Henderson +Mon Aug 24 23:31:03 1998 David S. Miller - * alpha.md (movdi): Handle CONST_DOUBLE for TARGET_BUILD_CONSTANTS. + * loop.c (scan_loop): Allocate some slop to handle pseudos + generated by move_movables. + (load_mems_and_recount_loop_regs_set): Honor AVOID_CC_MODE_COPIES + here too. - * alpha/alpha.c (output_prolog): New variable sa_reg. Use it for - out-or-range reg_offset. - (output_epilog): Likewise. +Mon Aug 24 19:45:40 1998 Jim Wilson -Mon Sep 15 15:39:26 1997 Jeffrey A Law (law@cygnus.com) + * tree.def (DECL_RESULT): Correct documentation. - * cse.c (simplify_relational_operation): If MODE specifies a - mode wider than HOST_WIDE_INT, then the high word of a CONST_INT - is derived from the sign bit of the low word. +Tue Aug 25 01:15:27 1998 J"orn Rennecke -Mon Sep 15 11:43:38 1997 Jason Merrill + * reload1.c (reload_reg_free_before_p): New argument EQUIV; Changed + all callers. Abort for RELOAD_FOR_INSN. RELOAD_FOR_OUTADDR_ADDR: + conflicts will all RELOAD_FOR_OUTPUT reloads. - Support dwarf2 unwinding on PUSH_ROUNDING targets like the x86. + * reload1.c (reload_cse_regs_1): When deleting a no-op move that + loads the function result, substitute with a USE. - * dwarf2.h: Add DW_CFA_GNU_args_size. - * frame.c (execute_cfa_insn): Likewise. - * dwarf2out.c (dwarf_cfi_name, output_cfi): Likewise. - (dwarf2out_args_size, dwarf2out_stack_adjust): New fns. - (dwarf2out_frame_debug): If this isn't a prologue or epilogue - insn, hand it off to dwarf2out_stack_adjust. - (dwarf2out_begin_prologue): Initialize args_size. - * frame.h (struct frame_state): Add args_size. - * libgcc2.c (__throw): Use args_size. - * final.c (final_scan_insn): If we push args, hand off all insns - to dwarf2out_frame_debug. - * defaults.h (DWARF2_UNWIND_INFO): OK for !ACCUMULATE_OUTGOING_ARGS. +Mon Aug 24 15:20:19 1998 David Edelsohn - * dwarf2out.c dwarf2out_frame_debug): Fix typo. - Handle epilogue restore of SP from FP. - * emit-rtl.c (gen_sequence): Still generate a sequence if the - lone insn has RTX_FRAME_RELATED_P set. + * rs6000.h (GO_IF_LEGITIMATE_ADDRESS): Use TARGET_POWERPC64 + when testing LEGITIMATE_INDEXED_ADDRESS_P DFmode and DImode. + (LEGITIMIZE_ADDRESS): Use TARGET_POWERPC64 for INDEXED fixup. + * rs6000.c (print_operand, case 'L'): Add UNITS_PER_WORD, not 4. + (print_operand, cases 'O' and 'T'): Fix typos in lossage strings. + * rs6000.md (fix_truncdfsi2_store): Remove %w from non-CONST_INT + operand. + (movdf_softfloat32, movdf_hardfloat64, movdf_softfloat64): Change + 'o' to 'm' for GPR variant constraints. - * frame.c (extract_cie_info): Handle "e" augmentation. - * dwarf2out.c (ASM_OUTPUT_DWARF_*): Provide definitions in the - absence of UNALIGNED_*_ASM_OP. - (UNALIGNED_*_ASM_OP): Only provide defaults if OBJECT_FORMAT_ELF. - (output_call_frame_info): Use "e" instead of "z" for augmentation. - Don't emit augmentation fields length. - (dwarf2out_do_frame): Move outside of #ifdefs. - * defaults.h (DWARF2_UNWIND_INFO): Don't require unaligned data - opcodes. +Mon Aug 24 10:25:46 1998 Jeffrey A Law (law@cygnus.com) - * sparc.h (UNALIGNED_INT_ASM_OP et al): Don't define here after all. - * sparc/sysv4.h (UNALIGNED_INT_ASM_OP): Define here. - * sparc/sunos4.h (DWARF2_UNWIND_INFO): Define to 0. - * sparc/sun4gas.h: New file. - * configure.in: Use sun4gas.h if SunOS 4 --with-gnu-as. + * loop.c (scan_loop): Honor AVOID_CC_MODE_COPIES. - * collect2.c (write_c_file_stat, write_c_file_glob): Declare - __register_frame_table and __deregister_frame. + * h8300.h (STRIP_NAME_ENCODING): Fix typo. -1997-09-15 Brendan Kehoe + * sparc.md (TFmode splits): Use reg_overlap_mentioned_p to detect + when the source and destination overlap. - * except.c (find_exception_handler_labels): Use xmalloc instead of - alloca, since MAX_LABELNO - MIN_LABELNO can be more than 1 million - in some cases. + * stmt.c (emit_case_nodes): Change rtx_function to rtx_fn to avoid + clash with global type. -Sun Sep 14 21:01:23 1997 Jeffrey A Law (law@cygnus.com) +Mon Aug 24 00:53:53 1998 Jason Merrill - * Makefile.in: Various changes to build info files - in the object tree rather than the source tree. + * fixinc.irix: Add curses.h handling from fixinc.wrap. -Sun Sep 14 12:24:30 1997 Jeffrey A Law (law@cygnus.com) + * c-common.c (combine_strings): Also set TREE_READONLY. + Change warn_write_strings to flag_const_strings. + * c-decl.c, c-tree.h: Likewise. - * fixinc.math: New file to fix math.h on some systems. - * configure.in (freebsd, netbsd): Use fixinc.math on these - systems. - * configure: Rebuilt. +Sun Aug 23 18:39:11 1998 David S. Miller -Sun Sep 14 11:11:05 1997 Jeffrey A Law (law@cygnus.com) + * config/sparc/sparc.c (sparc_emit_set_const32): If outputting a + CONST_INT, not a symbolic reference, don't use a HIGH/LO_SUM + sequence, use SET/IOR instead so CSE can see it. + * config/sparc/sparc.md (movhi_const64_special, + movsi_const64_special): New patterns necessitated by that change. + (movhi_high): Remove. + (movhi_lo_sum): Change to match an IOR. + (movdf_insn_sp32): Test TARGET_V9 not TARGET_ARCH64. + (movdf_insn_v9only): New pattern for when V9 but not ARCH64. + (movdf_insn_sp64): Test both TARGET_V9 and TARGET_ARCH64. + (movdf splits): Allow when not V9 or when not ARCH64 and integer + registers are involved. + (snesi_zero_extend split): Remove reload_completed test. + (unnamed plus and minus zero_extend sidi splits): Add it. - * regmove.c (regmove_optimize): If we end up moving the - original insn due to lifetime overlaps, make sure to move - REG_NOTES too. +Sun Aug 23 11:56:08 1998 Mark Mitchell -Sat Sep 13 15:51:11 1997 Manfred Hollstein + * extend.texi: Remove description of extension to explicit + instantiation that is now endorsed by standard C++. - * Makefile.in (INSTALL_{PROGRAM,DATA}): Use value found by configure. +Sun Aug 23 09:39:09 1998 David S. Miller -Sat Sep 13 12:57:26 1997 Jeffrey A Law (law@cygnus.com) + * config/arc/arc.c (arc_initialize_pic): Remove. + * config/arc/arc.h (INITIALIZE_PIC): Similarly, this routine does + nothing on any platform and is invoked by no-one, it does not even + appear in the documentation. + * config/sparc/sparc.h (INITIALIZE_PIC): Likewise. + * config/sparc/sparc.c (initialize_pic): Likewise. + (find_addr_reg): Remove this as well, no longer referenced after + my rewrite. - * haifa-sched.c (add_branch_dependences): Make each insn in - a SCHED_GROUP_P block explicitly depend on the previous insn. +Sun Aug 23 00:17:14 1998 Jeffrey A Law (law@cygnus.com) -Fri Sep 12 13:49:58 1997 Jason Merrill + * recog.c (validate_replace_rtx_group): New function. + * recog.h (validate_replace_rtx_group): Declare it. + * regmove.c (optimize_reg_copy_3): If any substitution fails, then undo + the entire group of substitutions. - * except.h: Prototype dwarf2 hooks. - * expr.c: Adjust. +Sat Aug 22 23:31:00 1998 Klaus-Georg Adams (Klaus-Georg.Adams@chemie.uni-karlsruhe.de) -Thu Sep 11 17:43:55 1997 Jim Wilson + * loop.c (load_mems): Fix initializers. - * configure.in (native_prefix): Delete. - (mips-dec-netbsd): Don't set prefix. - (*linux*): Don't set prefix. +Fri Aug 21 23:07:46 1998 David S. Miller -Thu Sep 11 15:48:32 1997 Fred Fish + * config/sparc/sparc.md (TFmode splits): Handle destination + registers being referenced in the address correctly. - * protoize.c: Include only if HAVE_VARARGS_H is - defined. If not defined, include if - HAVE_SYS_VARARGS_H is defined. - * configure.in: Test for varargs.h and sys/varargs.h. - * configure: Regenerate with autoconf. - * config.in: Regenerate with autoheader. + * expmed.c (make_tree) [CONST_INT]: Sign extend even if + TREE_UNSIGNED, when bitsize of type's mode is larger than + HOST_BITS_PER_WIDE_INT. - * cpplib.c (quote_string): Cast first arg of sprintf call - from "unsigned char *" to "char *". - (output_line_command): Ditto. - (macroexpand): Ditto. - (do_line): Cast atoi arg from "unsigned char *" to "char *". +Fri Aug 21 19:31:31 1998 Alexandre Petit-Bianco -Wed Sep 10 21:37:30 1997 Jeffrey A Law (law@cygnus.com) + * tree.def (LABELED_BLOCK_EXPR, EXIT_BLOCK_EXPR): New tree nodes. + * tree.h (LABELED_BLOCK_LABEL, LABELED_BLOCK_BODY, + EXIT_BLOCK_LABELED_BLOCK, EXIT_BLOCK_RETURN, LOOP_EXPR_BODY): New + macros. + * expr.c (expand_expr): Handle LABELED_BLOCK_EXPR and + EXIT_BLOCK_EXPR. - * version.c: Bump for snapshot. +Thu Aug 20 19:43:44 1998 Jeffrey A Law (law@cygnus.com) - * Makefile.in (compare): Exit with nonzero status if there - are comparison failures. Note which files failed the - comparison test in .bad_compare. + * h8300.c (h8300_encode_label): Use '&' for tiny data items. + * h8300.h (TINY_DATA_NAME_P): Likewise. + (STRIP_NAME_ENCODING): Handle '&'. -Wed Sep 10 17:05:46 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * mn10200.h (REG_OK_FOR_INDEX_P): Do not check the mode of the + register (it could be accessed via an outer SUBREG). + (REG_OK_FOR_BASE_P): Likewise. + (GO_IF_LEGITIMATE_ADDRESS): Consistently use REGNO_OK_FOR_BASE_P. - * config/alpha/elf.h (CPP_PREDEFINES): Remove -D__PIC__ -D__pic__. + * remove.c (optimize_reg_copy_3): Abort instead of silently generating + bogus rtl. -Wed Sep 10 16:37:28 1997 Fred Fish + * jump.c (rtx_renumbered_equal_p): Do not consider PLUS commutative. - * Makefile.in (LN, LN_S): New macros, use where appropriate. - * aclocal.m4 (GCC_PROG_LN_S, GCC_PROG_LN): New tests. - * configure.in: Use GCC_PROG_LN_S and GCC_PROG_LN. - * configure: Regenerated. +Thu Aug 20 17:35:20 1998 David S. Miller -Thu Sep 11 11:09:43 1997 Jeffrey A Law (law@cygnus.com) + * config/sparc/sparc.md (movtf_insn_sp32): All memory operands + must be offsettable so the splits can be made. - * loop.c (strength_reduce): Fix typo. +Thu Aug 20 13:56:53 1998 Michael Meissner -Wed Sep 10 16:01:15 1997 Jim Wilson + * config/i386/winnt.c: Include system.h, not stdio.h to get + sys/param.h pulled in before rtl.h in case the system defines MIN + and MAX. - * m88k/m88k.c (struct option): Rename to struct options. - * m88k/dolph.h (INITIALIZE_TRAMPOLINE): Delete here. - * m88k/sysv3.h (INITIALIZE_TRAMPOLINE): Delete ifdef and comments. - * libgcc2.c (__enable_execute_stack): Check for __sysV88__ not - __DOLPHIN__ or sysV88. +Thu Aug 20 13:44:20 1998 David Edelsohn -Wed Sep 10 14:58:40 1997 Jim Wilson + * rs6000.md (movqi, movhi): Add CONSTANT_P_RTX. - * emit-rtl.c (gen_lowpart_common): For a SUBREG, add in word when - create new subreg. +Thu Aug 20 13:15:11 1998 Dave Brolley -Wed Sep 10 15:19:22 1997 Jeffrey A Law (law@cygnus.com) + * stor-layout.c (layout_type): Compute TYPE_SIZE_UNIT correctly for + arrays of bits. + * cpplib.c (cpp_define): Handle macros with parameters. - * config.sub: Accept 'amigados' for backward compatability. +Wed Aug 19 21:33:19 1998 David Edelsohn -Wed Sep 10 14:05:08 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * rs6000.c (rs6000_output_load_toc_table): Use ld for 64-bit. + (output_toc): Use single TOC slot or llong minimal-toc for DFmode + and DImode 64-bit. Use llong for minimal-toc SFmode and + SYMBOL_REF / LABEL_REF 64-bit. + (output_function_profiler): Use llong for profiler label and ld to + load 64-bit label address. - * Makefile.in (testsuite/site.exp): New target. - (check-gcc, check-g++): Depend on testsuite/site.exp. - Don't stop for failure. +Wed Aug 19 17:52:27 1998 Nick Clifton (nickc@cygnus.com) -Wed Sep 10 12:59:57 1997 Jason Merrill + * config/arm/thumb.md (extendqisi2_insn): Cope with REG + + OFFSET addressing. - * expr.c (expand_builtin): Only support __builtin_dwarf_fp_regnum() - if DWARF2_UNWIND_INFO. +Wed Aug 19 14:13:31 1998 Jeff Law (law@cygnus.com) -Wed Sep 10 11:49:20 1997 Jason Merrill + * version.c: Bump for snapshot. - Add support for exception handling using DWARF 2 frame unwind info. - Currently works on SPARC and MIPS, and almost on x86. +Wed Aug 19 13:10:30 1998 Jeff Law (law@cygnus.com) - * libgcc2.c (get_reg, put_reg, get_return_addr, put_return_addr, - next_stack_level, in_reg_window): Helper fns. - (__throw): Implement for DWARF2_UNWIND_INFO. + * version.c: Bump for snapshot. - * expr.c (expand_builtin): Handle builtins used by __throw. - * tree.h (enum built_in_function): Add builtins used by __throw. - * c-decl.c (init_decl_processing): Declare builtins used by __throw. - * dwarf2out.c (expand_builtin_dwarf_fp_regnum): Used by __throw. - * except.c (expand_builtin_unwind_init): Hook for dwarf2 __throw. - (expand_builtin_extract_return_addr): Likewise. - (expand_builtin_frob_return_addr): Likewise. - (expand_builtin_set_return_addr_reg): Likewise. - (expand_builtin_eh_stub): Likewise. - (expand_builtin_set_eh_regs): Likewise. - (eh_regs): Choose two call-clobbered registers for passing back values. +Wed Aug 19 13:06:47 1998 Jason Merrill + + * collect2.c (extract_init_priority): Use atoi instead of strtoul. + +Wed Aug 19 13:51:35 1998 Hans-Peter Nilsson + + * tm.texi (Misc): Fix typo "teh". + + * tm.texi (PIC): Fix typo "PPIC". + + * tm.texi (Caller Saves): Say that DEFAULT_CALLER_SAVES has no + effect when -O2 and higher. + * invoke.texi (Optimize Options): Likewise for -fcaller-saves. + +1998-08-19 Michael Hayes + + * regclass.c: Changed register set documentation to be consistent + with GCC behavior. + + * final.c (final_start_function): Removed redundant test for + call_fixed_regs. + +Wed Aug 19 13:28:41 1998 Mark Mitchell + + * rtl.h (rtx_function): New type. + (for_each_rtx): New function. + * rtlanal.c (for_each_rtx): Define it. + + * recog.c (change_t): New type. + (change_objects, change_old_codes, change_locs, change_olds): + Replace with ... + (changes): New variable. + (validate_change): Dynamically allocate room for more changes, if + necessary. Uses changes array instead of change_objects, etc. + (apply_change_group): Use changes array instead of + change_objects, etc. + + * loop.c (loop_mem_info): New type. + (loop_mems): New variable. + (loop_mems_idx): Likewise. + (looop_mems_allocated): Likewise. + (scan_loop): Remove nregs parameter. + (next_insn_in_loop): New function. + (load_mems_and_recount_loop_regs_set): Likewise. + (load_mems): Likewise. + (insert_loop_mem): Likewise. + (replace_loop_mem): Likewise. + (replace_label): Likewise. + (INSN_IN_RANGE_P): New macro. + (loop_optimize): Don't pass max_reg_num() to scan_loop. + (scan_loop): Remove nregs parameter, compute it after any new + registers are created by load_mems. Use INSN_IN_RANGE_P and + next_insn_in_loop rather than expanding them inline. Call + load_mems to load memory into pseudos, if appropriate. + (prescan_loop): Figure out whether or not there are jumps from the + loop to targets other than the label immediately following the + loop. Call insert_loop_mem to notice all the MEMs used in the + loop, if it could be safe to pull MEMs into REGs for the duration + of the loop. + (strength_reduce): Use next_insn_in_loop. Tweak comments. + +Wed Aug 19 08:29:44 1998 Richard Earnshaw (rearnsha@arm.com) - * frame.c, frame.h: New files for parsing dwarf 2 frame info. - * Makefile.in (LIB2ADD): New variable. Add $(srcdir)/frame.c. - (libgcc2.a): Use it instead of $(LIB2FUNCS_EXTRA) $(LANG_LIB2FUNCS) - (stmp-multilib): Likewise. - ($(T)crtbegin.o, $(T)crtend.o): Add -fno-exceptions. + * arm.c (arm_override_options): Remove lie about ignoring PIC flag. - * except.c: #include "defaults.h". - (exceptions_via_longjmp): Default depends on DWARF2_UNWIND_INFO. - (emit_throw): Don't defeat assemble_external if DWARF2_UNWIND_INFO. - (register_exception_table_p): New fn. - (start_eh_unwinder): Don't do anything if DWARF2_UNWIND_INFO. - (end_eh_unwinder): Likewise. +Wed Aug 19 07:08:15 1998 David S. Miller - * crtstuff.c: Wrap .eh_frame section, use EH_FRAME_SECTION_ASM_OP, - call __register_frame and __deregister_frame as needed. - * varasm.c (eh_frame_section): New fn if EH_FRAME_SECTION_ASM_OP. - * dwarf2out.c (EH_FRAME_SECTION): Now a function-like macro. Check - EH_FRAME_SECTION_ASM_OP. - * sparc/sysv4.h (EH_FRAME_SECTION_ASM_OP): Define. - * mips/iris6.h: (EH_FRAME_SECTION_ASM_OP): Define. - (LINK_SPEC): Add __EH_FRAME_BEGIN__ to hidden symbols. + * config/sparc/sparc.c (finalize_pic): Check for the correct + nonlocal_goto_receiver UNSPEC number. + * config/sparc/sparc.md (nonlocal_goto_receiver): Add comment + making note of this dependency existing in sparc.c. + (negtf2_notv9 split): Give NEG SFmode. + (negsf2): Fix insn output string. - * dwarf2out.c (output_call_frame_info): If no support for - EXCEPTION_SECTION, mark the start of the frame info with a - collectable tag. - * collect2.c (frame_tables): New list. - (is_ctor_dtor): Recognise frame entries. - (scan_prog_file): Likewise. - (main): Pass -fno-exceptions to sub-compile. Also do collection - if there are any frame entries. - (write_c_file_stat): Call __register_frame_table and - __deregister_frame as needed. - (write_c_file_glob): Likewise. - - * defaults.h (DWARF2_UNWIND_INFO): Default to 1 if supported. - Also require unaligned reloc support. - * sparc.h (UNALIGNED_SHORT_ASM_OP, UNALIGNED_INT_ASM_OP, - UNALIGNED_DOUBLE_INT_ASM_OP): Define here. - * sparc/sysv4.h: Not here. - - * toplev.c (compile_file): Call dwarf2out_frame_{init,finish}. - * dwarf2out.c (dwarf2out_init): Don't call dwarf2out_frame_init. - (dwarf2out_finish): Don't call dwarf2out_frame_finish. - - * libgcc2.c (L_eh): Reorganize, moving code shared by different - EH implementations to the top. - (find_exception_handler): Split out. Start from 0. Compare against - end with >=. - (__find_first_exception_table_match): Use it. - * except.c (output_exception_table): Don't do anything if there's - no table. Don't output a first entry of zeroes. - (eh_outer_context): Adjust properly. - (add_eh_table_entry): Use xrealloc. - * toplev.c (compile_file): Just call output_exception_table. - -Wed Sep 10 11:30:36 1997 Jason Merrill - - * i386.c (ix86_prologue): Add dwarf2 support for !do_rtl case. - -Wed Sep 10 08:17:10 1997 Torbjorn Granlund - - * except.c (eh_outer_context): Do masking using expand_and. - -Wed Sep 10 01:38:30 1997 Doug Evans - - Add port done awhile ago for the ARC cpu. - * arc/arc.h: New file. - * arc/arc.c: New file. - * arc/arc.md: New file. - * arc/initfini.c: New file. - * arc/lib1funcs.asm: New file. - * arc/t-arc: New file. - * arc/xm-arc.h: New file. - * ginclude/va-arc.h: New file. - * ginclude/stdarg.h: Include va-arc.h ifdef __arc__. - * ginclude/varargs.h: Likewise. - * Makefile.in (USER_H): Add va-arc.h. - * configure.in (arc-*-elf*): Recognize. - * longlong.h: Add ARC support. +Tue Aug 18 12:40:27 1998 Richard Henderson -Wed Sep 10 01:32:54 1997 Jeffrey A Law (law@cygnus.com) + * c-common.c (decl_attributes): Issue an error if the argument + to alias is not a string. - * expr.c (clear_storage): Use CONST0_RTX instead of const0_rtx. - when clearing non-BLKmode data. +Tue Aug 18 10:33:30 1998 Jeffrey A Law (law@cygnus.com) -Wed Sep 10 00:29:29 1997 Manfred Hollstein + * haifa-sched.c (sched_analyze): Put all JUMP_INSNs on the last + pending memory flush list. - * m88k/sysv3.h (INITIALIZE_TRAMPOLINE) Define. - * libgcc2.c (__enable_execute_stack): Provide for sysV88 too. + * combine.c (can_combine_p): Allow combining insns with REG_RETVAL + notes. + (try_combine): Allow combining insns with REG_LIBCALL notes. - * xm-m88k.h (USG): Only define if it hasn't already been defined. + * expr.c (emit_block_move): Do not call memcpy as a libcall + instead build up a CALL_EXPR and call it like any other + function. + (clear_storage): Similarly for memset. - * Makefile.in (risky-stage1): Delete gratutious whitespace. + * regmove.c (fixup_match_2): Do not call reg_overlap_mentioned_p + on notes. - * Makefile.in (clean): Delete libgcc1-test. + * Makefile.in (cplus-dem.o): Provide explicit rules for building + cplus-dem.o. - * Makefile.in (INSTALL): cd to $(srcdir) before running texinfo. + * regmove.c (optimize_reg_copy_1): Update REG_N_CALLS_CROSSED + and REG_LIVE_LENGTH as successful substitutions are made. -Tue Sep 9 17:07:36 1997 Stan Cox +Tue Aug 18 07:15:27 1998 Kaveh R. Ghazi - * m88k.c (m88k_expand_prologue): Set MEM_IN_STRUCT_P of va_list - template. + * config/sparc/sparc.c (ultra_find_type): Add empty semicolon + statement after end of loop label. -Tue Sep 9 09:50:02 1997 Richard Kenner +Tue Aug 18 07:13:27 1998 David S. Miller - * dwarf2out.c (output_call_frame_info): Call named_section. + * config/sparc/sparc.c (ultra_types_avail): New variable. + (ultra_build_types_avail): New function to record mask of insn + types in ready list at this cycle. + (ultrasparc_sched_reorder): Call it. + (ultra_find_type): Use it to quicken the search. Also simplif + dependency check, don't use rtx_equal_p because we know exactly + what we are looking for. -Tue Sep 9 09:12:17 1997 Jeffrey A Law (law@cygnus.com) +Tue Aug 18 03:20:53 1998 Richard Earnshaw (rearnsha@arm.com) - * haifa-sched.c (print_value): Fix last change. + * arm.h (SECONDARY_INPUT_RELOAD_CLASS): Return NO_REGS if compiling + for architecture v4. -Tue Sep 9 01:30:37 1997 Jason Merrill +Mon Aug 17 21:26:38 1998 David S. Miller - * mips.h (DWARF_FRAME_REGNUM): Use the same numbering regardless of - write_symbols. + * config/sparc/sparc.md (sltu, sgeu): Don't FAIL, call + gen_compare_reg. + (movsf_const_intreg, movsf_const_high, movsf_const_lo, + movdf_const_intreg and helper splits): New patterns to move float + constants into integer registers. + (negtf2, negdf2, abstf2, absdf2): Rework using new patterns and + splits. -Mon Sep 8 16:32:43 1997 Jason Merrill +Mon Aug 17 11:46:19 1998 Jeffrey A Law (law@cygnus.com) - * mips.c (function_prologue): Set up the CFA when ABI_32. + * From Graham + * tree.c (build_index_type): Copy TYPE_SIZE_UNIT from sizetype + to itype. + * c-decl.c (finish_enum): Copy TYPE_SIZ_UNIT from enumtype to tem. - * sparc.c (save_regs): Check dwarf2out_do_frame instead of DWARF2_DEBUG - for dwarf2 unwind info. - (output_function_prologue, sparc_flat_output_function_prologue): Same. + * rs6000.c (secondary_reload_class): For TARGET_ELF, indicate that + a BASE_REGS register is needed as an intermediate when copying + a symbolic value into any register class other than BASE_REGS. - * final.c (final_end_function): Check dwarf2out_do_frame instead - of DWARF2_DEBUG for dwarf2 unwind info. - (final_scan_insn): Likewise. - (final_start_function): Likewise. Initialize dwarf2 frame debug here. - (final): Not here. + * expr.c (move_by_pieces): No longer static. Remove prototype. + * rtl.h (move_by_pieces): Add extern prototype. + * mips.c (expand_block_move): Handle aligned straight line copy by + calling move_by_pieces. - * expr.c (expand_builtin_return_addr): Only SETUP_FRAME_ADDRESSES if - count > 0. + * expr.c (expand_expr): Allow assignments from TImode PARM_DECLs + and VAR_DECLs. - * varasm.c (exception_section): Check EXCEPTION_SECTION first. +Mon Aug 17 10:28:52 1998 Mark Mitchell -Mon Sep 8 15:15:11 1997 Nick Clifton + * stmt.c (expand_end_loop): Tidy. Allow unconditional + jumps out of the loop to be treated as part of the exit test. - * v850.h (ASM_SPEC): Pass on target processor. - (CPP_PREDEFINES): Only define if not already specified. - (TARGET_VERSION): Only define if not already specified. - (MASK_CPU, MASK_V850, MASK_DEFAULT): Bits to specify target - processor. - (EXTRA_SWITCHES): Extra entries in the switches array. - (TARGET_DEFAULT): Set default target processor. +Mon Aug 17 10:06:11 1998 Kaveh R. Ghazi + Jeff Law -Mon Sep 8 18:26:35 1997 Jim Wilson + * Makefile.in (cplus-dep.o): Use cplus-dem.c from libiberty. + * cplus-dem.c: Delete. - * m68k.h (MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): In MOTOROLA - cases, add %# and %/, and add : to make them into extended asms. + * Makefile.in (fold-const.o): Depend on $(RTL_H). -Sun Sep 7 23:57:50 1997 Weiwen Liu + * fold-const.c: Include rtl.h to get the prototype for + `set_identifier_local_value'. - * alias.c (init_alias_analysis): Clean up incompatible pointer - type warning in bzero. - * regmove.c (regmove_optimize): Ditto. - * haifa-sched.c (find_rgns): Ditto. + * loop.c (express_from_1): Remove unused variable `tmp'. + (combine_givs): Cast the first argument of bzero to char *. - * haifa-sched.c (print_value): Clean up ptr->int cast - warnings. + * toplev.c (display_help): Remove unused variable `looking_for_start'. -Sun Sep 7 23:18:32 1997 Fred Fish + * c-decl.c (init_decl_processing): Remove unneeded &. - * INSTALL: Change 'amigados' to 'amigaos' to match current usage. - * install.texi (Configurations): Ditto. - * config.sub: Ditto. + * alpha.h (alpha_initialize_trampoline): Provide prototype. -Sun Sep 7 22:56:56 1997 Weiwen Liu (liu@hepvms.physics.yale.edu) + * except.c (set_exception_lang_code, set_exception_version_code): + Change parameter from `short' to `int' to avoid using a gcc + extension. - * Makefile.in (sdbout.o): Depend on insn-config.h. + * except.h (set_exception_lang_code, set_exception_version_code): + Likewise for prototypes. -Sun Sep 7 18:44:50 1997 Jim Wilson + * flow.c (count_reg_references): Remove unused variables `regno' + and `i'. - * m68k/m68k.h (TARGET_SWITCHES): For 68000, 68302, subtract MASK_68881. - For 68303, 68332, cpu32, subtract MASK_68040_ONLY. + * gcse.c (hash_scan_insn): Declare parameter `in_libcall_block'. -Sun Sep 7 18:30:46 1997 Jason Merrill + * prefix.c (translate_name): Cast the result of `alloca'. - * dwarf2out.c (dwarf2out_frame_debug): Assume that in a PARALLEL - prologue insn, only the first elt is significant. - (output_call_frame_info): For exception handling, always use 4-byte - fields as specified by the dwarf2 spec. - Don't skip trivial FDEs. + * varray.h (VARRAY_FREE): Reimplement as a `do-while(0)' statement. -Sun Sep 7 14:19:39 1997 Jeffrey A Law (law@cygnus.com) +Mon Aug 17 09:23:42 1998 Andreas Schwab - * version.c: Bump for snapshot. + * config/m68k/m68k.c: Include "system.h" instead of . + Include "toplev.h". + (valid_dbcc_comparison_p): Mark mode argument as unused. + (symbolic_operand): Likewise. + (legitimize_pic_address): Likewise. + (const_uint32_operand): Likewise. + (const_sint32_operand): Likewise. + * sched.c [!INSN_SCHEDULING]: Define only dummy function + schedule_insns and comment out rest of file. -Sun Sep 7 14:17:36 1997 Torbjorn Granlund (tege@pdc.kth.se) + * m68k.c (output_move_simode_const): Use subl to move a zero into an + address register. + (output_move_[hq]imode): Likewise. - * expmed.c (expand_divmod): Make op1_is_pow2 depend on unsignedp - for negative constants. Promote EXACT_DIV_EXPR to TRUNC_DIV_EXPR - when op1_is_pow2. +Mon Aug 17 09:15:47 1998 Jeffrey A Law (law@cygnus.com) -Sun Sep 7 13:46:46 1997 Jeffrey A Law (law@cygnus.com) + * toplev.c (main): Enable -fstrict-aliasing for -O2 and above. + * invoke.texi: Corresponding changes. - * final.c (shorten_branches): During first pass, assume worst - possible alignment for ADDR_VEC and ADDR_VEC_DIFF insns. +Mon Aug 17 02:03:55 1998 Richard Henderson - * Makefile.in (distclean): Remove various things left around - by running the testsuite. + * regclass.c (allocate_reg_info): Respect MIN when clearing data. -Sun Sep 7 13:16:06 1997 Manfred Hollstein +Sun Aug 16 17:37:06 1998 David S. Miller + + * config/sparc/sparc.c (ultra_code_from_mask, + ultra_cmove_results_ready_p, ultra_fpmode_conflict_exists, + ultra_find_type, ultra_schedule_insn, ultra_flush_pipeline, + ultrasparc_sched_init, ultrasparc_variable_issue, + ultra_rescan_pipeline_state, ultrasparc_sched_reorder): New + functions to describe UltraSPARC pipeline exactly to Haifa. + (ultrasparc_adjust_cost): Indicate IMUL type insns have zero cost, + as there is nothing the scheduler can do about it. Indicate that + REG_DEP_OUTPUT's collide. Fixup formatting. + * config/sparc/sparc.h (RTX_COSTS): Fixup integer multiply and + divide costs on Ultra for DImode. + (MD_SCHED_INIT, MD_SCHED_REORDER, MD_SCHED_VARIABLE_ISSUE): + Define. + * config/sparc/sparc.md (ieu_unnamed function unit): Rename to + ieuN and add call_no_delay_slot to type list. + (cti function unit): New unit for branches on UltraSPARC. + (subx/addx insns): Set type to misc. + (sidi zero/sign extension insns on arch64): Set type to shift. + (sign_extendhidi2_insn): Set type to sload. + +Sun Aug 16 13:52:00 1998 David Edelsohn + + * rs6000.c (rs6000_stack_info): Use if == 0 for sizes. + (output_epilog): Use if != 0 for offset. + (rs6000_fatal_bad_address): Prepare for Intl. + * rs6000.h (rs6000_fatal_bad_address): Declare. + * rs6000.md (movsfcc, movdfcc): Use else if. + (elf_high): Use {liu|lis}. + (elf_low): Use {cal|la}. Remove %a template from old mnemonics. + (movsi): Use rs6000_fatal_bad_address. - * configure.in (out_file): Emit definition to config.status in order - to have a defined value for configure.lang. - * configure: Re-built. +Sun Aug 16 01:53:21 1998 Richard Henderson -Sun Sep 7 09:59:08 1997 Jan-Jaap van der Heijden (J.J.vanderHeijden@student.utwente.nl) + * reload.c (find_equiv_reg): Reject equivalences separated + by a volatile instruction. - * configure.in: Make symlink to as-new rather than as.new. Similarly - for ld-new. - * configure: Rebuilt. +Sun Aug 16 00:21:44 1998 Franz Sirl -Fri Sep 5 16:54:55 1997 Jim Wilson + * rs6000/linux.h (CPP_OS_DEFAULT_SPEC): Define. - * profile.c (output_func_start_profiler): Set DECL_EXTERNAL to zero. +Sat Aug 15 20:51:35 1998 Richard Henderson -Fri Sep 5 16:16:44 1997 Christian Kuehnke + * alpha.md (movsicc): Fix mode mismatch. - * sparc/sparc.md: Add ultrasparc scheduling support. - * sparc/sparc.h (RTX_COSTS): For MULT give v9 a cost of 25 insns. +Sat Aug 15 20:22:33 1998 H.J. Lu (hjl@gnu.org) -Fri Sep 5 14:04:59 1997 Philippe De Muyter + * config/alpha/alpha.h (ASM_OUTPUT_MI_THUNK): Handle aggregated + return type. + * config/alpha/win-nt.h (ASM_OUTPUT_MI_THUNK): Likewise. - * integrate.c (save_for_inline_copying): Use 0, not NULL_PTR, - as initial value for real_label_map. - (copy_for_inline): Likewise. +Sat Aug 15 08:39:49 1998 David S. Miller -Fri Sep 5 13:36:44 1997 J"orn Rennecke + * config/sparc/sparc.md (movsi_lo_sum_pic_label_reg): Remove + write-only modifier from operand 1 constraint. - * sched.c (update_flow_info) When looking if to set found_split_dest - or found_orig_dest, look at all parts of a PARALLEL. - * haifa-sched.c (update_flow_info): Likewise. +Sat Aug 15 06:28:19 1998 David S. Miller -Fri Sep 5 10:08:44 1997 Jeffrey A Law (law@cygnus.com) + * config/sparc/sparc.c (sparc_emit_set_const64_quick1): If + emitting a XOR of -1 at the end, emit a NOT instead for combine's + sake. + (sparc_emit_set_const64): Likewise, also when computing trailing + bits do not negate low_bits and make fast_int an int. - * v850: New directory for v850 port. - * v850/lib1funcs.asm: New file. - * t-v850, v850.c, v850.h, v850.md, xm-v850.h: New files. - * ginclude/va-v850.h: New file. - * ginclude/varargs.h, ginclude/stdarg.h: Include va-mn10200.h. - * configure.in (mn10200-*-*): New target. - * configure: Rebuilt. - * config.sub: Handle v850-elf. - * Makefile.in (USER_H): Add va-mn10200.h. - * invoke.texi: Document v850 stuff. +Fri Aug 14 21:07:03 1998 Jeffrey A Law (law@cygnus.com) -Fri Sep 5 09:37:50 1997 Jim Wilson (wilson@cygnus.com) + * loop.c (add_label_notes): Do not ignore references to labels + before dispatch tables. Mirrors Apr 8 change to mark_jump_label. + * gcse.c (add_label_notes): Similarly. - * sdbout.c (plain_type_1, case ARRAY_TYPE): Verify that TYPE_DOMAIN - has integer TYPE_{MAX,MIN}_VALUE before using them. + * pa.h (ASM_OUTPUT_MI_THUNK): Strip name encoding. - * m68k/m68k.h (MACHINE_STATE_SAVE, MACHINE_STATE_RESTORE): Add - __HPUX_ASM__ versions. + * m68k.md (adddi_dilshr32): One of the operands must be a register. + (adddi_dishl32): Similarly. -Fri Sep 5 09:08:44 1997 Jeffrey A Law (law@cygnus.com) +Fri Aug 14 14:12:59 1998 Jason Merrill + + * i386.h (MODES_TIEABLE_P): Reorganize to shut up warnings. + * alias.c (memrefs_conflict_p): Add braces to shut up warnings. + * cse.c (cse_basic_block): Add parens to shut up warnings. + +Fri Aug 14 12:58:21 1998 David S. Miller + + * config/sparc/sparc.c (sparc_emit_set_const64_quick2, + sparc_emit_set_const64_longway, const64_is_2insns, + create_simple_focus_bits, sparc_emit_set_const64): Fix more bugs + in 64-bit constant formation. + * config/sparc/sparc.md (snesi_zero_extend split): Generate + rtl for addx not subx. + (define_insn movdi_const64_special): Make available even when + HOST_BITS_PER_WIDE_INT is not 64. + (movdi_lo_sum_sp64_cint, movdi_high_sp64_cint): Remove. + (losum_di_medlow, sethm, setlo): Make op2 symbolic_operand. + (cmp_siqi_trunc_set, cmp_diqi_trunc_set): Encapsulate both + instances of operand 1 inside a QI subreg. + (xordi3_sp64_dbl): Remove '%' constraint for op1. + (one_cmpldi2_sp64): Fix output string. + (one_cmplsi2_not_liveg0): Rewrite to remove unneeded extra + alternative case. + (unnamed arch64 ashift DI): Truncate shift count if greater than + 63, not 31. + +Fri Aug 14 21:52:53 1998 J"orn Rennecke - * install.sh: Delete duplicate install script. + * expr.c (store_expr): Don't optimize away load-store pair + when either source or destination have a side effect. -Thu Sep 4 23:14:27 1997 Stan Cox (coxs@dg-rtp.dg.com) +Fri Aug 14 16:50:10 1998 John Carr - * reg-stack.c (subst_stack_regs): Pop the stack register for a - computed goto which sets the same stack register. + * genrecog.c (add_to_sequence): Fatal error if the modes of the + operands of SET are incompatible. - * reg-stack.c (compare_for_stack_reg): Swap only if the source and - destination are both on the regstack. - (subst_stack_regs_pat): Put the destination at the top of the regstack. + * alpha.md: Fix max and min patterns so modes of SET operands match. -Thu Sep 4 15:02:27 1997 Jim Wilson +Fri Aug 14 12:22:55 1998 Ian Lance Taylor - * mips.md (nonlocal_goto_receiver): Define. + * configure.in: Avoid [[ by using test and changequote. + * configure: Rebuild. - * profile.c (output_arc_profiler): Check next_insert_after for non - NULL before deferencing it. +Fri Aug 14 01:22:31 1998 David S. Miller + + * rtl.def (CONSTANT_P_RTX): Fix typo in string name. + + * config/sparc/sparc.md (seqdi_special_trunc, snedi_special_trunc, + seqsi_special_extend, snesi_special_extend, snesi_zero_extend and + split, snedi_zero_trunc and split, seqsi_zero_extend and split, + seqdi_zero_trunc and split, pic_lo_sum_di, pic_sethi_di, + movdi_cc_sp64_trunc, movdi_cc_reg_sp64_trunc, addx_extend_sp32 and + split, addx_extend_sp64, subx_extend_sp64, subx_extend and split): + Fix mismatching modes in SET operands. + (conditional move patterns): Fix formatting. + (unnamed subx arch64 pattern): Remove duplicate insn. + +Fri Aug 14 00:34:34 1998 David S. Miller + + * config/sparc/sparc.c (const64_operand, const64_high_operand): + Get it right when HOST_BITS_PER_WIDE_INT is not 64. + (input_operand): Fixup test for what we accept for constant + integers. + (sparc_emit_set_const32, sparc_emit_set_symbolic_const64): Give + set VOIDmode. + (safe_constDI): Remove. + (sparc_emit_set_safe_HIGH64, gen_safe_SET64, gen_safe_OR64, + gen_safe_XOR64): New functions. + (sparc_emit_set_const64_quick1, sparc_emit_set_const64_quick2, + sparc_emit_set_const64_longway, sparc_emit_set_const64): Use + them. + * config/sparc/sparc.md (define_insn xordi3_sp64_dbl): Only make + available when HOST_BITS_PER_WIDE_INT is not 64. + (define_insn movdi_sp64_dbl, movdi_const64_special): Likewise and + move before movdi_insn_sp64 pattern. + (define_insn movdi_lo_sum_sp64_dbl, movdi_high_sp64_dbl): Remove. + (define_insn sethi_di_medlow, seth44, setm44, sethh): Use + symbolic_operand as predicate for second operand. + (DImode minus split on arch32, negsi2 expander, one_cmplsi2 + expander): Give set VOIDmode. - * i386/t-sol2 (TARGET_LIBGCC2_CFLAGS): Define to -fPIC. +Fri Aug 14 01:45:06 1998 Mumit Khan -Thu Sep 4 14:51:57 1997 Jeffrey A Law (law@cygnus.com) + * i386/cygwin32 (DEFAULT_PCC_STRUCT_RETURN): Define. - * i386.h (CPP_CPU_DEFAULT): Avoid using #elif. +Fri Aug 14 01:40:21 1998 Geoffrey Keating -Thu Sep 4 15:01:49 1997 Michael Meissner + * rs6000/linux.h (LINK_SPEC): Pass -G args to the linker. - * toplev.c (rest_of_compilation): For passes starting with - flow_analysis, use print_rtl_with_bb instead of print_rtl. +Fri Aug 14 01:23:23 1998 Richard Earnshaw (rearnsha@arm.com) - * print-rtl.c (print_rtl_single): Print a single rtl value to a - file. + * arm/netbsd.h (TARGET_DEFAULT): Default includes software floating + point. + (CPP_FLOAT_DEFAULT_SPEC): Re-define accordingly. - * flow.c (print_rtl_with_bb): Print which insns start and end - basic blocks. For the start of a basic block, also print the live - information. +Fri Aug 14 01:19:08 1998 Robert Lipe -Thu Sep 4 11:51:43 1997 Jim Wilson + * install.texi: Various SCO OpenServer tweaks. - * toplev.c (main): Change #elif to #else/#ifdef +Thu Aug 13 20:14:40 1998 Jim Wilson - * tlink.c: Include ctype.h. - * ginclude/va-mips.h: Add _VA_MIPS_H_ENUM ifdef/define/endif. + * reload1.c (eliminate_regs_in_insn): Handle another case when + eliminating the frame pointer to the hard frame pointer. Add + missing ep->to_rtx check to one existing case. -Thu Sep 4 11:17:16 1997 Mikeael Meissner (meissner@cygnus.com) + * mips/mips.md (movhi_internal2+2): Fix typo mem:SI -> mem:HI. - * bitmap.c: Conditionally include stdlib.h. - (free): Provide a declaration if NEED_DECLARATION_FREE. +Thu Aug 13 17:08:11 1998 Jason Merrill -Thu Sep 4 09:58:53 1997 Joel Sherrill (joel@OARcorp.com) + * tree.h: De-conditionalize init_priority code. - * i960/i960.h: Added default for SUBTARGET_SWITCHES macro. + * mips.h (NM_FLAGS): Change from -Bp to -Bn. + * collect2.c (NM_FLAGS): Change from -p to -n. -Thu Sep 4 09:53:20 1997 Jim Wilson (wilson@cygnus.com) + * configure.in: Turn on collect2 for mipstx39-elf. + Handle use_collect2=no properly. - * profile.c (output_arc_profiler): Verify next_insert_after is an - INSN before and after skipping a stack pop. + * c-common.c: De-conditionalize init_priority code. + * collect2.c (extract_init_priority, sort_ids): New fns. + (main): Call sort_ids. + Move sequence_number to file scope. -Thu Sep 4 07:39:19 1997 J"orn Rennecke + * configure.in: Handle --enable-init-priority. + * c-common.c (attrs): Add A_INIT_PRIORITY. + (init_attributes, decl_attributes): Likewise. + * tree.h (DEFAULT_INIT_PRIORITY, MAX_INIT_PRIORITY): New macros. + * tree.c (get_file_function_name_long): Split out... + (get_file_function_name): ...from here. - * final.c (shorten_branches): Don't count the lengths of deleted - instructions. +Thu Aug 13 16:09:53 1998 Martin von Loewis -Thu Sep 4 09:43:01 1997 Jeffrey A Law (law@cygnus.com) + * expr.c (safe_from_p): Change code to ERROR_MARK only when not + accessing nodes. - * version.c: Bump for snapshot. +Thu Aug 13 15:24:48 1998 Jason Merrill -Thu Sep 4 11:04:21 1997 Michael Meissner + * toplev.c (display_help): Add braces to shut up warnings. + * tree.c (simple_cst_equal): Likewise. - * bitmap.h (EXECUTE_IF_AND_IN_BITMAP): New macro, to iterate over - two bitmaps ANDed together. - (bitmap_print): Declare. + * fold-const.c (non_lvalue): Don't deal with null pointer + constants here. + (fold, case COMPOUND_EXPR): Wrap a constant 0 in a NOP_EXPR. - * bitmap.c (function_obstack): Don't declare any more. - (bitmap_obstack): Obstack for allocating links from. - (bitmap_obstack_init): New static to say whether to initialize - bitmap_obstack. - (bitmap_element_allocate): Use bitmap_obstack to allocate from. - (bitmap_release_memory): Free all memory allocated from - bitmap_obstack. + * c-typeck.c (initializer_constant_valid_p): Allow conversion of 0 + of any size to a pointer. - * basic-block.h (EXECUTE_IF_AND_IN_REG_SET): New macro, invoke - EXECUTE_IF_AND_IN_BITMAP. +Thu Aug 13 12:53:13 1998 Jim Wilson -Wed Sep 3 10:39:42 1997 Jim Wilson + * i386/winnt.c (i386_pe_asm_file_end): Check TREE_SYMBOL_REFERENCED. - * alias.c (true_dependence): Address with AND can alias scalars. - (anti_dependence, output_dependence): Likewise. +Wed Aug 12 17:25:18 1998 Jeffrey A Law (law@cygnus.com) - * alias.c (true_dependence): Test x for BLKmode, in addition to mem. + * mn10300.c (REG_SAVE_BYTES): Only reserve space for registers + which will be saved. + * mn10300.md (prologue insn): Only save registers which need saving. + (epilogue insn): Similarly. -Wed Sep 3 09:28:50 CDT 1997 Joel Sherrill (joel@OARcorp.com) + * mn10300.c, mn10300.h, mn10300.md: Remove "global zero register" + optimizations. - * i386/go32-rtems.h, i386/rtems.h, i960/rtems.h, m68k/rtems.h, - mips/rtems64.h, pa/rtems.h, rs6000/rtems.h, sh/rtems.h, - sparc/rtems.h (subtarget_switches): Removed SUBTARGET_SWITCHES - definitions. Use -qrtems instead of -mrtems. +Wed Aug 12 12:39:16 1998 Gavin Romig-Koch -Wed Sep 3 09:05:41 1997 Robert Lipe (robert@dgii.com) + * mips/mips.h (ENCODE_SECTION_INFO): Set SYMBOL_REF_FLAG for + VAR_DECL's in gp addressable sections. - * xm-sco5.h (sys_siglist): Define. - (SYS_SIGLIST_DECLARED): Likewise. +Tue Aug 11 23:02:31 1998 John Carr -Tue Sep 2 23:33:33 1997 Jeffrey A Law (law@cygnus.com) + * sparc.c: Change return to ; return; in functions + returning void. + * sparc.md: Add empty semicolon statement after final label in + move expanders. - * expr.c (convert_move): Handle truncation from TQFmode to QFmode. +Tue Aug 11 22:42:01 1998 David S. Miller -Wed Sep 3 02:09:30 1997 Torbjorn Granlund + * config/sparc/sparc.md (define_insn addx_extend): Rename to + addx_extend_sp64, only allow when TARGET_ARCH64. + (define_insn addx_extend_sp32 and split): Version that works when + not TARGET_ARCH64. + (define_insn subx_extend): Likewise. + (define_split adddi3 and subdi3 with zero extension): Fixup and + correct bugs when not TARGET_ARCH64. - * except.c (eh_outer_context): Expand masking operation using - expand_binop. +Tue Aug 11 16:04:34 1998 John Carr -Tue Sep 2 18:09:39 1997 Jim Wilson + * except.c (set_exception_lang_code, set_exception_version_code): + Use prototype-style definition if __STDC__, to match declaration + in except.h. - * alpha.md (floatdisf2-1): New pattern. + * genemit.c: Change FAIL and DONE macros not to use loops. -Tue Sep 2 18:41:55 1997 Jeffrey A Law (law@cygnus.com) +Tue Aug 11 12:27:03 1998 Jim Wilson - * xm-svr4.h (SYS_SIGLIST_DECLARED): Define. - * xm-news.h (SYS_SIGLIST_DECLARED): Likewise. - * xm-sysv4.h (SYS_SIGLIST_DECLARED): Likewise. - * gcc.texi: Note that if you define sys_siglist that you should - also define SYS_SIGLIST_DECLARED. + * dwarf2out.c (ASM_OUTPUT_DWARF_ADDR_CONST): Use + ASM_OUTPUT_DWARF2_ADDR_CONST if defined. - * mn10200.h (INITIALIZE_TRAMPOLINE): PC relative instructions - are relative to the next instruction, not the current instruction. + * mips/mips.md (reload_outsi): Use M16_REG_P when TARGET_MIPS16. -Tue Sep 2 14:22:43 1997 Jim Wilson +Tue Aug 11 18:12:53 1998 Dave Love - * local-alloc.c (contains_replace_regs): New function. - (update_equiv_regs): When adding a REG_EQUIV note for a set of a MEM, - verify that there is no existing REG_EQUIV note, and add a call to - contains_place_regs. + * README.g77: Update from Craig. -Tue Sep 2 12:48:11 1997 H.J. Lu (hjl@gnu.ai.mit.edu) +Tue Aug 11 04:46:01 1998 David S. Miller + + * config/sparc/sparc.c (sparc_emit_set_const32): INTVAL is of + type HOST_WIDE_INT. + (safe_constDI sparc_emit_set_const64_quick1, + sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, + analyze_64bit_constant, const64_is_2insns, + create_simple_focus_bits): Fix some bugs when compiled on real + 64-bit hosts. + (function_arg_record_value_3, function_arg_record_value_2, + function_arg_record_value): Add fully prototyped forward decls. + * config/sparc/sparc.md (define_insn cmpsi_insn_sp32): Rename back + to cmpsi_insn and use on both 64 and 32 bit targets. + (define_insn cmpsi_insn_sp64): Remove. + (define_expand zero_extendsidi2): Allow for 32-bit target too. + (define_insn zero_extendsidi2_insn): Rename to + zero_extendsidi2_insn_sp64. + (define_insn zero_extendsidi2_insn_sp32): New pattern and + associated forced split for it. + + * config/sparc/sparc.c (const64_operand, const64_high_operand): + New predicates. + * config/sparc/sparc.h: Declare them. + (PREDICATE_CODES): Add them. + * config/sparc/sparc.md (movdi_lo_sum_sp64_dbl, + movdi_high_sp64_dbl, xordi3_sp64_dbl): Use them. + +Mon Aug 10 22:57:24 1998 John Carr + + * config/sparc/sparc.md (define_insn jump): Output ba,pt not b,pt + in v9 case as the latter makes the Solaris assembler crash. + +Mon Aug 10 22:39:09 1998 David S. Miller + + * config/sparc/sparc.c (input_operand): Do not accept a LO_SUM MEM + for TFmode when !v9. We require offsettable memory addresses. + * config/sparc/sparc.h (ALTER_HARD_SUBREG): Handle TFmode to + DFmode register number conversions. + * config/sparc/sparc.md (define_split DFmode moves): If register + is a SUBREG do alter_subreg on it before using. + (define_expand movtf): Fixup comment about alignment on v9. + (define_split TFmode moves): Don't use gen_{high,low}part, create + explicit SUBREGs instead. + +Mon Aug 10 19:02:55 1998 John Carr + + * Makefile.in (mbchar.o): Depend on mbchar.c. + +Mon Aug 10 04:28:13 1998 David S. Miller + Richard Henderson + + Rewrite Sparc backend for better code generation and + improved sparc64 support. + * config/sparc/sp64-elf.h: Set JUMP_TABLES_IN_TEXT_SECTION to + zero. + * config/sparc/sysv4.h: Likewise. + * config/sparc/sparc.c (v8plus_regcmp_p, sparc_operand, + move_operand, v8plus_regcmp_op, emit_move_sequence, + singlemove_string, doublemove_string, mem_aligned_8, + output_move_double, output_move_quad, output_fp_move_double, + move_quad_direction, output_fp_move_quad, output_scc_insn): + Remove. + (small_int_or_double): New predicate. + (gen_compare_reg): Remove TARGET_V8PLUS cmpdi_v8plus emission. + (legitimize_pic_address): Emit movsi_{high,lo_sum}_pic instead of + old pic_{sethi,lo_sum}_si patterns. + (mem_min_alignment): New generic function to replace + mem_aligned_8, which uses REGNO_POINTER_ALIGN information when + available and can test for arbitrary alignments. All callers + changed. + (save_regs, restore_regs, build_big_number, + output_function_prologue, output_cbranch, output_return, + sparc_flat_save_restore, sparc_flat_output_function_prologue, + sparc_flat_output_function_epilogue): Prettify + insn output. + (output_function_epilogue): Likewise and add code to output + deferred case vectors. + (output_v9branch): Likewise, add new arg INSN and use it to tack + on branch prediction settings. All callers changed. + (print_operand): Likewise and output %l44 for LO_SUMs when + TARGET_CM_MEDMID. + (sparc_splitdi_legitimate): New function to make sure DImode + splits can be run properly when !arch64. + (sparc_initialize_trampoline, sparc64_initialize_trampoline): + Reformat example code in comments. + (set_extends): Remove UNSPEC/v8plus_clear_high case. + (sparc_addr_diff_list, sparc_addr_list): New statics to keep track + of deferred case vectors we need to output. + (sparc_defer_case_vector): Record a case vector. + (sparc_output_addr_vec, sparc_output_addr_diff_vec, + sparc_output_deferred_case_vectors): New functions to output them. + (sparc_emit_set_const32): New function to form 32-bit constants in + registers when that requires more than one instruction. + (safe_constDI, sparc_emit_set_const64_quick1, + sparc_emit_set_const64_quick2, sparc_emit_set_const64_longway, + analyze_64bit_constant, const64_is_2insns, + create_simple_focus_bits, sparc_emit_set_const64): New functions + which do the same for 64-bit constants when arch64. + (sparc_emit_set_symbolic_const64): New function to emit address + loading for all code models on v9. + * config/sparc/sparc.h (CONDITIONAL_REGISTER_USAGE): Do not make + %g1 fixed when arch64, unfix %g0 when TARGET_LIVE_G0. + (ALTER_HARD_SUBREG): Fix thinko, return REGNO + 1 not 1. + (SECONDARY_INPUT_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS): Fix + inaccuracies in comments, add symbolic and text_segment operands + when TARGET_CM_MEDANY and TARGET_CM_EMBMEDANY respectively. Use + GENERAL_REGS in these cases as a temp REG is needed to load these + addresses into a register properly. + (EXTRA_CONSTRAINT): Document more accurately, remove Q case as it + is no longer used. + (GO_IF_LEGITIMATE_ADDRESS): Allow TFmode for LO_SUM on v9 since fp + quads are guaranteed to have 16-byte alignment. + (LEGITIMIZE_ADDRESS): For SYMBOL_REF, CONST, and LABEL_REF use + copy_to_suggested_reg instead of explicit LO_SUM and HIGH. + (ASM_OUTPUT_ADDR_VEC, ASM_OUTPUT_ADDR_DIFF_VEC): New macros for + deferred case vector implementation. + (ASM_OUTPUT_ADDR_VEC_ELT): Use fputc to output newline. + (ASM_OUTPUT_ADDR_DIFF_ELT): Parenthesize LABEL in macro calls. + Generate "internal label - label" instead of "label - 1b". + (PRINT_OPERAND_ADDRESS): For LO_SUM use %l44 on TARGET_CM_MEDMID. + (PREDICATE_CODES): Remove sparc_operand, move_operand, + v8plus_regcmp_op. Add small_int_or_double, input_operand, and + zero_operand. + (doublemove_string, output_block_move, output_fp_move_double, + output_fp_move_quad, output_move_double, output_move_quad, + output_scc_insn, singlemove_string, mem_aligned_8, move_operand, + sparc_operand, v8plus_regcmp_op, v8plus_regcmp_p): Remove externs. + (sparc_emit_set_const32, sparc_emit_set_const64, + sparc_emit_set_symbolic_const64, input_operand, zero_operand, + mem_min_alignment, small_int_or_double): Add externs. + * config/sparc/sparc.md: Document the many uses of UNSPEC and + UNSPEC_VOLATILE in this backend. + (define_function_unit ieu): Rename to ieu_unnamed. Add move and + unary to types which execute in it. + (define_function_unit ieu_shift): Rename to ieu0. + (define_function_unit ieu1): New, executes compare, call, and + uncond_branch type insns. + (define_function_units for type fdivs, fdivd, fsqrt): These + execute in the fpu multiply unit not the adder on UltraSparc. + (define_expand cmpdi): Disallow TARGET_V8PLUS. + (define_insn cmpsi_insn): Rename to cmpsi_insn_sp32. + (define_insn cmpsi_insn_sp64): New, same as sp32 variant except it + allows the arith_double_operand predicate and rHI constraint when + TARGET_ARCH64. + (define_insn cmpdi_sp64, cmpsf_fpe, cmpdf_fpe, cmptf_fpe, + cmpsf_fp, cmpdf_fp, cmptf_fp, sltu_insn, neg_sltu_insn, + neg_sltu_minux_x, neg_sltu_plus_x, sgeu_insn, neg_sgeu_insn, + sltu_plus_x, sltu_plus_x, sltu_plus_x_plus_y, x_minus_sltu, + sgeu_plus_x, x_minus_sgeu, movqi_cc_sp64, movhi_cc_sp64, + movsi_cc_sp64, movdi_cc_sp64, movsf_cc_sp64, movdf_cc_sp64, + movtf_cc_sp64, movqi_cc_reg_sp64, movhi_cc_reg_sp64, + movsi_cc_reg_sp64, movdi_cc_reg_sp64, movsf_cc_reg_sp64, + movdf_cc_reg_sp64, movtf_cc_reg_sp64, zero_extendhisi2_insn, + cmp_siqi_trunc, cmp_siqi_trunc_set, sign_extendhisi2_insn, + sign_extendqihi2_insn, sign_extendqisi2_insn, + sign_extendqidi2_insn, sign_extendhidi2_insn, + extendsfdf2, extendsftf2, extenddftf2, truncdfsf2, trunctfsf2, + trunctfdf2, floatsisf2, floatsidf2, floatsitf2, floatdisf2, + floatdidf2, floatditf2, fix_truncsfsi2, fix_truncdfsi2, + fix_trunctfsi2, fix_truncsfdi2, fix_truncdfdi2, fix_trunctfdi2, + adddi3_sp64, addsi3, cmp_ccx_plus, cmp_cc_plus_set, subdi_sp64, + subsi3, cmp_minus_ccx, cmp_minus_ccx_set, mulsi3, muldi3, + muldi3_v8plus, cmp_mul_set, mulsidi3, mulsidi3_v8plus, + const_mulsidi3_v8plus, mulsidi3_sp32, const_mulsidi3, + smulsi3_highpart_v8plus, unnamed subreg mult, + const_smulsi3_highpart_v8plus, smulsi3_highpart_sp32, + const_smulsi3_highpart, umulsidi3_v8plus, umulsidi3_sp32, + const_umulsidi3, const_umulsidi3_v8plus, umulsi3_highpart_v8plus, + const_umulsi3_highpart_v8plus, umulsi3_highpart_sp32, + const_umulsi3_highpart, divsi3, divdi3, cmp_sdiv_cc_set, udivsi3, + udivdi3, cmp_udiv_cc_set, smacsi, smacdi, umacdi, anddi3_sp64, + andsi3, and_not_di_sp64, and_not_si, iordi3_sp64, iorsi3, + or_not_di_sp64, or_not_si, xordi3_sp64, xorsi3, xor_not_di_sp64, + xor_not_si, cmp_cc_arith_op, cmp_ccx_arith_op, + cmp_cc_arith_op_set, cmp_ccx_arith_op_set, cmp_ccx_xor_not, + cmp_cc_xor_not_set, cmp_ccx_xor_not_set, cmp_cc_arith_op_not, + cmp_ccx_arith_op_not, cmp_cc_arith_op_not_set, + cmp_ccx_arith_op_not_set, negdi2_sp64, cmp_cc_neg, cmp_ccx_neg, + cmp_cc_set_neg, cmp_ccx_set_neg, one_cmpldi2_sp64, cmp_cc_not, + cmp_ccx_not, cmp_cc_set_not, cmp_ccx_set_not, addtf3, adddf3, + addsf3, subtf3, subdf3, subsf3, multf3, muldf3, mulsf3, + muldf3_extend, multf3_extend, divtf3, divdf3, divsf3, negtf2, + negdf2, negsf2, abstf2, absdf2, abssf2, sqrttf2, sqrtdf2, sqrtsf2, + ashlsi3, ashldi3, unnamed DI ashift, cmp_cc_ashift_1, + cmp_cc_set_ashift_1, ashrsi3, ashrdi3, unnamed DI ashiftrt, + ashrdi3_v8plus, lshrsi3, lshrdi3, unnamed DI lshiftrt, + lshrdi3_v8plus, tablejump_sp32, tablejump_sp64, call_address_sp32, + call_symbolic_sp32, call_address_sp64, call_symbolic_sp64, + call_address_struct_value_sp32, call_symbolic_struct_value_sp32, + call_address_untyped_struct_value_sp32, + call_symbolic_untyped_struct_value_sp32, call_value_address_sp32, + call_value_symbolic_sp32, call_value_address_sp64, + call_value_symbolic_sp64, branch_sp32, branch_sp64, + flush_register_windows, goto_handler_and_restore, + goto_handler_and_restore_v9, goto_handler_and_restore_v9_sp64, + flush, all ldd/std peepholes, return_qi, return_hi, return_si, + return_addsi, return_di, return_adddi, return_sf, all call+jump + peepholes, trap, unnamed trap insns): Prettify output strings. + (define_insn anddi3_sp32, and_not_di_sp32, iordi3_sp32, + or_not_di_sp32, xordi3_sp32, xor_not_di_sp32, one_cmpldi2): + Likewise and force + implement splits for integer cases. + (define_insn return_sf_no_fpu): Likewise and allow to match when + no-fpu because of our subreg SFmode splits. + (define_insn zero_extendqihi2, zero_extendqisi2_insn, + zero_extendqidi2_insn, zero_extendhidi2_insn, + zero_extendsidi2_insn, sign_extendsidi2_insn): Likewise and use + input_operand for second operand. + (cmp_minus_cc, cmp_minus_cc_set): Likewise and use + reg_or_0_operand for operand 2 so new splits can use it. + (cmp_zero_extendqisi2, cmp_zero_extendqisi2_set, cmp_cc_plus, + cmp_cc_xor_not): Likewise and don't forget to check TARGET_LIVE_G0 + too. + (cmp_zero_extract, cmp_zero_extract_sp64): Likewise and allow + CONST_DOUBLEs for operand 2. + (define_insn move_label_di): Likewise and label distance + optimization because it no longer works with new deferred case + vector scheme. To be revisited. + (define_insn x_minus_y_minus_sltu, x_minus_sltu_plus_y): Likewise + and allow reg_or_0_operand and J constraint for second operand. + (define_insn jump): Set branch predict taken on V9. + (define_insn tablejump): Emit LABEL_REF + PLUS memory address for + new deferred case vector scheme. + (define_insn pic_tablejump_32, pic_tablejump_64): Remove. + (define_insn negdi2_sp32): Force + implement splits. + (define_insn negsi2, one_cmplsi2): Rename to negsi2_not_liveg0 and + one_cmplsi2_not_liveg0 respectively, and create expander of original + names which emit special rtl for TARGET_LIVE_G0. + (define_insn cmpdi_v8plus, scc_si, scc_di): Remove. + (define_insn seq, sne, slt, sge, sle, sltu, sgeu): Don't do + gen_compare_reg, FAIL instead. + (define_insn sgtu, sleu): Likewise and check gen_s*() return + values when trying to reverse condition codes, if they FAIL then + do likewise. + (define_insn snesi_zero, neg_snesi_zero, snesi_zero_extend, + snedi_zero, neg_snedi_zero, snedi_zero_trunc, seqsi_zero, + neg_seqsi_zero, seqsi_zero_extend, seqdi_zero, neg_seqdi_zero, + seqdi_zero_trunc, x_plus_i_ne_0, x_minus_i_ne_0, x_plus_i_eq_0, + x_minus_i_eq_0): Add new splits to perform these multi-insn cases, + set output string to # to indicate they are mandatory splits. + (define_insn pic_lo_sum_si, pic_sethi_si, pic_lo_sum_di, + pic_sethi_di, move_pic_label_si): Remove. + (define_insn movsi_low_sum, movsi_high, movsi_lo_sum_pic, + movsi_high_pic, movsi_pic_label_reg): New patterns to take their + place. + (define_expand movsi_pic_label_ref, define_insn + movsi_high_pic_label_ref, movsi_lo_sum_pic_label_ref): New + expander and insns to handle PIC label references and deferred + case vectors. + (define_insn get_pc_via_rdpc): Comment out as it is no longer + used. + (define_expand movqi, movhi, movsi, movdi, movsf, movdf, movtf): + Rewrite to not use emit_move_sequence, make use of new constant + formation code, and new splits for all multi-insn cases. + (define_insn movqi_insn): Remove sethi case, it can never happen. + Use reg_or_zero_operand instead of const0_rtx explicit test, + use input_operand instead of move_operand for source, and use + general_operand now for dest. + (define_insn movhi_insn): Similar but leave sethi case. + (define_insn lo_sum_qi, store_qi, store_hi): Remove. + (define_insn sethi_hi lo_sum_hi): Rename to movhi_high and + movhi_lo_sum respectively, prettify output string. + (define_insn movsi_zero_liveg0): New pattern to put zero into a + register when needed on TARGET_LIVE_G0. + (define_insn movsi_insn): Use general_operand and input_operand + for dest and src respectively. Simplify applicability test. + Prettify output strings, and add clr alternative for J + constraint. + (define_insn movdi_sp32_v9, movdi_sp32, define_splits for + deprecated std and reg-reg DI moves): Remove and... + (define_insn movdi_insn_sp32, movdi_insn_sp64): Replace with new + implementation which uses forced splits for all non-single insn + cases. + (define_split DI move cases on !arch64): New splits to handle all + situations of 64-bit double register DImode on 32bit, and + unaligned registers and memory addresses for all subtargets. + (define_insn movsf_const_insn, movdf_const_insn, store_sf): + Remove. + (define_insn movsf_insn, movsf_no_f_insn): Use general_operand and + input_operand for dest and src respectively, prettify output + strings. + (define_insn movdf_insn, movdf_no_e_insn, store_df, + movtf_const_insn, movtf_insn, movtf_no_e_insn, store_tf): Remove + and... + (define_insn movdf_insn_sp32, movdf_no_e_insn_sp32, + movdf_insn_sp64, movdf_no_e_insn_sp64, movtf_insn, + movtf_no_e_insn_sp32, movtf_insn_hq_sp64, movtf_insn_sp64, + movtf_no_e_insn_sp64): Replace with new + implementation which uses forced splits for all non-single insn + cases. + (define_split DF move cases): New splits in similar vein to DI + move counterparts. + (define_insn sethi_di_medlow, sethi_di_medium_pic, + sethi_di_embmedany_data, sethi_di_embmedany_text, sethi_di_sp64, + movdi_sp64_insn): Remove old v9 code model and constant loading + support insns and.. + (define_insn pic_lo_sum_di, pic_sethi_di, + sethi_di_medlow_embmedany_pic, sethi_di_medlow, losum_di_medlow, + seth44, setm44, setl44, sethh, setlm, sethm, setlo, + embmedany_sethi, embmedany_losum, embmedany_brsum, + embmedany_textuhi, embmedany_texthi, embmedany_textulo, + embmedany_textlo, movdi_lo_sum_sp64_cint, movdi_lo_sum_sp64_dbl, + movdi_high_sp64_cint, movdi_high_sp64_dbl): Replace with new + scheme, using unspecs, secondary reloads, and one to one sparc + insn to rtl insn mapping for better scheduling and code gen. + (define_expand reload_indi, reload_outdi): Reload helpers for + MEDANY and EMBMEDANY symbol address loading cases which require a + temporary register. + (define_expand movsicc): Remove v8plus_regcmp cases. + (define_insn movdi_cc_sp64_trunc, movdi_cc_reg_sp64_trunc, + cmp_zero_extendqidi2, cmp_zero_extendqidi2_set, cmp_qidi_trunc, + cmp_diqi_trunc_set): New patterns used by some of the new scc + splits on arch64. + (define_insn xordi3_sp64_dbl): New pattern used for constant + formation when crossing from 32-bit targets. + (define_insn movsi_cc_reg_v8plus, v8plus_clear_high, and helper + split): Remove. + (define_insn addx, subx): Make visible and prettify. + (define_insn adddi3_insn_sp32): Likewise and force split. + (define_insn addx_extend, subx_extend, unnamed): New patterns for + 64bit scc split usage. + (define_insn unnamed plusDI zero_extend, unnamed minusDI + zero_extend, subdi3): Force and implement splits. + + * final.c (final_scan_insn): Don't output labels if target + specifies ASM_OUTPUT_ADDR_{DIFF}_VEC. Do these macro operations + instead. - * config/alpha/elf.h (CPP_PREDEFINES): Add -D__PIC__ -D__pic__. - (STARTFILE_SPEC): Always use crtbegin.o%s - (ENDFILE_SPEC): Always use crtend.o%s. + * reorg.c (dbr_schedule): When taking on BR_PRED notes at the end, + don't forget to walk inside SEQUENCESs too as these are what the + delay slot scheduler will create. -Tue Sep 2 12:00:36 1997 Jim Wilson +Mon Aug 10 01:21:01 1998 Richard Henderson - * alpha/alpha.h (PREFERRED_RELOAD_CLASS): Return NO_REGS if NO_REGS - is passed in. - * emit-rtl.c (gen_lowpart_common): Add code to convert CONST_INT to - SFmode for 64 bit hosts. + * alpha.md (extxl+1,+2): New patterns to work around + combine lossage. -Tue Sep 2 13:42:38 1997 Paul N. Hilfinger +Sat Aug 8 19:20:22 1998 Gary Thomas (gdt@linuxppc.org) - * fixincludes: Permits spaces between # and define. Discard C++ - comments in sys/pci.h on HP/UX 10.20. + * rs6000.c (rs6000_allocate_stack_space): Fix typo which + caused bad assembly code to be generated. -Mon Sep 1 22:13:18 1997 Jeffrey A Law (law@cygnus.com) +Sat Aug 8 18:53:28 1998 Jeffrey A Law (law@cygnus.com) - * version.c: Bump for snapshot. + * netbsd.h: Fix typo. - * pa.c (restore_unscaled_index_insn_codes): New function. - (record_unscaled_index_insn_codes): Likewise. - (output_function_prologue): Call restore_unscaled_index_insn_codes. - (output_function_epilogue): Free memory for unscaled_index_insn_codes. - (pa_reorg): Call record_unscaled_index_insn_codes. +Mon Aug 3 00:06:42 1998 Robert Lipe - * haifa-sched.c (move_insn): Handle notes correctly for insns - with SCHED_GROUP_P set. + * config.sub: Fix typo. -Mon Sep 1 16:58:57 1997 H.J. Lu (hjl@gnu.ai.mit.edu) +Sun Aug 2 22:39:08 1998 Hans-Peter Nilsson - * alpha/xm-linux.h (USE_BFD): Undef before define. + * invoke.texi (Environment Variables): Typo: Change "ascpects" + into "aspects". + (Running Protoize): Typo: Change "ther" into "other". -Mon Sep 1 16:25:34 1997 Jim Wilson +Sun Aug 2 00:42:50 1998 Jeffrey A Law (law@cygnus.com) - * cse.c (cse_insn): Don't record BLKmode values. + * i386/netbsd.h: Undo previous change to DWARF2_UNWIND_INFO. + * m68k/netbsd.h: Likewise. + * ns32k/netbsd.h: Likewise. + * sparc/netbsd.h: Likewise. -Mon Sep 1 11:25:47 1997 Stephen Williams (steve@icarus.icarus.com) +Sat Aug 1 17:59:30 1998 Richard Henderson - * i960.h (LINK_SPEC): Handle "-mjX" and "-mrp" switches. + * ginclude/va-alpha.h (va_list): Use a typedef, not a define. + * ginclude/va-clipper.h (va_list): Likewise. -Mon Sep 1 08:29:46 1997 Jeffrey A Law (law@cygnus.com) +Fri Jul 31 20:22:02 1998 Michael Meissner - * cccp.c (sys_errlist): Remove special 4.4bsd declaration. - * collect2.c (sys_errlist): Likewise. - * cpplib.c (sys_errlist): Likewise. - * gcc.c (sys_errlist): Likewise. - * protoize (sys_errlist): Likewise. - * configure.in: Check for strerror. - * xm-freebsd.h (HAVE_STRERROR): Remove definition. - * xm-gnu.h (HAVE_STRERROR): Likewise. - * xm-linux.h (HAVE_STRERROR): Likewise. - * xm-netbsd.h (HAVE_STRERROR): Likewise. - * xm-bsd386.h (HAVE_STRERROR): Likewise. - * xm-cygwin32.h (HAVE_STRERROR): Likewise. - * xm-dos.h (HAVE_STRERROR): Likewise. - * xm-mingw32.h (HAVE_STRERROR): Likewise. - * xm-pa.h (HAVE_STRERROR): Likewise. - * xm-papro.h (HAVE_STRERROR): Likewise. - * xm-sysv4.h (HAVE_STRERROR): Likewise. - * configure, config.in: Rebuilt. + * rs6000.c (rs6000_override_options): If big endian and -Os, use + load/store multiple instructions unless user overrides. - * Makefile.in: Add several missing "else true" clauses. +Fri Jul 31 17:08:59 1998 Jeffrey A Law (law@cygnus.com) - * collect2.c: Change DONT_DECLARE_SYS_SIGLIST to SYS_SIGLIST_DECLARED. - * mips-tfile.c: Likewise. - * gcc.texi: DONT_DECLARE_SYS_SIGLIST: Remove docs. - * xm-linux.h (DONT_DECLARE_SYS_SIGLIST): Delete definition. - * xm-freebsd.h, xm-bsd386.h, xm-sysv4.h, xm-sol2.h: Likewise. - * configure.in: Check for sys_siglist declaration. - * configure, config.in: Rebuilt. - -Mon Sep 1 08:04:07 1997 Joel Sherrill (joel@OARcorp.com) - - * i386/go32-rtems.h, i386/rtems.h, i960/rtems.h, - m68k/rtems.h, mips/rtems64.h, pa/rtems.h, rs6000/rtems.h, - sparc/rtems.h (subtarget_switches): Added -mrtems as a switch. - * i960/i960.h: Added SUBTARGET_SWITCHES macro. - * rs6000/sysv4.h (extra_subtarget_switches): Added new - macro EXTRA_SUBTARGET_SWITCHES. - * configure.in (sh*-*-rtems*): New target. - * sh/rtems.h: New file. - * sh/sh.h: Added SUBTARGET_SWITCHES macro. - * configure: Rebuilt. + * ns32k/netbsd.h: Fix typo. -Sat Aug 30 22:54:26 1997 Jim Wilson +Fri Jul 31 10:23:55 1998 Doug Evans - * unroll.c (calculate_giv_inc): Handle increment with code PLUS. + * m32r/m32r.h (ASM_OUTPUT_SOURCE_LINE): Always output line number + labels with .debugsym if no parallel insns. -Sat Aug 30 10:49:46 1997 David Edelsohn +Thu Jul 30 19:15:53 1998 Richard Henderson - * rs6000.md: Make DF fused-add operations pay attention to - -mno-fused-add. + * alpha.md (fp cmp): Replicate patterns for ALPHA_TP_INSN. + (fcmov): Remove ALPHA_TP_INSN patterns -- fcmov doesn't trap. -Fri Aug 29 19:19:54 1997 Jim Wilson +Thu Jul 30 19:50:15 1998 David Edelsohn - * i386/xm-sysv4.h (DONT_DECLARE_SYS_SIGLIST): Define. + * rs6000/x-aix43 (AR_FOR_TARGET_FLAGS): Delete. + (AR_FOR_TARGET): Define. -Fri Aug 29 16:13:51 1997 Jeffrey A Law (law@cygnus.com) +Thu Jul 30 12:29:12 1998 Mark Mitchell - * pa.md (reload_peepholes): Make sure operand is a REG before - examining REGNO. Allow general registers too. + * dyn-string.h: New file. + * dyn-string.c: Likewise. + * Makefile.in (OBJS): Add dyn-string.o. + (dwarf2out.o): Add dyn-string.h dependency. + (dyn-string.o): List dependencies. + * dwarf2out.c: Include dyn-string.h. + (ASM_NAME_TO_STRING): Use dyn_string_append, rather than strcpy. + (addr_const_to_string): Take a dyn_string_t, not a char* as a + prototype. Use dyn_string_append rather than strcat, throughout. + (addr_to_string): Use dyn_string_t. -Fri Aug 29 11:42:04 1997 Jim Wilson +Thu Jul 30 13:08:07 1998 Ken Raeburn + + Function entry/exit profiling instrumentation: + * expr.h (profile_function_entry_libfunc, + profile_function_exit_libfunc): Declare new variables. + * optabs.c: Define them here. + (init_optabs): Initialize them. + * tree.h (struct tree_decl): New flag + no_instrument_function_entry_exit. + (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT): New accessor macro. + * c-decl.c (duplicate_decls): Merge it. + * c-common.c (enum attrs): New value A_NO_INSTRUMENT_FUNCTION. + (init_attributes): Use it for "no_instrument_function". + (decl_attributes): Handle it, for functions that have not yet been + compiled. Set decl flag. + * flags.h (flag_instrument_function_entry_exit): Declare new + variable. + * toplev.c (flag_instrument_function_entry_exit): Define it here. + (f_options): New option "instrument-functions". + * function.h (struct function): New field instrument_entry_exit. + * function.c (current_function_instrument_entry_exit): New + variable. + (push_function_context_to, pop_function_context_from): Save and + restore. + (expand_function_start): Set current_ variable, maybe emit return + label and entry profile call. + (expand_function_end): Maybe emit exit profile call. - * varasm.c (mark_constants): Don't look inside CONST_DOUBLEs. +Thu Jul 30 00:58:34 1998 Jeffrey A Law (law@cygnus.com) -Fri Aug 29 09:33:20 1997 Philipp Thomas (kthomas@lxi165.gwdg.de) + * i386.md (movqi): When optimizing a load of (const_int 1) into a + NON_QI_REG_P, pretend the register is SImode. - * dwarf2out.c (build_abbrev_table): Use xrealloc, not xmalloc - to reallocate abbrev_die_table. +Wed Jul 29 23:49:23 1998 Todd Vierling -Thu Aug 28 15:14:46 1997 Jim Wilson + * configure.in: Use xm-netbsd.h as the NetBSD xm file (not xm-siglist). + Accept arm32 as arm, m68k4k as m68k, mipsle as mips-dec, and any + manufacturer id for ns32k. + * configure: Regenerated. + * config/netbsd.h: When using ASM_WEAKEN_LABEL, make it global too. + * config/t-netbsd: Don't compile libgcc1-test as the fns are in libc. + * config/i386/netbsd.h: Undefine DWARF2_UNWIND_INFO, not define as 0. + * config/m68k/netbsd.h: Same. + * config/ns32k/netbsd.h: Same. + * config/sparc/netbsd.h: Same. - * m68k/m68k.md (iorsi_zexthi_ashl16): Disable. +Wed Jul 29 22:39:21 1998 Jeffrey A Law (law@cygnus.com) -1997-08-27 Andreas Schwab + * unroll.c (unroll_loop): Do not abort for an UNROLL_MODULO + or UNROLL_COMPLETELY loop that starts with a jump to its + exit code. - * Makefile.in (config.status): Depend on version.c +Wed Jul 29 22:18:14 1998 David Edelsohn - * expr.h (insn_gen_function): Reenable prototype. + * rs6000/rs6000.md (absdi2 define_split): Swap operands of MINUS. + * rs6000/rs6000.c (mask64_operand): Use HOST_BITS_PER_WIDE_INT. + (print_operand, case 'B'): Don't fall through. + (print_operand, case 'S'): Correct mask begin/end computation. + Use HOST_BITS_PER_WIDE_INT. + * rs6000/rs6000.h (CPP_PREDEFINES): Define _LONG_LONG. + (CONDITIONAL_REGISTER_USAGE): GPR13 fixed if TARGET_64BIT. + * rs6000/aix41.h (CPP_PREDEFINES): Same. + * rs6000/aix43.h (CPP_PREDEFINES): Same. - * expr.c (move_by_pieces_1, clear_by_pieces_1): Fix prototype of - first parameter. +Wed Jul 29 11:47:10 1998 Nick Clifton -Thu Aug 28 13:01:43 1997 Jim Wilson + * config/arm/thumb.md (extendqisi2_insn): Remove earlyclobber + constraint from second alternative. - * i386.c (ix86_expand_epilogue): Emit blockage instruction when pic. +Tue Jul 28 23:29:04 1998 Jason Merrill -Thu Aug 28 07:03:15 1997 Jeffrey A Law (law@cygnus.com) + * configure.in: Fix --without/--disable cases for local-prefix, + gxx-include-dir and checking. - * version.c: Bump for latest snapshot. +Tue Jul 28 22:01:23 1998 David S. Miller - * bc-optab.c: Conditionally include stdlib.h. - (free): Provide a declaration if NEED_DECLARATION_FREE. - * tree.c (free): Provide a declaration if NEED_DECLARATION_FREE. - * rtl.h (free): Remove declaration. - * tree.h (free): Remvoe declaration. + * configure.in (enable_haifa): Set by default for sparc64 too. + configure: Rebuilt. - * configure: Rebuilt. +Tue Jul 28 23:29:04 1998 Jason Merrill -Wed Aug 27 21:32:20 1997 Jeffrey A Law (law@cygnus.com) + * i386/cygwin32.h (VALID_MACHINE_TYPE_ATTRIBUTE): New macro. + * i386/winnt.c (associated_type): New fn. + (i386_pe_valid_type_attribute_p): New fn. + (i386_pe_check_vtable_importexport): Remove. + (i386_pe_dllexport_p): Use associated_type. + (i386_pe_dllimport_p): Likewise. - * flags.h (flag_move_all_movables): Declare. - (flag_reduce_all_givs): Likewise. - * loop.c (move_movables): Handle flag_move_all_movables. - (strength_reduce): Handle flag_reduce_all_givs. - * toplev.c (flag_move_all_movables): Define. - (flag_reduce_all_givs): Likewise. - (f_options): Add -fmove-all-movables and -freduce-all-givs. - * invoke.texi: Document new options, including alias stuff that - wasn't included last time. + From Antonio M. O. Neto : + * i386.c (i386_valid_type_attribute_p): Also accept + attributes for METHOD_TYPEs. -Wed Aug 27 18:08:51 1997 Bob Manson (manson@cygnus.com) +Tue Jul 28 23:17:39 1998 Peter Gerwinski - * t-h8300: Use TARGET_LIBGCC2_CFLAGS instead of LIBGCC2_CFLAGS. - * t-mn10200: Ditto. - * t-vxsparc: Ditto. - * t-vxworks68: Ditto. - * t-vxworks960: Ditto. - * t-vx29k: Ditto. + * tree.c (build_range_type): Copy TYPE_SIZE_UNIT. -Wed Aug 27 16:35:29 1997 Richard Henderson +Tue Jul 28 22:31:12 1998 Craig Burley - * alpha/xm-alpha.h (alloca): Define alloca to builtin_alloca for GNUC - if not already defined, and USE_C_ALLOCA not defined. + * gcc.c: Fix commentary describing %g, %u, %U, and %O. -Wed Aug 27 16:08:43 1997 Jim Wilson + * gcc.c (do_spec_1): Fix handling of %g%O and %U%O to prevent + them from generating a new base name for each occurrence of + a specific suffix. - * config.guess: Replace with script that uses ../config.guess. +1998-07-28 Vladimir N. Makarov - * config/alpha/elf.h (DEFAULT_VTABLE_THUNKS): New. Defined as 1 - if USE_GNULIBC_1 is not defined. + * cse.c (cse_insn): Enable substitution inside libcall only for REG, + SUBREG, MEM. + * rtlanal.c (replace_rtx): Prohibit replaces in CONST_DOUBLE. -Wed Aug 27 15:49:12 1997 Richard Henderson + * cplus-dem.c (type_kind_t): New type. + (demangle_template_value_parm): Add type_kind_t parameter. Rely + on this parameter, rather than demangling the type again. + (demangle_integral_value): Pass tk_integral. + (demangle_template_: Pass the value returned from do_type. + (do_type): Return a type_kind_t. Pass tk_integral to + demangle_template_value_parm for array bounds. + (demangle_fund_type): Likewise. - * alpha/elf.h (LINK_SPEC): Conditionalize on USE_GNULIBC_1. - * config.guess: Recognize alpha-linux-gnulibc1. - * configure.in (alpha-*-linux-gnulibc1): New target. - (alpha-*-linux-gnu*): Don't build crtbegin/end. +Mon Jul 27 00:54:41 1998 Jason Merrill -Wed Aug 27 11:52:58 1997 Jim Wilson + * tree.c (simple_cst_equal, case CONSTRUCTOR): OK if the elts are + identical. - * m68k.md (iorsi3_internal): Readd ! TARGET_5200 check lost in - last change. +Mon Jul 27 22:18:36 1998 Jeffrey A Law (law@cygnus.com) -Wed Aug 27 01:56:18 1997 Doug Evans + * pa.c (move_operand): Accept CONSTANT_P_RTX. - * loop.c (combine_movables): Earlier insns don't match later ones. +Mon Jul 27 17:18:52 1998 Dave Brolley -Wed Aug 27 01:24:25 1997 H.J. Lu (hjl@gnu.ai.mit.edu) + * stor-layout.c (layout_type): Handle arrays of bits, for Chill. - * config/linux.h (CC1_SPEC): Define it only if not defined. + * expr.c (get_inner_reference): Handle zero-based, unsigned, array + index conversion. - * config/m68k/linux.h (CC1_SPEC): Undefine it before include - +Mon Jul 27 14:51:33 1998 Jeffrey A Law (law@cygnus.com) - * config/linux.h (DEFAULT_VTABLE_THUNKS): New. Defined as 1 if - USE_GNULIBC_1 is not defined. + * mn10300.h (DEBUGGER_AUTO_OFFSET): Define. + (DEBUGGER_ARG_OFFSET): Likewise. - * config/rs6000/linux.h (DEFAULT_VTABLE_THUNKS): New. Defined as 1. + * mn10300.md (movsf): Remove last change. Not needed. - * config/sparc/linux.h (DEFAULT_VTABLE_THUNKS): New. Defined - as 1 if USE_GNULIBC_1 is not defined. +Mon Jul 27 14:22:36 1998 Dave Brolley -Wed Aug 27 00:49:14 1997 Jeffrey A Law (law@cygnus.com) + * c-lex.c (yylex): Fix boundary conditions in character literal and + string literal loops. - * reorg.c (dbr_schedule): Allow current_function_return_rtx - to be something other than a REG. - * function.c (expand_function_end): Fix current_function_return_rtx - if it was a pseudo. +Mon Jul 27 11:43:54 1998 Stan Cox - * t-freebsd (USER_H): Include EXTRA_HEADERS and LANG_EXTRA_HEADERS. - * x-netbsd: Likewise - * x-dgux (USER_H): Include EXTRA_HEADERS and LANG_EXTRA_HEADERS - (INSTALL_HEADERS): Delete. - * x-dguxbcs: Likewise. - * x-hp3bsd44: Likewise - * x-pa: Likewise. + * longlong.h (count_leading_zeros): Sparclite scan instruction was + being invoked incorrectly. -Wed Aug 27 00:30:00 1997 Bernd Schmidt + * i386.c (ix86_prologue): Added SUBTARGET_PROLOGUE invocation. + * i386/cygwin32.h (STARTFILE_SPEC, LIB_SPEC, SUBTARGET_PROLOGUE): + Add -pg support. + * i386/win32.h: New file. Hybrid mingw32.h/cygwin32.h configuration. + * configure.in: Added i[34567]86-*-win32. + * config.sub: Likewise. + * configure: Rebuilt. - * i386.md (pop): pop increments the stack pointer. - (prologue_set_stack_ptr): New pattern. - * i386.c (ix86_expand_prologue): Use prologue_set_stack_ptr - instead of subsi3. +Sun Jul 26 01:11:12 1998 H.J. Lu (hjl@gnu.org) -Tue Aug 26 18:50:32 1997 Jim Wilson + * i386.h (CONST_DOUBLE_OK_FOR_LETTER_P): Return 0 when eliminating + the frame pointer and compiling PIC code and reload has not completed. - * reload.c (find_reloads, case '0'): Reject matching a non-offsettable - address where an offsettable address is required. + * i386.c (output_to_reg): Add code to emulate non-popping DImode + case. -Tue Aug 26 17:54:56 1997 Michael P. Hayes (michaelh@ongaonga.chch.cri.nz> +Sun Jul 26 01:01:32 1998 Jeffrey A Law (law@cygnus.com) - * loop.c (check_final_value): Don't miss a biv increment in a - parallel. + * regmove.c (regmove_optimize): Fix typo initializing regmove_bb_head. -Tue Aug 26 12:03:49 1997 Jim Wilson (wilson@cygnus.com) +Sat Jul 25 23:29:23 1998 Gerald Pfeifer - * dwarfout.c (dwarfout_file_scope_decl, case TYPE_DECL): Check - TYPE_DECL_IS_STUB instead of DECL_NAME. + * Makefile.in (install-info): Only try to update the info + directory file if it exists in the first place. -Mon Aug 25 23:27:10 1997 H.J. Lu (hjl@gnu.ai.mit.edu) +Fri Jul 24 18:58:37 1998 Klaus Espenlaub - * objc/Make-lang.in ($(OBJC_O)): Also depend on cc1obj. + * rs6000.h (ASM_OUTPUT_CONSTRUCTOR, ASM_OUTPUT_DESTRUCTOR): Delete. -Mon Aug 25 23:27:10 1997 Jim Meyering +Fri Jul 24 14:20:26 1998 Jeffrey A Law (law@cygnus.com) - * objc/Make-lang.in ($(OBJC_O)): Also depend on $(GCC_PASSES). + * mn10300.md (movqi, movhi, movsi, movsf): Correctly handle + CONST_DOUBLE source. -Mon Aug 25 13:12:24 1997 Jeffrey A Law (law@cygnus.com) +Fri Jul 24 11:17:04 1998 Nick Clifton - * haifa-sched.c (find_pre_sched_live): Remove #if 0 code. - (find_post_sched_live): Likewise. + * config/arm/thumb.c (thumb_print_operand): Decode %_ in asm + strings as the insertion of USER_LABEL_PREFIX. + * config/arm/thumb.h (PRINT_OPERAND_PUNCT_VALID_P): Accept _ as a + valid code. + * config/arm/thumb.md: Use %_ as a prefix to gcc library function + calls. - * haifa-sched.c (schedule_block): Remove old code to get arguments - from hard regs into pseudos early. +Thu Jul 23 18:53:20 1998 Jim Wilson -Mon Aug 25 08:55:00 1997 Jeffrey A Law (law@cygnus.com) + * dbxout.c (dbxout_range_type): Only call dbxout_type_index for + already defined type. - * version.c: Bump for new snapshot. +Thu Jul 23 13:49:41 1998 Jeffrey A Law (law@cygnus.com) - * local-alloc.c (update_equiv_regs): All the target to reject - promotion of some REG_EQUAL to REG_EQUIV notes. - * pa.h (DONT_RECORD_EQUIVALENCE): Define. + * expr.c (check_max_integer_computation_mode): Allow conversions + of constant integers to MAX_INTEGER_COMPUTATION_MODE. + (expand_expr): Likewise. - * pa.c (secondary_reload_class): (mem (mem ... )) does not need - secondary reloads. +Thu Jul 23 11:12:06 1998 Alexandre Petit-Bianco - * pa.c (hppa_builtin_saveregs): Emit a blockage insn after the - store of the argument registers. + * expr.c (expand_expr): Expand RETURN_EXPR. -Mon Aug 25 08:39:02 1997 Craig Burley (burley@gnu.ai.mit.edu) +Thu Jul 23 11:00:29 1998 Jim Wilson - * fold-const.c (multiple_of_p): New function. - (fold): Turn some cases of *_DIV_EXPR into EXACT_DIV_EXPR. + * dwarf2out.c (dwarf2out_finish): Call stripattributes on TEXT_SECTION. -Mon Aug 25 01:47:41 1997 Jeffrey A Law (law@cygnus.com) +Wed Jul 22 19:10:00 1998 Catherine Moore - * expr.h (insn_gen_function): Temporarily remove prototype. + * dwarf2out.c (output_aranges): Call stripattributes + for TEXT_SECTION references. + (output_line_info): Likewise. -Sun Aug 24 17:22:21 1997 Jim Wilson +Wed Jul 22 14:08:54 1998 David S. Miller - * Makefile.in (install-info): Don't cd into srcdir. Add srcdir to - filenames. Use sed to extract base filename for install. + * profile.c (branch_prob): Call allocate_reg_info after outputting + profile rtl in instrument_arcs. -Sat Aug 23 18:19:40 1997 John F. Carr +Wed Jul 22 12:47:49 1998 Jim Wilson - * unroll.c (find_splittable_givs): Only share if two givs have the - same add and multiply values. + * fixinc.irix (math.h): Install wrapper instead of copying. -Sat Aug 23 14:36:27 1997 Jim Wilson +Wed Jul 22 12:37:14 1998 Alexandre Petit-Bianco - * m68k/next.h (GO_IF_INDEXABLE_BASE): Fix typo in undef. - * m68k/m68kemb.h (LIB_SPEC): Add missing comment end before it. + * tree.def (EXPR_WITH_FILE_LOCATION): Defined as an 'e' expression + so WFL are expanded correctly when contained in a COMPOUND_EXPR. + * tree.h (EXPR_WFL_EMIT_LINE_NOTE): Change macro not to use + lang_flag_0. Added documentation in the flag table. -Sat Aug 23 00:18:22 1997 Jeffrey A Law (law@cygnus.com) +Tue Jul 21 23:28:35 1998 Klaus Kaempf - * pa.c (pa_reorg): Always put begin_brtab and end_brtab insns - around branch tables. - * pa.md (begin_brtab, end_brtab): Only emit the .begin_brtab - and .end_brtab directives if TARGET_GAS. + * cccp.c (do_include): Fix vax c style include handling. -Fri Aug 22 14:05:55 1997 Jim Wilson +Tue Jul 21 13:28:19 1998 Jason Merrill - * alias.c (true_dependence): Pass x_addr not x to varies. + * cplus-dem.c (do_type): Use demangle_template_value_parm for arrays. - * acconfig.h (NEED_DECLARATION_CALLOC): Add. - * configure.in: Add GCC_NEED_DECLARATION call for calloc. - * rs6000/xm-rs6000.h (malloc, realloc, calloc, free): Delete - declarations. - * config.in, configure: Regenerate. +Sun Jul 12 01:27:05 1998 Jason Merrill -Thu Aug 21 23:52:16 1997 John F. Carr + * fold-const.c (non_lvalue): Don't deal with null pointer + constants here. + (fold, case COMPOUND_EXPR): Wrap a constant 0 in a NOP_EXPR. - * alias.c (find_base_value): Improve handling of PLUS, MINUS, and - LO_SUM. - (record_set): Handle LO_SUM like PLUS. - (init_alias_analysis): When following chains of base addresses, - do not stop on reaching a hard register. +Tue Jul 21 15:49:31 1998 David Edelsohn -Thu Aug 21 20:17:37 1997 Jeffrey A Law (law@cygnus.com) + * rs6000.h (PREDICATE_CODES): Add CONSTANT_P_RTX. + * rs6000.md (movsi, movdi): Add CONSTANT_P_RTX. + * rs6000.c (short_cint_operand): Add CONSTANT_P_RTX. + (u_short_cint_operand): Same. + (reg_or_cint_operand): Same. + (logical_operand): Same. + (input_operand): Same. + (reg_or_short_operand): Use u_short_cint_operand. - * version.c: Bump for new snapshot. +Tue Jul 21 08:56:42 1998 Richard Henderson -Thu Aug 21 17:28:00 1997 Jim Wilson + * alpha.md (fix_truncdfsi2, fix_truncsfsi2): Remove the define_expands, + but keep the insns and splits. Adjust so when the ultimate destination + is memory, use cvtql. - * alpha.h (ARCH_ASM_FILE_START): Define. - (ASM_FILE_START): Use ARCH_ASM_FILE_START. - * osf12.h, osf2or3.h (ARCH_ASM_FILE_START): Redefine to null string. +Tue Jul 21 08:55:09 1998 Richard Henderson -Thu Aug 21 10:22:19 1997 Jeffrey A Law (law@cygnus.com) + * flow.c (regno_uninitialized): Fixed regs are never uninitialized. - * Makefile.in (install-common): Put gcov comment at start of line. +Tue Jul 21 00:31:01 1998 Jeffrey A Law (law@cygnus.com) -Wed Aug 20 22:47:33 1997 Jeffrey A Law (law@cygnus.com) + * gcc.c (do_spec): Call "error" not "warning". - * alias.c (init_alias_analysis): When simplifying the reg_base_value - array, simplify entries for hard registers too. + * configure.in: Fix minor problems with gas feature detection code. + * configure: Rebuilt. -Wed Aug 20 12:35:47 1997 Dave Love + * gcc.c (do_spec): Issue a warning for '%[]' usage. - * dwarf2.h (enum dwarf_call_frame_info): Remove trailing comma from - list. + * Undo this change. + * gcc.c: Delete %[spec] support. + (do_spec_1, case '('): Likewise. + (do_spec_1, case '['): Call error. -Wed Aug 20 11:58:33 1997 Jim Wilson +Mon Jul 20 22:34:17 1998 Richard Henderson - * stmt.c (start_cleanup_deferal, end_cleanup_deferal): Test - block_stack before dereferencing it. + * alpha.h (CPP_SPEC): Tidy. Hook to cpp_cpu and cpp_subtarget. + (CPP_SUBTARGET_SPEC): Default to empty string. + (CPP_AM_*, CPP_IM_*, CPP_CPU_*, CPP_CPU_SPEC): New. + (EXTRA_SPECS, SUBTARGET_EXTRA_SPECS): New. + * alpha/elf.h (LD_SPEC): Use %(elf_dynamic_linker). + * alpha/linux-elf.h (SUBTARGET_EXTRA_SPECS): New. + (LIB_SPEC): Tidy. + * alpha/linux.h (CPP_PREDEFINES): Tidy. + * alpha/netbsd-elf.h (SUBTARGET_EXTRA_SPECS): New. + * alpha/netbsd.h (CPP_PREDEFINES): Tidy. + * alpha/osf.h (CPP_PREDEFINES): Remove bits subsumed by CPP_CPU_SPEC. + * alpha/win-nt.h (CPP_PREDEFINES): Likewise. + * alpha/vsf.h (CPP_PREDEFINES): Likewise. + (CPP_SUBTARGET_SPEC): New. Do this instead of overriding CPP_SPEC. + * alpha/vxworks.h: Likewise. -Wed Aug 20 11:57:11 1997 Michael Meissner +Mon Jul 20 22:51:57 1998 Ken Raeburn - * rs6000.h (ISSUE_RATE): Define instead of MACHINE_issue_rate. + * mips.md (reload_outsi): Added missing REGNO call. + (smulsi3_highpart, umulsi3_highpart): Provide prototype for + function pointer. + (mul_acc_di, mul_acc_64bit_di): Don't use match_op_dup, use + another match_operator and compare the codes. -Tue Aug 19 17:10:56 1997 Jason Merrill + * mips.h (MASK_DEBUG_E, MASK_DEBUG_I): Set to zero. - * cplus-dem.c: Add 'extern' to prepends_underscore. + * MIPS multiply pattern fixes: + * mips.h (enum reg_class, REG_CLASS_NAMES, REG_CLASS_CONTENTS): + Add union classes for HI, LO, or HILO plus general registers. + (GENERATE_MADD): Deleted. + * mips.md (mulsi3_mult3): Don't disparage output-LO alternative. + Add TARGET_MAD to condition. + (mulsi3): Test HAVE_mulsi3_mult3, not specific flags. + (mul_acc_si): Expand GENERATE_MADD here; it's the only use. Use + "*d" for accumulator, to give preference to LO initially but not + during reload. -Tue Aug 19 09:34:57 1997 Jeffrey A Law (law@cygnus.com) +Mon Jul 20 16:16:38 1998 Dave Brolley - * haifa-sched.c (ISSUE_RATE): Renamed from MACHINE_issue_rate. - (get_issue_rate): Delete. - * pa.h (ISSUE_RATE): Define. + * configure.in (enable_c_mbchar): New configure option. + (extra_cpp_objs): Always available now. - * configure.in: Turn on haifa by default for the PA. - * configure: Rebuilt. - * pa.c (override_options): Accept -mschedule=7200 option. - (pa_adjust_cost): No longer need to scale costs for newer - processors. - * pa.h (enum processor_type): Add PROCESSOR_7200. - * pa.md: Revamp scheduling parameters to work better with - haifa. Add scheduling parameters for the 7200. + * cexp.y (mbchar.h): #include it. + (yylex): Handle Multibyte characters in character literals. - * haifa-sched.c (move_insn): Reemit notes for SCHED_GROUP_P - insns too. - (schedule_block): When adjusting basic_block_{head,end}, account - for movement of SCHED_GROUP_P insns too. + * cccp.c (mbchar.h): #include it. + (main): Set character set based on LANG environment variable. + (rescan): Handle multibyte characters in comments. + (skip_if_group): See above. + (validate_else): See above. + (skip_to_end_of_comment): See above. + (macarg1): See above. + (discard_comments): See above. + (rescan): Handle multibyte characters in string and character literals. + (collect_expansion): See above. + (skip_quoted_string): See above. + (macroexpand): See above. + (macarg1): See above. + (discard_comments): See above. + (change_newlines): See above. - * haifa-sched.c (debug_dependencies): Fix thinko. + * c-lex.c (mbchar.h): #include it. + (GET_ENVIRONMENT): New macro. + (init_lex): Set character set based on LANG environment variable. + (yylex): Handle multibyte characters in character literals. + (yylex): Handle multibyte characters in string literals. - * Makefile.in (EXPECT, RUNTEST, RUNTESTFLAGS): Define. - (site.exp, check, check-g++, check-gcc): New targets. + * Makefile.in (mbchar.o): New target. + (cccp$(exeext)): @extra_cpp_objs@ is always available. + (cppmain$(exeext)): @extra_cpp_objs@ is always available. - * haifa-sched.c: Make lots of variables static. + * mbchar.[ch]: New files for multibyte character handling. -Tue Aug 19 07:18:34 1997 H.J. Lu (hjl@gnu.ai.mit.edu) +Mon Jul 20 01:11:11 1998 David S. Miller - * expr.h, real.h: Finish prototyping. + * jump.c (jump_optimize): When simplifying noop moves and + PUSH_ROUNDING, fix thinko so we use same criterion for identifying + the PUSHes to rewrite in second loop as we did in the first. -Mon Aug 18 21:49:02 1997 Jim Wilson +Sun Jul 19 08:23:53 1998 Kaveh R. Ghazi - * reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR - reloads to RELOAD_FOR_OPERAND_ADDRESS reloads. - * reload1.c: Undo bugfix from Aug 11. + * cplus-dem.c (demangle_nested_args): Make function definition + static to match the prototype. -Mon Aug 18 17:39:02 1997 Mike Meissner +Fri Jul 17 14:58:44 1998 Richard Henderson + + * alloca.c: Respect USE_C_ALLOCA. + * gencheck.c (xmalloc): Ignore __GNUC__ for definition. + * gengenrtl.c (xmalloc): Likewise. + +Fri Jul 17 14:18:14 1998 Richard Henderson + + * loop.h (struct induction): Add no_const_addval. + * loop.c (the_movables, reg_address_cost): New variables. + (init_loop): Init reg_address_cost. + (loop_optimize): Call end_alias_analysis. + (scan_loop): Init the_movables. + (record_giv): Init induction->no_const_addval. + (basic_induction_var) [PLUS]: Use rtx_equal_p instead of ==. + [REG]: Rearrange loop search test to catch more cases. + (general_induction_var): Return success not benefit; take an extra + argument for that. Change all callers. + (simplify_giv_expr) [PLUS]: Always combine invariants. Use sge_plus. + [MULT]: Use rtx_equal_p instead of ==. Combine simple invariants. + [default]: Search the_movables for additional combinations. + (sge_plus_constant, sge_plus): New functions. + (express_from_1): New function. + (express_from): Always define. Rewrite using express_from_1. + (combine_givs_p): Handle more cases. Ignore address cost. + (cmp_combine_givs_stats): New function. + (combine_givs_used_once, combine_givs_benefit_from): New functions. + (combine_givs): Rewrite to do best-fit combination. + + * fold-const.c (operand_equal_p): Handle RTL_EXPR. + (fold): Do a complete (A*C)+(B*C) association check. + +Fri Jul 17 11:21:55 1998 Jim Wilson - * configure.in ({powerpc,rs6000}*-*-*, --with-cpu): Remove single - quotes around the name. - * configure: Regenerate. + * function.c (fixup_var_refs_insns): Handle CLOBBER of a CONCAT. -Mon Aug 18 13:46:47 1997 Jim Wilson +Fri Jul 17 11:48:55 1998 Jeffrey A Law (law@cygnus.com) - * Makefile.in (stmp-multilib-sub): Fix typo in last change. + * mn10300.c (MODES_TIEABLE_P): Fix typo. -Thu Aug 7 10:33:13 1997 Manfred Hollstein +Fri Jul 17 03:26:12 1998 Rihcard Earnshaw (rearnsha@arm.com) - * Makefile.in (sub-makes): Pass the current value of LANGUAGES down - to sub-makes to avoid building more passes than the user might have - requested on the command line. + * tree.c (valid_machine_attribute): Only create a new type variant if + there is a decl to use it. -Sun Aug 17 15:42:17 1997 Dave Love (d.love@dl.ac.uk) +Thu Jul 16 14:48:04 1998 Nick Clifton - * configure.in: Expurgate `broken_install' (install is - autoconfed). + * gcc.c (do_spec_1): Cope with %g/%u/%U options which do not have + a suffix. - * configure.lang: Substitute autoconfed ${INSTALL} (not currently - relevant). +Fri Jul 17 03:24:40 1998 Hans-Peter Nilsson -Sat Aug 16 01:08:12 1997 Jeffrey A Law (law@cygnus.com) + * extend.texi (Explicit Reg Vars): Typo: change "may deleted" into "may + be deleted" - * loop.c (is_power_of_2, is_conditional_branch): Delete unused - functions and declarations. - (analyze_loop_iterations): Use condjump_p. - (insert_bct): Likewise. Use exact_log2. +Thu Jul 16 14:48:47 1998 Jeffrey A Law (law@cygnus.com) -Fri Aug 15 23:48:32 1997 Jeffrey A Law (law@cygnus.com) + * mn10300.c (count_tst_insns): New arg oreg_countp. Callers changed. + Simplify tests for clearing an address register. + (expand_prologue): Corresponding changes. - * haifa-sched.c (find_post_sched_live): Call FREE_REG_SET as needed. - (schedule_region): Likewise. - (schedule_insns): Likewise. + * mn10300.md (movXX patterns): Make sure the destination is an + ADDRESS_REG when substituting "zero_areg" for (const_int 0). + (logical patterns): Split into expanders + patterns. + (zero and sign extension patterns): Similarly. + (shift patterns): Similarly. - * PROJECTS: Update with Haifa stuff. +Thu Jul 16 01:17:44 1998 Richard Henderson -Fri Aug 15 12:49:56 1997 Jeffrey A Law (law@cygnus.com) + * loop.c (emit_iv_add_mult): Scan the entire insn list generated + for the sequence, recording base values. - * version.c: Change the version string to look like: - egcs-2.90.00 970814 (gcc2-970802 experimental). +Wed Jul 15 10:49:55 1998 Richard Henderson - * loop.c (is_conditional_branch): Make definition match declaration. + * i386.h (CPP_CPU_SPEC): Remove -Asystem(unix). - * gcc.c: Take out experimental snapshot warning message. +Tue Jul 14 14:15:30 1998 Nick Clifton -Fri Aug 15 13:43:39 1997 Michael Meissner + * gcc.c: Remove ANSI-C ism from --help code. - * haifa-sched.c (debug_dependencies): Use GET_NOTE_INSN_NAME to - print out the names of the notes. Print out the name of the insn - that is not a note, and not an {,CALL_,JUMP_}INSN. + * toplev.c: Support --help with USE_CPPLIB. -Wed Aug 13 17:32:38 1997 Jason Merrill +Tue Jul 14 14:46:08 1998 Jeffrey A Law (law@cygnus.com) - * expr.c (expand_expr, case TARGET_EXPR): Call mark_addressable - again for the slot after we give it RTL. + * configure.in: Rework gas feature code to work with symlink based + source trees. -Wed Aug 13 01:03:37 1997 Doug Evans + * extend.texi: Clarify some issues related to local variables + assigned to explicit registers. - * configure.in (haifa configury): Fix typo. - * configure: Regenerate. + * mn10300.md (mulsi): Turn into expander + pattern. -Tue Aug 12 10:20:36 1997 Jeffrey A Law (law@cygnus.com) + * mn10300.md (movsi, movsf, movdi, movdf): Remove "x" from I -> a + alternative. - * version.c: Bump version to "gcc-3.0.0 970802 experimental". +Tue Jul 14 07:41:59 1998 Richard Earnshaw (rearnsha@arm.com) - * gcc.info*: Rebuilt. + * arm/tcoff.h (USER_LABEL_PREFIX): Make it empty to match coff.h. - * COPYING.g77, README.g77: New files. - * real.c (ereal_unto_float, ereal_unto_double): New functions. - * real.h (ereal_unto_float, ereal_unto_double): Declare them. - (REAL_VALUE_UNTO_TARGET_DOUBLE, REAL_VALUE_UNTO_TARGET_SINGLE): Define. +Tue Jul 14 03:02:44 1998 Jeffrey A Law (law@cygnus.com) -Mon Aug 11 14:50:55 1997 Jeffrey A Law (law@cygnus.com) + * version.c: Bump again to distinguish mainline tree from the + egcs-1.1 branch. - * Integrate Haifa instruction scheduler. - * Makefile.in (ALL_CFLAGS): Add SCHED_CFLAGS. Prefix all references - to sched with $(SCHED_CFLAGS. - * configure.in: Handle --enable-haifa. - * configure: Rebuilt. - * flags.h: Add new flags for haifa instruction scheduler. - * genattrtab.c (expand_units): For haifa, don't subtract one - when computing blockage. - * toplev.h (flag_schedule_interblock): Haifa scheduler flag. - (flag_schedule_speculative): Ditto. - (flag_schedule_speculative_load): Ditto. - (flag_schedule_speculative_load_dangerous): Ditto. - (flag_schedule_reverse_before_reload): Ditto. - (flag_schedule_reverse_after_reload): Ditto. - (flag_branch_on_count_reg): Ditto. - (f_options): Add Haifa switches. - (main): Turn off some Haifa options if appropriate macro is - defined. Process Haifa switches. - * unroll.c (iteration_info): No longer static, since Haifa - scheduler uses it. - (unroll_loop): Inform HAIFA scheduler about loop unrolling factor. - * unroll.c (unroll_loop): Set loop_unroll_iter, loop_start_value. - * loop.h (loop_unroll_factor, loop_number): Add HAIFA decls. - * loop.h (loop_initial_value,loop_unroll_iter): New globals. - * loop.c (loop_optimize): If HAIFA is defined, allocate additional - storage for the Haifa scheduler. - (mark_loop_jump): If HAIFA defined, set LABEL_OUTSIDE_LOOP_P and - LABEL_NEXTREF. - (strength_reduce): If HAIFA and HAVE_decrement_and_branch_on_count - are defined, call analyze_loop_iterations and insert_bct to use - countdown loops. - (record_giv): Refine test for jumps out of loops if HAIFA is - defined. - (analyze_loop_iterations): New function to identify if we can use - a countdown loop. - (insert_bct): Insert countdown loop. - (instrument_loop_bct): Low level code to insert countdown loop. - (loop_number): Calculate UID of loop. - (indirect_jump_in_function_p): Return true if an indirect jump is - in the function. - (is_power_of_2): Return true if value is a power of 2. - (is_conditional_branch): Return true if insn is a conditional - jump. - (fix_bct_param): Process -fbct-{min,max}-N switches. - (check_bct_param): Return true if loop should be instrumented. - * loop.c (loop_initial_value,loop_unroll_iter): New globals. - (loop_optimize): Initialize. - (get_condition_for_loop): Ditto. - * loop.c (strength_reduce): Inside of code that uses #ifdef - HAVE_decrement_and_branch_on_count code, test it to make sure the - condition is true. - (instrument_loop_bct): Ditto. - * haifa-sched.c: New file. - - - * Integrate regmove pass. - * Makefile.in (OBJS): Add regmove.o - (regmove.o): Add dependencies. - * flow.c (find_use_as_address): No longer static. - * rtl.h (find_use_as_address): Declare. - * toplev.c (regmove_dump, flag_regmove): Define. - (f_options): Add -fregmove. - (regmove_dump_file, regmove_time): Define. - (fatal_insn): Close the regmove dump file. - (compile_file): Initialize regmove_time; open/close the regmove dump - file as needed. Print regmove time as needed. - (rest_of_compilation): Run regmove pass if requested, dump - RTL after regmove if requested. - (main): If -O2 or more, turn on regmove. Handle dump switches. - * regmove.c: New file. - -Mon Aug 11 14:15:02 1997 Jeffrey A Law (law@cygnus.com) - - * Integrate tlink patch from jason@cygnus.com - * gcc.c (SWITCH_TAKES_ARG): Add 'V', 'B' and 'b'. - (process_command): Increment n_switches for them. Don't discard - their args. Validate them. - (main): Escape " marks when creating COLLECT_GCC_OPTIONS. - From Rohan Lenard. - (process_command): Set include_prefixes from COMPILER_PATH. - (main): Set COLLECT_GCC_OPTIONS sooner. - * confiugre.in: Link ../ld/ld.new to collect-ld rather than real-ld. - * tlink.c, hash.c, hash.h: New files. - * Makefile.in (USE_COLLECT2): Always use collect2. - (collect2): Depend on and link in hash.o and tlink.o. - (tlink.o, hash.o): Add dependencies. - -Mon Aug 11 10:04:49 1997 Jeffrey A Law (law@cygnus.com) - - * Integrate alias analysis changes from jfc@mit.edu - * Makefile.in (OBJS): Add alias.o - (alias.o): Add dependencies. - * alias.c: New file. - * sched.c: Remove alias analysis code. It lives in alias.c now. - (sched_analyze_2): Add new arguments to true_dependence. - (schedule_insns): Always call init_alias_analysis. - * calls.c (expand_call): Note calls to malloc, calloc, and realloc; - mark return value from such functions as a pointer and keep track of - them for alias analysis. If a return value from a function is a - pointer, mark it as such. - * combine.c (distribute_notes): Handle REG_NOALIAS. - * cse.c (struct write_data): Delete. No longer needed. - (invalidate): Don't call set_nonvarying_address_components anymore. - Use true_dependence to decide if an entry should be removed from - the hash table. - (invalidate_memory): Remove WRITES argument, simplify appropriately. - Fix all callers. - (note_mem_written): Similarly for WRITE_PTR argument. - (invalidate_from_clobbers): Similarly for W argument. - (invalidate_for_call): Remove memory elements from the hash table. - (refers_to_mem_p, cse_rtx_addr_varies_p): Deleted. - (cse_rtx_varies_p): New function. Derived from old - cse_rtx_addr_varies_p. - (cse_insn): Remove WRITES_MEMORY and INIT variables and all references. - Don't call note_mem_written anymore. Stack pushes invalidate the stack - pointer if PUSH_ROUNDING is defined. No longer need to call - cse_rtx_addr_varies_p to decide if a MEM should be invalidated. - (skipped_writes_memory): Remove variable. - (invalidate_skipped_set): Simplify and wewrite to use invalidate_memory. - (invalidate_skipped_block): Simplify for new alias analysis code. - (cse_set_around_loop): Likewise. - (cse_main): Call init_alias_analysis. - * flags.h (flag_alias_check, flag_argument_noalias): Declare. - * toplev.c (flag_alias_check, flag_argument_noalias): Define. - (f_options): Add new alias checking arguments. - (main): Set flag_alias_check when optimizing. - * local_alloc (validate_equiv_mem_from_store): Add new arguments - to true_dependence. - (memref_referenced_p): Likewise. - * loop.c (NUM_STORES): Increase to 30. - (prescan_loop): Only non-constant calls set unknown_address_altered. - (invariant_p): Add new arguments to true_dependence. - (record_giv): Initialize unrolled and shared fields. - (emit_iv_add_mult): Call record_base_value as needed. - * loop.h (struct induction): Add unrolled and shared fields. - * unroll.c (unroll_loop): Call record_base_value as needed. - (copy_loop_body): Likewise. - (final_biv_value): Likewise. - (final_giv_value): Likewise. - (find_splittable_regs): Likewise. Only create one new pseudo - if we have multiple address GIVs that were combined with the same - dst_reg GIV. Note when a new register is created due to unrolling. - * rtl.c (reg_note_name): Add REG_NOALIAS. - * rtl.h (enum reg_note): Similarly. - (rtx_varies_p, may_trap_p, side_effects_p): Declare. - (volatile_refs_p, volatile_insn_p, remove_note): Likewise. - (note_stores, refers_to_regno_p, reg_overlap_mentioned_p): Likewise. - (true_dependence, read_dependence, anti_dependence): Likewise. - (output_dependence, init_alias_analysis, end_alias_analysis): Likewise. - (mark_user_reg, mark_reg_pointer): Likewise. - - - * Integrate reload bugfix from Wilon which enables the PA port - to bootstrap again. - * reload1.c (reload): Sum needs for both OPADDR_ADDR and - OPERAND_ADDRESS when computing how many registers an insn needs. - (reload_reg_free_p): OPADDR_ADDR and OPERAND_ADDRESS reloads do - conflict. - (reload_reg_free_before_p): Treat OPERAND_ADDRESS reloads just like - OPADDR_ADDR reload. - (reload_reg_reaches_end_p): For RELOAD_FOR_OPADDR_ADDR insns, registers - in reload_reg_use_in_op_addr do not reach the end. - do not reach the end. - (reloads_conflict): RELOAD_FOR_OPADDR_ADDR conflicts with - RELOAD_FOR_OPERAND_ADDRESS. - -Sun Aug 10 12:00:20 1997 Jeffrey A Law (law@cygnus.com) - - * egcs project officially starts. +See ChangeLog.0 for earlier changes. Local Variables: add-log-time-format: current-time-string diff --git a/contrib/gcc/FSFChangeLog b/contrib/gcc/FSFChangeLog new file mode 100644 index 0000000..9a0e7f8 --- /dev/null +++ b/contrib/gcc/FSFChangeLog @@ -0,0 +1,2154 @@ +Wed Sep 30 14:27:49 1998 Andreas Schwab + + * function.c (assign_parms): Undo change of June 9. + +Tue Sep 29 09:57:26 1998 Richard Kenner + + * expr.c (get_inner_reference): Fix typo in last change. + +Mon Sep 27 21:34:00 1998 Paul Eggert + + * po/en_UK.po (Project-Id-Version): Set to cc 2.8.1.19980813 for now. + (PO-Revision-Date): Set to the current date. + +Sun Sep 27 07:33:18 1998 Richard Kenner + + * m68k/vxm68k.h (LINK_SPEC): Always use -r. + (WIDEST_HARDWARE_FP_SIZE): Define. + + * reload.c (push_reload): If in STRICT_LOW_PART, always reload + inside even if SUBREG_WORD is not zero. + + * flow.c (print_rtl_with_bb): Don't say not in basic block if we + aren't making basic blocks.8 + +Sat Sep 26 10:57:09 1998 Richard Kenner + + * function.c (optimize_bit_field): Don't remove SUBREG from dest + if SUBREG_REG is multi-word. + +Wed Sep 23 05:43:23 1998 Richard Kenner + + * reload.c (find_reloads_address): Deal with address which is + an AND; clean up return values some more. + +Fri Sep 11 13:02:26 1998 Richard Kenner + + * function.c (purge_addressof_1): Properly copy flags when making MEM. + +Mon Sep 7 18:33:06 1998 Richard Kenner + + * expr.c (get_inner_reference): If not COMPONENT_REF or BITFIELD_REF + and mode is BLKmode, set size_tree. + + * expr.c (expand_builtin, case BUILT_IN_LONGJMP): Fix typo in + last change. + +Wed Sep 2 15:38:01 1998 Paul Eggert + + * libgcc2.c (__floatdisf): Use signed comparison to test + whether u is close to zero; unsigned comparison is not what's + wanted here. + +Mon Aug 17 02:19:30 1998 David Edelsohn + + * xcoffout.c (UNKNOWN_STAB): Fix typo in previous change; missing + backslash before newline. + +Mon Aug 17 00:12:42 1998 Paul Eggert + + * reorg.c (check_annul_list_true_false): Fix typo in Jul 17 change. + +Sun Aug 2 01:10:15 1998 Paul Eggert + + Add Native Language Support. + + * intl/, ABOUT-NLS, mkinstalldirs, po/Makefile.in.in: New + subdirectory and files. They should be kept identical to the + corresponding items from the GNU gettext distribution. + + * ABOUT-GCC-NLS, exgettext, intl.c, intl.h, po/POTFILES.in, + po/en_UK.po: New files. + + * Makefile.in (AWK, datadir, localedir, top_builddir, USE_NLS, + INTLLIBS, POSUB, INTL_SUBDIRS, HOST_INTLLIBS, + PREPEND_DOTDOT_TO_RELATIVE_PATHS, SUBDIR_FLAGS_TO_PASS, GCC_OBJS, + COLLECT2_OBJS, CCCP_OBJS, CPPMAIN_OBJS, PROTO_OBJS, GCOV_OBJS, + INTL_DISTCLEAN, GEN_PROTOS_OBJS): New vars. + (LIBDEPS, LIBS): Add $(INTLLIBS). + (HOST_LIBDEPS, HOST_LIBS): Add $(HOST_INTLLIBS). + (LIBS): Add @LIBS@. + (ORDINARY_FLAGS_TO_PASS): New var, containing all the old values + from FLAGS_TO_PASS, except for CC. + (FLAGS_TO_PASS): Pass datadir, distdir, localedir. + (OBJS): Add intl.o. + (GEN): Add gencheck. + (STAGESTUFF): Add tree-check.h, gencheck$(exeext). + (native): Depend on intl.all. + (xgcc, collect2, cccp, cppmain, protoize, unprotoize, gcov): Link + intl.o. + (c-typeck.o, c-lex.o, collect2.o, gcc.o, toplev.o, integrate.o, + final.o, cccp.o, cppmain.o, cpplib.o, cpperror.o, s-proto, + gcov.o): Depend on intl.h. + (gencheck): Depend on $(HOST_LIBDEPS) instead of tree.h and + tree.def. + (gencheck.o, intl.o, $(top_builddir)/intl/libintl.a, + $(srcdir)/cp/parse.c, intl.all, intl.install, intl.uninstall, + intl.distdir, intl.mostlyclean, intl.clean, intl.distclean, + intl.maintainer-clean, intl.distdir-fixup, distdir-check): New + rules. + (gen-protos): Link cpperror.o, cppexp.o, cpphash.o, cpplib.o, + prefix.o, version.o; needed for `cpp_notice'. + (mostlyclean): Depend on intl.mostlyclean. + (clean): Depend on intl.clean. + (distclean): Depend on intl.disclean, unless the invoker defines + INTL_DISTCLEAN to be empty. Remove intl/libintl.h and libintl.h + (created by configure). + (maintainer-clean): Make intl.maintainer-clean, but define + INTL_DISTCLEAN to be empty. + (install-normal): Depend on intl.install. + (uninstall): Depend on intl.uninstall. + (distdir-start): Make sure invoker configured with --enable-nls. + Use $(AWK), not awk. Make tmp/intl and tmp/po directories. + (distdir-finish): Make distdir-check at the end. + (distdir): Depend on intl.distdir, intl.distdir-fixup. + (compare, compare3, gnucompare, gnucompare3, stage1-start, + stage2-start, stage3-start, stage4-start): Handle intl + subdirectory. + + * acconfig.h (ENABLE_NLS, HAVE_CATGETS, HAVE_GETTEXT, + HAVE_LC_MESSAGES, HAVE_STPCPY, PACKAGE, VERSION): New macros. + + * aclocal.m4 (AC_ISC_POSIX, AM_WITH_NLS, AM_GNU_GETTEXT, + AM_LC_MESSAGES, AM_PATH_PROG_WITH_TEST): New functions; taken from + gettext distribution. + + * bi-arity.c, bi-opcode.c, bi-opname.c: Include config file first. + + * c-common.c: Don't include . + (tfaff): Now a function, not a string. All users changed. + (check_format_info): Use is_C_digit, not isdigit. + Reword messages to ease localization. + + * c-decl.c (redeclaration_error_message): Now returns int, not + message. + (poplevel, duplicate_decls, pushdecl): Revamp to pass explicit + strings to diagnostic generators. + (duplicate_decls, parmlist_tags_warning, finish_struct): Reword + messages to ease localization. + + * c-iterate.c (prdecl): Reword messages so that they do not require + localization. + + * c-lex.c: Include limits.h if available. + Include intl.h. + Include ctype.h only if MAP_CHARACTER is defined. + (UCHAR_MAX): Define if limits.h doesn't. + (C_alnum_array): New var. + (init_lex): Initialize it. + (yyerror): Localize msgid arg. + (yylex): Use is_C_alnum and is_C_digit, not isalnum and isdigit. + + * c-lex.h (C_alnum_array): New decl. + (is_C_alnum, is_C_digit): New macros. + + * c-typeck.c: Include intl.h. + (warning_init): Now takes just one arg. + (incomplete_type_error, build_unary_op, lvalue_or_else, + readonly_warning, build_modify_expr): Reword messages to ease + localization. + (build_unary_op, readonly_warning): Revamp to pass explicit + strings to diagnostic generators. + (build_modify_expr, warn_for_assignment, c_expand_return): + Translate strings passed to functions expecting translated + strings. + (get_spelling): Remove; it was a no-op. All callers changed. + (error_init, pedwarn_init): Now takes just one arg. All callers + and decls changed. This makes it easier to localize. + + * cccp.c: Include intl.h. + (char_name): Remove. + (check_macro_name): Now takes int 2nd arg, not char *. All + callers changed. + (macarg): Now returns int, not char *. All callers changed. + (notice, vnotice, pedwarn_strange_white_space): New functions. + (verror): Now extern; used by cexp.y. + (main): Set message locale, and defer memory allocation until + after. + (main, do_include, print_containing_files): Invoke `notice' to + localize notices. + (handle_directive): Invoke pedwarn_strange_white_space instead of + using char_name. + (do_include, check_macro_name): Reword messages to ease + localization. + (my_strerror): Reword message so that it does not require + localization. + (verror, vwarning, verror_with_line, vwarning_with_line, + pedwarn_with_file_and_line, fatal): Invoke vnotice to localize + msgid. + (initialize_char_syntax): No need to initialize char_name. + + * cexp.y (yyerror): Now takes msgid format and args, not just string. + (verror): New decl. + (parse_number, yylex): Reword messages to ease + localization. + (verror): New test function. + (pedwarn, warning): Translate msgid arg. + + * collect2.c: Include intl.h. + (my_strerror, main, collect_execute, scan_prog_file, + scan_libraries, read_file, end_file): Reword messages so that they + do not require localization. + (notice): Nwe function. + (fatal, error, main, collect_execute, maybe_unlink, + write_c_file_stat, locatelib, scan_libraries, scan_prog_file, + add_func_table): Use it to translate msgid strings. + (main): Set message locale, and defer memory allocation until + after. + (collect_wait): Reword messages to ease localization. + (bad_header): Revamp to pass explicit strings to diagnostic + generators. + + * combine.c (dump_combine_stats, dump_combine_total_stats): + Use fnotice to translate diagnostic messages. + + * config/1750a/1750a.c (memop_valid): Don't use `valid' as an + identifier; it runs afoul of SunOS 4.1.4 . + + * config/arc/initfini.c (__do_global_dtors): Put backslash before + newline in strings, to pacify xgettext. + + * config/dsp16xx/dsp16xx.c, config/dsp16xx/dsp16xx.h + (dsp16xx_invalid_register_for_compare): New function. + * config/dsp16xx/dsp16xx.md: Use it to report invalid registers. + + * config/i370/i370.h: Include . + + * config/i386/i386.c: Include config.h first. + + * config/m32r/initfini.c (__do_global_dtors): Put backslash before + newline in strings, to pacify xgettext. + * config/m88k/dguxbcs.h (CPP_SPEC): Likewise. + + * config/rs6000/rs6000.c: Include config.h first. + * config/rs6000/rs6000.c, config/rs6000/rs6000.h + (rs6000_fatal_bad_address): New function. + * config/rs6000/rs6000.md: Use it to report bad addresses. + + * config/v850/v850.c: Include config.h first. + + * configure.in: When generating config.h and mentioning a file + taken from the config directory, surround it with #ifdef IN_GCC, + so that programs compiled without IN_GCC -- notably in the intl + subdirectory -- don't need to be compiled with -Iconfig. + (PACKAGE, VERSION, ALL_LINGUAS): New vars. + (AC_ARG_ENABLE): Add --enable-nls. + (AM_GNU_GETTEXT): Add. Override XGETTEXT so that we use exgettext + instead of xgettext to extract strings. + (all_outputs): Add intl/Makefile, po/Makefile.in. + Do not use the shell variable 'l'; it runs afoul of gettext's + aclocal mechanism! + If libintl.h is created, echo '#include "intl/libintl.h"' + >libintl.h so that we don't have to futz with our include paths. + + * cp/Make-lang.in (g++.o): Depend on gansidecl.h, intl.h, Makefile; + do not depend on config.status. + (GXX_OBJS): New var. + (g++$(exeext)): Link intl.o. + + * cp/Makefile.in (top_builddir, INTLLIBS): New vars. + (LIBS): Add $(INTLLIBS). + + * cppalloc.c (memory_full): Use `cpp_notice' to print diagnostic. + + * cpperror.c: Include intl.h. + (cpp_print_containing_files): Use cpp_notice to translate messages. + (cpp_message): is_error is -1 for notices. Translate "warning:". + (cpp_fatal): Translate msgid arg. + + * cppexp.c (cpp_lex): Revamp to pass explicit strings to + diagnostic generators. + (cpp_parse_expr): Use cpp_error, not fprintf, to report + unimplemented operators. + + * cpplib.c: Include intl.h. + (check_macro_name): Now takes int 2nd arg, not char *. All + callers changed. + (check_macro_name, do_define): Reword messages to ease + localization. + (do_define): Revamp to pass explicit strings to diagnostic + generators. + (do_define, cpp_start_read, cpp_handle_options): Use cpp_notice to + translate messages. + (cpp_error, cpp_warning, cpp_warning_with_line, + cpp_pedwarn_with_file_and_line): Translate msgid arg. + (cpp_notice): New function. + (my_strerror): Reword message so that it does not require + localization. + + * cpplib.h (cpp_notice): New decl. + + * cppmain.c: Include intl.h. + (main): Set message locale. + + * cse.c (cse_main): Use fnotice to print diagnostic. + + * final.c: Include intl.h; do not include ctype.h. + (output_operand_lossage): Translate msgid arg. + + * fold-const.c (optimize_bit_field_compare, fold_truthop): Reword + messages to ease localization. + + * gcc.c: Include intl.h. + (my_strerror, snapshot_warning): Reword messages so that they do + not require localization. + (init_spec, set_spec, read_specs, execute, do_spec_1, main, + snapshot_warning): Invoke `notice' to localize notices. + (struct switchstr): Don't use `valid' as an identifier; it runs + afoul of SunOS 4.1.4 . All uses changed. + (do_spec_1): Treat %e string as msgid format, which needs + translation. + (main): Set message locale. + (pfatal_with_name): Invoke perror_with_name, not fatal, so that we + don't have to translate "%s: %s". + (perror_with_name): Invoke printf, not error, so that we don't + have to translate "%s: %s". + (pfatal_pexecute): Invoke pfatal_with_name, not fatal, so that we + don't have to translate "%s: %s". + (fatal, error): Translate msgid arg. + (notice): New function. + + * gcov.c: Include intl.h; include stdarg.h if __STDC__ is defined. + (main): Set message locale. + (fnotice): New function. + (xmalloc, fancy_abort, print_usage, open_files, read_files, + function_summary, output_data): Use it to to print diagnostics. + + * install.texi: Explain new configure options --enable-nls, + --with-included-gettext, --with-catgets. + + * integrate.c: Include intl.h. + (function_cannot_inline_p): Mark msgids with N_. + + * invoke.texi: Describe environment variables affecting locale. + + * pexecute.c: Include libintl.h if ENABLE_NLS, otherwise define + gettext to be a noop. + (_, N_): New macros. + (install_error_msg): Wrap inside N_. + (pexecute): Translate diagnostics. + + * protoize.c: Include intl.h. + (__attribute__): New macro. + (notice): New function. + (my_strerror): Reword message so that it does not require + localization. + (xmalloc, xrealloc, fancy_abort, safe_write, usage, + file_normally_convertible, abspath, find_file, aux_info_corrupted, + save_def_or_dec, gen_aux_info_file, process_aux_info_file, + rename_c_file, find_extern_def, find_static_definition, + declare_source_confusing, edit_fn_declaration, edit_formals_lists, + add_local_decl, add_global_decls, edit_fn_definition, + scan_for_missed_items, edit_file, main): Use `notice' to print + diagnostic. + (main): Set message locale. + + * real.c (NMSGS, ermsg): Remove. + (mtherr): Revamp to pass explicit strings to diagnostic + generators. Abort on invalid operations. + + * regclass.c (fix_register): Reword messages to ease localization. + + * toplev.c: Include intl.h; do not include ctype.h. + (v_really_sorry, really_sorry): Remove unused functions. + (count_error, fatal_io_error): Translate strings. + (default_print_error_function, report_error_function, main, + print_version): Reword messages to ease localization. Use + `notice' to translate diagnostics. + (vnotice, notice, fnotice): New functions. + (vmessage): Remove. + (v_message_with_file_and_line, vsorry): Translate msgid with + vnotice. + (v_message_with_file_and_line, v_message_with_decl): Use + report_file_and_line. Now takes int warning flag, not prefix; + this is easier to localize. All callers changed. + (v_message_with_decl): Abort if first format spec is neither %% + nor %s. Translate "((anonymous))". + (main): Set message locale. + (set_target_switch): Don't use `valid' as an identifier; it runs + afoul of SunOS 4.1.4 . + (__VERSION__): Reword message so that it does not require + localization. + (print_switch_values): Translate "options passed" and "options + enabled". + + * tree.c (valid_machine_attribute): Don't use `valid' as an + identifier; it runs afoul of SunOS 4.1.4 . + + * xcoffout.c (xcoff_output_standard_types): Use `error' to + output diagnostic, so that it gets translated. + + * patch-apollo-includes: Remove; this is part of README.APOLLO. + +Mon Jul 27 18:28:58 1998 Richard Kenner + + * reload.c (find_reloads): If no_input_reloads, abort if + reloads were made for addresses. + * m68k.md (sxx): Operand 0 cannot be memory. + +Fri Jul 17 07:31:04 1998 Andreas Schwab + + * m68k.c (output_move_simode_const): Use subl to move 0 into addr reg. + (output_move_[hq]imode): Likewise. + + * m68k.md (extend[sd]fxf2): Accept constants and general reg as + source operand if the destination is a floating point register. + +Fri Jul 17 07:23:49 1998 Herman ten Brugge + + * reorg.c (check_annul_list_true_false): New function. + (steal_delay_list_from_{target,fallthrough}): Call it and also + refine tests for when we may annul if already filled a slot. + (fill_slots_from_thread): Likewise. + (delete_from_delay_slot): Return newly-created thread. + (try_merge_delay_isns): Use its new return value. + +Sat Jul 4 11:07:33 1998 Eberhard Mattes + + * function.c (assign_parms): Handle PARALLEL which include stack. + +Sat Jul 4 09:44:29 1998 Paul Edwards + + * tree.c, print-tree.c, c-lang.c: Include stdio.h before tree.h. + * expr.c (bc_expand_component_address): Correct args to + bc_push_offset_and_size. + * reload1.c (reload_cse_simplify_operands): Add missing return value. + +Fri Jul 3 07:17:19 1998 Richard Kenner + + * alpha.c (normal_memory_operand): Handle case when REG will be + eliminated by reload. + +Thu Jul 2 18:43:53 1998 James Carlson + + * floatlib.c (HIDDEND_LL, MANTD_LL, PACKD_LL): New macros. + (__addsf3): Fixed cases returning wrong type and causing unintended + conversions and data corruption. + (__mulsf3): Fixed rounding flaws caused wrong scaling. + (__float{didf,sisf,disf},__fix{,uns}dfdi): New functions. + (__{gt,ge,lt,le,eq,ne}df2): Likewise. + (__truncdfsf2): Fixed normalization problems + (__fixunsdfsi): Fixed compiler warning + (__{add,sub,mul}df3): Rewrite to do real DP math. + (__divdf3): Removed previous version by Barrett Richardson. + +Thu Jul 2 17:57:20 1998 Douglas B. Rupp + + * cpperror.c: Include errno.h. + +Thu Jul 2 16:46:36 1998 Andreas Schwab + + * c-decl.c (grokdeclarator): Don't warn about implicit int in + `typedef foo = bar'. + +Tue Jun 30 18:32:49 1998 Geert Bosch + + * alpha/vxworks.h (LINK_SPEC): Add -taso -T 0. + +Tue Jun 30 09:39:32 1998 David Edelsohn + + * expr.c (expand_builtin_{set,long}jmp): If STACK_SAVEAREA_MODE + defined, override sa_mode using its value. + * explow.c (emit_stack_save): Likewise. + + * rs6000/aix41.h (ASM_CPU_SPEC): Define relative to ASM_DEFAULT_SPEC. + (CPP_CPU_SPEC): Define relative to CPU_DEFAULT_SPEC. + * rs6000.c (processor_target_table, 620): Don't affect MASK_POWERPC64. + (rs6000_override_options): Ignore flag_pic for AIX. + (rs6000_immed_double_const): Delete. + ({reg_or_u_short,u_short_cint}_operand): Don't assume 32-bit CONST_INT. + ({non_logical_cint,logical}_operand): Likewise. + (num_insns_constant): mask64_operand is 2 insns. + (easy_fp_constant): Any CONST_DOUBLE_HIGH is okay for 64-bit. + (mask_constant): HOST_WIDE_INT parameter. + (non_and_cint_operand): Delete. + ({mask,and}64_operand): New functions. + (function_arg{,_advance}): DImode arguments don't need special + alignment when 64-bit. + (setup_incoming_varargs): Reverse reg_size assignment. + (print_operand): HOST_WIDE_INT second parameter. + (print_operand, case 'B', 'S'): New cases. + (print_operand, case 'M'): Fix typo in lossage string. + (rs6000_stack_info): Reverse reg_size assignment. Use total_raw_size + to compute AIX push_p. Use reg_size to compute {cr,lr}_save_offset. + (rs6000_output_load_toc_table): Reverse init_ptr assignment. Use + TARGET_64BIT not TARGET_POWERPC64. Convert fprintf to fputs. + Load GOT highpart, don't add it. Add lowpart with {cal|la}. + (rs6000_allocate_stack_space): Use {cal|la}. + (output_epilog): Use {cal|la} + (output_function_profiler): Add call glue to mcount call. + Load GOT highpart, don't add it. Add lowpart with {cal|la}. + Use asm_fprintf and convert fprintf to fputs. + + * rs6000.h (TARGET_SWITCHES): Add powerpc64. + (STACK_BOUNDARY): Depend on TARGET_32BIT. + (ADJUST_FIELD_ALIGN): Calculate array alignment using innermost type. + (CONST_OK_FOR_LETTER_P): Don't assume 32-bit CONST_INT. + (EXTRA_CONSTRAINTS): Remove 'S' and 'T'. Replace 'S' with + 64-bit mask operand. + (RS6000_SAVE_TOC): Depend on TARGET_32BIT. + (STACK_SAVEAREA_MODE): New macro. + (LEGITIMATE_CONSTANT_P): DImode okay for 64bit. + (RTX_COSTS, AND/IOR/XOR): Reflect current machine description. + (ASM_FILE_START): Emit 64-bit ABI directive. + (ASM_DECLARE_FUNCTION_NAME): Align CSECT on doubleword in 64-bit mode. + (ASM_OUTPUT_SPECIAL_POOL_ENTRY): DImode okay for 64-bit. + (PREDICATE_CODES): Add "and64_operand" and "mask64_operand". + Delete "non_and_cint_operand". "input_operand" includes CONST_DOUBLE. + + * rs6000.md (iorsi3, xorsi3): Use HOST_WIDE_INT for mask. + Restore define_split. + (floatsidf2, floatunssidf2): Remove !TARGET_POWERPC64 final constraint. + (floatsidf2_internal, floatunssidf2_internal2): Likewise. + Do not specify base register operand mode. + (floatsidf2_loadaddr): Don't specify base register operand mode. + (floatsidf2_store1, floatsidf2_store2): Operand 1 must be base + register; do not specify mode. Remove !TARGET_POWERPC64 final + constraint. + (floatsidf2_load): Don't specify base register operand mode. + Remove !TARGET_POWERPC64 final constraint. + (fix_truncdfsi2_internal, fix_truncdfsi2_{store,load}): Don't specify + base register operand mode. + (mulsidi3): Add !TARGET_POWERPC64 constraint. + (adddi3): Split large constants early. + (absdi3): Shift by 63, not 31. + (rotldi3): Add masking combiner patterns. + (anddi3): Add rldic{r,l} masking. Remove split of large constants. + (iordi3, xordi3): Split large constants early. + (movsi matcher): Remove S and T constraints. + (movsf const_double): create SImode constant from TARGET_DOUBLE. + (movdf_hardfloat32): Add default abort case. + (movdf easy_fp_const): create DImode constant from TARGET_DOUBLE. + (movdi): Remove 64-bit constant generator. Try to convert + CONST_DOUBLE to CONST_INT. Handle TOC memory constants. + (movdi_32): Add default abort case. + (movdi_64): Add numerous ways to split 64-bit constants. + Make catch-all define_split more optimal and never FAIL. + (movti_ppc64): Add default abort case. + (allocate_stack): Remove operand modes; use Pmode. + (restore_stack_block): Remove operand modes. Generate Pmode + temporary. Generate MEM and specify mode. + (save_stack_nonlocal, restore_stack_nonlocal): Generate Pmode + temporary. Save area is double Pmode. + (call_indirect_aix64, call_value_indirect_aix64): New patterns. + (call, call_value): Do not specify address operand mode. Choose + appropriate AIX ABI. + (*call_local64, *ret_call_local64): New patterns. + (*call_nonlocal_aix64, *ret_call_nonlocal_aix64): New patterns. + (*ret_call_nonlocal_aix32): Use call_value_indirect for REG. + (compare): Materialize DImode truthvalues. + +Tue Jun 30 06:31:40 1998 Richard Henderson + + * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'. + * alpha.c (print_operand): Handle it. + * alpha.md (fix_truncdfsi2, fix_truncsfsi2): New patterns and + related define_splits. + +Tue Jun 30 06:02:07 1998 Richard Kenner + + * calls.c (emit_library_call{,_value}): Pass null + to REG_PARM_STACK_SPACE. + + * alpha.c (normal_memory_operand): New function. + * alpha.h (EXTRA_CONSTRAINT, case 'Q'): Call it. + + * fold-const.c (count_cond): New function. + (fold): Don't try to build COND_EXPR from binary op when both sides + are COND_EXPR unless not nested too deeply. + +Thu Jun 25 09:54:55 1998 Nick Clifton + + * arm.h (REG_ALLOC_ORDER): Add ARG_POINTER_REGNUM, noticed by + grahams@rcp.co.uk. + +Mon Jun 15 17:41:33 1998 Richard Kenner + + * reload1.c (reload): Issue guidance message on stack frame too large + for reliable stack check. + + * fold-const.c (fold_range_test): Prevent falling through with no ret. + +Sat Jun 13 15:49:53 1998 Carol LePage + + * configure.in (sparc-hal-solaris2*): New target. + * sparc/hal.h, sparc/t-halos: New files. + +Sat Jun 13 14:30:25 1998 David W. Schuler + + * i386/aix386ng.h (CPP_SPEC): Remove bogus quote. + +Sat Jun 13 14:16:34 1998 Andreas Schwab + + * regmove.c (try_auto_increment): Fix typo. + + * c-common.c (truthvalue_conversion): Protect side effects in the + expression when splitting a complex value. + * fold-const.c (fold): Likewise. + + * expr.c (do_jump, case EQ_EXPR, NE_EXPR): When comparing complex + prevent operands from being evaluated twice. + +Sat Jun 13 12:53:22 1998 Richard Earnshaw (rearnsha@arm.com) + + * unroll.c (verify_addresses): Use validate_replace_rtx to undo + changes; abort if undo fails. + +Sat Jun 13 11:46:38 1998 Anders Blomdell + + * flags.h (flag_volatile_static): Declare. + * toplev.c (flag_volatile_static): Define. + (f_options): Include -fvolatile-static. + * varasm.c (make_decl_rtl): Support -fvolatile-static. + +Sat Jun 13 08:26:21 1998 Richard Kenner + + * reload1.c (reload_cse_regno_equal_p): If -ffloat-store, don't + consider a MEM in FP mode as equal. + + * varasm.c (assemble_variable): Never put decl with specified section + name into bss. + + * output.h (current_function_addresses_labels): Declare. + * function.h (struct function): New field `addresses_labels'. + * function.c (current_function_addresses_labels): Define. + ({push,pop}_function_context): Save/restore it. + (init_function_start): Initialize it. + * rtl.h (FUNCTION_FLAGS_ADDRESSES_LABELS): New flag. + * expr.c (expand_expr, case LABEL_DECL): Show addresses labels. + * integrate.c (function_cannot_inline_p): Can't if addresses labels. + (initialize_for_inline): Save current_function_addresses_labels. + (output_inline_function): Restore it. + + * reload.c (find_reloads, case 'o'): All reloaded addresses + are offsettable. + (find_reloads_address): If replacing address, don't return 1. + + * profile.c (output_func_start_profiler): Add missing steps in + defining function. + +Fri Jun 12 17:10:16 1998 Richard Kenner + + * m68k.md (extendqidi2): Operand 1 must be in data register. + +Tue Jun 9 07:24:01 1998 Richard Kenner + + * cccp.c (handle_directive): If -dM, also include #undef. + * cpplib.c (handle_directive): Likewise. + + * calls.c (expand_call): Allow function pointer to be a REFERENCE_TYPE. + + * function.c (assign_parms): Use proper mode for location of arg + on stack when promotions are occurring. + + * regmove.c ({next,prev}_insn_for_regmove): Properly handle end of + function. + +Mon Jun 8 15:26:49 1998 Juha Sarlin + + * h8300.c (get_shift_alg): Add special cases for shifts of 8 and 24. + +Mon Jun 8 14:40:02 1998 John Wehle (john@feith.com) + + * i386.md (movsf_push, movsf_mem): Remove. + (movsf_push): Rename from movsf_push_nomove and move in front of + movsf; allow memory operands during and after reload. + (movsf_push_memory): New pattern. + (movsf): Don't bother checking for push_operand. If TARGET_MOVE and + both operands refer to memory then force operand[1] into a register. + (movsf_normal): Change to unnamed pattern. + Likewise for movdf, movxf, and friends. + +Mon Jun 8 13:18:04 1998 Martin v. Loewis + + * Makefile.in (TREE_H): Add tree-check.h. + (tree-check.h, s-check, gencheck): New targets. + (STAGESTUFF): Add s-check. + * gencheck.c: New file. + * tree.c (tree_check, tree_class_check, expr_check): New functions. + * tree.h (TREE_CHECK, TREE_CLASS_CHECK): Define. + (TYPE_CHECK, DECL_CHECK): Define. + Modify all access macros to use generated checking macros. + * acconfig.h (ENABLE_CHECKING): Undefine. + * configure.in (--enable-checking): New option. + +Mon Jun 8 12:13:25 1998 Richard Kenner + + * regmove.c: Remove include for varargs or stdarg. + +Mon Jun 8 07:49:41 1998 Andris Pavenis + + * gcc.c (link_command_spec): Support LINK_COMMAND_SPEC. + +Sun Jun 7 18:00:28 1998 Andreas Schwab + + * fold-const.c (fold, case EQ_EXPR): When folding VAR++ == CONST + or VAR-- == CONST construct a proper mask if VAR is a bitfield. + Cope with CONST being out of range for the bitfield. + +Sun Jun 7 17:19:35 1998 Tom Quiggle + + * mips/iris6.h (DWARF2_FRAME_INFO): Define. + * dwarf2out.c (dwarf2out_do_frame): Do something if DWARF2_FRAME_INFO. + +Sun Jun 7 15:29:04 1998 Andreas Schwab + + * regmove.c: New file. + * Makefile.in (OBJS): Add regmove.o. + (regmove.o): New rules. + (mostlyclean): Remove regmove dumps. + * toplev.c (regmove_{dump,dump_file,time}, flag_regmove): New vars. + (f_options): Add -foptimize-register-move. + (compile_file): Run regmove pass after combine pass and do its dump. + (main): Enable regmove dump when -dN or -da. + (fatal_insn): Flush regmove dump file. + * flags.h (flag_regmove): Declare. + * flow.c (find_use_as_address): Export. + * rtl.h (find_use_as_address): Declare. + * local-alloc.c (optimize_reg_copy_{1,2}): Removed, all calls deleted. + * reload1.c (count_occurrences): Export. + * reload.h (count_occurrences): Declare. + +Sun Jun 7 09:30:31 1998 Richard Kenner + + * Makefile.in (uninstall): Uninstall gcov. + + * alpha.h (ASM_COMMENT_START): Define. + + * alpha.h (EXTRA_CONSTRAINT, case 'S'): New case. + * alpha.md ({ashl,ashr,lshr}di3): Use 'S' for constraint. + + * i386.md (cmpxf): Add missing extend pattern from SFmode and fix + operand numbers in one extend pattern from DFmode. + + * pa.md ({pre,post}_{ld,st}wm and similar): When operand is being + incremented, use '+', not '=', for constraint. + + * reload.c (find_reloads): Give preference to pseudo that was the + reloaded output of previous insn. + + * emit-rtl.c (init_emit_once): Provide default for DOUBLE_TYPE_SIZE. + + * expr.c (init_expr_once): Free all RTL we generate here. + * expmed.c (init_expmed): Allocate all RTX in memory we'll free. + + * genemit.c (main): Generate #include "reload.h". + + * expr.c (expand_expr, case INDIRECT_EXPR): A dereference of + a REFERENCE_TYPE is always considered in a structure. Likewise for + a dereference of a NOP_EXPR whose input is a pointer to aggregate. + +Sat Jun 6 17:25:14 1998 Richard Kenner + + * mips.md (reload_{in,out}di): Allow other operand to be invalid + MEM and get any reload replacement before using address. + +Tue May 26 18:52:23 1998 Richard Kenner + + * reload1.c (reload): Get MEM_IN_STRUCT_P and RTX_UNCHANGING_P + from reg_equiv_memory_loc; set the latter when changing REG to MEM. + (alter_reg): Don't set RTX_UNCHANGING_P for shared slots. + +Mon May 25 12:07:12 1998 Hans-Peter Nilsson + + * cplus-dem.c (MBUF_SIZE): Bumped from 512 to 32767. + +Sun May 24 21:50:12 1998 Alan Modra + + * i386/linux{,-aout,oldld}.h (ASM_COMMENT_START): Define. + +Sun May 24 11:58:37 1998 Andreas Schwab + + * m68k.md (adddi3, subdi3): Properly negate the DImode constant. + +Sun May 24 11:30:08 1998 Torbjorn Granlund + + * m68k/lb1sf68.asm (__addsf3): Fix typo in exg on coldfire. + +Sun May 24 09:38:17 1998 John Wehle (john@feith.com) + + * i386.md (movsi): Remove redundant integer push patterns. + Don't check for TARGET_PUSH_MEMORY when pushing constants or registers. + +Sun May 24 08:59:27 1998 Richard Kenner + + * fold-const.c (fold, case EQ_EXPR): Split COMPLEX_TYPE operands + if either is COMPLEX_CST in addition to COMPLEX_EXPR. + + * expr.c (do_jump, case EQ_EXPR, case NE_EXPR): Check for COMPLEX + before testing for operand 1 being zero. + + * genattrtab.c (optimize): Define. + + * configure.lang: Fix substitution of target_alias. + +Sat May 23 22:31:17 1998 Michael P. Hayes + + * emit_rtl.c (double_mode): New variable. + (init_emit_once): Set and use it. + * real.c (ereal_atof, real_value_truncate): Handle double_mode not + being DFmode for C4x. + +Sat May 23 22:19:55 1998 Mike Stump + + * expr.c (expand_builtin_setjmp): Handle BUILTIN_SETJMP_FRAME_VALUE. + * i960.h (SETUP_FRAME_ADDRESSES, BUILTIN_SETJMP_FRAME_VALUE): Define. + * i960.md (ret, flush_register_windows): Define. + (nonlocal_goto): Likewise. Nested function nonlocal gotos don't + work yet. + +Sat May 23 18:45:59 1998 Andreas Schwab + + * m68k/t-linux: Remove stuff already included in config/t-linux. + +Sat May 23 18:35:07 1998 Richard Kenner + + * final.c: Select and "gstab.h" with NO_STAB_H. + + * gcc.c (default_compilers): Remove ".ada" extension. + + * combine.c (rtx_equal_for_field_assignment): Remove code that + checks get_last_value. + + * Makefile.in (uninstall): Delete info files. + +Sat May 23 18:28:27 1998 Herman A.J. ten Brugge + + * c-decl.c (start_decl): Use new macro SET_DEFAULT_DECL_ATTRIBUTES. + * c-lex.c (check_newline): Put last read character back on input + stream. + +Sat May 23 18:13:53 1998 David Edelsohn + + * rs6000.md (floatsidf2_loadaddr): rs6000_fpmem_offset will be + negative in a stackless frame. + * rs6000.c (rs6000_stack_info): Don't include fixed-size link area + in stackless frame size. Support 64-bit stackless frame size. + Combine fpmem offset calculations and don't add total_size to + offset if not pushing a stack frame. + + * tree.c (get_inner_array_type): New function. + * tree.h (get_inner_array_type): Likewise. + +Wed May 20 15:42:22 1998 Richard Kenner + + * expmed.c (expand_divmod): Save last divison constant and + if rem is same as div, don't adjust rem cost. + +Thu May 14 14:11:37 1998 Richard Kenner + + * alpha/vxworks.h: New file. + * configure.in (alpha*-*-vxworks*): New target. + + * alpha.c (tree.h): Include earlier. + (alpha_initialize_trampoline): New function. + * alpha.h (INITIALIZE_TRAMPOLINE): Call it. + * alpha/linux.h (INITIALIZE_TRAMPOLINE): Don't redefine. + +Thu May 14 13:35:53 1998 Cyrille Comar + + * Makefile.in (STAGESTUFF): Add s-under. + +Wed May 13 17:38:35 1998 Richard Kenner + + * combine.c (simplify_comparison, case AND): Don't commute AND + with SUBREG if constant is whole mode and don't do if lowpart + and not WORD_REGISTER_OPERATIONS. + + * expmed.c (expand_mult): Use 0 as add_target if should preserve + subexpressions. + +Mon May 11 17:26:06 1998 Paul Eggert + + * dwarf2out.c: Undo most recent change. + +Sun May 10 17:09:20 1998 Richard Kenner + + * fold-const.c (fold_range_test, fold): If need to make SAVE_EXPR + to do optimization, suppress if contains_placeholder_p. + +Thu May 7 18:14:31 Paul Eggert + + * dwarf2out.c: Don't assume `.section ".text"' causes assembler to + treat .text as label for start of section; instead, output + `.section ".text"; .LLtext0:' and use .LLtext0 in label contexts. + (ABBREV_LABEL, DEBUG_INFO_LABEL, DEBUG_LINE_LABEL, TEXT_LABEL): New. + (abbrev_label, debug_info_label, debug_line_label, text_label): New. + (dwarf2out_init): Initialize the vars. Output defn for text_label. + (dwarf2out_finish): Output defns for the other 3 vars. + (dw_val_node): Rename val_section to val_section_label, as it's + now a label, not a section. + (add_AT_section_offset): Arg is now a label, not a section. + (print_die): In label contexts, output section label, not section. + (output_die, output_compilation_unit_header): Likewise. + (output_{pubnames,aranges,line_info}, dwarf2out_finish): Likewise. + + * fixinc.wrap: Renamed from fixinc.math. Put wrapper around + curses.h if it contains `typedef char bool;'. + + * configure.in (arm-*-netbsd*): Rename fixinc.math to fixinc.wrap. + (i[34567]86-*-freebsdelf*, i[34567]86-*-freebsd*): Likewise. + (i[34567]86-*-netbsd*, i[34567]86-*-solaris2*): Likewise. + (m68k-*-netbsd*, mips-dec-netbsd*, ns32k-pc532-netbsd*): Likewise. + (powerpcle-*-solaris2*, sparc-*-netbsd*, sparc-*-solaris2*): Likewise. + (vax-*-netbsd*): Likewie. + +Wed May 6 06:44:28 1998 Richard Kenner + + * combine.c (simplify_rtx, case TRUNCATE): Reflect that it sign-extends + instead of zero-extending. + +Sat May 2 20:39:22 1998 Richard Kenner + + * fold-const.c (fold): When commutting COND_EXPR and binary operation, + avoid quadratic behavior if have nested COND_EXPRs. + +Tue Apr 28 17:30:05 1998 Richard Kenner + + * mips.h (HOST_WIDE_INT): Define if not already. + (compute_frame_size, mips_debugger_offset): Return HOST_WIDE_INT. + (DEBUGGER_{AUTO,ARG}_OFFSET): Cast second arg to HOST_WIDE_INT. + * mips.c (mips_debugger_offset): Now returns HOST_WIDE_INT. + Likewise for internal variable frame_size. + + * final.c (alter_subreg): Make new SUBREG if reload replacement + scheduled inside it. + + * dwarf2out.c (add_bound_info, case SAVE_EXPR): Pass + SAVE_EXPR_RTL address through fix_lexical_addr. + +Mon Apr 27 18:57:18 1998 Jim Wilson + + * mips/sni-svr4.h (CPP_PREDEFINES): Add -Dsinix and -DSNI. + +Mon Apr 20 14:48:29 1998 Michael Meissner + + * rs6000.md (mov{sf,df} define_splits): When splitting move of + constant to int reg, don't split insns that do simple AND and OR + operations; just split each word and let normal movsi define split + handle it further. + +Sun Apr 19 20:21:19 1998 Michael P. Hayes + + * real.h (C4X_FLOAT_FORMAT): New macro. + * real.c (c4xtoe, etoc4x, toc4x): New functions. + +Sun Apr 19 20:17:32 1998 Niklas Hallqvist + + * m68k.c (notice_update_cc): Use modified_in_p to check for update. + +Sun Apr 19 18:48:07 1998 K. Richard Pixley + + * fixincludes: Discard empty C++ comments. + Special case more files with C++ comments nested in C comments. + +Sun Apr 19 18:30:11 1998 Andreas Schwab + + * m68k.md ({add,sub}di3): Optimize for constant operand. + +Sun Apr 19 18:27:11 1998 Alan Modra + + * i386.c (output_387_binary_op): Swap operands when popping if result + is st(0). + +Sun Apr 19 17:58:01 1998 Peter Jeremy + + * expr.c (do_jump_by_parts_equality_rtx): Now public. + * expmed.c (do_cmp_and_jump): New function. + (expand_divmod): Use do_cmp_and_jmp instead of emit_cmp_insn and + emit_jump_insn. + +Sun Apr 19 07:48:37 1998 Richard Kenner + + * c-typeck.c (build_c_cast): Check underlying type when seeing + if discarding const or volatile. + + * c-decl.c (pushdecl): Avoid duplicate warning about implicit redecl. + + * configure.in (stab.h): Check for it. + (i386-*-vsta): Include xm-i386.h too. + * dbxout.c (stab.h): Include based on autoconf results. + * vax/xm-vms.h (NO_STAB_H): Deleted. + * alpha/xm-vms.h, xm-mips.h, i386/xm-mingw32.h, i386/go32.h: Likewise. + * i386/xm-cygwin32.h: Likewise. + * i386/xm-vsta.h (NO_STAB_H): Likewise. + (i386/xm-i386.h): No longer include. + + * mips.c: Cleanups and reformatting throughout. + ({expand,output}_block_move): Use HOST_WIDE_INT for sizes. + (mips_debugger_offset, compute_frame_size): Likewise. + (save_restore_insns, mips_expand_{pro,epi}logue): Likewise. + (siginfo): Deleted. + (override_options): Don't set up to call it; don't call setvbuf. + +Mon Apr 13 06:40:17 1998 Richard Kenner + + * configure.in (sparc-*-vxsim*): Include xm-siglist.h and + define USG and POSIX. + +Sun Apr 12 21:59:27 1998 Jeffrey A. Law + + * calls.c (expand_call): Fix typo in STRICT_ARGUMENT_NAMING. + +Sun Apr 12 21:42:23 1998 D. Karthikeyan + + * m68k.h (TARGET_SWITCHES): Add missing comma. + +Sun Apr 12 21:33:33 1998 Eric Valette + + * configure.in (i[34567]86-*-rtemself*): New configuration. + * i386/rtemself.h: New file. + +Sun Apr 12 21:08:28 1998 Jim Wilson + + * loop.c (loop_optimize): Reset max_uid_for_loop after + find_and_verify_loops call. + (strength_reduce): In auto_inc_opt code, verify v->insn has valid + INSN_LUID. + +Sun Apr 12 20:54:59 1998 Richard Earnshaw (rearnsha@arm.com) + + * configure.in (sparc-*-solaris2*): Add xm-siglist.h to xm_file. + Add USG and POSIX to xm_defines. + +Sun Apr 12 20:47:37 1998 Pat Rankin + + * cccp.c (eprint_string): New function. + (do_elif, do_else, verror): Use it instead of fwrite(,,,stderr). + (error_from_errno, vwarning): Likewise. + ({verror,vwarning,pedwarn}_with_line): Likewise. + (pedwarn_with_file_and_line, print_containing_files): Likewise. + +Sun Apr 12 20:40:44 1998 Richard Henderson + + * configure.in (alpha*-*-linux-gnu*): Add alpha/t-crtbe. + Add crt{begin,end}.o in extra_parts and delete crt{begin,end}S.o.o + * alpha/t-crtbe, alpha/crt{begin,end}.asm: New files. + + * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Accept '(' for s/sv/svi. + * alpha.c (print_operand): Handle it. + * alpha.md (fix_trunc[ds]fdi2): Use it. Add earlyclobber pattern + for ALPHA_TP_INSN. + +Sun Apr 12 13:09:46 1998 Scott Christley + + * objc/encoding.c (objc_sizeof_type, _C_VOID): New case. + +Sun Apr 12 13:04:55 1998 Nikolay Yatsenko (nikolay@osf.org) + + * configure.in (i[34567]86-*-osf1*): New entry. + * i386/osf1-c[in].asm: New files for OSF/1. + * i386/osf1elf{,gdb}.h, i386/[xt]-osf1elf, i386/xm-osf1elf.h: Likewise. + +Sun Apr 12 10:03:51 1998 Noel Cragg + + * fixincludes: Remove specification of parameters when renaming + functions in Alpha DEC Unix include files. + +Sun Apr 12 07:33:46 1998 Richard Kenner + + * mips.c (large_int): Use HOST_WIDE_INT, not int. + (print_operand): Use HOST_WIDE_INT_PRINT_* macros. + + * toplev.c (main): Sort order of handling of -d letters. + Use `F' instead of `D' for addressof_dump. + + * libgcc2.c (_eh_compat): Deleted. + * Makefile.in (LIB2FUNCS): Delete _eh_compat. + + * configure.in (alpha*-*-linux-gnu*): Don't include alpha/xm-linux.h. + + * c-common.c (check_format_info): Properly test for nested pointers. + + * pa.md (casesi0): Add missing mode for operand 0. + + * function.c (purge_addressof_1, case MEM): If BLKmode, put ADDRESSOF + into stack. + + * c-parse.in (label): Give warning if pedantic and label not integral. + + * c-decl.c (grokdeclarator): Don't warn about return type if in + system header. + + * reload.c (reload_nongroup): New variable. + (push{_secondary,}_reload): Initialize it. + (find_reloads): Compute it. + (debug_reload): Print it. + * reload.h (reload_nongroup): Declare. + * reload1.c (reload): Use reload_nongroup instead of local computation. + Check caller_save_spill_class against any nongroup reloads. + (reloads_conflict): No longer static. + +Sun Apr 12 05:52:18 1998 John David Anglin + + * vax.md (call patterns): Operand 1 is always a CONST_INT. + +Sat Apr 11 16:01:11 1998 Richard Kenner + + * convert.c (convert_to_{pointer,integer,real,complex}): Use switch. + Add missing integer-like types. + Simplify return of zero in error case. + (convert_to_pointer): Remove dubious abort. + (convert_to_integer, case POINTER_TYPE): Make recursive call. + (convert_to_integer, case COND_EXPR): Always convert arms. + * tree.c (type_precision): Deleted. + + * cccp.c (do_warning): Give pedantic warning if -pedantic and not + in system file. + * cpplib.c (do_warning): Likewise. + + * function.c (target_temp_slot_level): Define here. + (push_temp_slots_for_target, {get,set}_target_temp_slot_level): New. + * stmt.c (target_temp_slot_level): Don't define here. + * expr.h (temp_slot_level): New declaration. + +Fri Apr 10 16:35:48 1998 Paul Eggert + + * c-common.c (decl_attributes): Support strftime format checking. + (record_function_format, {check,init_function}_format_info): Likewise. + (enum format_type): New type. + (record_function_format): Now static; takes value of type + enum format_type instead of int. + (time_char_table): New constant. + (struct function_format_info): format_type member renamed from is_scan. + (check_format_info): Use `warning' rather than sprintf followed by + `warning', to avoid mishandling `%' in warnings. + Change a `pedwarn' to `warning'. + * c-tree.h (record_function_format): Remove decl. + +Thu Apr 2 17:34:27 1998 Manfred Hollstein + + * regclass.c (memory_move_secondary_cost): Protect uses of + SECONDARY_{INPUT,OUTPUT}_RELOAD_CLASS with #ifdef tests. + +Thu Apr 2 07:06:57 1998 Andreas Schwab + + * m68k.c (standard_68881_constant_p): Don't use fmovecr on 68060. + +Thu Apr 2 06:19:25 1998 Ken Raeburn + + * Makefile.in (version.c): Put "cvs log" output in build directory. + + * reload.h (MEMORY_MOVE_COST): Define here if not already defined. + (memory_move_secondary_cost): Declare. + * regclass.c (MEMORY_MOVE_COST): Don't define default here. + (memory_move_secondary_cost) [HAVE_SECONDARY_RELOADS]: New function. + (regclass, record_reg_classes, copy_cost, record_address_regs): + Pass register class and direction of move to MEMORY_MOVE_COST. + (top_of_stack) [HAVE_SECONDARY_RELOADS]: New static array. + (init_regs) [HAVE_SECONDARY_RELOADS]: Initialize it. + * reload1.c (MEMORY_MOVE_COST): Don't define default here. + (emit_reload_insns, reload_cse_simplify_set): Pass register class + and direction of move to MEMORY_MOVE_COST. + * 1750a.h (MEMORY_MOVE_COST): Add extra ignored arguments. + * a29k.h, alpha.h, arc.h, arm.h, dsp16xx.h, i386.h, m32r.h: Likewise. + * m88k.h, rs6000.h: Likewise. + * mips.h (MEMORY_MOVE_COST): Likewise. + Add memory_move_secondary_cost result to cpu-specific cost. + +Mon Mar 30 13:56:30 1998 Jim Wilson + + * mips/ultrix.h (SUBTARGET_CPP_SPEC): Define. + +Wed Mar 25 16:09:01 1998 Michael Meissner + + * rs6000.h (FUNCTION_ARG_PADDING): Cast result to be enum direction. + (function_arg_padding): Declare. + + * rs6000.c: Include stdlib.h if we have it. + (function_arg_padding): Change return type to int, cast enum's to int. + + (From Kaveh R. Ghazi ) + * rs6000.c (rs6000_override_options): Change type of `i', `j' and + `ptt_size' from int to size_t. + (rs6000_file_start): Likewise for `i'. + (rs6000_replace_regno): Add default case in enumeration switch. + (output_epilog): Remove unused variable `i'. + (rs6000_longcall_ref): Remove unused variables `len', `p', `reg[12]'. + + * rs6000.h (ADDITIONAL_REGISTER_NAMES): Add missing braces around + initializer. + (get_issue_rate, non_logical_cint_operand): Add prototype. + (rs6000_output_load_toc_table): Likewise. + + * rs6000.md (udivmodsi4): Add explicit braces to avoid ambiguous + `else'. + +Wed Mar 25 02:39:01 1998 Paul Eggert + + * configure.in (i[34567]86-*-solaris2*, powerpcle-*-solaris2*, + sparc-*-solaris2*): Use fixinc.svr4 if Solaris 2.0 through 2.4. + +Mon Mar 23 07:27:19 1998 Philippe De Muyter + + * m68k.md (ashldi_const): Allow shift count in range ]32,63]. + (ashldi3): Allow constant shift count in range ]32,63]. + (ashrdi_const, ashrid3, lshrdi_const, lshrdi3): Likewise. + + * m68k.md (zero_extend[qh]idi2, iordi_zext): New patterns. + (zero_extendsidi2): Avoid useless copy. + (iorsi_zexthi_ashl16): Avoid "0" constraint for operand 2. + (iorsi_zext): New name for old unnamed pattern; indentation fixes. + +Mon Mar 23 07:12:05 1998 Richard Kenner + + * final.c (only_leaf_regs_used): If pic_offset_table_rtx used, + make sure it is a permitted register. + +Sun Mar 22 06:57:04 1998 Richard Kenner + + * expmed.c (extract_bit_field): Don't confuse SUBREG_WORD with + endian adjustment in SUBREG case. + Don't abort if can't make SUBREG needed for extv/extzv. + +Sat Mar 21 08:02:17 1998 Richard Gorton + + * alpha.md (zero_extendqi[hsd]i2): Use "and", not "zapnot". + +Sat Mar 21 07:47:04 1998 Richard Kenner + + * unroll.c (verify_addresses): Use validate_replace_rtx. + (find_splittable_givs): If invalid address, show nothing same_insn. + +Fri Mar 20 10:24:12 1998 Philippe De Muyter + + * fold-const.c (fold, case CONVERT_EXPR): Replace sign-extension of + a zero-extended value by a single zero-extension. + +Thu Mar 19 14:59:32 1998 Andrew Pochinsky + + * sparc.h (ASM_OUTPUT_LOOP_ALIGN): Fix error in last change. + +Thu Mar 19 14:48:35 1998 Michael Meissner + + * gcc.c (default_arg): Don't wander off the end of allocated memory. + + * rs6000/sysv4.h (RELATIVE_PREFIX_NOT_LINKDIR): Undef for System V + and EABI. + +Thu Mar 19 06:17:59 1998 Richard Kenner + + * Makefile.in (toplev.o): Depend on Makefile. + +Wed Mar 18 17:40:09 1998 Michael P. Hayes + + * expr.c (convert_move): Add [QH]Imode/P[QH]Imode conversions. + * machmode.def (PQImode, PHImode): New modes. + +Wed Mar 18 17:11:18 1998 Andreas Schwab + + * m68k.md (movsf+1): Optimize moving a CONST_DOUBLE zero. + +Wed Mar 18 17:07:54 1998 Ken Raeburn + + * regclass.c (init_reg_sets): Delete init of reg-move cost tables. + (init_reg_sets_1): Put it here. + +Wed Mar 18 16:43:11 1998 Jim Wilson + + * i960.md (tablejump): Handle flag_pic. + + * profile.c (branch_prob): If see computed goto, call fatal. + + * calls.c (expand_call): Fix typos in n_named_args computation. + +Wed Mar 18 05:54:25 1998 Richard Kenner + + * fold-const.c (operand_equal_for_comparison_p): See if equal + when nop conversions are removed. + + * expr.c (expand_expr, case COND_EXPR): If have conditional move, + don't use ORIGINAL_TARGET unless REG. + + * function.c (fixup_var_refs_insns): Also delete insn storing pseudo + back into arg list. + + * combine.c (gen_binary): Don't make AND that does nothing. + (simplify_comparison, case AND): Commute AND and SUBREG. + * i386.h (CONST_CONSTS, case CONST_INT): One-byte integers are cost 0. + +Mon Mar 16 15:57:17 1998 Geoffrey Keating + + * rs6000.c (small_data_operand): Ensure any address referenced + relative to small data area is inside SDA. + +Sun Mar 15 16:01:19 1998 Andrew Pochinsky + + * sparc.h (ASM_OUTPUT_LOOP_ALIGN): Write nop's. + +Sun Mar 15 15:53:39 1998 Philippe De Muyter + + * libgcc2.c (exit): Don't call __bb_exit_func if HAVE_ATEXIT. + +Sun Mar 15 15:44:41 1998 Paul Eggert + + * cccp.c: Fix bugs relating to NUL in input file name, + e.g. with `#line 2 "x\0y"'. + (PRINTF_PROTO_4): New macro. + (struct {file_buf,definition,if_stack}): New member nominal_fname_len. + (main, expand_to_temp_buffer): Store length of input file names. + (finclude, create_definition, do_line, conditional_skip): Likewise. + (skip_if_group, macroexpand): Likewise. + (make_{definition,undef,assertion}): Likewise. + (special_symbol, do_include): Use stored length of input file names. + (do_define, do_elif, do_else, output_line_directive, verror): Likewise. + (error_from_errno, vwarning, verror_with_line): Likewise. + (vwarning_with_line, pedwarn_with_file_and_line): Likewise. + (print_containing_files): Likewise. + (do_line): Fix off-by-1 problem: 1 too many bytes were being allocated. + (quote_string, pedwarn_with_file_and_line): New arg specifies length. + All callers changed. + +Sun Mar 15 15:38:16 1998 Andreas Schwab + + * c-typeck.c: Collect pending initializers in AVL tree instead of list. + (add_pending_init, pending_init_member): New functions. + (output_init_element): Use them. + (output_pending_init_elements): Rewritten to exploit AVL order. + +Sun Mar 15 05:10:49 1998 Richard Kenner + + * gnu.h (GNU_CPP_PREDEFINES): Deleted; not valid in traditional C. + * {i386,mips}/gnu.h (CPP_PREDEFINES): Don't call GNU_CPP_PREDEFINES. + + * flow.c (insn_dead_p): A CLOBBER of a dead pseudo is dead. + + * alpha.h (REG_ALLOC_ORDER): Put $f1 after other nonsaved. + + * sparc.c (sparc_type_code): Fix error in previous change. + +Sat Mar 14 05:45:21 1998 Richard Kenner + + * i386/xm-aix.h, i386/xm-osf.h (i386/xm-i386.h): Don't include. + (USG): Don't define. + * i386/xm-isc.h (i386/xm-sysv3.h): Don't include. + * i386/xm-sco.h (i386/xm-sysv3.h): Likewise. + (BROKEN_LDEXP, SMALL_ARG_MAX, NO_SYS_SIGLIST): Don't define. + * m68k/xm-3b1.h (m68k/xm-m68k.h): Don't include. + (USG): Don't define. + * m68k/xm-atari.h (m68k/xm-m68kv.h): Don't include. + (HAVE_VPRINTF, FULL_PROTOTYPES): Don't define. + * m68k/xm-crds.h (m68k/xm-m68k.h): Don't include. + (USE_C_ALLOCA, unos, USG): Don't define. + * m68k/xm-mot3300.h (m68k/xm-m68k.h): Don't include. + (USE_C_ALLOCA, NO_SYS_SIGLIST): Don't define. + * m68k/xm-plexus.h (m68k/xm-m68k.h): Don't include. + (USE_C_ALLOCA, USG): Don't define. + * m88k/xm-sysv3.h (m88k/xm-m88k.h): Don't include. + * m68k/xm-next.h (m68k/xm-m68k.h): Don't include. + * ns32k/xm-pc532-min.h (ns32k/xm-ns32k.h): Don't include. + (USG): Don't define. + * rs6000/xm-mach.h: Don't include xm-rs6000.h. + * rs6000/xm-cygwin32.h (rs6000/xm-rs6000.h): Don't include. + (NO_STAB_H): Don't define. + * sparc/xm-linux.h (xm-linux.h): Don't include. + * sparc/xm-sol2.h (sparc/xm-sysv4.h): Don't include. + * a29k/xm-unix.h, alpha/xm-linux.h, arm/xm-linux.h: Deleted. + * arm/xm-netbsd.h, i386/xm-bsd386.h, i386/xm-gnu.h: Deleted. + * i386/xm-linux.h, i386/xm-sun.h, i386/xm-sysv3.h: Deleted. + * i386/xm-winnt.h, m68k/xm-altos3068.h, m68k/xm-amix.h: Deleted. + * m68k/xm-amix.h, m68k/xm-hp320.h, m68k/xm-linux.h: Deleted. + * m68k/xm-m68kv.h, mips/xm-iris5.h, ns32k/xm-genix.h: Deleted. + * sparc/xm-pbd.h, vax/xm-vaxv.h, xm-svr3.h, xm-linux.h: Deleted. + * configure.in: Reflect above changes. + + * xm-siglist.h, xm-alloca.h: New files. + * i386/xm-sysv4.h (i386/xm-i386.h, xm-svr4.h): Don't include. + (USE_C_ALLOCA, SMALL_ARG_MAX): Don't define. + * i386/xm-sco5.h (i386/xm-sysv3.h): Don't include. + (SYS_SIGLIST_DECLARED, USE_C_ALLOCA): Don't define. + * rs6000/xm-sysv4.h, sparc/xm-sysv4.h: Don't include xm-svr4.h. + * xm-svr4.h, i386/xm-dgux.h, mips/xm-news.h, mips/xm-sysv4.h: Deleted. + * configure.in: Reflect above changes. + + * configure.in ({,host_,build_}xm_defines): New variables. + Set to USG instead of including xm-usg.h. + Write #define lines in config.h files from xm_defines vars. + * xm-usg.h: Deleted. + +Fri Mar 13 07:10:59 1998 Richard Kenner + + * calls.c (expand_call): Fix typo in previous change. + + * sparc.c (sparc_type_code): Avoid infinite loop when have + pointer to array of same pointer. + (sparc_type_code, case REAL_TYPE): Process subtypes here too. + + * mips/bsd-4.h, mips/iris3.h, mips/news{4,5}.h: Don't include mips.h. + * mips/news5.h, mips/osfrose.h, mips/svr{3,4}-4.h: Likewise. + * mips/ultrix.h: Likewise. + * mips/cross64.h: Don't include iris6.h. + * mips/ecoff.h: Don't include mips.h or gofast.h. + * mips/elforion.h: Don't include elf64.h. + * mips/iris4.h: Don't include iris3.h. + * mips/iris4loser.h: Don't include iris4.h. + * mips/iris5gas.h: Don't include iris5.h. + * mips/elflorion.h, mips/nws3250v4.h, mips/xm-iris{3,4}.h: Deleted. + * mips/xm-nws3250v4.h, mips/xm-sysv.h: Deleted. + * mips/rtems64.h: Don't include elflorion.h. + * mips/sni-gas.h: Don't include sni-svr4.h. + * mips/svr4-t.h: Don't include svr4-5.h. + * mips/dec-osf1.h: Also include mips.h. + * mips/ecoffl.h, mips/elf.h: Also include mips.h and gofast.h. + * mips/iris5.h: Also include iris3.h and mips.h. + * xm-usg.h: New file. + * mips/xm-iris5.h: Don't include xm-mips.h; don't define USG. + * mips/xm-news.h, mips/xm-sysv4.h: Don't include xm-sysv.h. + * configure.in: Reflect above changes. + +Thu Mar 12 07:18:48 1998 Richard Kenner + + * expr.h (STRICT_ARGUMENT_NAMING): Provide default value of 0. + * calls.c (expand_call): Use value of STRICT_ARGUMENT_NAMING. + * function.c (assign_parm): Likewise. + * mips/abi64.h (STRICT_ARGUMENT_NAMING): Return 0 for ABI_32. + * sparc.h (STRICT_ARGUMENT_NAMING): Only nonzero for V9. + + * calls.c (expand_call, expand_library_call{,_value}, store_one_arg): + Rework handling of REG_PARM_STACK_SPACE to treat return value of + zero as if macro not defined; add new arg to emit_push_insn. + * expr.c (emit_push_insn): New arg, REG_PARM_STACK_SPACE. + * expr.h (emit_push_insn): Likewise. + * mips/abi64.h (REG_PARM_STACK_SPACE): Define. + +Wed Mar 11 06:58:13 1998 Andreas Schwab + + * m68k.h (CONST_OK_FOR_LETTER_P, case 'M'): Correct range check. + +Wed Mar 11 06:15:52 1998 Richard Kenner + + * expr.c (emit_push_insn): Use loop to find movstr patterns + instead of explicit tests. + + * Makefile.in (extraclean): Don't delete install1.texi. + +Tue Mar 10 14:27:51 1998 Richard Kenner + + * combine.c (make_field_assignment): Don't get confused if OTHER + has VOIDmode and don't do anything if DEST is wider than a host word. + + * vax.c (check_float_value): Cast bcopy args to char *. + +Tue Mar 10 13:56:12 1998 Jim Wilson + + * mips/abi64.h (LONG_MAX_SPEC): Check MIPS_ABI_DEFAULT and + TARGET_DEFAULT and define __LONG_MAX__ appropriately. + Add support for -mabi=X, -mlong64, and -mgp{32,64} options. + * mips.c (mips_abi): Change type to int. + * mips.h (enum mips_abi_type): Delete. + (ABI_32, ABI_N32, ABI_64, ABI_EABI): Define as constants. + (mips_abi): Change type to int. + +Mon Mar 2 08:06:58 1998 Richard Kenner + + * Version 2.8.1 released. + + * Makefile.in (mostlyclean): Remove duplicate deletion of temp + files. Delete more stamp files and [df]p-bit.c + (clean): Don't delete stamp files here. + (VERSION_DEP): New variable. + (distdir-finish): Pass a value of null for it. + (version.c): Use it. + Avoid broken pipe with cvs log. + + * objc/Make-lang.in (objc/runtime-info.h): Rename emptyfile to + tmp-runtime and delete at end. + +Sun Mar 1 05:50:25 1998 Richard Kenner + + * tree.c (build_reference_type): Handle obstacks like + build_pointer_type. + + * Makefile.in (tmp-gcc.xtar): Renamed from gcc.xtar. + (gcc.xtar.gz): Deleted; merged with `dist'. + (diff): Create gcc-$(oldversion)-$(version).diff. + (distdir): Depend on distdir-cvs. + (distdir-cvs): New rule. + (distdir-start): Depend on version.c and TAGS. + (TAGS): Use tmp-tags instead of temp. + (dist): Create gcc-$(version).tar.gz. + + * varasm.c (compare_constant_1): Fix typo in previous change. + + * objc/Make-lang.in (objc-distdir): Properly rebuild objc-parse.c. + +Sat Feb 28 16:58:08 1998 Tristan Gingold + + * stmt.c (expand_decl): If -fcheck-memory-usage, put vars in memory. + * expr.c (get_memory_usage_from_modifier): Convert + EXPAND_{CONST_ADDRESS, INITIALIZER} to MEMORY_USE_DONT. + +Sat Feb 28 08:13:43 1998 Richard Kenner + + * i860/fx2800.h (DATA_ALIGNMENT): Use POINTER_TYPE_P. + * m68k/a-ux.h (FUNCTION_VALUE): Likewise. + * expr.c (get_pointer_alignment, compare, do_store_flag): Likewise. + (expand_builtin): Likewise. + * fold-const.c (force_fit_type, fold_convert, fold): Likewise. + * function.c (assign_parms): Likewise. + * integrate.c (expand_inline_function): Likewise. + * sdbout.c (sdbout_field_types): Likewise. + * tree.c (integer_pow2p, tree_log2, valid_machine_attribute): Likewise. + * stmt.c (expand_decl): Likewise. + ({,bc_}expand_decl_init): Also test for REFERENCE_TYPE. + + * configure.in (version_dep): New variable; if srcdir is CVS working + directory, set to ChangeLog. + (version): Supply default if no version.c. + * Makefile.in (version.c): New rule. + + * gcc.c (snapshot_warning): New function. + (main): Call it for snapshots. + + * dwarf2out.c (expand_builtin_dwarf_reg_size): If reg_raw_mode + not valid for reg, use last size. Also refine range assertion. + +Sat Feb 28 05:04:47 1998 Michael P. Hayes + + * enquire.c (cprop): Don't perform exhaustive search for char_min + and char_max when bits_per_byte > 16. + +Thu Feb 26 15:12:03 1998 Christopher Taylor + + * fixincludes: Avoid using '0-~' in egrep. + +Thu Feb 26 08:04:05 1998 Tristan Gingold + + * function.c (assign_parms): Call 'chkr_set_right' when DECL_RTL + is stack_parm. + * expr.c (get_memory_usage_from_modifier): Convert + EXPAND_{SUM, CONST_ADDRESS, INITIALIZER} to MEMORY_USE_RO. + +Thu Feb 26 07:33:53 1998 Paul Eggert + + * c-lex.c (yylex): Don't munge errno before using it. + * cccp.c (error_from_errno, perror_with_name): Likewise. + * cpplib.c (cpp_error_from_errno): Likewise. + * gcc.c (pfatal_pexecute): Likewise. + * protoize.c (safe_write, find_file, process_aux_info_file): Likewise. + (rename_c_file, edit_file): Likewise. + + * c-lex.c (yylex): Remove unused variable exceeds_double. + +Thu Feb 26 07:05:14 1998 Michael P. Hayes + + * reorg.c (fill_slots_from_thread): Don't steal delay list from target + if condition code of jump conflicts with opposite_needed. + +Thu Feb 26 06:45:23 1998 Richard Kenner + + * Makefile.in (distdir-start): Don't copy CVS subdirectory of config. + + * varasm.c ({compare,record}_constant_1, case CONSTRUCTOR): + Handle the case when we have TREE_PURPOSE values. + +Thu Feb 26 05:59:01 1998 Philippe De Muyter + + * fixincludes (sys/limits.h): Fix a nested comment problem with + HUGE_VAL definition on sysV68 R3V7.1. + +Wed Feb 25 21:09:38 1998 Philippe De Muyter + + * toplev.c (TICKS_PER_SECOND): Renamed from CLOCKS_PER_SECOND. + +Wed Feb 25 20:50:08 1998 Michael P. Hayes + + * reorg.c (fill_slots_from_thread): Mark resources referenced in + opposite_needed thread. Return delay_list even when cannot get + any more delay insns from end of subroutine. + +Wed Feb 25 19:50:01 1998 Mikael Pettersson + + * gcc.c (lookup_compiler): Remove redundant test. + +Wed Feb 25 07:24:22 1998 Richard Kenner + + * vax.md (call insns): Second operand to CALL rtl is SImode. + + * configure.in (i[34567]86-*-mingw32): Support msv and crt suffix. + * i386/crtdll.h: New file. + + * sparc.c (pic_setup_code): If -O0, write USE of pic_offset_table_rtx. + + * expr.c (safe_from_p): Add new arg, TOP_P; all callers changed. + +Sat Feb 21 07:02:39 1998 Jim Wilson + + * mips/iris5.h (DWARF2_UNWIND_INFO): Define to 0. + * mips/iris5gas.h (DWARF2_UNWIND_INFO): Define to 1. + +Fri Feb 20 08:27:46 1998 Paul Eggert + + * sparc/sol2-sld.h: New file. + * configure.in (sparc-*-solaris2*): Use it when using system linker. + * toplev.c (main): Don't default to DWARF2_DEBUG with -ggdb + if LINKER_DOES_NOT_WORK_WITH_DWARF2 is defined. + +Fri Feb 20 08:21:49 1998 H.J. Lu (hjl@gnu.org) + + * alpha/elf.h (STARTFILE_SPEC, ENDFILE_SPEC): Support shared library. + (LIB_SPEC, DEFAULT_VTABLE_THUNKS): Defined #ifndef USE_GNULIBC_1. + * sparc/linux.h (DEFAULT_VTABLE_THUNKS): Likewise. + (LIB_SPEC): Add -lc for -shared #ifndef USE_GNULIBC_1. + * linux.h (LIB_SPEC): Likewise. + * sparc/linux64.h (LIB_SPEC): Likewise; also updated for glibc 2. + (LIBGCC_SPEC): Removed. + (CPP_SUBTARGET_SPEC): Add %{pthread:-D_REENTRANT}. + +Fri Feb 20 05:22:12 1998 Richard Kenner + + * Makefile.in (distdir-start): Add dependence on bi-parser.[ch]. + +Thu Feb 19 18:07:11 1998 Jim Wilson + + * m68k.h (TARGET_SWITCHES): For 68000, 68302, subtract MASK_68881. + For 68303, 68332, cpu32, subtract MASK_68040_ONLY. + +Wed Feb 18 09:37:29 1998 Paul Eggert + + * fixincludes (stdlib.h): Do not double-wrap the size_t typedef. + +Wed Feb 18 07:32:11 1998 Jim Wilson + + * i960.c (emit_move_sequence): Handle unaligned stores to pseudos. + * i960.md (store_unaligned_[dt]i_reg): Handle register dest. + (store_unaligned_ti_reg): Likewise. + + * m68k.h (MACHINE_STATE_{SAVE,RESTORE} [MOTOROLA]): Add %# and %/; + add : to make them into extended asms. + +Wed Feb 18 07:08:05 1998 Richard Kenner + + * reg-stack.c (compare_for_stack_reg): Only handle FP conditional + move as next insn specially. + + * reload.c (find_reloads): Always convert address reload for + non-reloaded operand to RELOAD_FOR_OPERAND_ADDRESS. + + * emit-rtl.c (hard-reg-set.h): Include. + (get_lowpart_common): Don't make new REG for hard reg in a + class that cannot change size. + * Makefile.in (emit-rtl.o): Depend on hard-reg-set.h. + +Sat Feb 14 09:59:00 1998 Richard Earnshaw (rearnsha@arm.com) + + * arm.md (movsfcc): Also validate operands[3] for hard float. + (movdfcc): Only accept fpu_add_operand for operands[3].8 + +Sat Feb 14 09:32:34 1998 Jim Wilson + + * dwarf2out.c (expand_builtin_dwarf_reg_size): New variable mode. + Convert CCmode to word_mode before calling GET_MODE_SIZE. + +Sat Feb 14 09:27:42 1998 David Edelsohn + + * rs6000.h (MY_ISCOFF): Check for U803XTOCMAGIC. + +Sat Feb 14 08:29:43 1998 Arvind Sankar + + * t-svr4 (TARGET_LIBGCC_CFLAGS): New definition. + +Sat Feb 14 07:45:16 1998 Ken Rose (rose@acm.org) + + * reorg.c (fill_slots_from_thread): New parameter, delay_list. + All callers changed. + +Sat Feb 14 07:14:02 1998 Richard Kenner + + * reload.c (debug_reload): Properly output insn codes. + + * pa.c (emit_move_sequence): If in reload, call find_replacement. + + * gansidecl.h (bcopy, bzero, {,r}index): Don't define if IN_LIBGCC2. + + * combine.c (distribute_notes, case REG_DEAD): When seeing if place + to put new note sets register, use reg_bitfield_target_p, as in + original code. + + * gcc.c (process_command): If file is for linker, set lang to "*". + (lookup_compiler): Return 0 for language of "*". + + * sched.c (attach_deaths, case SUBREG): Fix error in last change. + + * i386.md (mov[sdx]fcc): Disable for now. + (mov[sd]fcc_1): Add earlyclobber for output on last alternative. + +Sat Feb 14 06:42:50 1998 Jason Merrill + + * except.c (get_dynamic_handler_chain): Only make call once per func. + (expand_fixup_region_{start,end}): New functions. + (expand_eh_region_start_tree): Store cleanup into finalization here. + * stmt.c (expand_cleanups): Use new functions to protect fixups. + + * except.c (get_dynamic_handler_chain): Build up a FUNCTION_DECL. + * optabs.c (init_optabs): Don't init get_dynamic_handler_chain_libfunc. + * expr.h (get_dynamic_handler_chain_libfunc): Deleted. + +Sat Feb 14 06:34:41 1998 Peter Lawrence + + * optabs.c (emit_conditional_move): Don't reverse condition for FP. + +Fri Feb 13 07:22:04 1998 Richard Kenner + + * Makefile.in (mostlyclean): Only use s-* convention for stamp + files in main dir. + + * configure.in: Add support for i786 (Pentium II); same as i686. + +Thu Feb 12 20:16:35 1998 Michael Meissner + + * rs6000.md: Replace gen_rtx (CONST_INT,...) with GEN_INT. + +Thu Feb 12 10:08:14 1998 John Hassey + + * configure.in (i[3456]86-dg-dgux*): Don't need fixincludes. + +Thu Feb 12 07:27:39 1998 Mumit Khan + + * i386/cygwin32.h (NO_IMPLICIT_EXTERN_C): Define. + about system headers. + (LIB_SPEC): Add -ladvapi32 -lshell32. + +Thu Feb 12 07:19:31 1998 Richard Kenner + + * expr.c (expand_assignment): Fix typo in checking OFFSET. + + * gbl-ctors.h (atexit): Don't define unless needed. + + * combine.c (distribute_notes): Completely check for note operand being + only partially set on potential note target; adjust what notes + we make in that case. + + * i386/xm-go32.h (HAVE_{BCOPY,BZERO,INDEX,RINDEX}): Deleted. + +Wed Feb 11 08:53:27 1998 Richard Kenner + + * calls.c (emit_call_1): Size args now HOST_WIDE_INT. + (expand_call): struct_value_size now HOST_WIDE_INT. + +Tue Feb 10 09:04:39 1998 Richard Kenner + + * integrate.c (initialize_for_inline): Ensure DECL_INCOMING_RTL + is always copied. + +Tue Feb 10 06:10:49 1998 Paul Eggert + + * cccp.c (rescan): Fix bug with macro name appearing + immediately after L'x'. + +Mon Feb 9 20:45:32 1998 Andreas Schwab + + * c-common.c (format_char_info): Add new field zlen. + (print_char_table): Remove entry for 'Z' as a format character. + Initialize zlen field as appropriate. + (scan_char_table): Set zlen field to NULL in each entry. + (check_format_info): Recognize 'Z' as a length modifier, with a + warning in pedantic mode. + Avoid infinite loop when a repeated flag character is detected. + +Mon Feb 9 09:24:04 1998 Paul Eggert + + * c-parse.in (primary): Minor wording fix in diagnostic. + +Mon Feb 9 07:50:19 1998 Richard Kenner + + * c-decl.c (grokdeclarator): Remove warning on inline of varargs. + + * reload.c (find_reloads): Check for const_to_mem case before + checking for invalid reload; use force_const_mem if no_input_reloads. + + * function.c (push_function_context_to): Call init_emit last. + + * protoize.c (my_link): Define as -1 in mingw32. + (link): Remove declaration. + + * rs6000.c (setup_incoming_varargs): Always set rs6000_sysv_varargs_p. + + * integrate.c (expand_inline_function): Clear label_map with bzero. + + * unroll.c (copy_loop_body, case JUMP_INSN): Correct error in last + change: call single_set on COPY, not INSN. + +Sun Feb 8 08:07:37 1998 Richard Kenner + + * msdos/top.sed, winnt/config-nt.sed: Change version number to 2.8.1. + + * configure.in (i[3456]86-*-sco3.2v5*): Use cpio for headers. + +Sat Feb 7 07:32:46 1998 Richard Kenner + + * i386/mingw32.h (LIBGCC_SPEC, STARTFILE_SPEC, MATH_LIBRARY): + Use msvcrt, not crtdll. + +Fri Feb 6 20:32:06 1998 Geert Bosch + + * i386/xm-os2.h (EMX, USG, BSTRING, HAVE_{PUTENV,VPRINTF,STRERROR}): + Define ifdef __EMX__. + (strcasecmp): Define to be stricmp if __EMX__. + (spawnv{,p}): Don't define if EMX. + (OBJECT_SUFFIX): Don't define if EMX. + (MKTEMP_EACH_FILE): Define. + +Fri Feb 6 16:37:29 1998 Kaveh R. Ghazi + + * objc/Make-lang.in (objc.stage1): Depend on stage1-start. + (objc.stage2, objc.stage3, objc.stage4): Likewise for the + respective stageN-start targets. + (objc/sendmsg.o): Depend on objc/runtime-info.h. + +Fri Feb 6 16:27:09 1998 Bernd Schmidt + + * stmt.c (expand_asm_operands): Properly treat asm statement + statements with no operands as volatile. + +Fri Feb 6 16:03:25 1998 Greg McGary + + * c-decl.c (pushdecl): Set DECL_ORIGINAL_TYPE once only. + +Fri Feb 6 15:57:36 1998 Mumit Khan + + * i386/cygwin32.h (STRIP_NAME_ENCODING): New macro. + +Fri Feb 6 15:50:42 1998 Paul Eggert + + * libgcc2.c (__floatdi[xtds]f): Round properly even when rounding + large negative integer to plus or minus infinity. + +Fri Feb 6 15:45:16 1998 Philippe De Muyter + + * sdbout.c (plain_type_1): Return T_DOUBLE, not T_VOID, for + long double #ifndef EXTENDED_SDB_BASIC_TYPES. + +Fri Feb 6 15:23:49 1998 John David Anglin + + * vax/ultrix.h (HAVE_ATEXIT): Define. + * x-vax: File deleted. + +Fri Feb 6 14:34:19 1998 Douglas Rupp + + * gcc.c (process_command, case "-dumpversion"): Print spec_version. + +Fri Feb 6 11:01:13 1998 Josh Littlefield + + * i386/gmon-sol2.c (internal_mcount): Do set-up when program starts + and install hook to do clean-up when it exits. + * i386/sol2-c1.asm (_mcount): Make a weak instead of global symbol. + * i386/sol2dbg.h (ASM_SPEC): Support Solaris bundled assembler's -V + argument; pass -s argument to assembler. + +Fri Feb 6 09:13:21 1998 Jim Wilson (wilson@cygnus.com) + + * function.c (assign_parms): New variable named_arg, with value + depending on STRICT_ARGUMENT_NAMING. Use instead of ! last_named. + + * crtstuff.c (__frame_dummy): New function for irix6. + (__do_global_ctors): Call __frame_dummy for irix6. + * mips/iris6.h (LINK_SPEC): Hide __frame_dummy too. + +Fri Feb 6 09:08:21 1998 Mike Stump + + * rtlanal.c (dead_or_set_regno_p): Ignore REG_DEAD notes after reload. + * genattrtab.c (reload_completed): Define. + + * configure.in (i960-wrs-vxworks): Same as i960-wrs-vxworks5*. + +Fri Feb 6 08:47:38 1998 Richard Kenner + + * Makefile.in (diff): Add INSTALL, configure, and config.in; + remove objc-*. + * objc/config-lang.in (diff_excludes): Add objc-parse.[cy]. + + * i386/xm-mingw32.h (link): Delete macro. + + * alpha.c (output_prolog): Write out frame sizes as longs and + print too large sizes as zero. + + * function.c (combine_temp_slots): No need to allocate and free rtx. + Don't do anything if too many slots in the list. + (put_var_into_stack): Don't use ADDRESSOF if not optimizing. + + * function.c (purge_addressof_1): Force into mem if VOLATILE reference. + + * calls.c (expand_call): Show VAR_DECL made for structure return + address is used; remove bogus set of MEM_IN_STRUCT_P. + * expr.c (expand_expr, case SAVE_EXPR, case TARGET_EXPR): Show used. + (expand_builtin, case BUILT_IN_LONGJMP): Show __dummy used. + * function.c (put_reg_into_stack): New arg USED_P; all callers changed. + + * expr.c (expand_expr, case SAVE_EXPR): assign_temp with KEEP of 3. + * function.c (var_temp_slot_level): New variable. + (push_function_context_to, pop_function_context_from): Save/restore + it and target_temp_slot_level. + (assign_stack_temp): Implement KEEP of 3. + (push_temp_slots_for_block): New function. + (init_temp_slots): Initialize var_temp_slot_level. + * function.h (struct function, fields {var,target}_temp_slot_level): + New fields. + * stmt.c (expand_start_bindings): Call push_temp_slots_for_block. + + * function.c (struct temp_slot): SIZE, BASE_OFF_SET, and FULL_SIZE + now HOST_WIDE_INT. + (assign_{,outer_}stack_local, assign_{,stack_}temp): Size arg is + now HOST_WIDE_INT. + (assign_stack_temp): Do size computations in HOST_WIDE_INT. + (fixup_var_refs_1, optimize_bit_field, instantiate_decls): Likewise. + (instantiate_virtual_regs_1, fix_lexical_address): Likewise. + * rtl.h (assign_stack_{local,temp}): Size arg is HOST_WIDE_INT. + (assign_temp): Likewise. + * expr.h (struct args_size): Field CONSTANT is now HOST_WIDE_INT. + + * sched.c (attach_deaths, case REG): Don't check for REG_UNUSED. + (attach_deaths, case SUBREG, STRICT_LOW_PART, {ZERO,SIGN}_EXTRACT): + Don't pass set_p of 1 if partial assignment. + + * tree.h (size_in_bytes): Returns HOST_WIDE_INT. + * tree.c (size_in_bytes): Likewise. + Tighen up logic some to avoid returning a bogus value instead of -1. + + * expr.c (get_inner_reference, case ARRAY_EXPR): Make WITH_RECORD_EXPR + just for index. + (expand_expr, case PLACEHOLDER_EXPR): Refine search again; look + at each expression and look for pointer to type. + + * expr.c (safe_from_p, case ADDR_EXPR): If TREE_STATIC, no trampoline. + (expand_expr, case ADDR_EXPR): Likewise. + + * expr.c (emit_block_move): Use conservative range for movstr mode. + + * configure.in: See if "cp -p" works if "ln -s" doesn't; else "cp". + + * combine.c (try_combine.c): Pass elim_i2 and elim_i1 to + distribute_notes for i3dest_killed REG_DEAD note. + + * configure.in (mips-dec-netbsd*): Remove bogus setting of prefix. + + * c-decl.c (duplicate_decls): Set DECL_IGNORED_P in newdecl if + different bindings levels. + + * configure.in: Test ln -s by symlinking gcc.c. + + * configure.in (i[3456]86-dg-dgux): Add wildcard for version. + + * crtstuff.c (__do_global_ctors_aux): Switch back to text section + in proper place. + + * rtlanal.c (rtx_varies_p, case REG): pic_offset_table_rtx is fixed. + * genattrtab.c (pic_offset_table_rtx): Define (dummy). + * cse.c (set_nonvarying_address_components): Understand PIC refs. + + * loop.c (strength_reduce): When placing increment for auto-inc + case, do comparison in loop order. + + * i860.c (output_delayed_branch): Add missing arg to recog. + (output_delay_insn): Add missing arg to constrain_operands. + + * configure.in: Truncate target after finished comparing it with host. + + * i386.h (MAX_FIXED_MODE_SIZE): Delete. + + * c-parse.in (expr_no_comma): Clarify undefined error. + + * prefix.c (get_key_value): Don't default to PREFIX here. + (translate_name): Remove bogus addition of "$" if getenv fails; + clean up application of default value of PREFIX. + + * fold-const.c (fold_convert): Call force_fit_type even if input + already overflows. + +Fri Feb 6 07:45:01 1998 Robert Hoehne + + * i386/xm-go32.h (HAVE_{BCOPY,BZERO,BCMP,RINDEX,INDEX}): Define. + + * gcc.c (main): Treat paths starting with '$' or DOS drives + as absolute in standard_startfile_prefix. + +Thu Feb 5 21:07:12 1998 John David Anglin + + * cpplib.c (IS_INCLUDE_DIRECTIVE_TYPE): Add casts from enum to int. + * cccp.c (IS_INCLUDE_DIRECTIVE_TYPE, handle_directive): Likewise. + +Thu Feb 5 19:00:44 1998 Richard Kenner + + * expr.c (expand_expr, case CONSTRUCTOR): Correct shift count + when making signed bit field; use EXPAND_NORMAL, not 0. + +Thu Feb 5 17:42:43 1998 Manfred Hollstein + + * libgcc2.c (__clear_insn_cache): On sysV68 enable the memctl + stuff only if MCT_TEXT is #define'd. + +Thu Feb 5 17:32:01 1998 Robert Hoehne + + * Makefile.in: Changed most stamp-* to s-*. + +Tue Feb 3 19:45:50 1998 James Hawtin + + * i386/sol2.h (STARTFILE_SPEC, LIB_SPEC): Update -pg files. + * configure.in (i[3456]86-*-solaris2*): Add gcrt1.o and gmon.o + to extra_parts. + +Tue Feb 3 17:28:48 1998 Christopher C Chimelis + + * configure.in (alpha*-*-linux-gnu*): Add extra_parts for crtstuff. + +Tue Feb 3 17:18:19 1998 Richard Earnshaw + + * arm.c (find_barrier): Fix one-too-many bug if fail to find barrier. + + * arm.c (arm_reload_in_hi): Handle cases where the MEM is too + complex for a simple offset. + +Tue Feb 3 16:14:21 1998 Robert Hoehne + + * i386/xm-go32.h (EXECUTABLE_SUFFIX): Define. + + * configure.in (i[3456]86-pc-msdosdjgpp*): New entry. + +Tue Feb 3 07:33:58 1998 Richard Kenner + + * explow.c (probe_stack_range): Properly check for small + number of probes. + + * gcc.c (process_command, case 'V'): Validate arg. + + * configure.in (sbrk): Add check for needed declaration. + * acconfig.h (NEED_DECLARATION_SBRK): New entry. + * toplev.c (sbrk): Update declaration conditional. + * mips-tfile.c (sbrk, free): Likewise. + + * sparc/sysv4.h (DBX_REGISTER_NUMBER): Remove abort. + + * mips.c (mips_expand_prologue): Pass reg 25 to gen_loadgp. + * mips.md (loadgp): Add second operand for register number to add. + (builtin_setjmp_receiver): Pass new label and reg 31 to loadgp. + + * toplev.c: Include insn-codes.h, insn-config.h, and recog.h. + (compile_file): Try to emit nop to separate gcc_compiled symbol. + * Makefile.in (toplev.o): Depends on insn-{codes,config}.h, recog.h. + +Tue Feb 3 06:58:46 1998 Mark Mitchell + + * integrate.c (get_label_from_map): New function. + (expand_inline_function): Use it. + Initialize label_map to NULL_RTX instead of gen_label_rtx. + (copy_rtx_and_substitute): Use get_label_from_map. + * integrate.h (get_label_from_map): New function. + (set_label_from_map): New macro. + * unroll.c (unroll_loop, copy_loop_body): Use them. + +Mon Feb 2 16:33:01 1998 Richard Kenner + + * i386.md (mov{si,hi,sf,df,xf}cc{,_1}): Remove cases with branches. + + * rs6000/x-aix31 (INSTALL): Deleted. + * mips/x-dec-osf1, mips/x-osfrose, i386/x-osfrose: Likewise. + * arm/x-riscix: Likewise. + + * c-typeck.c (signed_or_unsigned_type): Properly handle pointer types. + +Mon Feb 2 15:33:58 1998 Michael P. Hayes + + * unroll.c (copy_loop_body): Use single_set instead of + PATTERN to detect increment of an iv inside a PARALLEL. + +Fri Jan 16 20:29:50 1998 Paul Eggert + + * toplev.c (): New include. + (get_run_time): Prefer CLK_TCK (if available) to HZ, and + prefer sysconf (_SC_CLK_TCK) (if available) to CLK_TCK. + * configure.in (sysconf): Call AC_CHECK_FUNCS. + +Wed Jan 14 20:10:51 1998 Paul Eggert + + * cccp.c: (rescan): Don't report line 0 as the possible real start + of an unterminated string constant. + Don't mishandle backslash-newlines that in are the output of + a macro expansion. Properly skip // style comments between a function + macro name and '(', as well as backslash-newlines in comments there. + (handle_directive): Handle / \ newline * between # and directive name. + In #include directives, \ does not escape ". + (do_include): For `#include "file', do not bother expanding into temp + buffer. When error encountered when expanding, do not try result. + (skip_if_group): When skipping an include directive, use include + tokenization, not normal tokenization. Backslash-newline is still + special when skipping. Handle * \ newline / correctly in comments + when skipping. + (skip_quoted_string): After \ newline, set *backslash_newlines_p + even if count_newlines is 0. + (macroexpand): Newline space is not a special marker inside a string. + (macroexpand, macarg): Do not generate \ddd for control characters + when stringifying; the C Standard does not allow this. + (macarg1): New arg MACRO. All callers changed. + Do not treat /*, //, or backslash-newline specially when processing + the output of a macro. + (discard_comments): Don't go past limit if looking for end of comment. + Discard backslash-newline properly when discarding comments. + (change_newlines): \" does not end a string. + (make_definition): Do not treat backslash-newline specially, as it + has already been removed before we get here. + + * profile.c (output_func_start_profiler): Don't fflush output + if -quiet. + * toplev.c (rest_of_compilation): Likewise. + + * i386/x-sco5 (CC): Remove trailing white space. + * x-convex (CCLIBFLAGS): Likewise. + * arm/t-semi (LIBGCC2_CFLAGS): Likewise. + +Wed Jan 7 18:02:42 1998 Richard Kenner + + * Version 2.8.0 released. + +Wed Jan 7 17:54:41 1998 J. Kean Johnston + + * i386/sco5.h ({END,START}FILE_SPEC): Link with correct crtbegin.o + and crtend.o when using -static. + +Wed Jan 7 17:49:14 1998 Jan Christiaan van Winkel + + * cppexp.c (gansidecl.h): Include. + +Wed Jan 7 17:45:07 1998 Tristan Gingold + + * expr.c (get_push_address): Use copy_to_reg instead of force_operand. + (emit_push_insn): Avoid null pointer deference if aggregate has no + types. + (expand_expr): Avoid finite but useless recursion. + (expand_builtin): Fix typo in calling function. + * function.c (assign_parms): Avoid useless call to chkr_set_right. + +Wed Jan 7 17:31:13 1998 Christian Iseli + + * combine.c (force_to_mode): Return if operand is a CLOBBER. + +Wed Jan 7 17:23:24 1998 Richard Kenner + + * x-rs6000 (INSTALL): Remove. + + * jump.c (jump_optimize): Don't use a hard reg as an operand + of a conditional move if small register classes. + +Wed Jan 7 17:09:28 1998 Jim Wilson + + * cse.c (max_insn_uid): New variable. + (cse_around_loop): Use it. + (cse_main): Set it. + +See ChangeLog.11 for earlier changes. + +Use a consistent time stamp format in ChangeLog entries. +Not everyone has Emacs 20 yet, so stick with Emacs 19 format for now. + +Local Variables: +add-log-time-format: current-time-string +End: diff --git a/contrib/gcc/LANGUAGES b/contrib/gcc/LANGUAGES index bce134c..c3d4223 100644 --- a/contrib/gcc/LANGUAGES +++ b/contrib/gcc/LANGUAGES @@ -6,6 +6,18 @@ time as we can formally start documenting the interface this file will serve as a repository for information on these interface and any incompatable changes we've made. +Aug 31, 1998: + The interface to HANDLE_PRAGMA has changed. It now takes three arguments. + The first two are pointers to functions that should be used to read characters + from the input stream, and to push them back into the input stream respectively. + The third argument is a pointer to a null terminate string which is the first + word after #pragma. The expression supplied by HANDLE_PRAGMA should return + non-zero if it parsed and implemented the pragma. Otherwise it should return + zero, and leave the input stream as it was before the expression was evaluated. + + A new back-end definable macro has been added: INSERT_ATTRIBUTES. This macro + allows backend to add attributes to decls as they are created. + Jun 10, 1998: The interface to lang_decode_option has changed. It now uses and argc/argv interface to allow for options that use more than one input string. The new diff --git a/contrib/gcc/Makefile.in b/contrib/gcc/Makefile.in index 15a789e..0240f72 100644 --- a/contrib/gcc/Makefile.in +++ b/contrib/gcc/Makefile.in @@ -1,5 +1,5 @@ # Makefile for GNU C compiler. -# Copyright (C) 1987, 88, 90-97, 1998 Free Software Foundation, Inc. +# Copyright (C) 1987, 88, 90-98, 1999 Free Software Foundation, Inc. #This file is part of GNU CC. @@ -39,7 +39,13 @@ SUBDIRS =@subdirs@ # Selection of languages to be made. # This is overridden by configure. -LANGUAGES = c proto gcov$(exeext) @all_languages@ +CONFIG_LANGUAGES = @all_languages@ +LANGUAGES = c proto gcov$(exeext) $(CONFIG_LANGUAGES) + +# Languages should create dependencies of $(INTL_TARGETS) on generated +# sources in Make-lang.in. Example: +# $(INTL_TARGETS): $(srcdir)/cp/parse.c +INTL_TARGETS = intl.all intl.install intl.distdir # Selection of languages to be made during stage1 build. # This is overridden by configure. @@ -53,7 +59,8 @@ ALLOCA_FINISH = true # CFLAGS is for the user to override to, e.g., do a bootstrap with -O2. # BOOT_CFLAGS is the value of CFLAGS to pass # to the stage2 and stage3 compilations -# WARN_CFLAGS are the warning flags to pass to stage2 and stage3. It is +# WARN_CFLAGS are the warning flags to pass to stage2 and stage3. +# (And for stage 1 if the native compiler is GCC.) It is # separate from BOOT_CFLAGS because people tend to override optimization # flags and we'd like them to still have warnings turned on. They are free # to explicitly turn warnings off if they wish. @@ -61,9 +68,10 @@ ALLOCA_FINISH = true # TCFLAGS is used for compilations with the GCC just built. XCFLAGS = TCFLAGS = +# -W -Wall warnings are disabled for releases. CFLAGS = -g BOOT_CFLAGS = -O2 $(CFLAGS) -WARN_CFLAGS = +#WARN_CFLAGS = -W -Wall # These exists to be overridden by the x-* and t-* files, respectively. X_CFLAGS = T_CFLAGS = @@ -71,6 +79,7 @@ T_CFLAGS = X_CPPFLAGS = T_CPPFLAGS = +AWK = @AWK@ CC = @CC@ # srcdir might be a relative pathname which won't be valid in a subdirectory, # so we must use objdir/srcdir instead to make it safe. objdir is always @@ -78,7 +87,7 @@ CC = @CC@ BISON = `if [ -f $(objdir)/../bison/bison ] ; then case $(srcdir) in \ /*) echo $(objdir)/../bison/bison -L $(srcdir)/../bison/ ;; \ *) echo $(objdir)/../bison/bison -L $(objdir)/$(srcdir)/../bison/ ;; \ - esac else echo bison ; fi` + esac; else echo bison ; fi` BISONFLAGS = LEX = `if [ -f $(objdir)/../flex/flex ] ; then echo $(objdir)/../flex/flex ; else echo flex ; fi` LEXFLAGS = @@ -96,7 +105,9 @@ LN_S=@LN_S@ # These permit overriding just for certain files. INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ -MAKEINFO = makeinfo +MAKEINFO = `if [ -f $(objdir)/../texinfo/makeinfo/Makefile ] ; \ + then echo $(objdir)/../texinfo/makeinfo/makeinfo ; \ + else echo makeinfo ; fi` MAKEINFOFLAGS = TEXI2DVI = texi2dvi # For GNUmake: let us decide what gets passed to recursive makes. @@ -111,7 +122,9 @@ P = # How to invoke ranlib. RANLIB = ranlib # Test to use to see whether ranlib exists on the system. -RANLIB_TEST = [ -f /usr/bin/ranlib -o -f /bin/ranlib ] +RANLIB_TEST = \ + [ -f $(RANLIB) ] \ + || [ -f /usr/bin/ranlib -o -f /bin/ranlib ] # Compiler to use for compiling libgcc1.a. # OLDCC should not be the GNU C compiler, @@ -144,7 +157,7 @@ USER_H = $(srcdir)/ginclude/stdarg.h $(srcdir)/ginclude/stddef.h \ $(srcdir)/ginclude/va-m32r.h $(srcdir)/ginclude/va-sh.h \ $(srcdir)/ginclude/va-v850.h $(srcdir)/ginclude/va-arc.h \ $(srcdir)/ginclude/iso646.h $(srcdir)/ginclude/va-ppc.h \ - $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) \ + $(srcdir)/ginclude/va-c4x.h $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) \ $(srcdir)/ginclude/proto.h $(srcdir)/ginclude/stdbool.h # Target to use whe installing assert.h. Some systems may @@ -154,7 +167,7 @@ INSTALL_ASSERT_H = install-assert-h # The GCC to use for compiling libgcc2.a, enquire, and libgcc1-test. # Usually the one we just built. # Don't use this as a dependency--use $(GCC_PASSES) or $(GCC_PARTS). -GCC_FOR_TARGET = ./xgcc -B./ +GCC_FOR_TARGET = ./xgcc -B$(build_tooldir)/bin/ -B./ -I$(build_tooldir)/include # This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. # It omits XCFLAGS, and specifies -B./. @@ -187,7 +200,7 @@ AR_FOR_TARGET = ` \ t='$(program_transform_name)'; echo ar | sed -e $$t ; \ fi; \ fi` -AR_FOR_TARGET_FLAGS = rc +AR_FLAGS_FOR_TARGET = rc RANLIB_FOR_TARGET = ` \ if [ -f $(objdir)/../binutils/ranlib ] ; then \ echo $(objdir)/../binutils/ranlib ; \ @@ -203,18 +216,6 @@ RANLIB_TEST_FOR_TARGET = \ || ( [ "$(host_canonical)" = "$(target)" ] \ && [ -f /usr/bin/ranlib -o -f /bin/ranlib ] ) -# We always act like a cross-compiler, even when we're -# compiling native. This is because we want to use our own tools if -# we can. We don't just set RANLIB to a complicated expression, -# because the top level Makefile.in might override RANLIB_FOR_TARGET. -# These are from the FSF file "cross-make". -AR = $(AR_FOR_TARGET) -AR_FLAGS = $(AR_FOR_TARGET_FLAGS) -OLDAR = $(AR_FOR_TARGET) -OLDAR_FLAGS = $(AR_FOR_TARGET_FLAGS) -RANLIB = $(RANLIB_FOR_TARGET) -RANLIB_TEST = $(RANLIB_TEST_FOR_TARGET) - # Dir to search for system headers. Overridden by cross-make. SYSTEM_HEADER_DIR = /usr/include @@ -243,7 +244,10 @@ build_xm_file=@build_xm_file_list@ host_xm_file=@host_xm_file_list@ lang_specs_files=@lang_specs_files@ lang_options_files=@lang_options_files@ +lang_tree_files=@lang_tree_files@ GCC_THREAD_FILE=@thread_file@ +OBJC_BOEHM_GC=@objc_boehm_gc@ +JAVAGC=@JAVAGC@ GTHREAD_FLAGS=@gthread_flags@ # Be prepared for gcc2 merges. gcc_version=@gcc_version@ @@ -267,21 +271,28 @@ bindir = @bindir@ libdir = @libdir@ # Directory in which the compiler finds executables, libraries, etc. libsubdir = $(libdir)/gcc-lib/$(target_alias)/$(version) +# Used to produce a relative $(gcc_tooldir) in gcc.o +unlibsubdir = ../../.. +# Directory in which to find other cross-compilation tools and headers. +dollar = @dollar@ +# Used in install-cross. +gcc_tooldir = @gcc_tooldir@ +# Since tooldir does not exist at build-time, use -B$(build_tooldir)/bin/ +build_tooldir = $(exec_prefix)/$(target_alias) # Directory in which the compiler finds g++ includes. -gxx_include_dir= @gxx_include_dir@ -# Directory in which the old g++ header files may be found. -# The reason we use $(libdir)/g++-include rather than using libsubdir -# is for compatibility with older versions of libg++. -old_gxx_include_dir= $(libdir)/g++-include +gcc_gxx_include_dir= @gcc_gxx_include_dir@ # Directory to search for site-specific includes. includedir = $(local_prefix)/include # assertdir is overridden in cross-make. # (But this currently agrees with what is in cross-make.) -assertdir = $(tooldir)/include +assertdir = $(gcc_tooldir)/include # where the info files go infodir = @infodir@ # Where cpp should go besides $prefix/bin if necessary cpp_install_dir = @cpp_install_dir@ +# where the locale files go +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale # Extension (if any) to put in installed man-page filename. manext = .1 objext = .o @@ -289,13 +300,24 @@ exeext = @host_exeext@ build_exeext = @build_exeext@ # Directory in which to put man pages. -mandir = @mandir@/man1 -# Directory in which to find other cross-compilation tools and headers. -# Used in install-cross. -tooldir = $(exec_prefix)/$(target_alias) +mandir = @mandir@ +man1dir = $(mandir)/man1 # 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@ + +# List of internationalization subdirectories. +POSUB = @POSUB@ +INTL_SUBDIRS = intl $(POSUB) + # Additional system libraries to link with. CLIB= @@ -372,6 +394,9 @@ EXTRA_HEADERS =@extra_headers_list@ # Set this to `collect2' to enable use of collect2. USE_COLLECT2 = @will_use_collect2@ +# If we might be using collect2, then this variable will be set to +# -DUSE_COLLECT2. toplev.c, collect2.c and libgcc2.c all need to +# if we may be using collect2. MAYBE_USE_COLLECT2 = @maybe_use_collect2@ # It is convenient for configure to add the assignment at the beginning, # so don't override it here. @@ -389,13 +414,9 @@ LIB2FUNCS_EXTRA = INSTALL_CPP= UNINSTALL_CPP= -# Default float.h source to use for cross-compiler. -# This is overridden by configure. -CROSS_FLOAT_H=$(srcdir)/config/float-@float_format@.h - # We do not try to build float.h anymore. Let configure select the # appropriate pre-built float.h file for the target. -FLOAT_H=$(srcdir)/config/float-@float_format@.h +FLOAT_H=@float_h_file@ # Program to convert libraries. LIBCONVERT = @@ -406,10 +427,6 @@ INSTALL_HEADERS=install-headers # Options for tar when copying trees. So HPUX can override it. TAROUTOPTS = xpBf -# Select which version of fixincludes to use (I.E. regular versus SVR4) -# This value is overridden directly by configure. -FIXINCLUDES = @fixincludes@ - # Additional directories of header files to run fixincludes on. # These should be directories searched automatically by default # just as /usr/include is. @@ -449,6 +466,7 @@ HOST_PREFIX_1=loser- HOST_CC=$(CC) HOST_CFLAGS=$(ALL_CFLAGS) HOST_CLIB=$(CLIB) +HOST_INTLLIBS=$(INTLLIBS) HOST_LDFLAGS=$(LDFLAGS) HOST_CPPFLAGS=$(ALL_CPPFLAGS) HOST_ALLOCA=$(ALLOCA) @@ -459,8 +477,10 @@ HOST_DOPRINT=$(DOPRINT) # Actual name to use when installing a native compiler. GCC_INSTALL_NAME = `t='$(program_transform_name)'; echo gcc | sed -e $$t` +CPP_INSTALL_NAME = `t='$(program_transform_name)'; echo cpp | sed -e $$t` PROTOIZE_INSTALL_NAME = `t='$(program_transform_name)'; echo protoize | sed -e $$t` UNPROTOIZE_INSTALL_NAME = `t='$(program_transform_name)'; echo unprotoize | sed -e $$t` +GCOV_INSTALL_NAME = `t='$(program_transform_name)'; echo gcov | sed -e $$t` # Actual name to use when installing a cross-compiler. GCC_CROSS_NAME = `t='$(program_transform_cross_name)'; echo gcc | sed -e $$t` @@ -524,13 +544,14 @@ all: all.indirect all.indirect: $(ALL) -# IN_GCC tells obstack.h that we are using gcc's file. -# ??? IN_GCC should be obsolete now. -INTERNAL_CFLAGS = $(CROSS) -DIN_GCC @extra_c_flags@ +# IN_GCC tells various files that system.h, toplev.c, etc are available. +INTERNAL_CFLAGS = $(CROSS) -DIN_GCC $(SCHED_CFLAGS) @extra_c_flags@ # 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. ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) \ - @DEFS@ $(SCHED_CFLAGS) + @DEFS@ # Likewise. ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) @@ -546,21 +567,22 @@ USE_HOST_DOPRINT= ` case "${HOST_DOPRINT}" in ?*) echo ${HOST_PREFIX}${HOST_DOPR # Dependency on obstack, alloca, malloc or whatever library facilities # are not installed in the system libraries. # We don't use USE_ALLOCA because backquote expansion doesn't work in deps. -LIBDEPS= $(OBSTACK) $(ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT) +LIBDEPS= $(INTLLIBS) $(OBSTACK) $(ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT) # Likewise, for use in the tools that must run on this machine # even if we are cross-building GCC. # We don't use USE_ALLOCA because backquote expansion doesn't work in deps. -HOST_LIBDEPS= $(HOST_PREFIX)$(HOST_OBSTACK) $(HOST_PREFIX)$(HOST_ALLOCA) $(HOST_PREFIX)$(HOST_MALLOC) $(HOST_PREFIX)$(HOST_VFPRINTF) $(HOST_PREFIX)$(HOST_DOPRINT) +HOST_LIBDEPS= $(HOST_PREFIX)$(HOST_INTLLIBS) $(HOST_PREFIX)$(HOST_OBSTACK) $(HOST_PREFIX)$(HOST_ALLOCA) $(HOST_PREFIX)$(HOST_MALLOC) $(HOST_PREFIX)$(HOST_VFPRINTF) $(HOST_PREFIX)$(HOST_DOPRINT) # How to link with both our special library facilities # and the system's installed libraries. -LIBS = $(OBSTACK) $(USE_ALLOCA) $(MALLOC) $(VFPRINTF) $(DOPRINT) $(CLIB) +LIBS = $(OBSTACK) $(USE_ALLOCA) $(MALLOC) $(INTLLIBS) @LIBS@ $(VFPRINTF) $(DOPRINT) $(CLIB) ../libiberty/libiberty.a # Likewise, for use in the tools that must run on this machine # even if we are cross-building GCC. HOST_LIBS = $(USE_HOST_OBSTACK) $(USE_HOST_ALLOCA) $(USE_HOST_MALLOC) \ - $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) $(HOST_CLIB) + $(HOST_INTLLIBS) $(USE_HOST_VFPRINTF) $(USE_HOST_DOPRINT) \ + $(HOST_CLIB) HOST_RTL = $(HOST_PREFIX)rtl.o $(HOST_PREFIX)bitmap.o HOST_RTLANAL = $(HOST_PREFIX)rtlanal.o @@ -570,7 +592,7 @@ HOST_PRINT = $(HOST_PREFIX)print-rtl.o # Both . and srcdir are used, in that order, # so that tm.h and config.h will be found in the compilation # subdirectory rather than in the source directory. -INCLUDES = -I. -I$(srcdir) -I$(srcdir)/config +INCLUDES = -I. -I$(srcdir) -I$(srcdir)/config -I$(srcdir)/../include # Always use -I$(srcdir)/config when compiling. .c.o: @@ -595,12 +617,11 @@ LANG_EXTRA_HEADERS = @all_headers@ # because we need CC="stage1/xgcc -Bstage1/" to work in the language # subdirectories. # ??? The choices here will need some experimenting with. -FLAGS_TO_PASS = \ - "AR_FLAGS=$(AR_FOR_TARGET_FLAGS)" \ +ORDINARY_FLAGS_TO_PASS = \ + "AR_FLAGS_FOR_TARGET=$(AR_FLAGS_FOR_TARGET)" \ "AR_FOR_TARGET=$(AR_FOR_TARGET)" \ "BISON=$(BISON)" \ "BISONFLAGS=$(BISONFLAGS)" \ - "CC=@cc_set_by_configure@" \ "CFLAGS=$(CFLAGS)" \ "CLIB=$(CLIB)" \ "GCC_FOR_TARGET=$(GCC_FOR_TARGET)" \ @@ -621,10 +642,23 @@ FLAGS_TO_PASS = \ "exec_prefix=$(exec_prefix)" \ "prefix=$(prefix)" \ "local_prefix=$(local_prefix)" \ - "gxx_include_dir=$(gxx_include_dir)" \ + "gxx_include_dir=$(gcc_gxx_include_dir)" \ "tooldir=$(tooldir)" \ + "gcc_tooldir=$(gcc_tooldir)" \ "bindir=$(bindir)" \ - "libsubdir=$(libsubdir)" + "libsubdir=$(libsubdir)" \ + "datadir=$(datadir)" \ + "distdir=../tmp/\$$(subdir)" \ + "localedir=$(localedir)" +FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) "CC=@cc_set_by_configure@" +PREPEND_DOTDOT_TO_RELATIVE_PATHS = sed \ + -e 's|^ *[^ /][^ /]*/|%&|' \ + -e 's| -B| -B%|g' \ + -e 's|% *[^- /]|%&|g' \ + -e 's|%% *|../|g' \ + -e 's|%||g' +SUBDIR_FLAGS_TO_PASS = $(ORDINARY_FLAGS_TO_PASS) \ + "CC=`echo @quoted_cc_set_by_configure@ | $(PREPEND_DOTDOT_TO_RELATIVE_PATHS)`" # # Lists of files for various purposes. @@ -641,14 +675,14 @@ SCHED_CFLAGS = @sched_cflags@ # Language-independent object files. OBJS = toplev.o version.o tree.o print-tree.o stor-layout.o fold-const.o \ function.o stmt.o except.o expr.o calls.o expmed.o explow.o optabs.o \ - varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o regmove.o \ - dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o \ + intl.o varasm.o rtl.o print-rtl.o rtlanal.o emit-rtl.o genrtl.o real.o \ + dbxout.o sdbout.o dwarfout.o dwarf2out.o xcoffout.o bitmap.o alias.o gcse.o \ integrate.o jump.o cse.o loop.o unroll.o flow.o stupid.o combine.o varray.o \ - regclass.o local-alloc.o global.o reload.o reload1.o caller-save.o gcse.o \ + regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \ insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \ - insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \ + insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o lcm.o \ profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \ - dyn-string.o + mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o # GEN files are listed separately, so they can be built before doing parallel # makes for cc1 or cc1plus. Otherwise sequent parallel make attempts to load @@ -661,7 +695,7 @@ CCCP=@cpp_main@ # Files to be copied away after each stage in building. 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 genrtl.c genrtl.h tree-check.h \ + insn-attr.h insn-attrtab.c insn-opinit.c tree-check.h \ s-flags s-config s-codes s-mlib s-under\ s-output s-recog s-emit s-extract s-peep s-check \ s-attr s-attrtab s-opinit s-crt s-crtS s-crt0 \ @@ -670,15 +704,15 @@ 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) \ - xgcc$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \ + xgcc$(exeext) xcpp$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \ $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \ $(CCCP)$(exeext) cc1obj$(exeext) enquire$(exeext) \ protoize$(exeext) unprotoize$(exeext) \ specs collect2$(exeext) $(USE_COLLECT2) underscore.c \ gcov$(exeext) *.bp \ *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \ - *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse \ - *.[si] \ + *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.gcse *.flow2 \ + *.[si] libcpp.a \ $(LANG_STAGESTUFF) # Members of libgcc1.a. @@ -721,14 +755,14 @@ DPBIT_FUNCS = _pack_df _unpack_df _addsub_df _mul_df _div_df \ # If it is, rm *.o is an easy way to do it. # CONFIG_H = $(host_xm_file) $(tm_file) CONFIG_H = -RTL_BASE_H = rtl.h rtl.def gansidecl.h machmode.h machmode.def +RTL_BASE_H = rtl.h rtl.def machmode.h machmode.def RTL_H = $(RTL_BASE_H) genrtl.h -TREE_H = tree.h real.h tree.def gansidecl.h machmode.h machmode.def tree-check.h -BASIC_BLOCK_H = basic-block.h bitmap.h -DEMANGLE_H = demangle.h gansidecl.h -RECOG_H = recog.h gansidecl.h +TREE_H = tree.h real.h tree.def machmode.h machmode.def tree-check.h +BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h +DEMANGLE_H = $(srcdir)/../include/demangle.h +RECOG_H = recog.h EXPR_H = expr.h insn-codes.h -REGS_H = regs.h varray.h machmode.h machmode.def gansidecl.h +REGS_H = regs.h varray.h machmode.h machmode.def # # Language makefile fragments. @@ -764,7 +798,7 @@ Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \ $(SHELL) $(srcdir)/configure.frag $(srcdir) "$(SUBDIRS)" \ "$(xmake_file)" "$(tmake_file)" cp config.status config.run - $(SHELL) config.run + LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.run rm -f config.run $(srcdir)/configure: $(srcdir)/configure.in @@ -786,7 +820,7 @@ $(srcdir)/cstamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h 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 $(SHELL) config.status + CONFIG_HEADERS=auto-host.h:config.in 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 @@ -796,24 +830,25 @@ config.status: configure version.c echo You must configure gcc. Look at the INSTALL file for details.; \ false; \ else \ - $(SHELL) config.status --recheck; \ + LANGUAGES="$(CONFIG_LANGUAGES)" $(SHELL) config.status --recheck; \ fi -all.internal: start.encap rest.encap +all.internal: start.encap rest.encap doc # This is what to compile if making a cross-compiler. # Note that we can compile enquire using the cross-compiler just built, # although we can't run it on this machine. all.cross: native gcc-cross specs stmp-headers $(STMP_FIXPROTO) $(LIBGCC) \ - $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross + $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross doc # This is what to compile if making gcc with a cross-compiler. -all.build: native xgcc$(exeext) $(EXTRA_PARTS) lang.all.build +all.build: native xgcc$(exeext) xcpp$(exeext) $(EXTRA_PARTS) lang.all.build # This is what must be made before installing GCC and converting libraries. -start.encap: native xgcc$(exeext) specs $(LIBGCC1) xlimits.h lang.start.encap +start.encap: native xgcc$(exeext) xcpp$(exeext) specs $(LIBGCC1) \ + xlimits.h lang.start.encap # These can't be made until after GCC can run. rest.encap: stmp-headers $(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 cpp$(exeext) $(LANGUAGES) \ +native: config.status auto-host.h cpp$(exeext) intl.all $(LANGUAGES) \ $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2) # Define the names for selecting languages in LANGUAGES. @@ -825,7 +860,7 @@ PROTO: proto # On the target machine, finish building a cross compiler. # This does the things that can't be done on the host machine. -rest.cross: $(LIBGCC) gfloat.h specs +rest.cross: $(LIBGCC) specs # Verify that it works to compile and link libgcc1-test. # If it does, then there are sufficient replacements for libgcc1.a. @@ -848,10 +883,20 @@ stamp-objlist: $(OBJS) # We call this executable `xgcc' rather than `gcc' # to avoid confusion if the current directory is in the path # and CC is `gcc'. It is renamed to `gcc' when it is installed. -xgcc$(exeext): gcc.o version.o choose-temp.o pexecute.o prefix.o version.o \ - mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o prefix.o version.o \ - choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS) +xgcc$(exeext): gcc.o gccspec.o version.o intl.o prefix.o \ + version.o $(LIBDEPS) $(EXTRA_GCC_OBJS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o gccspec.o intl.o \ + prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS) + +# We call this executable `xcpp' rather than `cpp' +# since the real preprocessor is named `cpp'. It too is renamed +# when it is installed. +# The only difference from xgcc is that it's linked with cppspec.o +# instead of gccspec.o. +xcpp$(exeext): gcc.o cppspec.o version.o intl.o prefix.o \ + version.o $(LIBDEPS) $(EXTRA_GCC_OBJS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ gcc.o cppspec.o intl.o \ + prefix.o version.o $(EXTRA_GCC_OBJS) $(LIBS) # Dump a specs file to make -B./ read these specs over installed ones. specs: xgcc$(exeext) @@ -864,13 +909,8 @@ specs: xgcc$(exeext) gcc-cross: xgcc$(exeext) cp xgcc$(exeext) gcc-cross$(exeext) -cc1$(exeext): $(P) $(C_OBJS) $(OBJS) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) $(OBJS) $(LIBS) - -# Copy float.h from its source. -gfloat.h: $(FLOAT_H) - -rm -f gfloat.h - cp $(FLOAT_H) gfloat.h +cc1$(exeext): $(P) $(OBJS) $(C_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(C_OBJS) $(LIBS) # Build the version of limits.h that we will install. xlimits.h: glimits.h limitx.h limity.h @@ -897,7 +937,7 @@ libgcc1.conv: libgcc1.a libgcc1.null: $(GCC_PASSES) echo "void __foo () {}" > dummy.c $(GCC_FOR_TARGET) $(GCC_CFLAGS) -c dummy.c - $(OLDAR) $(OLDAR_FLAGS) libgcc1.null dummy$(objext) + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) libgcc1.null dummy$(objext) rm -f dummy$(objext) dummy.c # This is $(LIBGCC1) for a cross-compiler. @@ -957,7 +997,9 @@ libgcc1.a: libgcc1.c $(CONFIG_H) $(LIB1FUNCS_EXTRA) config.status else true; \ fi; \ done - -if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc1.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) tmplibgcc1.a; \ + else true; fi mv tmplibgcc1.a libgcc1.a # Build libgcc1.a from assembler source. LIB1ASMFUNCS is the list of @@ -980,7 +1022,7 @@ libgcc1-asm.a: libgcc2.ready config.status $(srcdir)/config/$(LIB1ASMSRC) $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} libgcc1.S; \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ mv libgcc1$(objext) $${name}$(objext); \ - $(AR) $(AR_FLAGS) tmplibgcc1.a $${name}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc1.a $${name}$(objext); \ rm -f $${name}$(objext); \ done -rm -f libgcc1.S @@ -1015,7 +1057,7 @@ libgcc2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs $(STMP_FIXPROTO) LIB2ADD = $(srcdir)/frame.c $(LIB2FUNCS_EXTRA) $(LANG_LIB2FUNCS) libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ - machmode.h longlong.h frame.h gansidecl.h gbl-ctors.h config.status + machmode.h longlong.h frame.h gbl-ctors.h config.status # Actually build it in tmplibgcc2.a, then rename at end, # so that libgcc2.a itself remains nonexistent if compilation is aborted. -rm -f tmplibgcc2.a @@ -1029,9 +1071,9 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ do \ echo $${name}; \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \ - $(srcdir)/libgcc2.c -o $${name}$(objext); \ + $(MAYBE_USE_COLLECT2) $(srcdir)/libgcc2.c -o $${name}$(objext); \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \ rm -f $${name}$(objext); \ done for name in $(LIB2FUNCS_EH); \ @@ -1040,7 +1082,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -fexceptions $(INCLUDES) -c \ -DL$${name} $(srcdir)/libgcc2.c -o $${name}$(objext); \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \ rm -f $${name}$(objext); \ done if [ x$(FPBIT) != x ]; then \ @@ -1050,7 +1092,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \ -DFINE_GRAINED_LIBRARIES $(FPBIT) -o $${name}$(objext); \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \ rm -f $${name}$(objext); \ done; \ else true; fi; @@ -1061,7 +1103,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \ -DFINE_GRAINED_LIBRARIES $(DPBIT) -o $${name}$(objext); \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${name}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \ rm -f $${name}$(objext); \ done; \ else true; fi; @@ -1077,13 +1119,14 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ if [ $${name}.txt = $${file} ]; then \ for f in .. `cat $${file}`; do if [ x$${f} != x.. ]; then \ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ - AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" CC="$(CC)" \ CFLAGS="$(CFLAGS)" HOST_PREFIX="$(HOST_PREFIX)" \ HOST_PREFIX_1="$(HOST_PREFIX_1)" \ LANGUAGES="$(LANGUAGES)" \ LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $${f}; \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${f}; \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${f}; \ rm -f $${f}; \ else true; \ fi; done; \ @@ -1094,7 +1137,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ else true; fi; \ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c $${file}; \ if [ $$? -eq 0 ] ; then true; else exit 1; fi; \ - $(AR) $(AR_FLAGS) tmplibgcc2.a $${oname}$(objext); \ + $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${oname}$(objext); \ rm -f $${name}.s $${oname}$(objext); \ fi; \ done @@ -1102,7 +1145,9 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ # These lines were deleted from above the mv command # because ranlibing libgcc.a itself should suffice. # -if [ x${HPUX_GAS} = x ] ; then \ -# if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc2.a; else true; fi; \ +# if $(RANLIB_TEST_FOR_TARGET) ; then \ +# $(RANLIB_FOR_TARGET) tmplibgcc2.a; +# else true; fi; \ # else true; fi # Combine the various libraries into a single library, libgcc.a. @@ -1110,7 +1155,7 @@ libgcc.a: $(LIBGCC1) $(LIBGCC2) -rm -rf tmplibgcc.a libgcc.a tmpcopy mkdir tmpcopy -if [ x$(LIBGCC1) != x ]; \ - then (cd tmpcopy; $(AR) x ../$(LIBGCC1)); \ + then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \ else true; \ fi # Some versions of ar (specifically the one in RISC/os 5.x), create an @@ -1118,10 +1163,12 @@ libgcc.a: $(LIBGCC1) $(LIBGCC2) # the second ar command tries to overwrite this file. To avoid the error # message from ar, we make sure all files are writable. -(cd tmpcopy; chmod +w * > /dev/null 2>&1) - (cd tmpcopy; $(AR) x ../$(LIBGCC2)) - (cd tmpcopy; $(AR) $(AR_FLAGS) ../tmplibgcc.a *$(objext)) + (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2)) + (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext)) rm -rf tmpcopy - -if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) tmplibgcc.a; \ + else true; fi # Actually build it in tmplibgcc.a, then rename at end, # so that libgcc.a itself remains nonexistent if compilation is aborted. mv tmplibgcc.a libgcc.a @@ -1142,14 +1189,17 @@ s-mlib: $(srcdir)/genmultilib Makefile # Build multiple copies of libgcc.a, one for each target switch. stmp-multilib: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \ - frame.h gansidecl.h \ + frame.h \ $(LIB2ADD) machmode.h longlong.h gbl-ctors.h config.status for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \ dir=`echo $$i | sed -e 's/;.*$$//'`; \ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ - AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \ - RANLIB="$(RANLIB)" RANLIB_TEST="$(RANLIB_TEST)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \ + CC="$(CC)" CFLAGS="$(CFLAGS)" \ + RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \ + RANLIB_TEST_FOR_TARGET="$(RANLIB_TEST_FOR_TARGET)" \ LANGUAGES="$(LANGUAGES)" \ HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \ LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS) $${flags}" \ @@ -1169,7 +1219,9 @@ stmp-multilib-sub: else true; \ fi $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ - AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \ + CC="$(CC)" CFLAGS="$(CFLAGS)" \ HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \ LANGUAGES="$(LANGUAGES)" \ LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $(LIBGCC2) @@ -1181,7 +1233,9 @@ stmp-multilib-sub: then true; \ else \ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ - AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \ + CC="$(CC)" CFLAGS="$(CFLAGS)" \ HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \ LANGUAGES="$(LANGUAGES)" \ LIBGCC2_CFLAGS="$(LIBGCC2_CFLAGS)" $(LIBGCC1); \ @@ -1189,18 +1243,27 @@ stmp-multilib-sub: rm -rf tmplibgcc.a tmpcopy mkdir tmpcopy if [ x$(LIBGCC1) != x ]; \ - then (cd tmpcopy; $(AR) x ../$(LIBGCC1)); \ + then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \ else true; \ fi - (cd tmpcopy; $(AR) x ../$(LIBGCC2)) - (cd tmpcopy; $(AR) $(AR_FLAGS) ../tmplibgcc.a *$(objext)) +# Some versions of ar (specifically the one in RISC/os 5.x), create an +# unwritable table of contents file, and then print an error message when +# the second ar command tries to overwrite this file. To avoid the error +# message from ar, we make sure all files are writable. + -(cd tmpcopy; chmod +w * > /dev/null 2>&1) + (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2)) + (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext)) rm -rf libgcc2.a tmpcopy - if $(RANLIB_TEST) ; then $(RANLIB) tmplibgcc.a; else true; fi + if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) tmplibgcc.a; \ + else true; fi if [ -d $(dir) ]; then true; else mkdir $(dir); fi mv tmplibgcc.a $(dir)/libgcc.a for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \ $(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \ - AR="$(AR)" AR_FLAGS="$(AR_FLAGS)" CC="$(CC)" CFLAGS="$(CFLAGS)" \ + AR_FOR_TARGET="$(AR_FOR_TARGET)" \ + AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \ + CC="$(CC)" CFLAGS="$(CFLAGS)" \ HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \ LANGUAGES="$(LANGUAGES)" \ MULTILIB_CFLAGS="$(MULTILIB_CFLAGS)" T="t" t$${f}; \ @@ -1261,7 +1324,7 @@ c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) c-lex.h \ $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/c-parse.c $(srcdir)/c-parse.h: $(srcdir)/c-parse.c $(srcdir)/c-parse.c: $(srcdir)/c-parse.y - cd $(srcdir); $(BISON) $(BISONFLAGS) -d c-parse.y -o c-parse.c + cd $(srcdir); $(BISON) $(BISONFLAGS) -d -o c-parse.c c-parse.y $(srcdir)/c-parse.y: c-parse.in echo '/*WARNING: This file is automatically generated!*/' >tmp-c-parse.y sed -e "/^ifobjc$$/,/^end ifobjc$$/d" \ @@ -1270,42 +1333,56 @@ $(srcdir)/c-parse.y: c-parse.in $(srcdir)/move-if-change tmp-c-parse.y $(srcdir)/c-parse.y $(srcdir)/c-gperf.h: c-parse.gperf - gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$$ \ - $(srcdir)/c-parse.gperf >tmp-gperf.h + gperf -L C -F ', 0, 0' -p -j1 -i 1 -g -o -t -G -N is_reserved_word \ + -k1,3,$$ $(srcdir)/c-parse.gperf >tmp-gperf.h $(srcdir)/move-if-change tmp-gperf.h $(srcdir)/c-gperf.h c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h flags.h \ output.h toplev.h c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h flags.h \ - output.h $(EXPR_H) $(RTL_H) toplev.h + intl.h output.h $(EXPR_H) $(RTL_H) toplev.h c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h toplev.h \ output.h c-lex.o : c-lex.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-lex.h c-tree.h \ - $(srcdir)/c-parse.h input.h flags.h $(srcdir)/c-gperf.h c-pragma.h \ - toplev.h output.h -c-aux-info.o : c-aux-info.c $(CONFIG_H) system.h $(TREE_H) c-tree.h flags.h + $(srcdir)/c-parse.h input.h intl.h flags.h $(srcdir)/c-gperf.h c-pragma.h \ + toplev.h output.h mbchar.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-pragma.o: c-pragma.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) except.h \ function.h defaults.h c-pragma.h toplev.h c-iterate.o: c-iterate.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \ flags.h toplev.h $(EXPR_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) \ + hard-reg-set.h $(BASIC_BLOCK_H) +sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H) -collect2$(exeext): collect2.o tlink.o hash.o cplus-dem.o underscore.o \ - version.o choose-temp.o mkstemp.o $(LIBDEPS) +COLLECT2_OBJS = collect2.o tlink.o hash.o intl.o underscore.o version.o +collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) # Don't try modifying collect2 (aka ld) in place--it might be linking this. -rm -f collect2$(exeext) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ collect2.o tlink.o hash.o \ - cplus-dem.o underscore.o version.o choose-temp.o mkstemp.o $(LIBS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(COLLECT2_OBJS) $(LIBS) -collect2.o : collect2.c $(CONFIG_H) system.h gansidecl.h gstab.h obstack.h \ - $(DEMANGLE_H) +collect2.o : collect2.c $(CONFIG_H) system.h gstab.h intl.h \ + $(srcdir)/../include/obstack.h $(DEMANGLE_H) collect2.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DTARGET_MACHINE=\"$(target_alias)\" $(MAYBE_USE_COLLECT2) \ -c `echo $(srcdir)/collect2.c | sed 's,^\./,,'` -tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h +tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h collect2.h hash.o: hash.c hash.h system.h toplev.h -cplus-dem.o: cplus-dem.c $(DEMANGLE_H) + +vfprintf.o: $(srcdir)/../libiberty/vfprintf.c $(CONFIG_H) system.h + rm -f vfprintf.c + $(LN_S) $(srcdir)/../libiberty/vfprintf.c vfprintf.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) vfprintf.c + +splay-tree.o: $(srcdir)/../libiberty/splay-tree.c \ + $(srcdir)/../include/splay-tree.h $(srcdir)/../include/libiberty.h + rm -f splay-tree.c + $(LN_S) $(srcdir)/../libiberty/splay-tree.c splay-tree.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) splay-tree.c underscore.c: s-under ; @true @@ -1325,7 +1402,7 @@ s-under: $(GCC_PASSES) # A file used by all variants of C. c-common.o : c-common.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-lex.h \ - flags.h toplev.h output.h + flags.h toplev.h output.h c-pragma.h $(RTL_H) # Language-independent files. @@ -1335,33 +1412,38 @@ DRIVER_DEFINES = \ -DDEFAULT_TARGET_VERSION=\"$(version)\" \ -DDEFAULT_TARGET_MACHINE=\"$(target_alias)\" \ -DTOOLDIR_BASE_PREFIX=\"$(exec_prefix)/\" -gcc.o: gcc.c $(CONFIG_H) system.h gansidecl.h multilib.h Makefile \ - $(lang_specs_files) +gcc.o: gcc.c $(CONFIG_H) system.h intl.h multilib.h \ + Makefile $(lang_specs_files) prefix.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(DRIVER_DEFINES) \ -c `echo $(srcdir)/gcc.c | sed 's,^\./,,'` +gccspec.o: gccspec.c $(CONFIG_H) system.h +cppspec.o: cppspec.c $(CONFIG_H) system.h + tree-check.h: s-check ; @true s-check : gencheck $(srcdir)/move-if-change ./gencheck > tmp-check.h $(srcdir)/move-if-change tmp-check.h tree-check.h touch s-check -gencheck : gencheck.o tree.def $(HOST_LIBDEPS) +gencheck : gencheck.o $(lang_tree_files) $(HOST_LIBDEPS) $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \ gencheck.o $(HOST_LIBS) -gencheck.o : gencheck.c hconfig.h system.h - $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gencheck.c +gencheck.o : gencheck.c tree.def $(CONFIG_H) hconfig.h system.h + $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/gencheck.c dumpvers: dumpvers.c version.o: version.c -obstack.o: obstack.c $(CONFIG_H) -choose-temp.o: choose-temp.c $(CONFIG_H) gansidecl.h system.h -mkstemp.o: mkstemp.c $(CONFIG_H) gansidecl.h system.h -pexecute.o: pexecute.c $(CONFIG_H) system.h gansidecl.h -prefix.o: prefix.c $(CONFIG_H) system.h gansidecl.h Makefile +obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H) + rm -f obstack.c + $(LN_S) $(srcdir)/../libiberty/obstack.c obstack.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) obstack.c + +prefix.o: prefix.c $(CONFIG_H) system.h Makefile prefix.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DPREFIX=\"$(prefix)\" \ -c `echo $(srcdir)/prefix.c | sed 's,^\./,,'` @@ -1372,11 +1454,12 @@ tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h excep print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \ function.h $(EXPR_H) $(RTL_H) toplev.h except.h -fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h +fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \ + $(RTL_H) toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \ flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \ - insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h dwarfout.h \ - dwarf2out.h sdbout.h dbxout.h \ + insn-codes.h insn-config.h intl.h $(RECOG_H) Makefile toplev.h dwarfout.h \ + dwarf2out.h sdbout.h dbxout.h $(EXPR_H) $(BASIC_BLOCK_H) \ $(lang_options_files) $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(MAYBE_USE_COLLECT2) \ -DTARGET_NAME=\"$(target_alias)\" \ @@ -1384,7 +1467,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \ rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h -print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h +print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h basic-block.h rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H) varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \ @@ -1392,30 +1475,33 @@ varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \ xcoffout.h output.h c-pragma.h toplev.h except.h dbxout.h sdbout.h function.o : function.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ function.h insn-flags.h insn-codes.h $(EXPR_H) $(REGS_H) hard-reg-set.h \ - insn-config.h $(RECOG_H) output.h toplev.h except.h + insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h stmt.o : stmt.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \ insn-flags.h insn-config.h insn-codes.h hard-reg-set.h $(EXPR_H) except.h \ - loop.h $(RECOG_H) toplev.h output.h + loop.h $(RECOG_H) toplev.h output.h varray.h except.o : except.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ function.h insn-flags.h $(EXPR_H) $(REGS_H) hard-reg-set.h \ - insn-config.h $(RECOG_H) output.h except.h toplev.h + insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h expr.o : expr.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h function.h \ - $(REGS_H) insn-flags.h insn-codes.h $(EXPR_H) insn-config.h $(RECOG_H) output.h \ - typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h + $(REGS_H) insn-flags.h insn-codes.h $(EXPR_H) insn-config.h $(RECOG_H) \ + output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h except.h calls.o : calls.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h $(EXPR_H) \ insn-flags.h $(REGS_H) toplev.h output.h expmed.o : expmed.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ - insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) real.h + insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) real.h toplev.h explow.o : explow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ - hard-reg-set.h insn-config.h $(EXPR_H) $(RECOG_H) insn-flags.h insn-codes.h + hard-reg-set.h insn-config.h $(EXPR_H) $(RECOG_H) insn-flags.h \ + insn-codes.h toplev.h optabs.o : optabs.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ - insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h + insn-flags.h insn-config.h insn-codes.h $(EXPR_H) $(RECOG_H) reload.h \ + toplev.h dbxout.o : dbxout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h $(REGS_H) \ insn-config.h reload.h gstab.h xcoffout.h defaults.h output.h dbxout.h \ toplev.h sdbout.o : sdbout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h except.h \ function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) defaults.h real.h \ - insn-config.h obstack.h xcoffout.h c-pragma.h sdbout.h toplev.h + insn-config.h $(srcdir)/../include/obstack.h xcoffout.h c-pragma.h \ + sdbout.h toplev.h dwarfout.o : dwarfout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf.h \ flags.h insn-config.h reload.h output.h defaults.h toplev.h dwarfout.h dwarf2out.o : dwarf2out.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) dwarf2.h \ @@ -1425,33 +1511,40 @@ xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \ flags.h toplev.h output.h dbxout.h emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ except.h function.h $(REGS_H) insn-config.h $(RECOG_H) real.h \ - $(EXPR_H) obstack.h hard-reg-set.h bitmap.h + $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.h getpwd.o : getpwd.c $(CONFIG_H) system.h integrate.o : integrate.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \ integrate.h insn-flags.h insn-config.h $(EXPR_H) real.h $(REGS_H) \ - function.h output.h $(RECOG_H) except.h toplev.h + intl.h function.h output.h $(RECOG_H) except.h toplev.h jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \ insn-config.h insn-flags.h $(RECOG_H) $(EXPR_H) real.h except.h \ toplev.h insn-attr.h stupid.o : stupid.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \ - flags.h toplev.h + $(BASIC_BLOCK_H) insn-config.h reload.h flags.h toplev.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 -gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \ - real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h + real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h \ + $(srcdir)/../include/splay-tree.h +gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \ + flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \ + output.h toplev.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 toplev.h +lcm.o : lcm.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \ + real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) profile.o : profile.c $(CONFIG_H) system.h $(RTL_H) flags.h insn-flags.h \ - gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h + gcov-io.h $(TREE_H) output.h $(REGS_H) toplev.h insn-config.h loop.o : loop.c $(CONFIG_H) system.h $(RTL_H) flags.h loop.h insn-config.h \ insn-flags.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) real.h \ - toplev.h + toplev.h varray.h unroll.o : unroll.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \ - integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h + integrate.h $(REGS_H) $(RECOG_H) flags.h $(EXPR_H) loop.h toplev.h varray.h flow.o : flow.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 + $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h recog.h \ + insn-flags.h combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h \ insn-config.h insn-flags.h insn-codes.h insn-attr.h $(REGS_H) $(EXPR_H) \ $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h @@ -1463,7 +1556,7 @@ local-alloc.o : local-alloc.c $(CONFIG_H) system.h $(RTL_H) flags.h \ insn-attr.h toplev.h bitmap.o : bitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H) \ $(REGS_H) -global.o : global.c $(CONFIG_H) system.h $(RTL_H) flags.h \ +global.o : global.c $(CONFIG_H) system.h $(RTL_H) flags.h reload.h \ $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h output.h toplev.h varray.o : varray.c $(CONFIG_H) system.h varray.h $(RTL_H) $(TREE_H) bitmap.h @@ -1477,26 +1570,26 @@ 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) \ $(RECOG_H) reload.h $(EXPR_H) toplev.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 \ - insn-flags.h $(RECOG_H) flags.h output.h $(EXPR_H) + $(BASIC_BLOCK_H) $(REGS_H) insn-config.h insn-attr.h insn-flags.h \ + $(RECOG_H) flags.h output.h $(EXPR_H) toplev.h alias.o : alias.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h \ - $(REGS_H) toplev.h $(EXPR_H) + $(REGS_H) toplev.h output.h $(EXPR_H) regmove.o : regmove.c $(CONFIG_H) system.h $(RTL_H) insn-config.h \ $(RECOG_H) output.h reload.h $(REGS_H) hard-reg-set.h flags.h \ $(EXPR_H) insn-flags.h $(BASIC_BLOCK_H) toplev.h $(SCHED_PREFIX)sched.o : $(SCHED_PREFIX)sched.c $(CONFIG_H) system.h $(RTL_H) \ - $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \ - toplev.h -final.o : final.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h $(REGS_H) \ - $(RECOG_H) conditions.h insn-config.h insn-attr.h except.h real.h output.h \ - hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h defaults.h \ - toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h + $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h flags.h insn-config.h \ + insn-attr.h toplev.h recog.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 except.h real.h \ + output.h hard-reg-set.h insn-flags.h insn-codes.h gstab.h xcoffout.h \ + defaults.h toplev.h reload.h dwarfout.h dwarf2out.h sdbout.h dbxout.h recog.o : recog.c $(CONFIG_H) system.h $(RTL_H) \ $(REGS_H) $(RECOG_H) hard-reg-set.h flags.h insn-config.h insn-attr.h \ - insn-flags.h insn-codes.h real.h -reg-stack.o : reg-stack.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) \ + insn-flags.h insn-codes.h real.h toplev.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 insn-flags.h toplev.h -dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h gansidecl.h +dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h $(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) \ $(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \ @@ -1520,9 +1613,11 @@ halfpic.o: halfpic.c $(CONFIG_H) $(RTL_H) $(TREE_H) system.h # Normally this target is not used; but it is used if you # define ALLOCA=alloca.o. In that case, you must get a suitable alloca.c # from the GNU Emacs distribution. -alloca.o: alloca.c +alloca.o: $(srcdir)/../libiberty/alloca.c + rm -f alloca.c + $(LN_S) $(srcdir)/../libiberty/alloca.c alloca.c $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(ALLOCA_FLAGS) \ - -c `echo $(srcdir)/alloca.c | sed 's,^\./,,'` + -c `echo alloca.c | sed 's,^\./,,'` $(ALLOCA_FINISH) # # Generate header and source files from the machine description, @@ -1570,7 +1665,7 @@ s-codes : $(md_file) gencodes $(srcdir)/move-if-change touch s-codes insn-emit.o : insn-emit.c $(CONFIG_H) $(RTL_H) $(EXPR_H) real.h output.h \ - insn-config.h insn-flags.h insn-codes.h system.h reload.h + insn-config.h insn-flags.h insn-codes.h system.h reload.h recog.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-emit.c insn-emit.c: s-emit ; @true @@ -1599,7 +1694,8 @@ s-opinit : $(md_file) genopinit $(srcdir)/move-if-change $(srcdir)/move-if-change tmp-opinit.c insn-opinit.c touch s-opinit -insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h +insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h toplev.h \ + insn-config.h recog.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-extract.c insn-extract.c: s-extract ; @true @@ -1608,7 +1704,8 @@ s-extract : $(md_file) genextract $(srcdir)/move-if-change $(srcdir)/move-if-change tmp-extract.c insn-extract.c touch s-extract -insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h system.h +insn-peep.o : insn-peep.c $(CONFIG_H) $(RTL_H) $(REGS_H) output.h real.h \ + system.h insn-config.h recog.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-peep.c insn-peep.c: s-peep ; @true @@ -1617,8 +1714,8 @@ s-peep : $(md_file) genpeep $(srcdir)/move-if-change $(srcdir)/move-if-change tmp-peep.c insn-peep.c touch 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 +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 $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-attrtab.c insn-attr.h: s-attr ; @true @@ -1771,7 +1868,8 @@ $(HOST_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtl.c > $(HOST_PREFIX)rtl.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)rtl.c -$(HOST_PREFIX_1)print-rtl.o: $(srcdir)/print-rtl.c $(CONFIG_H) $(RTL_H) +$(HOST_PREFIX_1)print-rtl.o: $(srcdir)/print-rtl.c $(CONFIG_H) $(RTL_H) \ + bitmap.h basic-block.h rm -f $(HOST_PREFIX)print-rtl.c sed -e 's/config[.]h/hconfig.h/' $(srcdir)/print-rtl.c > $(HOST_PREFIX)print-rtl.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)print-rtl.c @@ -1787,19 +1885,19 @@ $(HOST_PREFIX_1)rtlanal.o: $(srcdir)/rtlanal.c $(CONFIG_H) $(RTL_H) sed -e 's/config[.]h/hconfig.h/' $(srcdir)/rtlanal.c > $(HOST_PREFIX)rtlanal.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)rtlanal.c -$(HOST_PREFIX_1)alloca.o: alloca.c +$(HOST_PREFIX_1)alloca.o: $(srcdir)/../libiberty/alloca.c rm -f $(HOST_PREFIX)alloca.c - cp $(srcdir)/alloca.c $(HOST_PREFIX)alloca.c + $(LN_S) $(srcdir)/../libiberty/alloca.c $(HOST_PREFIX)alloca.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)alloca.c -$(HOST_PREFIX_1)obstack.o: obstack.c +$(HOST_PREFIX_1)obstack.o: $(srcdir)/../libiberty/obstack.c rm -f $(HOST_PREFIX)obstack.c - sed -e 's/config[.]h/hconfig.h/' $(srcdir)/obstack.c > $(HOST_PREFIX)obstack.c + sed -e 's/config[.]h/hconfig.h/' $(srcdir)/../libiberty/obstack.c > $(HOST_PREFIX)obstack.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)obstack.c -$(HOST_PREFIX_1)vfprintf.o: vfprintf.c +$(HOST_PREFIX_1)vfprintf.o: $(srcdir)/../libiberty/vfprintf.c rm -f $(HOST_PREFIX)vfprintf.c - sed -e 's/config[.]h/hconfig.h/' $(srcdir)/vfprintf.c > $(HOST_PREFIX)vfprintf.c + sed -e 's/config[.]h/hconfig.h/' $(srcdir)/../libiberty/vfprintf.c > $(HOST_PREFIX)vfprintf.c $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(HOST_PREFIX)vfprintf.c $(HOST_PREFIX_1)doprint.o: doprint.c @@ -1817,6 +1915,40 @@ $(HOST_PREFIX_1)malloc.o: malloc.c $(HOST_PREFIX_1): touch $(HOST_PREFIX_1) + +# +# Remake internationalization support. + +intl.o: intl.c intl.h gansidecl.h Makefile + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + -DLOCALEDIR=\"$(localedir)\" \ + -c `echo $(srcdir)/intl.c | sed 's,^\./,,'` + +# This is needed to when doing a partial build after a `make clean'. +# libintl.a does not depend on intl.all, +# as that would force a lot of recompiling. +$(top_builddir)/intl/libintl.a: + @echo "$(MAKE) intl.all" + @$(MAKE) $(FLAGS_TO_PASS) intl.all + +# Make sure all the headers are there for xgettext to scan. +$(INTL_TARGETS): $(srcdir)/c-gperf.h \ + $(srcdir)/c-parse.c $(srcdir)/c-parse.h $(srcdir)/cexp.c + +intl.all intl.install intl.uninstall intl.distdir \ + 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); \ + done + +# intl.distdir doesn't copy the intl makefiles (since they aren't distributed), +# but we need them for the `make extraclean' in distdir-finish. +intl.distdir-fixup: + for d in $(INTL_SUBDIRS); do \ + ln $$d/Makefile tmp/$$d || cp $$d/Makefile tmp/$$d || exit; \ + done # # Remake cpp and protoize. @@ -1824,92 +1956,95 @@ $(HOST_PREFIX_1): cpp$(exeext): $(CCCP)$(exeext) -rm -f cpp$(exeext) $(LN) $(CCCP)$(exeext) cpp$(exeext) -cccp$(exeext): cccp.o cexp.o version.o prefix.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ cccp.o cexp.o prefix.o \ - version.o $(LIBS) -cexp.o: $(srcdir)/cexp.c $(CONFIG_H) system.h gansidecl.h +CCCP_OBJS = cccp.o cexp.o intl.o prefix.o version.o @extra_cpp_objs@ mbchar.o +cccp$(exeext): $(CCCP_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(CCCP_OBJS) $(LIBS) +cexp.o: $(srcdir)/cexp.c $(CONFIG_H) system.h $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/cexp.c $(srcdir)/cexp.c: $(srcdir)/cexp.y cd $(srcdir); $(BISON) -o cexp.c cexp.y -cccp.o: cccp.c $(CONFIG_H) pcp.h version.c config.status system.h gansidecl.h +# We use $(libsubdir)/$(unlibsubdir) to match the +# -iprefix argument which gcc will pass if GCC_EXEC_PREFIX is used. +cccp.o: cccp.c $(CONFIG_H) intl.h pcp.h version.c config.status system.h \ + mbchar.h prefix.h Makefile.in $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \ - -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \ - -DOLD_GPLUSPLUS_INCLUDE_DIR=\"$(old_gxx_include_dir)\" \ + -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \ - -DCROSS_INCLUDE_DIR=\"$(tooldir)/sys-include\" \ - -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \ + -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \ + -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \ -c `echo $(srcdir)/cccp.c | sed 's,^\./,,'` -cppmain$(exeext): cppmain.o cpplib.o cpphash.o cppalloc.o cpperror.o cppexp.o \ - prefix.o version.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ cppmain.o cpplib.o cpphash.o \ - cppalloc.o cpperror.o cppexp.o prefix.o version.o $(LIBS) - -cppmain.o: cppmain.c $(CONFIG_H) cpplib.h system.h gansidecl.h +LIBCPP_OBJS = cpplib.o cpphash.o cppalloc.o cpperror.o cppexp.o cppfiles.o \ + cppinit.o cppulp.o prefix.o version.o mbchar.o @extra_cpp_objs@ -cpplib.o: cpplib.c $(CONFIG_H) cpplib.h cpphash.h config.status system.h \ - gansidecl.h +# All the other archives built/used by this makefile are for targets. This +# one is strictly for the host. +# +libcpp.a: $(LIBCPP_OBJS) + $(AR) $(AR_FLAGS) libcpp.a $(LIBCPP_OBJS) + if $(RANLIB_TEST) ; then $(RANLIB) libcpp.a ; else true ; fi + +cppmain$(exeext): cppmain.o intl.o libcpp.a $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o cppmain$(exeext) cppmain.o \ + intl.o libcpp.a $(LIBS) + +cppmain.o: cppmain.c $(CONFIG_H) cpplib.h intl.h system.h + +cppulp.o: cppulp.c $(CONFIG_H) system.h output.h +cpplib.o: cpplib.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h +cpphash.o: cpphash.c $(CONFIG_H) cpplib.h intl.h system.h cpphash.h +cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h intl.h system.h +cpperror.o: cpperror.c $(CONFIG_H) cpplib.h intl.h system.h +cppexp.o: cppexp.c $(CONFIG_H) cpplib.h intl.h system.h +cppfiles.o: cppfiles.c $(CONFIG_H) cpplib.h intl.h system.h + +cppinit.o: cppinit.c $(CONFIG_H) cpplib.h intl.h system.h \ + cpphash.h prefix.h output.h Makefile $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \ - -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \ - -DOLD_GPLUSPLUS_INCLUDE_DIR=\"$(old_gxx_include_dir)\" \ + -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \ - -DCROSS_INCLUDE_DIR=\"$(tooldir)/sys-include\" \ - -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \ - -c `echo $(srcdir)/cpplib.c | sed 's,^\./,,'` - -cpperror.o: cpperror.c $(CONFIG_H) cpplib.h system.h gansidecl.h - -cppexp.o: cppexp.c $(CONFIG_H) cpplib.h system.h gansidecl.h - -cpphash.o: cpphash.c cpplib.h cpphash.h $(CONFIG_H) system.h gansidecl.h - -cppalloc.o: cppalloc.c $(CONFIG_H) cpplib.h system.h gansidecl.h + -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \ + -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \ + -c `echo $(srcdir)/cppinit.c | sed 's,^\./,,'` # Note for the stamp targets, we run the program `true' instead of # having an empty command (nothing following the semicolon). proto: config.status protoize$(exeext) unprotoize$(exeext) SYSCALLS.c.X -protoize$(exeext): protoize.o getopt.o getopt1.o getpwd.o version.o \ - pexecute.o choose-temp.o mkstemp.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ - protoize.o getopt.o getopt1.o getpwd.o version.o \ - pexecute.o choose-temp.o mkstemp.o $(LIBS) +PROTO_OBJS = getpwd.o intl.o version.o -unprotoize$(exeext): unprotoize.o getopt.o getopt1.o getpwd.o version.o \ - pexecute.o choose-temp.o mkstemp.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ - unprotoize.o getopt.o getopt1.o getpwd.o version.o \ - pexecute.o choose-temp.o mkstemp.o $(LIBS) +protoize$(exeext): protoize.o $(PROTO_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ protoize.o $(PROTO_OBJS) $(LIBS) -protoize.o: protoize.c getopt.h $(CONFIG_H) system.h +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 $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \ - -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \ - -DCROSS_INCLUDE_DIR=\"$(tooldir)/sys-include\" \ - -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \ + -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \ + -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \ + -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \ -DSTD_PROTO_DIR=\"$(libsubdir)\" \ $(srcdir)/protoize.c -unprotoize.o: unprotoize.c protoize.c getopt.h $(CONFIG_H) system.h +unprotoize.o: unprotoize.c protoize.c $(srcdir)/../include/getopt.h \ + $(CONFIG_H) system.h Makefile $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DGCC_INCLUDE_DIR=\"$(libsubdir)/include\" \ - -DGPLUSPLUS_INCLUDE_DIR=\"$(gxx_include_dir)\" \ - -DCROSS_INCLUDE_DIR=\"$(tooldir)/sys-include\" \ - -DTOOL_INCLUDE_DIR=\"$(tooldir)/include\" \ + -DGPLUSPLUS_INCLUDE_DIR=\"$(gcc_gxx_include_dir)\" \ + -DCROSS_INCLUDE_DIR=\"$(gcc_tooldir)/sys-include\" \ + -DTOOL_INCLUDE_DIR=\"$(gcc_tooldir)/include\" \ -DLOCAL_INCLUDE_DIR=\"$(includedir)\" \ -DSTD_PROTO_DIR=\"$(libsubdir)\" \ $(srcdir)/unprotoize.c -getopt.o: getopt.c getopt.h - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/getopt.c -getopt1.o: getopt1.c getopt.h - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/getopt1.c - # This info describes the target machine, so compile with GCC just built. SYSCALLS.c.X: $(srcdir)/sys-types.h $(srcdir)/sys-protos.h $(GCC_PASSES) \ stmp-int-hdrs @@ -1945,12 +2080,13 @@ 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 system.h +gcov.o: gcov.c gcov-io.h intl.h system.h # Only one of 'gcov' or 'gcov.exe' is actually built, depending # upon whether $(exeext) is empty or not. -gcov$(exeext): gcov.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) gcov.o $(LIBS) -o $@ +GCOV_OBJS = gcov.o intl.o +gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(GCOV_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 @@ -1958,7 +2094,7 @@ gcov$(exeext): gcov.o $(LIBDEPS) # Build the include directory including float.h (which no longer depends upon # enquire). -stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h +stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h # Copy in the headers provided with gcc. # The sed command gets just the last file name component; # this is necessary because VPATH could add a dirname. @@ -1977,8 +2113,8 @@ stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h cp xlimits.h include/limits.h chmod a+r include/limits.h rm -f include/float.h - if [ -s gfloat.h ]; then \ - cp gfloat.h include/float.h && \ + if [ x$(FLOAT_H) != xMakefile.in ]; then \ + cp $(srcdir)/config/$(FLOAT_H) include/float.h && \ chmod a+r include/float.h; \ else :; fi # Install the README @@ -1987,37 +2123,46 @@ stmp-int-hdrs: stmp-fixinc $(USER_H) xlimits.h gfloat.h chmod a+r include/README touch $@ -# Now that gfloat.h no longer depends upon enquire, this is actually a no-op. +# Now that float.h no longer depends upon enquire, this is actually a no-op. stmp-headers: touch $@ -fixinc.sh : - DEST=`cd $(srcdir) ; pwd`/$@ CC=$(CC) MAKE=$(MAKE) CFLAGS="$(CFLAGS)" \ - export DEST CC MAKE CFLAGS ; \ - echo DEST=$$DEST CC=$$CC MAKE=$$MAKE CFLAGS=$$CFLAGS ; \ - cd ../contrib/fixinc ; \ - $(SHELL) mkfixinc.sh $(target) $$DEST +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)/server.h $(FIXINCSRCDIR)/inclhack.def + MAKE="$(MAKE)"; srcdir=`cd $(srcdir)/fixinc; pwd` ; \ + export MAKE srcdir ; \ + cd ./fixinc; $(SHELL) $${srcdir}/mkfixinc.sh $(target) + +##stmp-fixinc: $(FIXINCLUDES) gsyslimits.h +## rm -rf include +## mkdir include +## if [ x$(FIXINCLUDES) != xMakefile.in ]; \ +## then \ +## for dir in $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); do \ +## if [ -d $$dir ]; \ +## then \ +## $(SHELL) $(srcdir)/$(FIXINCLUDES) include $$dir; \ +## else true; fi; \ +## done; \ +## if [ x$(INSTALL_ASSERT_H) != x ] ; \ +## then \ +## rm -f include/assert.h; \ +## cp $(srcdir)/assert.h include/assert.h; \ +## chmod a+r include/assert.h; \ +## fi \ +## else true; \ +## fi # Build fixed copies of system files. -stmp-fixinc: $(FIXINCLUDES) gsyslimits.h - rm -rf include - mkdir include - if [ x$(FIXINCLUDES) != xMakefile.in ]; \ - then \ - for dir in $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS); do \ - if [ -d $$dir ]; \ - then \ - $(SHELL) $(srcdir)/$(FIXINCLUDES) include $$dir; \ - else true; fi; \ - done; \ - if [ x$(INSTALL_ASSERT_H) != x ] ; \ - then \ - rm -f include/assert.h; \ - cp $(srcdir)/assert.h include/assert.h; \ - chmod a+r include/assert.h; \ - fi \ - else true; \ - fi +stmp-fixinc: fixinc.sh gsyslimits.h + rm -rf include; mkdir include + TARGET_MACHINE=$(target); srcdir=`cd $(srcdir); pwd`; \ + INSTALL_ASSERT_H=$(INSTALL_ASSERT_H); SHELL=$(SHELL) ;\ + export TARGET_MACHINE srcdir INSTALL_ASSERT_H SHELL ; \ + $(SHELL) ./fixinc.sh `pwd`/include $(SYSTEM_HEADER_DIR) $(OTHER_FIXINCLUDES_DIRS) rm -f include/syslimits.h if [ -f include/limits.h ]; then \ mv include/limits.h include/syslimits.h; \ @@ -2025,6 +2170,21 @@ stmp-fixinc: $(FIXINCLUDES) gsyslimits.h cp $(srcdir)/gsyslimits.h include/syslimits.h; \ fi chmod a+r include/syslimits.h +# If $(SYSTEM_HEADER_DIR) is $(tooldir)/sys-include, and +# that directory exists, then make sure that $(libsubdir) exists. +# This is because cpp is compiled to find $(tooldir)/include via +# $(libsubdir)/$(unlibsubdir), which will only work if $(libsubdir) +# exists. +# We deliberately use tooldir instead of gcc_tooldir here. gcc_tooldir +# won't work because libsubdir doesn't exist yet. + if [ "$(SYSTEM_HEADER_DIR)" = "$(tooldir)/sys-include" ] \ + && [ -d $(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 + touch stmp-fixinc # Files related to the fixproto script. @@ -2040,9 +2200,10 @@ deduced.h: $(GCC_PASSES) $(srcdir)/scan-types.sh stmp-int-hdrs touch deduced.h; \ fi -gen-protos: gen-protos.o scan.o cppalloc.o $(HOST_LIBDEPS) - ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \ - gen-protos.o scan.o cppalloc.o $(HOST_LIBS) +GEN_PROTOS_OBJS = gen-protos.o scan.o libcpp.a +gen-protos: $(GEN_PROTOS_OBJS) $(HOST_LIBDEPS) + ${HOST_CC} $(HOST_CFLAGS) $(HOST_LDFLAGS) -o gen-protos \ + $(GEN_PROTOS_OBJS) $(HOST_LIBS) gen-protos.o: gen-protos.c scan.h $(build_xm_file) system.h $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gen-protos.c @@ -2060,16 +2221,15 @@ xsys-protos.h: $(GCC_PASSES) $(srcdir)/sys-protos.h deduced.h gen-protos Makefil rm -rf fixtmp.c fix-header: fix-header.o scan-decls.o scan.o xsys-protos.h $(HOST_LIBDEPS) \ - cpplib.o cpphash.o cppalloc.o cppexp.o prefix.o version.o + libcpp.a $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ fix-header.o \ - scan-decls.o scan.o cpplib.o cpphash.o cppalloc.o prefix.o \ - version.o cppexp.o $(HOST_LIBS) + scan-decls.o scan.o libcpp.a $(HOST_LIBS) -fix-header.o: fix-header.c obstack.h scan.h xsys-protos.h $(build_xm_file) \ - system.h cpplib.h cpphash.h +fix-header.o: fix-header.c $(srcdir)/../include/obstack.h scan.h \ + xsys-protos.h $(build_xm_file) system.h cpplib.h cpphash.h $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c -scan-decls.o: scan-decls.c scan.h cpplib.h $(build_xm_file) system.h gansidecl.h +scan-decls.o: scan-decls.c scan.h cpplib.h $(build_xm_file) system.h $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/scan-decls.c # stmp-fixproto depends on this, not on fix-header directly. @@ -2093,6 +2253,8 @@ stmp-fixproto: fixhdr.ready fixproto stmp-headers else \ : This line works around a 'make' bug in BSDI 1.1.; \ FIXPROTO_DEFINES="$(FIXPROTO_DEFINES)"; export FIXPROTO_DEFINES; \ + mkinstalldirs="$(SHELL) $(srcdir)/mkinstalldirs"; \ + export mkinstalldirs; \ if [ -d $(SYSTEM_HEADER_DIR) ] ; then \ $(SHELL) ${srcdir}/fixproto include include $(SYSTEM_HEADER_DIR); \ else true; fi; \ @@ -2130,7 +2292,7 @@ cpp.dvi: $(srcdir)/cpp.texi INSTALL: $(srcdir)/install1.texi $(srcdir)/install.texi - cd $(srcdir); $(MAKEINFO) -D INSTALLONLY --no-header \ + cd $(srcdir); $(MAKEINFO) -D INSTALLONLY \ --no-split -o INSTALL install1.texi # # Deletion of files made during compilation. @@ -2147,7 +2309,7 @@ INSTALL: $(srcdir)/install1.texi $(srcdir)/install.texi # (less duplicated code). -mostlyclean: lang.mostlyclean +mostlyclean: intl.mostlyclean lang.mostlyclean -rm -f $(STAGESTUFF) # Delete the temporary source copies for cross compilation. -rm -f $(HOST_PREFIX_1)rtl.c $(HOST_PREFIX_1)rtlanal.c @@ -2164,12 +2326,12 @@ mostlyclean: lang.mostlyclean # Delete debugging dump files. -rm -f *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop -rm -f *.dbr *.jump2 *.sched *.cse2 *.sched2 *.stack *.addressof - -rm -f *.regmove *.mach *.bp *.gcse + -rm -f *.regmove *.mach *.bp *.gcse *.flow2 -rm -f */*.greg */*.lreg */*.combine */*.flow */*.cse */*.jump */*.rtl -rm -f */*.tree */*.loop */*.dbr */*.jump2 */*.sched */*.cse2 - -rm -f */*.sched2 */*.stack */*.regmove */*.gcse + -rm -f */*.sched2 */*.stack */*.regmove */*.gcse */*.flow2 # Delete some files made during installation. - -rm -f specs gfloat.h float.h-* enquire SYSCALLS.c.X SYSCALLS.c + -rm -f specs float.h-* enquire SYSCALLS.c.X SYSCALLS.c -rm -f collect collect2 mips-tfile mips-tdump alloca.s # Delete files generated for fixproto -rm -rf fix-header xsys-protos.h deduced.h tmp-deduced.h \ @@ -2185,7 +2347,7 @@ mostlyclean: lang.mostlyclean # Delete all files made by compilation # that don't exist in the distribution. -clean: mostlyclean lang.clean +clean: mostlyclean intl.clean lang.clean # It may not be quite desirable to delete unprotoize.c here, # but the spec for `make clean' requires it. # Using unprotoize.c is not quite right in the first place, @@ -2210,12 +2372,13 @@ clean: mostlyclean lang.clean # Delete all files that users would normally create # while building and installing GCC. -distclean: clean lang.distclean +INTL_DISTCLEAN = intl.distclean +distclean: clean $(INTL_DISTCLEAN) lang.distclean -rm -f tm.h config.h auto-host.h auto-build.h tconfig.h hconfig.h -rm -f md 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 specs.h options.h *.oaux + -rm -f Makefile specs.h options.h gencheck.h *.oaux -rm -f gthr-default.h -rm -f */stage1 */stage2 */stage3 */stage4 */include -rm -f c-parse.output @@ -2223,6 +2386,7 @@ distclean: clean lang.distclean -rm -f float.h -rm -f site.exp site.bak testsuite/site.exp testsuite/site.bak -rm -f testsuite/{gcc,g++}.{log,sum} + -rm -f intl/libintl.h libintl.h # Delete anything likely to be found in the source directory # that shouldn't be in the distribution. @@ -2235,6 +2399,7 @@ extraclean: distclean lang.extraclean -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 @@ -2243,10 +2408,13 @@ extraclean: distclean lang.extraclean # 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 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) distclean lang.maintainer-clean + $(MAKE) INTL_DISTCLEAN= distclean \ + intl.maintainer-clean lang.maintainer-clean -rm -f c-parse.y c-gperf.h -rm -f c-parse.c c-parse.h c-parse.output -rm -f cexp.c cexp.output TAGS @@ -2265,7 +2433,7 @@ install: $(INSTALL_TARGET) ; @true # Install the driver last so that the window when things are # broken is small. install-normal: install-common $(INSTALL_HEADERS) $(INSTALL_LIBGCC) \ - $(INSTALL_CPP) install-man install-info lang.install-normal \ + $(INSTALL_CPP) install-man install-info intl.install lang.install-normal \ install-driver # Do nothing while making gcc with a cross-compiler. The person who @@ -2276,29 +2444,27 @@ install-build: force # Run this on the target machine # to finish installation of cross compiler. +# This is not used anymore now that float.h does not depend on enquire. install-cross-rest: install-float-h-cross # Handle cpp installation. -install-cpp: cpp.sh - -rm -f $(bindir)/cpp - $(INSTALL_PROGRAM) -m 755 cpp.sh $(bindir)/cpp +install-cpp: xcpp$(exeext) + -rm -f $(bindir)/$(CPP_INSTALL_NAME)$(exeext) + $(INSTALL_PROGRAM) -m 755 xcpp$(exeext) $(bindir)/$(CPP_INSTALL_NAME)$(exeext) if [ x$(cpp_install_dir) != x ]; then \ - rm -f $(cpp_install_dir)/cpp; \ - $(INSTALL_PROGRAM) -m 755 cpp.sh $(cpp_install_dir)/cpp; \ + rm -f $(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \ + $(INSTALL_PROGRAM) -m 755 xcpp$(exeext) $(prefix)/$(cpp_install_dir)/$(CPP_INSTALL_NAME)$(exeext); \ else true; fi -cpp.sh: $(srcdir)/cpp.in Makefile - sed -e 's%@GCC@%'$(GCC_INSTALL_NAME)'%' $(srcdir)/cpp.in > xcpp.T - mv -f xcpp.T cpp.sh - uninstall-cpp: -rm -f $(bindir)/cpp -if [ x$(cpp_install_dir) != x ]; then \ - rm -f $(cpp_install_dir)/cpp; \ + rm -f $(prefix)/$(cpp_install_dir)/cpp; \ else true; fi # Install float.h for cross compiler. # Run this on the target machine! +# This is not used anymore now that float.h does not depend on enquire. install-float-h-cross: installdirs # if [ -f enquire ] ; then true; else false; fi # Note: don't use -. We should fail right away if enquire was not made. @@ -2322,15 +2488,15 @@ installdirs: done -if [ -d $(bindir) ] ; then true ; else mkdir $(bindir) ; chmod a+rx $(bindir) ; fi -if [ -d $(includedir) ] ; then true ; else mkdir $(includedir) ; chmod a+rx $(includedir) ; fi - -if [ -d $(tooldir) ] ; then true ; else mkdir $(tooldir) ; chmod a+rx $(tooldir) ; fi + -if [ -d $(gcc_tooldir) ] ; then true ; else mkdir $(gcc_tooldir) ; chmod a+rx $(gcc_tooldir) ; fi -if [ -d $(assertdir) ] ; then true ; else mkdir $(assertdir) ; chmod a+rx $(assertdir) ; fi -if [ -d $(infodir) ] ; then true ; else mkdir $(infodir) ; chmod a+rx $(infodir) ; fi -# We don't use mkdir -p to create the parents of mandir, +# We don't use mkdir -p to create the parents of man1dir, # because some systems don't support it. -# Instead, we use this technique to create the immediate parent of mandir. - -parent=`echo $(mandir)|sed -e 's@/[^/]*$$@@'`; \ +# Instead, we use this technique to create the immediate parent of man1dir. + -parent=`echo $(man1dir)|sed -e 's@/[^/]*$$@@'`; \ if [ -d $$parent ] ; then true ; else mkdir $$parent ; chmod a+rx $$parent ; fi - -if [ -d $(mandir) ] ; then true ; else mkdir $(mandir) ; chmod a+rx $(mandir) ; fi + -if [ -d $(man1dir) ] ; then true ; else mkdir $(man1dir) ; chmod a+rx $(man1dir) ; fi # Install the compiler executables built during cross compilation. install-common: native installdirs $(EXTRA_PARTS) lang.install-common @@ -2384,19 +2550,18 @@ install-common: native installdirs $(EXTRA_PARTS) lang.install-common -if [ -f gcov$(exeext) ]; \ then \ rm -f $(bindir)/gcov$(exeext); \ - $(INSTALL_PROGRAM) gcov$(exeext) $(bindir)/gcov$(exeext); \ - chmod a+x $(bindir)/gcov$(exeext); \ + $(INSTALL_PROGRAM) gcov$(exeext) $(bindir)/$(GCOV_INSTALL_NAME)$(exeext); \ fi # Install the driver program as $(target_alias)-gcc -# and also as either gcc (if native) or $(tooldir)/bin/gcc. +# and also as either gcc (if native) or $(gcc_tooldir)/bin/gcc. install-driver: xgcc$(exeext) -if [ -f gcc-cross$(exeext) ] ; then \ rm -f $(bindir)/$(GCC_CROSS_NAME)$(exeext); \ $(INSTALL_PROGRAM) gcc-cross$(exeext) $(bindir)/$(GCC_CROSS_NAME)$(exeext); \ - if [ -d $(tooldir)/bin/. ] ; then \ - rm -f $(tooldir)/bin/gcc$(exeext); \ - $(INSTALL_PROGRAM) gcc-cross$(exeext) $(tooldir)/bin/gcc$(exeext); \ + if [ -d $(gcc_tooldir)/bin/. ] ; then \ + rm -f $(gcc_tooldir)/bin/gcc$(exeext); \ + $(INSTALL_PROGRAM) gcc-cross$(exeext) $(gcc_tooldir)/bin/gcc$(exeext); \ else true; fi; \ else \ rm -f $(bindir)/$(GCC_INSTALL_NAME)$(exeext); \ @@ -2426,25 +2591,25 @@ install-info: doc installdirs lang.install-info # Install the man pages. install-man: installdirs $(srcdir)/gcc.1 $(srcdir)/cccp.1 lang.install-man -if [ -f gcc-cross$(exeext) ] ; then \ - rm -f $(mandir)/$(GCC_CROSS_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/gcc.1 $(mandir)/$(GCC_CROSS_NAME)$(manext); \ - chmod a-x $(mandir)/$(GCC_CROSS_NAME)$(manext); \ + rm -f $(man1dir)/$(GCC_CROSS_NAME)$(manext); \ + $(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_CROSS_NAME)$(manext); \ + chmod a-x $(man1dir)/$(GCC_CROSS_NAME)$(manext); \ else \ - rm -f $(mandir)/$(GCC_INSTALL_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/gcc.1 $(mandir)/$(GCC_INSTALL_NAME)$(manext); \ - chmod a-x $(mandir)/$(GCC_INSTALL_NAME)$(manext); \ + rm -f $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \ + $(INSTALL_DATA) $(srcdir)/gcc.1 $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \ + chmod a-x $(man1dir)/$(GCC_INSTALL_NAME)$(manext); \ fi - -rm -f $(mandir)/cccp$(manext) - -$(INSTALL_DATA) $(srcdir)/cccp.1 $(mandir)/cccp$(manext) - -chmod a-x $(mandir)/cccp$(manext) + -rm -f $(man1dir)/cccp$(manext) + -$(INSTALL_DATA) $(srcdir)/cccp.1 $(man1dir)/cccp$(manext) + -chmod a-x $(man1dir)/cccp$(manext) # Install the library. install-libgcc: libgcc.a installdirs -if [ -f libgcc.a ] ; then \ rm -f $(libsubdir)/libgcc.a; \ $(INSTALL_DATA) libgcc.a $(libsubdir)/libgcc.a; \ - if $(RANLIB_TEST) ; then \ - (cd $(libsubdir); $(RANLIB) libgcc.a); else true; fi; \ + if $(RANLIB_TEST_FOR_TARGET) ; then \ + (cd $(libsubdir); $(RANLIB_FOR_TARGET) libgcc.a); else true; fi; \ chmod a-x $(libsubdir)/libgcc.a; \ else true; fi @@ -2457,8 +2622,9 @@ install-multilib: stmp-multilib installdirs rm -f $(libsubdir)/$${dir}/$${f}; \ $(INSTALL_DATA) $${dir}/$${f} $(libsubdir)/$${dir}/$${f}; \ done; \ - if $(RANLIB_TEST); then \ - (cd $(libsubdir)/$${dir}; $(RANLIB) libgcc.a); else true; fi; \ + if $(RANLIB_TEST_FOR_TARGET); then \ + (cd $(libsubdir)/$${dir}; $(RANLIB_FOR_TARGET) libgcc.a); \ + else true; fi; \ chmod a-x $(libsubdir)/$${dir}/libgcc.a; \ done @@ -2487,7 +2653,11 @@ install-include-dir: installdirs # Install the include directory using tar. install-headers-tar: stmp-headers $(STMP_FIXPROTO) install-include-dir - (cd include; \ +# We use `pwd`/include instead of just include to problems with CDPATH +# Unless a full pathname is provided, some shells would print the new CWD, +# found in CDPATH, corrupting the output. We could just redirect the +# output of `cd', but some shells lose on redirection within `()'s + (cd `pwd`/include ; \ tar -cf - .; exit 0) | (cd $(libsubdir)/include; tar $(TAROUTOPTS) - ) # /bin/sh on some systems returns the status of the first tar, # and that can lose with GNU tar which always writes a full block. @@ -2495,7 +2665,9 @@ install-headers-tar: stmp-headers $(STMP_FIXPROTO) install-include-dir # Install the include directory using cpio. install-headers-cpio: stmp-headers $(STMP_FIXPROTO) install-include-dir - (cd include; find . -print) | (cd include; cpio -pdum $(libsubdir)/include) +# See discussion about the use of `pwd` above + cd `pwd`/include ; \ + find . -print | cpio -pdum $(libsubdir)/include # Put assert.h where it won't override GNU libc's assert.h. # It goes in a dir that is searched after GNU libc's headers; @@ -2527,18 +2699,20 @@ install-collect2: collect2 installdirs $(INSTALL_PROGRAM) xgcc$(exeext) $(libsubdir)/gcc$(exeext) # Cancel installation by deleting the installed files. -uninstall: lang.uninstall $(UNINSTALL_CPP) +uninstall: intl.uninstall lang.uninstall $(UNINSTALL_CPP) -rm -rf $(libsubdir) -rm -rf $(bindir)/$(GCC_INSTALL_NAME)$(exeext) -rm -rf $(bindir)/$(GCC_CROSS_NAME)$(exeext) - -rm -rf $(bindir)/protoize$(exeext) - -rm -rf $(bindir)/unprotoize$(exeext) - -rm -rf $(bindir)/gcov$(exeext) - -rm -rf $(mandir)/$(GCC_INSTALL_NAME)$(manext) - -rm -rf $(mandir)/$(GCC_CROSS_NAME)$(manext) - -rm -rf $(mandir)/cccp$(manext) - -rm -rf $(mandir)/protoize$(manext) - -rm -rf $(mandir)/unprotoize$(manext) + -rm -rf $(bindir)/$(PROTOIZE_INSTALL_NAME)$(exeext) + -rm -rf $(bindir)/$(PROTOIZE_CROSS_NAME)$(exeext) + -rm -rf $(bindir)/$(UNPROTOIZE_INSTALL_NAME)$(exeext) + -rm -rf $(bindir)/$(UNPROTOIZE_CROSS_NAME)$(exeext) + -rm -rf $(bindir)/$(GCOV_INSTALL_NAME)$(exeext) + -rm -rf $(man1dir)/$(GCC_INSTALL_NAME)$(manext) + -rm -rf $(man1dir)/$(GCC_CROSS_NAME)$(manext) + -rm -rf $(man1dir)/cccp$(manext) + -rm -rf $(man1dir)/protoize$(manext) + -rm -rf $(man1dir)/unprotoize$(manext) -rm -f $(infodir)/cpp.info* $(infodir)/gcc.info* # # These targets are for the dejagnu testsuites. The file site.exp @@ -2593,7 +2767,7 @@ site.exp: ./config.status Makefile -e '1,/^## All variables above are.*##/ d' >> site.exp -@rm -f ./tmp? -CHECK_TARGETS = check-gcc check-g++ check-g77 +CHECK_TARGETS = check-gcc check-g++ check-g77 check-objc check: $(CHECK_TARGETS) @@ -2612,7 +2786,7 @@ check-g++: testsuite/site.exp cd testsuite; \ EXPECT=${EXPECT} ; export EXPECT ; \ if [ -f $${rootme}/../expect/expect ] ; then \ - TCL_LIBRARY=$${srcdir}/../tcl/library ; \ + TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \ export TCL_LIBRARY ; fi ; \ $(RUNTEST) --tool g++ $(RUNTESTFLAGS) @@ -2622,7 +2796,7 @@ check-gcc: testsuite/site.exp cd testsuite; \ EXPECT=${EXPECT} ; export EXPECT ; \ if [ -f $${rootme}/../expect/expect ] ; then \ - TCL_LIBRARY=$${srcdir}/../tcl/library ; \ + TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \ export TCL_LIBRARY ; fi ; \ $(RUNTEST) --tool gcc $(RUNTESTFLAGS) @@ -2632,10 +2806,20 @@ check-g77: testsuite/site.exp cd testsuite; \ EXPECT=${EXPECT} ; export EXPECT ; \ if [ -f $${rootme}/../expect/expect ] ; then \ - TCL_LIBRARY=$${srcdir}/../tcl/library ; \ + TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \ export TCL_LIBRARY ; fi ; \ $(RUNTEST) --tool g77 $(RUNTESTFLAGS) +check-objc: testsuite/site.exp + -rootme=`pwd`; export rootme; \ + srcdir=`cd ${srcdir}; pwd` ; export srcdir ; \ + cd testsuite; \ + EXPECT=${EXPECT} ; export EXPECT ; \ + if [ -f $${rootme}/../expect/expect ] ; then \ + TCL_LIBRARY=`cd .. ; cd ${srcdir}/../tcl/library ; pwd` ; \ + export TCL_LIBRARY ; fi ; \ + $(RUNTEST) --tool objc $(RUNTESTFLAGS) + # These exist for maintenance purposes. # Update the tags table. @@ -2657,22 +2841,27 @@ tmp-gcc.xtar: distdir tar -chf tmp-gcc.xtar gcc-$(version) distdir-cvs: force - if [ -d $(srcdir)/CVS ]; then cvs -r update; fi + if [ -d $(srcdir)/CVS ]; then cd $(srcdir) && cvs -r update; fi # This target exists to do the initial work before the language specific # stuff gets done. distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \ $(srcdir)/c-parse.c $(srcdir)/cexp.c $(srcdir)/config.in \ $(srcdir)/version.c TAGS + @case '$(USE_NLS)' in \ + yes) ;; \ + *) echo "configure with --enable-nls before making a distribution"; \ + exit 1;; \ + esac @if grep -s "for version ${mainversion}" gcc.texi > /dev/null; \ then true; \ else echo "You must update the version number in \`gcc.texi'"; sleep 10;\ fi # Update the version number in README - awk '$$1 " " $$2 " " $$3 == "This directory contains" \ + $(AWK) '$$1 " " $$2 " " $$3 == "This directory contains" \ { $$6 = version; print $$0 } \ $$1 " " $$2 " " $$3 != "This directory contains"' \ - version=$(version) README > tmp.README + version=$(version) $(srcdir)/README > tmp.README mv tmp.README README -rm -rf gcc-$(version) tmp # Put all the files in a temporary subdirectory @@ -2680,31 +2869,35 @@ distdir-start: doc $(srcdir)/INSTALL $(srcdir)/c-parse.y $(srcdir)/c-gperf.h \ mkdir tmp mkdir tmp/config mkdir tmp/ginclude - for file in *[0-9a-zA-Z+]; do \ - $(LN) $$file tmp; \ + mkdir tmp/objc + mkdir tmp/intl + mkdir tmp/po + for file in `(cd $(srcdir) && echo *[0-9a-zA-Z+])`; do \ + test -f $(srcdir)/$$file && $(LN_S) $(srcdir)/$$file tmp; \ done - cd config; \ - for file in *[0-9a-zA-Z+]; do \ - if test -d $$file && test "$$file" != RCS && test "$$file" != CVS; then \ - mkdir ../tmp/config/$$file; \ - cd $$file; \ - for subfile in *[0-9a-zA-Z+]; do \ - $(LN) $$subfile ../../tmp/config/$$file; \ + if test "$(srcdir)" != "." ; then \ + for file in c-parse.c cexp.c ; do \ + test -f ./$$file && $(LN_S) ../$$file tmp; \ + done; \ + fi + for file in `(cd $(srcdir)/config && echo *[0-9a-zA-Z+])`; do \ + if test -d $(srcdir)/config/$$file \ + && test "$$file" != RCS && test "$$file" != CVS; then \ + mkdir tmp/config/$$file; \ + for subfile in `(cd $(srcdir)/config/$$file && echo *[0-9a-zA-Z+])`; do \ + $(LN_S) $(srcdir)/config/$$file/$$subfile tmp/config/$$file; \ done; \ - cd ..; \ else \ - $(LN) $$file ../tmp/config; \ + $(LN_S) $(srcdir)/config/$$file tmp/config; \ fi; \ done - cd ginclude; \ - for file in *[0-9a-zA-Z+]; do \ - $(LN) $$file ../tmp/ginclude; \ + for file in `(cd $(srcdir)/ginclude && echo *[0-9a-zA-Z+])`; do \ + $(LN_S) $(srcdir)/ginclude/$$file tmp/ginclude; \ done - cd objc; \ - for file in *[0-9a-zA-Z+]; do \ - $(LN) $$file ../tmp/objc; \ + for file in `(cd $(srcdir)/objc && echo *[0-9a-zA-Z+])`; do \ + $(LN_S) $(srcdir)/objc/$$file tmp/objc; \ done - $(LN) .gdbinit tmp + $(LN_S) .gdbinit tmp # Finish making `distdir', after the languages have done their thing. distdir-finish: @@ -2712,9 +2905,21 @@ distdir-finish: # Get rid of everything we don't want in the distribution. We'd want # this to use Makefile.in, but it doesn't have the `lang.foo' targets # expanded. - cd gcc-$(version); make extraclean VERSION_DEP= + cd gcc-$(version); make extraclean distdir-check VERSION_DEP= + +distdir-check: + ($(AWK) '/^[^#]/{print} /^#[A-Za-z]/{print substr($$1, 2)}' | sort) \ + < po/POTFILES.in > tmp.POTFILES + ls [A-Za-z]*.[ch] [a-z]*/[A-Za-z]*.[ch] \ + [a-z]*/[a-z]*/[A-Za-z]*.[ch] | sort > tmp.src + diff tmp.POTFILES tmp.src || { \ + echo "po/POTFILES.in and sources do not match -- please fix"; \ + exit 1; \ + } + rm -f tmp.* -distdir: distdir-cvs distdir-start lang.distdir distdir-finish +distdir: distdir-cvs distdir-start intl.distdir intl.distdir-fixup \ + lang.distdir distdir-finish # make diff oldversion=M.N # creates a diff file between an older distribution and this one. @@ -2739,22 +2944,22 @@ bootstrap bootstrap-lean: force # To prevent `make install' from compiling alloca.o and then relinking cc1 # because alloca.o is newer, we permit these recursive makes to compile # alloca.o. Then cc1 is newer, so it won't have to be relinked. - $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)" $(MAKE) stage2 -if test $@ = bootstrap-lean; then rm -rf stage1; else true; fi - $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" bootstrap2 bootstrap2-lean: force - $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage1/xgcc$(exeext) -Bstage1/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage1/ LANGUAGES="$(LANGUAGES)" $(MAKE) stage2 -if test $@ = bootstrap2-lean; then rm -rf stage1; else true; fi - $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" bootstrap3 bootstrap3-lean: force - $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage2/xgcc$(exeext) -Bstage2/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage2/ LANGUAGES="$(LANGUAGES)" bootstrap4 bootstrap4-lean: force - $(MAKE) CC="stage3/xgcc$(exeext) -Bstage3/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage3/ LANGUAGES="$(LANGUAGES)" + $(MAKE) CC="stage3/xgcc$(exeext) -Bstage3/ -B$(build_tooldir)/bin/" CFLAGS="$(WARN_CFLAGS) $(BOOT_CFLAGS)" LDFLAGS="$(BOOT_LDFLAGS)" libdir=$(libdir) STAGE_PREFIX=stage3/ LANGUAGES="$(LANGUAGES)" # Compare the object files in the current directory with those in the # stage2 directory. @@ -2769,16 +2974,14 @@ compare compare3 compare4 compare-lean compare3-lean compare4-lean: force && (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 $(SUBDIRS); do \ + for dir in tmp-foo intl $(SUBDIRS); do \ if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \ for file in $$dir/*$(objext); do \ - if [ $$file != objc/NXConstStr.o -a $$file != objc/Object.o -a $$file != objc/Protocol.o -a $$file != objc/linking.o ] ; then \ - 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; \ - else true; fi; \ + 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; \ - fi; \ + 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; \ @@ -2804,14 +3007,12 @@ gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4- (cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&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 $(SUBDIRS); do \ + for dir in tmp-foo intl $(SUBDIRS); do \ if [ "`echo $$dir/*$(objext)`" != "$$dir/*$(objext)" ] ; then \ for file in $$dir/*$(objext); do \ - if [ $$file != objc/NXConstStr.o -a $$file != objc/Object.o -a $$file != objc/Protocol.o -a $$file != objc/linking.o ] ; then \ - (cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \ - else true; fi; \ + (cmp --ignore-initial=16 $$file stage$$stage/$$file > /dev/null 2>&1 || echo $$file differs >> .bad_compare) || true; \ done; \ - fi; \ + 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 \ @@ -2827,11 +3028,12 @@ gnucompare gnucompare3 gnucompare4 gnucompare-lean gnucompare3-lean gnucompare4- # Copy the object files from a particular stage into a subdirectory. stage1-start: -if [ -d stage1 ] ; then true ; else mkdir stage1 ; fi - -for dir in . $(SUBDIRS) ; \ + -for dir in intl $(SUBDIRS) ; \ do \ if [ -d stage1/$$dir ] ; then true ; else mkdir stage1/$$dir ; fi ; \ done -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 $(LN_S) ../as$(exeext) stage1 ; else true ; fi @@ -2839,7 +3041,9 @@ stage1-start: -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage1 ; else true ; fi -rm -f stage1/libgcc.a -cp libgcc.a stage1 - -if $(RANLIB_TEST) ; then $(RANLIB) stage1/libgcc.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) stage1/libgcc.a; \ + else true; fi -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \ cp stage1/$${f} . ; \ else true; \ @@ -2848,11 +3052,12 @@ stage1: force stage1-start lang.stage1 stage2-start: -if [ -d stage2 ] ; then true ; else mkdir stage2 ; fi - -for dir in . $(SUBDIRS) ; \ + -for dir in intl $(SUBDIRS) ; \ do \ if [ -d stage2/$$dir ] ; then true ; else mkdir stage2/$$dir ; fi ; \ done -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 $(LN_S) ../as$(exeext) stage2 ; else true ; fi @@ -2860,7 +3065,9 @@ stage2-start: -if [ -f collect-ld ] ; then $(LN_S) ../collect-ld$(exeext) stage2 ; else true ; fi -rm -f stage2/libgcc.a -cp libgcc.a stage2 - -if $(RANLIB_TEST) ; then $(RANLIB) stage2/libgcc.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) stage2/libgcc.a; \ + else true; fi -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \ cp stage2/$${f} . ; \ else true; \ @@ -2869,11 +3076,12 @@ stage2: force stage2-start lang.stage2 stage3-start: -if [ -d stage3 ] ; then true ; else mkdir stage3 ; fi - -for dir in . $(SUBDIRS) ; \ + -for dir in intl $(SUBDIRS) ; \ do \ if [ -d stage3/$$dir ] ; then true ; else mkdir stage3/$$dir ; fi ; \ done -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 $(LN_S) ../as$(exeext) stage3 ; else true ; fi @@ -2881,7 +3089,9 @@ stage3-start: -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage3 ; else true ; fi -rm -f stage3/libgcc.a -cp libgcc.a stage3 - -if $(RANLIB_TEST) ; then $(RANLIB) stage3/libgcc.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) stage3/libgcc.a; \ + else true; fi -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \ cp stage3/$${f} . ; \ else true; \ @@ -2890,11 +3100,12 @@ stage3: force stage3-start lang.stage3 stage4-start: -if [ -d stage4 ] ; then true ; else mkdir stage4 ; fi - -for dir in . $(SUBDIRS) ; \ + -for dir in intl $(SUBDIRS) ; \ do \ if [ -d stage4/$$dir ] ; then true ; else mkdir stage4/$$dir ; fi ; \ done -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 $(LN_S) ../as$(exeext) stage4 ; else true ; fi @@ -2902,7 +3113,9 @@ stage4-start: -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage4 ; else true ; fi -rm -f stage4/libgcc.a -cp libgcc.a stage4 - -if $(RANLIB_TEST) ; then $(RANLIB) stage4/libgcc.a; else true; fi + -if $(RANLIB_TEST_FOR_TARGET) ; then \ + $(RANLIB_FOR_TARGET) stage4/libgcc.a; \ + else true; fi -for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \ cp stage4/$${f} . ; \ else true; \ diff --git a/contrib/gcc/NEWS b/contrib/gcc/NEWS index 628b03c..427df25 100644 --- a/contrib/gcc/NEWS +++ b/contrib/gcc/NEWS @@ -1,3 +1,11 @@ +Noteworthy changes in GCC after EGCS 1.1. +----------------------------------------- + +Target specific NEWS + + RS6000/PowerPC: -mcpu=401 was added as an alias for -mcpu=403. -mcpu=e603e + was added to do -mcpu=603e and -msoft-float. + Noteworthy changes in GCC for EGCS 1.1. --------------------------------------- diff --git a/contrib/gcc/README b/contrib/gcc/README index c606f65..a12bf75 100644 --- a/contrib/gcc/README +++ b/contrib/gcc/README @@ -1,8 +1,8 @@ -This directory contains the egcs version 1.1.2 release of the GNU C -compiler. It includes all of the support for compiling C++ and -Objective C, including a run-time library for Objective C. +This directory contains the GNU Compiler Collection (GCC) version 2.95. +It includes all of the support for compiling C, C++, Objective C, Fortran, +Java, and Chill. -The GNU C compiler is free software. See the file COPYING for copying +The GNU Compiler Collection is free software. See the file COPYING for copying permission. See the file gcc.texi (together with other files that it includes) for diff --git a/contrib/gcc/acconfig.h b/contrib/gcc/acconfig.h index e1ac384..d702b0e 100644 --- a/contrib/gcc/acconfig.h +++ b/contrib/gcc/acconfig.h @@ -1,9 +1,21 @@ +/* Define if you can safely include both and . */ +#undef STRING_WITH_STRINGS + /* Define if printf supports "%p". */ #undef HAVE_PRINTF_PTR /* Define if you want expensive run-time checks. */ #undef ENABLE_CHECKING +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + /* Define if your cpp understands the stringify operator. */ #undef HAVE_CPP_STRINGIFY @@ -17,9 +29,22 @@ /* Define if your assembler supports .balign and .p2align. */ #undef HAVE_GAS_BALIGN_AND_P2ALIGN +/* 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 uses the old HImode fild and fist notation. */ +#undef HAVE_GAS_FILDS_FISTS + /* Define if you have a working header file. */ #undef HAVE_INTTYPES_H +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define as 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + /* Whether malloc must be declared even if is included. */ #undef NEED_DECLARATION_MALLOC @@ -53,6 +78,9 @@ /* Whether atol must be declared even if is included. */ #undef NEED_DECLARATION_ATOL +/* Whether atof must be declared even if is included. */ +#undef NEED_DECLARATION_ATOF + /* Whether sbrk must be declared even if is included. */ #undef NEED_DECLARATION_SBRK @@ -62,6 +90,12 @@ /* Whether strerror must be declared even if is included. */ #undef NEED_DECLARATION_STRERROR +/* Whether strsignal must be declared even if is included. */ +#undef NEED_DECLARATION_STRSIGNAL + +/* Whether strstr must be declared even if is included. */ +#undef NEED_DECLARATION_STRSTR + /* Whether getcwd must be declared even if is included. */ #undef NEED_DECLARATION_GETCWD @@ -74,6 +108,24 @@ /* Whether setrlimit must be declared even if is included. */ #undef NEED_DECLARATION_SETRLIMIT -/* Define if you want expensive run-time checks. */ -#undef ENABLE_CHECKING +/* Whether putc_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_PUTC_UNLOCKED + +/* Whether fputs_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_FPUTS_UNLOCKED + +/* Define to enable the use of a default assembler. */ +#undef DEFAULT_ASSEMBLER + +/* Define to enable the use of a default linker. */ +#undef DEFAULT_LINKER + +/* Define if host mkdir takes a single argument. */ +#undef MKDIR_TAKES_ONE_ARG + +/* Define to the name of the distribution. */ +#undef PACKAGE + +/* Define to the version of the distribution. */ +#undef VERSION @TOP@ diff --git a/contrib/gcc/aclocal.m4 b/contrib/gcc/aclocal.m4 index febe8a7..fe4d832 100644 --- a/contrib/gcc/aclocal.m4 +++ b/contrib/gcc/aclocal.m4 @@ -1,3 +1,14 @@ +dnl See whether we can include both string.h and strings.h. +AC_DEFUN(GCC_HEADER_STRING, +[AC_CACHE_CHECK([whether string.h and strings.h may both be included], + gcc_cv_header_string, +[AC_TRY_COMPILE([#include +#include ], , gcc_cv_header_string=yes, gcc_cv_header_string=no)]) +if test $gcc_cv_header_string = yes; then + AC_DEFINE(STRING_WITH_STRINGS) +fi +]) + dnl See whether we need a declaration for a function. dnl GCC_NEED_DECLARATION(FUNCTION [, EXTRA-HEADER-FILES]) AC_DEFUN(GCC_NEED_DECLARATION, @@ -5,12 +16,17 @@ AC_DEFUN(GCC_NEED_DECLARATION, AC_CACHE_VAL(gcc_cv_decl_needed_$1, [AC_TRY_COMPILE([ #include -#ifdef HAVE_STRING_H -#include +#ifdef STRING_WITH_STRINGS +# include +# include #else -#ifdef HAVE_STRINGS_H -#include -#endif +# ifdef HAVE_STRING_H +# include +# else +# ifdef HAVE_STRINGS_H +# include +# endif +# endif #endif #ifdef HAVE_STDLIB_H #include @@ -156,6 +172,27 @@ if test $gcc_cv_c_volatile = yes ; then fi ]) +dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead +dnl of the usual 2. +AC_DEFUN(GCC_FUNC_MKDIR_TAKES_ONE_ARG, +[AC_CACHE_CHECK([if mkdir takes one argument], gcc_cv_mkdir_takes_one_arg, +[AC_TRY_COMPILE([ +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_DIRECT_H +# include +#endif], [mkdir ("foo", 0);], + gcc_cv_mkdir_takes_one_arg=no, gcc_cv_mkdir_takes_one_arg=yes)]) +if test $gcc_cv_mkdir_takes_one_arg = yes ; then + AC_DEFINE(MKDIR_TAKES_ONE_ARG) +fi +]) + AC_DEFUN(EGCS_PROG_INSTALL, [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Find a good install program. We prefer a C program (faster), @@ -219,3 +256,404 @@ AC_SUBST(INSTALL_PROGRAM)dnl test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' AC_SUBST(INSTALL_DATA)dnl ]) + +#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"]) + ] +) + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 5 + +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) + + USE_INCLUDED_LIBINTL=no + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + AC_DEFINE(ENABLE_NLS) + 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 gettext or catgets are available (in this order) we + dnl use this. Else we have to fall back to GNU NLS library. + dnl catgets is only used if permitted by option --with-catgets. + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + AC_CHECK_HEADER(libintl.h, + [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, + [AC_TRY_LINK([#include ], [return (int) gettext ("")], + gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) + + if test "$gt_cv_func_gettext_libc" != "yes"; then + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CACHE_CHECK([for gettext in libintl], + gt_cv_func_gettext_libintl, + [AC_CHECK_LIB(intl, gettext, + gt_cv_func_gettext_libintl=yes, + gt_cv_func_gettext_libintl=no)], + gt_cv_func_gettext_libintl=no)]) + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + AC_DEFINE(HAVE_GETTEXT) + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + AC_CHECK_FUNCS(dcgettext) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + INSTOBJEXT=.mo + fi + fi + ]) + + if test "$CATOBJEXT" = "NONE"; then + AC_MSG_CHECKING([whether catgets can be used]) + AC_ARG_WITH(catgets, + [ --with-catgets use catgets functions if available], + nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) + AC_MSG_RESULT($nls_cv_use_catgets) + + if test "$nls_cv_use_catgets" = "yes"; then + dnl No gettext in C library. Try catgets next. + AC_CHECK_LIB(i, main) + AC_CHECK_FUNC(catgets, + [AC_DEFINE(HAVE_CATGETS) + INTLOBJS="\$(CATOBJS)" + AC_PATH_PROG(GENCAT, gencat, no)dnl + if test "$GENCAT" != "no"; then + AC_PATH_PROG(GMSGFMT, gmsgfmt, no) + if test "$GMSGFMT" = "no"; then + AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) + fi + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi]) + fi + fi + + if test "$CATOBJEXT" = "NONE"; then + dnl Neither gettext nor catgets in included 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, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_SUBST(MSGFMT) + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + 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 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.in. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLDEPS) + AC_SUBST(INTLLIBS) + AC_SUBST(INTLOBJS) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +AC_DEFUN(AM_GNU_GETTEXT, + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_CC])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 + AC_REQUIRE([AC_FUNC_MMAP])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ +unistd.h sys/param.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next]) + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + AC_CHECK_FUNCS(stpcpy) + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + AC_DEFINE(HAVE_STPCPY) + fi + + AM_LC_MESSAGES + AM_WITH_NLS + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl The reference to in the installed file + dnl must be resolved because we cannot expect the users of this + dnl to define HAVE_LOCALE_H. + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + AC_SUBST(INCLUDE_LOCALE_H) + + dnl Determine which catalog format we have (if any is needed) + dnl For now we know about two different formats: + dnl Linux libc-5 and the normal X/Open format + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) + + dnl Transform the SED scripts while copying because some dumb SEDs + dnl cannot handle comments. + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + dnl po2tbl.sed is always needed. + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + dnl In the intl/Makefile.in we have a special dependency which makes + dnl only sense for gettext. We comment this out for non-gettext + dnl packages. + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + fi + AC_SUBST(GT_NO) + AC_SUBST(GT_YES) + + 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) + + dnl *** For now the libtool support in intl/Makefile is not for real. + l= + AC_SUBST(l) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +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 ], [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) + fi + fi]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +# serial 1 + +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 -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) diff --git a/contrib/gcc/alias.c b/contrib/gcc/alias.c index 172b676..9d8aac7 100644 --- a/contrib/gcc/alias.c +++ b/contrib/gcc/alias.c @@ -1,5 +1,5 @@ /* Alias analysis for GNU C - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by John Carr (jfc@mit.edu). This file is part of GNU CC. @@ -26,7 +26,51 @@ Boston, MA 02111-1307, USA. */ #include "regs.h" #include "hard-reg-set.h" #include "flags.h" +#include "output.h" #include "toplev.h" +#include "splay-tree.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 to not alias each other. There is one + exception, however. Consider something like: + + 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' + and vice versa.) We indicate this via a tree structure that looks + like: + struct S + / \ + / \ + |/_ _\| + int double + + (The arrows are directed and point downwards.) If, when comparing + two alias sets, we can hold one set fixed, and trace the other set + downwards, and at some point find the first set, the two MEMs can + alias one another. In this situation we say the alias set for + `struct S' is the `superset' and that those for `int' and `double' + are `subsets'. + + 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 { + /* The alias set number, as stored in MEM_ALIAS_SET. */ + int alias_set; + + /* The children of the alias set. These are not just the immediate + children, but, in fact, all children. 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; +}* alias_set_entry; static rtx canon_rtx PROTO((rtx)); static int rtx_equal_for_memref_p PROTO((rtx, rtx)); @@ -35,34 +79,27 @@ static int memrefs_conflict_p PROTO((int, rtx, int, rtx, HOST_WIDE_INT)); static void record_set PROTO((rtx, rtx)); static rtx find_base_term PROTO((rtx)); -static int base_alias_check PROTO((rtx, rtx)); +static int base_alias_check PROTO((rtx, rtx, enum machine_mode, + enum machine_mode)); static rtx find_base_value PROTO((rtx)); +static int mems_in_disjoint_alias_sets_p PROTO((rtx, rtx)); +static int insert_subset_children PROTO((splay_tree_node, + void*)); +static alias_set_entry get_alias_set_entry PROTO((int)); +static rtx fixed_scalar_and_varying_struct_p PROTO((rtx, rtx, int (*)(rtx))); +static int aliases_everything_p PROTO((rtx)); +static int write_dependence_p PROTO((rtx, rtx, int)); /* Set up all info needed to perform alias analysis on memory references. */ #define SIZE_FOR_MODE(X) (GET_MODE_SIZE (GET_MODE (X))) -/* Perform a basic sanity check. Namely, that there are - no alias sets if we're not doing strict aliasing. This helps - to catch bugs whereby someone uses PUT_CODE, but doesn't clear - MEM_ALIAS_SET, or where a MEM is allocated in some way other - than by the use of gen_rtx_MEM, and the MEM_ALIAS_SET is not - cleared. */ -#ifdef ENABLE_CHECKING -#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) \ - (!flag_strict_aliasing \ - && (MEM_ALIAS_SET (MEM1) || MEM_ALIAS_SET (MEM2)) \ - ? (abort (), 0) : 0) -#else -#define CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2) ((void)0) -#endif - /* Returns nonzero if MEM1 and MEM2 do not alias because they are in - different alias sets. */ -#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \ - (CHECK_ALIAS_SETS_FOR_CONSISTENCY(MEM1, MEM2), \ - MEM_ALIAS_SET (MEM1) && MEM_ALIAS_SET (MEM2) \ - && MEM_ALIAS_SET (MEM1) != MEM_ALIAS_SET (MEM2)) + different alias sets. We ignore alias sets in functions making use + of variable arguments because the va_arg macros on some systems are + not legal ANSI C. */ +#define DIFFERENT_ALIAS_SETS_P(MEM1, MEM2) \ + mems_in_disjoint_alias_sets_p (MEM1, MEM2) /* Cap the number of passes we make over the insns propagating alias information through set chains. @@ -89,7 +126,7 @@ rtx *reg_base_value; rtx *new_reg_base_value; unsigned int reg_base_value_size; /* size of reg_base_value array */ #define REG_BASE_VALUE(X) \ - (REGNO (X) < reg_base_value_size ? reg_base_value[REGNO (X)] : 0) + ((unsigned) REGNO (X) < reg_base_value_size ? 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 @@ -126,6 +163,148 @@ char *reg_known_equiv_p; static int copying_arguments; +/* The splay-tree used to store the various alias set entries. */ + +static splay_tree 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) + int alias_set; +{ + splay_tree_node sn = + splay_tree_lookup (alias_sets, (splay_tree_key) alias_set); + + return sn ? ((alias_set_entry) sn->value) : ((alias_set_entry) 0); +} + +/* Returns nonzero value 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; +{ + alias_set_entry ase; + +#ifdef ENABLE_CHECKING +/* Perform a basic sanity check. Namely, that there are no alias sets + if we're not using strict aliasing. This helps to catch bugs + whereby someone uses PUT_CODE, but doesn't clear MEM_ALIAS_SET, or + where a MEM is allocated in some way other than by the use of + gen_rtx_MEM, and the MEM_ALIAS_SET is not cleared. If we begin to + use alias sets to indicate that spilled registers cannot alias each + other, we might need to remove this check. */ + if (!flag_strict_aliasing && + (MEM_ALIAS_SET (mem1) || MEM_ALIAS_SET (mem2))) + abort (); +#endif + + /* The code used in varargs macros are often not conforming ANSI C, + which can trick the compiler into making incorrect aliasing + assumptions in these functions. So, we don't use alias sets in + such a function. FIXME: This should be moved into the front-end; + it is a language-dependent notion, and there's no reason not to + still use these checks to handle globals. */ + if (current_function_stdarg || current_function_varargs) + return 0; + + if (!MEM_ALIAS_SET (mem1) || !MEM_ALIAS_SET (mem2)) + /* We have no alias set information for one of the MEMs, so we + have to assume it can alias anything. */ + return 0; + + if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2)) + /* The two alias sets are the same, so they may alias. */ + return 0; + + /* Iterate through each of the children of the first alias set, + comparing it with the second alias set. */ + ase = get_alias_set_entry (MEM_ALIAS_SET (mem1)); + if (ase && splay_tree_lookup (ase->children, + (splay_tree_key) MEM_ALIAS_SET (mem2))) + return 0; + + /* Now do the same, but with the alias sets reversed. */ + ase = get_alias_set_entry (MEM_ALIAS_SET (mem2)); + if (ase && splay_tree_lookup (ase->children, + (splay_tree_key) MEM_ALIAS_SET (mem1))) + return 0; + + /* The two MEMs are in distinct alias sets, and neither one is the + child of the other. Therefore, they cannot alias. */ + return 1; +} + +/* Insert the NODE into the splay tree given by DATA. Used by + record_alias_subset via splay_tree_foreach. */ + +static int +insert_subset_children (node, data) + splay_tree_node node; + void *data; +{ + splay_tree_insert ((splay_tree) data, + node->key, + node->value); + + 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. At + present any given alias set may only be a subset of one superset. + + It is illegal for SUPERSET to be zero; everything is implicitly a + subset of alias set zero. */ + +void +record_alias_subset (superset, subset) + int superset; + int subset; +{ + alias_set_entry superset_entry; + alias_set_entry subset_entry; + + if (superset == 0) + abort (); + + superset_entry = get_alias_set_entry (superset); + if (!superset_entry) + { + /* 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->alias_set = superset; + superset_entry->children + = splay_tree_new (splay_tree_compare_ints, 0, 0); + splay_tree_insert (alias_sets, + (splay_tree_key) superset, + (splay_tree_value) superset_entry); + + } + + subset_entry = get_alias_set_entry (subset); + if (subset_entry) + /* There is an entry for the subset. Enter all of its children + (if they are not already present) as children of the SUPERSET. */ + splay_tree_foreach (subset_entry->children, + insert_subset_children, + superset_entry->children); + + /* Enter the SUBSET itself as a child of the SUPERSET. */ + splay_tree_insert (superset_entry->children, + (splay_tree_key) subset, + /*value=*/0); +} + /* Inside SRC, the source of a SET, find a base address. */ static rtx @@ -153,7 +332,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 (src) >= FIRST_PSEUDO_REGISTER - && REGNO (src) < reg_base_value_size + && (unsigned) REGNO (src) < reg_base_value_size && reg_base_value[REGNO (src)]) return reg_base_value[REGNO (src)]; @@ -336,7 +515,7 @@ record_base_value (regno, val, invariant) rtx val; int invariant; { - if (regno >= reg_base_value_size) + if ((unsigned) regno >= reg_base_value_size) return; /* If INVARIANT is true then this value also describes an invariant @@ -347,7 +526,7 @@ record_base_value (regno, val, invariant) if (GET_CODE (val) == REG) { - if (REGNO (val) < reg_base_value_size) + if ((unsigned) REGNO (val) < reg_base_value_size) { reg_base_value[regno] = reg_base_value[REGNO (val)]; } @@ -391,9 +570,8 @@ canon_rtx (x) if (addr != XEXP (x, 0)) { rtx new = gen_rtx_MEM (GET_MODE (x), addr); - MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x); RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); - MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x); + MEM_COPY_ATTRIBUTES (new, x); MEM_ALIAS_SET (new) = MEM_ALIAS_SET (x); x = new; } @@ -568,10 +746,55 @@ find_base_term (x) case PLUS: case MINUS: { - rtx tmp = find_base_term (XEXP (x, 0)); - if (tmp) - return tmp; - return find_base_term (XEXP (x, 1)); + rtx tmp1 = XEXP (x, 0); + rtx tmp2 = XEXP (x, 1); + + /* This is a litle bit tricky since we have to determine which of + the two operands represents the real base address. Otherwise this + routine may return the index register instead of the base register. + + That may cause us to believe no aliasing was possible, when in + fact aliasing is possible. + + We use a few simple tests to guess the base register. Additional + tests can certainly be added. For example, if one of the operands + is a shift or multiply, then it must be the index register and the + other operand is the base register. */ + + /* If either operand is known to be a pointer, then use it + to determine the base term. */ + if (REG_P (tmp1) && REGNO_POINTER_FLAG (REGNO (tmp1))) + return find_base_term (tmp1); + + if (REG_P (tmp2) && REGNO_POINTER_FLAG (REGNO (tmp2))) + return find_base_term (tmp2); + + /* Neither operand was known to be a pointer. Go ahead and find the + base term for both operands. */ + tmp1 = find_base_term (tmp1); + tmp2 = find_base_term (tmp2); + + /* If either base term is named object or a special address + (like an argument or stack reference), then use it for the + base term. */ + if (tmp1 + && (GET_CODE (tmp1) == SYMBOL_REF + || GET_CODE (tmp1) == LABEL_REF + || (GET_CODE (tmp1) == ADDRESS + && GET_MODE (tmp1) != VOIDmode))) + return tmp1; + + if (tmp2 + && (GET_CODE (tmp2) == SYMBOL_REF + || GET_CODE (tmp2) == LABEL_REF + || (GET_CODE (tmp2) == ADDRESS + && GET_MODE (tmp2) != VOIDmode))) + return tmp2; + + /* We could not determine which of the two operands was the + base register and which was the index. So we can determine + nothing from the base alias check. */ + return 0; } case AND: @@ -592,8 +815,9 @@ find_base_term (x) objects, 1 if they might be pointers to the same object. */ static int -base_alias_check (x, y) +base_alias_check (x, y, x_mode, y_mode) rtx x, y; + enum machine_mode x_mode, y_mode; { rtx x_base = find_base_term (x); rtx y_base = find_base_term (y); @@ -625,17 +849,25 @@ base_alias_check (x, y) if (rtx_equal_p (x_base, y_base)) return 1; - /* The base addresses of the read and write are different - expressions. If they are both symbols and they are not accessed - via AND, there is no conflict. */ - /* XXX: We can bring knowledge of object alignment and offset into - play here. For example, on alpha, "char a, b;" can alias one - another, though "char a; long b;" cannot. Similarly, offsets - into strutures may be brought into play. Given "char a, b[40];", - a and b[1] may overlap, but a and b[20] do not. */ + /* The base addresses of the read and write are different expressions. + If they are both symbols and they are not accessed via AND, there is + no conflict. We can bring knowledge of object alignment into play + here. For example, on alpha, "char a, b;" can alias one another, + though "char a; long b;" cannot. */ if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS) { - return GET_CODE (x) == AND || GET_CODE (y) == AND; + if (GET_CODE (x) == AND && GET_CODE (y) == AND) + return 1; + if (GET_CODE (x) == AND + && (GET_CODE (XEXP (x, 1)) != CONST_INT + || GET_MODE_UNIT_SIZE (y_mode) < -INTVAL (XEXP (x, 1)))) + return 1; + if (GET_CODE (y) == AND + && (GET_CODE (XEXP (y, 1)) != CONST_INT + || GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1)))) + return 1; + /* Differing symbols never alias. */ + return 0; } /* If one address is a stack reference there can be no alias: @@ -656,6 +888,45 @@ base_alias_check (x, y) return ! (GET_MODE (x_base) == VOIDmode && GET_MODE (y_base) == VOIDmode); } +/* Return the address of the (N_REFS + 1)th memory reference to ADDR + where SIZE is the size in bytes of the memory reference. If ADDR + 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; +{ + int offset = 0; + + switch (GET_CODE (addr)) + { + case PRE_INC: + offset = (n_refs + 1) * size; + break; + case PRE_DEC: + offset = -(n_refs + 1) * size; + break; + case POST_INC: + offset = n_refs * size; + break; + case POST_DEC: + offset = -n_refs * size; + break; + + default: + return addr; + } + + if (offset) + addr = gen_rtx_PLUS (GET_MODE (addr), XEXP (addr, 0), GEN_INT (offset)); + else + addr = XEXP (addr, 0); + + return addr; +} + /* Return nonzero if X and Y (memory addresses) could reference the same location in memory. C is an offset accumulator. When C is nonzero, we are testing aliases between X and Y + C. @@ -685,13 +956,13 @@ memrefs_conflict_p (xsize, x, ysize, y, c) else if (GET_CODE (x) == LO_SUM) x = XEXP (x, 1); else - x = canon_rtx (x); + x = canon_rtx (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 (y); + y = canon_rtx (addr_side_effect_eval (y, ysize, 0)); if (rtx_equal_for_memref_p (x, y)) { @@ -726,11 +997,14 @@ memrefs_conflict_p (xsize, x, ysize, y, c) if (rtx_equal_for_memref_p (x0, y0)) return memrefs_conflict_p (xsize, x1, ysize, y1, c); if (GET_CODE (x1) == CONST_INT) - if (GET_CODE (y1) == CONST_INT) - return memrefs_conflict_p (xsize, x0, ysize, y0, - c - INTVAL (x1) + INTVAL (y1)); - else - return memrefs_conflict_p (xsize, x0, ysize, y, c - INTVAL (x1)); + { + if (GET_CODE (y1) == CONST_INT) + return memrefs_conflict_p (xsize, x0, ysize, y0, + c - INTVAL (x1) + INTVAL (y1)); + else + return memrefs_conflict_p (xsize, x0, ysize, y, + c - INTVAL (x1)); + } else if (GET_CODE (y1) == CONST_INT) return memrefs_conflict_p (xsize, x, ysize, y0, c + INTVAL (y1)); @@ -784,7 +1058,7 @@ memrefs_conflict_p (xsize, x, ysize, y, c) /* Are these registers known not to be equal? */ if (alias_invariant) { - int r_x = REGNO (x), r_y = REGNO (y); + 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]; @@ -804,18 +1078,24 @@ memrefs_conflict_p (xsize, x, ysize, y, c) } /* Treat an access through an AND (e.g. a subword access on an Alpha) - as an access with indeterminate size. - ??? Could instead convert an n byte reference at (and x y) to an - n-y byte reference at (plus x y). */ + as an access with indeterminate size. Assume that references + besides AND are aligned, so if the size of the other reference is + at least as large as the alignment, assume no other overlap. */ if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT) - return memrefs_conflict_p (-1, XEXP (x, 0), 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); + } if (GET_CODE (y) == AND && GET_CODE (XEXP (y, 1)) == CONST_INT) { - /* XXX: If we are indexing far enough into the array/structure, we + /* ??? If we are indexing far enough into the array/structure, we may yet be able to determine that we can not overlap. But we also need to that we are far enough from the end not to overlap - a following reference, so we do nothing for now. */ - return memrefs_conflict_p (xsize, x, -1, XEXP (y, 0), 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); } if (CONSTANT_P (x)) @@ -883,6 +1163,56 @@ read_dependence (mem, x) return MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem); } +/* Returns MEM1 if and only if MEM1 is a scalar at a fixed address and + MEM2 is a reference to a structure at a varying address, or returns + MEM2 if vice versa. Otherwise, returns NULL_RTX. If a non-NULL + value is returned MEM1 and MEM2 can never alias. VARIES_P is used + to decide whether or not an address may vary; it should return + nozero whenever variation is possible. */ + +static rtx +fixed_scalar_and_varying_struct_p (mem1, mem2, varies_p) + rtx mem1; + rtx mem2; + int (*varies_p) PROTO((rtx)); +{ + rtx mem1_addr = XEXP (mem1, 0); + rtx mem2_addr = XEXP (mem2, 0); + + if (MEM_SCALAR_P (mem1) && MEM_IN_STRUCT_P (mem2) + && !varies_p (mem1_addr) && varies_p (mem2_addr)) + /* MEM1 is a scalar at a fixed address; MEM2 is a struct at a + varying address. */ + return mem1; + + if (MEM_IN_STRUCT_P (mem1) && MEM_SCALAR_P (mem2) + && varies_p (mem1_addr) && !varies_p (mem2_addr)) + /* MEM2 is a scalar at a fixed address; MEM1 is a struct at a + varying address. */ + return mem2; + + return NULL_RTX; +} + +/* Returns nonzero if something about the mode or address format MEM1 + indicates that it might well alias *anything*. */ + +static int +aliases_everything_p (mem) + rtx mem; +{ + if (GET_MODE (mem) == QImode) + /* ANSI C says that a `char*' can point to anything. */ + return 1; + + if (GET_CODE (XEXP (mem, 0)) == AND) + /* If the address is an AND, its very hard to know at what it is + actually pointing. */ + return 1; + + return 0; +} + /* True dependence: X is read after store in MEM takes place. */ int @@ -910,59 +1240,46 @@ true_dependence (mem, mem_mode, x, varies) if (RTX_UNCHANGING_P (x) && ! RTX_UNCHANGING_P (mem)) return 0; - if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0))) + if (mem_mode == VOIDmode) + mem_mode = GET_MODE (mem); + + if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x), mem_mode)) return 0; x_addr = canon_rtx (XEXP (x, 0)); mem_addr = canon_rtx (XEXP (mem, 0)); - if (mem_mode == VOIDmode) - mem_mode = GET_MODE (mem); - if (! memrefs_conflict_p (GET_MODE_SIZE (mem_mode), mem_addr, SIZE_FOR_MODE (x), x_addr, 0)) return 0; - /* If both references are struct references, or both are not, nothing - is known about aliasing. - - If either reference is QImode or BLKmode, ANSI C permits aliasing. - - If both addresses are constant, or both are not, nothing is known - about aliasing. */ - if (MEM_IN_STRUCT_P (x) == MEM_IN_STRUCT_P (mem) - || mem_mode == QImode || mem_mode == BLKmode - || GET_MODE (x) == QImode || GET_MODE (x) == BLKmode - || GET_CODE (x_addr) == AND || GET_CODE (mem_addr) == AND - || varies (x_addr) == varies (mem_addr)) + if (aliases_everything_p (x)) return 1; - /* One memory reference is to a constant address, one is not. - One is to a structure, the other is not. - - If either memory reference is a variable structure the other is a - fixed scalar and there is no aliasing. */ + /* We cannot use aliases_everyting_p to test MEM, since we must look + at MEM_MODE, rather than GET_MODE (MEM). */ + if (mem_mode == QImode || GET_CODE (mem_addr) == AND) + return 1; - /* Disabled by default for egcs 1.1.x as alias analysis isn't good - enough yet to discover all cases where this doesn't apply. */ - if (flag_structure_noalias) - { - if ((MEM_IN_STRUCT_P (mem) && varies (mem_addr)) - || (MEM_IN_STRUCT_P (x) && varies (x_addr))) - return 0; - } + /* In true_dependence we also allow BLKmode to alias anything. Why + don't we do this in anti_dependence and output_dependence? */ + if (mem_mode == BLKmode || GET_MODE (x) == BLKmode) + return 1; - return 1; + return !fixed_scalar_and_varying_struct_p (mem, x, varies); } -/* Anti dependence: X is written after read in MEM takes place. */ +/* Returns non-zero if a write to X might alias a previous read from + (or, if WRITEP is non-zero, a write to) MEM. */ -int -anti_dependence (mem, x) +static int +write_dependence_p (mem, x, writep) rtx mem; rtx x; + int writep; { rtx x_addr, mem_addr; + rtx fixed_scalar; if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) return 1; @@ -970,10 +1287,11 @@ anti_dependence (mem, x) /* 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 (RTX_UNCHANGING_P (mem)) + if (!writep && RTX_UNCHANGING_P (mem)) return 0; - if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0))) + if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0), GET_MODE (x), + GET_MODE (mem))) return 0; x = canon_rtx (x); @@ -985,16 +1303,25 @@ anti_dependence (mem, x) x_addr = XEXP (x, 0); mem_addr = XEXP (mem, 0); - return (memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, - SIZE_FOR_MODE (x), x_addr, 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && GET_CODE (mem_addr) != AND - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && GET_CODE (x_addr) != AND - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); + if (!memrefs_conflict_p (SIZE_FOR_MODE (mem), mem_addr, + SIZE_FOR_MODE (x), x_addr, 0)) + return 0; + + fixed_scalar + = fixed_scalar_and_varying_struct_p (mem, x, rtx_addr_varies_p); + + return (!(fixed_scalar == mem && !aliases_everything_p (x)) + && !(fixed_scalar == x && !aliases_everything_p (mem))); +} + +/* Anti dependence: X is written after read in MEM takes place. */ + +int +anti_dependence (mem, x) + rtx mem; + rtx x; +{ + return write_dependence_p (mem, x, /*writep=*/0); } /* Output dependence: X is written after store in MEM takes place. */ @@ -1004,28 +1331,7 @@ output_dependence (mem, x) register rtx mem; register rtx x; { - if (MEM_VOLATILE_P (x) && MEM_VOLATILE_P (mem)) - return 1; - - if (! base_alias_check (XEXP (x, 0), XEXP (mem, 0))) - return 0; - - x = canon_rtx (x); - mem = canon_rtx (mem); - - if (DIFFERENT_ALIAS_SETS_P (x, mem)) - return 0; - - return (memrefs_conflict_p (SIZE_FOR_MODE (mem), XEXP (mem, 0), - SIZE_FOR_MODE (x), XEXP (x, 0), 0) - && ! (MEM_IN_STRUCT_P (mem) && rtx_addr_varies_p (mem) - && GET_MODE (mem) != QImode - && GET_CODE (XEXP (mem, 0)) != AND - && ! MEM_IN_STRUCT_P (x) && ! rtx_addr_varies_p (x)) - && ! (MEM_IN_STRUCT_P (x) && rtx_addr_varies_p (x) - && GET_MODE (x) != QImode - && GET_CODE (XEXP (x, 0)) != AND - && ! MEM_IN_STRUCT_P (mem) && ! rtx_addr_varies_p (mem))); + return write_dependence_p (mem, x, /*writep=*/1); } @@ -1046,6 +1352,8 @@ init_alias_once () if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i)) && HARD_REGNO_MODE_OK (i, Pmode)) SET_HARD_REG_BIT (argument_registers, i); + + alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0); } void @@ -1054,6 +1362,7 @@ init_alias_analysis () int maxreg = max_reg_num (); int changed, pass; register int i; + register unsigned int ui; register rtx insn; reg_known_value_size = maxreg; @@ -1194,13 +1503,13 @@ init_alias_analysis () } /* Now propagate values from new_reg_base_value to reg_base_value. */ - for (i = 0; i < reg_base_value_size; i++) + for (ui = 0; ui < reg_base_value_size; ui++) { - if (new_reg_base_value[i] - && new_reg_base_value[i] != reg_base_value[i] - && ! rtx_equal_p (new_reg_base_value[i], reg_base_value[i])) + 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])) { - reg_base_value[i] = new_reg_base_value[i]; + reg_base_value[ui] = new_reg_base_value[ui]; changed = 1; } } @@ -1227,16 +1536,16 @@ init_alias_analysis () { changed = 0; pass++; - for (i = 0; i < reg_base_value_size; i++) + for (ui = 0; ui < reg_base_value_size; ui++) { - rtx base = reg_base_value[i]; + rtx base = reg_base_value[ui]; if (base && GET_CODE (base) == REG) { - int base_regno = REGNO (base); - if (base_regno == i) /* register set from itself */ - reg_base_value[i] = 0; + unsigned int base_regno = REGNO (base); + if (base_regno == ui) /* register set from itself */ + reg_base_value[ui] = 0; else - reg_base_value[i] = reg_base_value[base_regno]; + reg_base_value[ui] = reg_base_value[base_regno]; changed = 1; } } diff --git a/contrib/gcc/basic-block.h b/contrib/gcc/basic-block.h index 552f74a..fa3d56f 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 Free Software Foundation, Inc. + Copyright (C) 1987, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -20,6 +20,8 @@ Boston, MA 02111-1307, USA. */ #include "bitmap.h" +#include "sbitmap.h" +#include "varray.h" typedef bitmap regset; /* Head of register set linked list. */ @@ -94,29 +96,65 @@ do { \ /* Grow any tables needed when the number of registers is calculated or extended. For the linked list allocation, nothing needs to be done, other than zero the statistics on the first allocation. */ -#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P) +#define MAX_REGNO_REG_SET(NUM_REGS, NEW_P, RENUMBER_P) -/* Number of basic blocks in the current function. */ +/* Control flow edge information. */ +typedef struct edge_def { + /* Links through the predecessor and successor lists. */ + struct edge_def *pred_next, *succ_next; -extern int n_basic_blocks; + /* The two blocks at the ends of the edge. */ + struct basic_block_def *src, *dest; + + /* Instructions queued on the edge. */ + rtx insns; + + /* Auxiliary info specific to a pass. */ + void *aux; + + int flags; /* see EDGE_* below */ + int probability; /* biased by REG_BR_PROB_BASE */ +} *edge; + +#define EDGE_FALLTHRU 1 +#define EDGE_CRITICAL 2 +#define EDGE_ABNORMAL 4 +#define EDGE_ABNORMAL_CALL 8 +#define EDGE_EH 16 +#define EDGE_FAKE 32 + + +/* Basic block information indexed by block number. */ +typedef struct basic_block_def { + /* The first and last insns of the block. */ + rtx head, end; + + /* The edges into and out of the block. */ + edge pred, succ; -/* Index by basic block number, get first insn in the block. */ + /* Liveness info. */ + regset local_set; + regset global_live_at_start; + regset global_live_at_end; -extern rtx *basic_block_head; + /* Auxiliary info specific to a pass. */ + void *aux; -/* Index by basic block number, get last insn in the block. */ + /* The index of this block. */ + int index; + /* The loop depth of this block plus one. */ + int loop_depth; +} *basic_block; -extern rtx *basic_block_end; +/* Number of basic blocks in the current function. */ -/* Index by basic block number, determine whether the block can be reached - through a computed jump. */ +extern int n_basic_blocks; -extern char *basic_block_computed_jump_target; +/* Index by basic block number, get basic block struct info. */ -/* Index by basic block number, get address of regset - describing the registers live at the start of that block. */ +extern varray_type basic_block_info; -extern regset *basic_block_live_at_start; +#define BASIC_BLOCK(N) (VARRAY_BB (basic_block_info, (N))) /* What registers are live at the setjmp call. */ @@ -176,91 +214,49 @@ extern void free_int_list PROTO ((int_list_block **)); /* Stuff for recording basic block info. */ -#define BLOCK_HEAD(B) basic_block_head[(B)] -#define BLOCK_END(B) basic_block_end[(B)] +#define BLOCK_HEAD(B) (BASIC_BLOCK (B)->head) +#define BLOCK_END(B) (BASIC_BLOCK (B)->end) /* Special block numbers [markers] for entry and exit. */ #define ENTRY_BLOCK (-1) #define EXIT_BLOCK (-2) +/* Similarly, block pointers for the edge list. */ +extern struct basic_block_def entry_exit_blocks[2]; +#define ENTRY_BLOCK_PTR (&entry_exit_blocks[0]) +#define EXIT_BLOCK_PTR (&entry_exit_blocks[1]) + /* from flow.c */ -extern void free_regset_vector PROTO ((regset *, int nelts)); -extern int *uid_block_number; -#define BLOCK_NUM(INSN) uid_block_number[INSN_UID (INSN)] - -extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *, - int *, int *)); -extern void dump_bb_data PROTO ((FILE *, int_list_ptr *, int_list_ptr *)); -extern void free_bb_mem PROTO ((void)); -extern void free_basic_block_vars PROTO ((int)); +extern void free_regset_vector PROTO ((regset *, int nelts)); - -/* Simple bitmaps. - 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 - while more important issues are dealt with. */ - -#define SBITMAP_ELT_BITS HOST_BITS_PER_WIDE_INT -#define SBITMAP_ELT_TYPE unsigned HOST_WIDE_INT - -typedef struct simple_bitmap_def { - /* Number of bits. */ - int n_bits; - /* Size in elements. */ - int size; - /* Size in bytes. */ - int bytes; - /* The elements. */ - SBITMAP_ELT_TYPE elms[1]; -} *sbitmap; - -typedef SBITMAP_ELT_TYPE *sbitmap_ptr; - -/* Return the set size needed for N elements. */ -#define SBITMAP_SET_SIZE(n) (((n) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS) - -/* set bit number bitno in the bitmap */ -#define SET_BIT(bitmap, bitno) \ -do { \ - (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS; \ -} while (0) +extern varray_type basic_block_for_insn; +#define BLOCK_FOR_INSN(INSN) VARRAY_BB (basic_block_for_insn, INSN_UID (INSN)) +#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0) -/* test if bit number bitno in the bitmap is set */ -#define TEST_BIT(bitmap, bitno) \ -((bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] & ((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS)) +extern void set_block_for_insn PROTO ((rtx, basic_block)); -/* reset bit number bitno in the bitmap */ -#define RESET_BIT(bitmap, bitno) \ -do { \ - (bitmap)->elms [(bitno) / SBITMAP_ELT_BITS] &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS); \ -} while (0) +extern void dump_bb_data PROTO ((FILE *, int_list_ptr *, + int_list_ptr *, int)); +extern void free_bb_mem PROTO ((void)); +extern void free_basic_block_vars PROTO ((int)); + +extern basic_block split_edge PROTO ((edge)); +extern void insert_insn_on_edge PROTO ((rtx, edge)); +extern void commit_edge_insertions PROTO ((void)); -extern void dump_sbitmap PROTO ((FILE *, sbitmap)); -extern void dump_sbitmap_vector PROTO ((FILE *, char *, char *, - sbitmap *, int)); -extern sbitmap sbitmap_alloc PROTO ((int)); -extern sbitmap *sbitmap_vector_alloc PROTO ((int, int)); -extern void sbitmap_copy PROTO ((sbitmap, sbitmap)); -extern void sbitmap_zero PROTO ((sbitmap)); -extern void sbitmap_ones PROTO ((sbitmap)); -extern void sbitmap_vector_zero PROTO ((sbitmap *, int)); -extern void sbitmap_vector_ones PROTO ((sbitmap *, int)); -extern int sbitmap_union_of_diff PROTO ((sbitmap, sbitmap, sbitmap, sbitmap)); -extern void sbitmap_difference PROTO ((sbitmap, sbitmap, sbitmap)); -extern void sbitmap_not PROTO ((sbitmap, sbitmap)); -extern int sbitmap_a_or_b_and_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap)); -extern int sbitmap_a_and_b_or_c PROTO ((sbitmap, sbitmap, sbitmap, sbitmap)); -extern int sbitmap_a_and_b PROTO ((sbitmap, sbitmap, sbitmap)); -extern int sbitmap_a_or_b PROTO ((sbitmap, sbitmap, sbitmap)); -extern void sbitmap_intersect_of_predsucc PROTO ((sbitmap, sbitmap *, - int, int_list_ptr *)); -extern void sbitmap_intersect_of_predecessors PROTO ((sbitmap, sbitmap *, int, - int_list_ptr *)); -extern void sbitmap_intersect_of_successors PROTO ((sbitmap, sbitmap *, int, - int_list_ptr *)); -extern void sbitmap_union_of_predecessors PROTO ((sbitmap, sbitmap *, int, - int_list_ptr *)); -extern void sbitmap_union_of_successors PROTO ((sbitmap, sbitmap *, int, +extern void compute_preds_succs PROTO ((int_list_ptr *, int_list_ptr *, + int *, int *)); +extern void compute_dominators PROTO ((sbitmap *, sbitmap *, + int_list_ptr *, int_list_ptr *)); -extern void compute_dominators PROTO ((sbitmap *, sbitmap *, - int_list_ptr *, int_list_ptr *)); +extern void compute_immediate_dominators PROTO ((int *, sbitmap *)); + +/* In lcm.c */ +extern void pre_lcm PROTO ((int, int, int_list_ptr *, + int_list_ptr *, + sbitmap *, sbitmap *, + sbitmap *, sbitmap *)); +extern void pre_rev_lcm PROTO ((int, int, int_list_ptr *, + int_list_ptr *, + sbitmap *, sbitmap *, + sbitmap *, sbitmap *)); diff --git a/contrib/gcc/bitmap.c b/contrib/gcc/bitmap.c index a5aa2e7..b4fc097 100644 --- a/contrib/gcc/bitmap.c +++ b/contrib/gcc/bitmap.c @@ -613,10 +613,10 @@ void bitmap_print (file, head, prefix, suffix) FILE *file; bitmap head; - char *prefix; - char *suffix; + const char *prefix; + const char *suffix; { - char *comma = ""; + const char *comma = ""; int i; fputs (prefix, file); diff --git a/contrib/gcc/bitmap.h b/contrib/gcc/bitmap.h index 2941574..4ff0bf4 100644 --- a/contrib/gcc/bitmap.h +++ b/contrib/gcc/bitmap.h @@ -1,5 +1,5 @@ /* Functions to support general ended bitmaps. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -48,7 +48,7 @@ typedef struct bitmap_element_def typedef struct bitmap_head_def { bitmap_element *first; /* First element in linked list. */ bitmap_element *current; /* Last element looked at. */ - int indx; /* Index of last element looked at. */ + unsigned int indx; /* Index of last element looked at. */ } bitmap_head, *bitmap; /* Enumeration giving the various operations we support. */ @@ -89,7 +89,7 @@ extern void bitmap_debug PROTO((bitmap)); extern void bitmap_debug_file PROTO((FILE *, bitmap)); /* Print a bitmap */ -extern void bitmap_print PROTO((FILE *, bitmap, char *, char *)); +extern void bitmap_print PROTO((FILE *, bitmap, const char *, const char *)); /* Initialize a bitmap header. */ extern bitmap bitmap_initialize PROTO((bitmap)); diff --git a/contrib/gcc/c-aux-info.c b/contrib/gcc/c-aux-info.c index 3e2edde..9a66350 100644 --- a/contrib/gcc/c-aux-info.c +++ b/contrib/gcc/c-aux-info.c @@ -1,7 +1,7 @@ /* Generate information regarding function declarations and definitions based on information stored in GCC's tree structure. This code implements the -aux-info option. - Copyright (C) 1989, 91, 94, 95, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 91, 94, 95, 97-98, 1999 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@segfault.us.com). This file is part of GNU CC. @@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" +#include "toplev.h" #include "flags.h" #include "tree.h" #include "c-tree.h" @@ -35,67 +36,75 @@ enum formals_style_enum { typedef enum formals_style_enum formals_style; -static char *data_type; +static const char *data_type; -static char *concat PROTO((char *, char *)); -static char *concat3 PROTO((char *, char *, char *)); -static char *affix_data_type PROTO((char *)); -static char *gen_formal_list_for_type PROTO((tree, formals_style)); +static char *affix_data_type PROTO((const char *)); +static const char *gen_formal_list_for_type PROTO((tree, formals_style)); static int deserves_ellipsis PROTO((tree)); -static char *gen_formal_list_for_func_def PROTO((tree, formals_style)); -static char *gen_type PROTO((char *, tree, formals_style)); -static char *gen_decl PROTO((tree, int, formals_style)); +static const char *gen_formal_list_for_func_def PROTO((tree, formals_style)); +static const char *gen_type PROTO((const char *, tree, formals_style)); +static const char *gen_decl PROTO((tree, int, formals_style)); -/* Take two strings and mash them together into a newly allocated area. */ +/* Concatenate a sequence of strings, returning the result. -static char * -concat (s1, s2) - char *s1; - char *s2; + This function is based on the one in libiberty. */ + +/* This definition will conflict with the one from prefix.c in + libcpp.a when linking cc1 and cc1obj. So only provide it if we are + not using libcpp.a */ +#ifndef USE_CPPLIB +char * +concat VPROTO((const char *first, ...)) { - int size1, size2; - char *ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - ret_val = xmalloc (size1 + size2 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - return ret_val; -} + register int length; + register char *newstr; + register char *end; + register const char *arg; + va_list args; +#ifndef ANSI_PROTOTYPES + const char *first; +#endif + + /* First compute the size of the result and get sufficient memory. */ + + VA_START (args, first); +#ifndef ANSI_PROTOTYPES + first = va_arg (args, const char *); +#endif + + arg = first; + length = 0; + + while (arg != 0) + { + length += strlen (arg); + arg = va_arg (args, const char *); + } -/* Take three strings and mash them together into a newly allocated area. */ + newstr = (char *) malloc (length + 1); + va_end (args); -static char * -concat3 (s1, s2, s3) - char *s1; - char *s2; - char *s3; -{ - int size1, size2, size3; - char *ret_val; - - if (!s1) - s1 = ""; - if (!s2) - s2 = ""; - if (!s3) - s3 = ""; - - size1 = strlen (s1); - size2 = strlen (s2); - size3 = strlen (s3); - ret_val = xmalloc (size1 + size2 + size3 + 1); - strcpy (ret_val, s1); - strcpy (&ret_val[size1], s2); - strcpy (&ret_val[size1+size2], s3); - return ret_val; + /* Now copy the individual pieces to the result string. */ + + VA_START (args, first); +#ifndef ANSI_PROTOTYPES + first = va_arg (args, char *); +#endif + + end = newstr; + arg = first; + while (arg != 0) + { + while (*arg) + *end++ = *arg++; + arg = va_arg (args, const char *); + } + *end = '\000'; + va_end (args); + + return (newstr); } +#endif /* ! USE_CPPLIB */ /* Given a string representing an entire type or an entire declaration which only lacks the actual "data-type" specifier (at its left end), @@ -112,13 +121,16 @@ concat3 (s1, s2, s3) that look as expected. */ static char * -affix_data_type (type_or_decl) - char *type_or_decl; +affix_data_type (param) + const char *param; { + char *type_or_decl = (char *) alloca (strlen (param) + 1); char *p = type_or_decl; char *qualifiers_then_data_type; char saved; + strcpy (type_or_decl, param); + /* Skip as many leading const's or volatile's as there are. */ for (;;) @@ -140,13 +152,13 @@ affix_data_type (type_or_decl) add a blank after the data-type of course. */ if (p == type_or_decl) - return concat3 (data_type, " ", type_or_decl); + return concat (data_type, " ", type_or_decl, NULL_PTR); saved = *p; *p = '\0'; - qualifiers_then_data_type = concat (type_or_decl, data_type); + qualifiers_then_data_type = concat (type_or_decl, data_type, NULL_PTR); *p = saved; - return concat3 (qualifiers_then_data_type, " ", p); + return concat (qualifiers_then_data_type, " ", p, NULL_PTR); } /* Given a tree node which represents some "function type", generate the @@ -156,12 +168,12 @@ affix_data_type (type_or_decl) we are currently aiming for is non-ansi, then we just return a pair of empty parens here. */ -static char * +static const char * gen_formal_list_for_type (fntype, style) tree fntype; formals_style style; { - char *formal_list = ""; + const char *formal_list = ""; tree formal_type; if (style != ansi) @@ -170,16 +182,16 @@ gen_formal_list_for_type (fntype, style) formal_type = TYPE_ARG_TYPES (fntype); while (formal_type && TREE_VALUE (formal_type) != void_type_node) { - char *this_type; + const char *this_type; if (*formal_list) - formal_list = concat (formal_list, ", "); + formal_list = concat (formal_list, ", ", NULL_PTR); this_type = gen_type ("", TREE_VALUE (formal_type), ansi); formal_list = ((strlen (this_type)) - ? concat (formal_list, affix_data_type (this_type)) - : concat (formal_list, data_type)); + ? concat (formal_list, affix_data_type (this_type), NULL_PTR) + : concat (formal_list, data_type, NULL_PTR)); formal_type = TREE_CHAIN (formal_type); } @@ -228,10 +240,10 @@ gen_formal_list_for_type (fntype, style) petered out to a NULL (i.e. without being terminated by a void_type_node) then we need to tack on an ellipsis. */ if (!formal_type) - formal_list = concat (formal_list, ", ..."); + formal_list = concat (formal_list, ", ...", NULL_PTR); } - return concat3 (" (", formal_list, ")"); + return concat (" (", formal_list, ")", NULL_PTR); } /* For the generation of an ANSI prototype for a function definition, we have @@ -276,37 +288,37 @@ deserves_ellipsis (fntype) This routine returns a string which is the source form for the entire function formal parameter list. */ -static char * +static const char * gen_formal_list_for_func_def (fndecl, style) tree fndecl; formals_style style; { - char *formal_list = ""; + const char *formal_list = ""; tree formal_decl; formal_decl = DECL_ARGUMENTS (fndecl); while (formal_decl) { - char *this_formal; + const char *this_formal; if (*formal_list && ((style == ansi) || (style == k_and_r_names))) - formal_list = concat (formal_list, ", "); + formal_list = concat (formal_list, ", ", NULL_PTR); this_formal = gen_decl (formal_decl, 0, style); if (style == k_and_r_decls) - formal_list = concat3 (formal_list, this_formal, "; "); + formal_list = concat (formal_list, this_formal, "; ", NULL_PTR); else - formal_list = concat (formal_list, this_formal); + formal_list = concat (formal_list, this_formal, NULL_PTR); formal_decl = TREE_CHAIN (formal_decl); } if (style == ansi) { if (!DECL_ARGUMENTS (fndecl)) - formal_list = concat (formal_list, "void"); + formal_list = concat (formal_list, "void", NULL_PTR); if (deserves_ellipsis (TREE_TYPE (fndecl))) - formal_list = concat (formal_list, ", ..."); + formal_list = concat (formal_list, ", ...", NULL_PTR); } if ((style == ansi) || (style == k_and_r_names)) - formal_list = concat3 (" (", formal_list, ")"); + formal_list = concat (" (", formal_list, ")", NULL_PTR); return formal_list; } @@ -351,9 +363,9 @@ gen_formal_list_for_func_def (fndecl, style) to do at this point is for the initial caller to prepend the "data_type" string onto the returned "seed". */ -static char * +static const char * gen_type (ret_val, t, style) - char *ret_val; + const char *ret_val; tree t; formals_style style; { @@ -368,14 +380,14 @@ gen_type (ret_val, t, style) { case POINTER_TYPE: if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); + ret_val = concat ("const ", ret_val, NULL_PTR); if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); + ret_val = concat ("volatile ", ret_val, NULL_PTR); - ret_val = concat ("*", ret_val); + ret_val = concat ("*", ret_val, NULL_PTR); if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE || TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - ret_val = concat3 ("(", ret_val, ")"); + ret_val = concat ("(", ret_val, ")", NULL_PTR); ret_val = gen_type (ret_val, TREE_TYPE (t), style); @@ -383,21 +395,26 @@ gen_type (ret_val, t, style) case ARRAY_TYPE: if (TYPE_SIZE (t) == 0 || TREE_CODE (TYPE_SIZE (t)) != INTEGER_CST) - ret_val = gen_type (concat (ret_val, "[]"), TREE_TYPE (t), style); + ret_val = gen_type (concat (ret_val, "[]", NULL_PTR), + TREE_TYPE (t), style); else if (int_size_in_bytes (t) == 0) - ret_val = gen_type (concat (ret_val, "[0]"), TREE_TYPE (t), style); + ret_val = gen_type (concat (ret_val, "[0]", NULL_PTR), + TREE_TYPE (t), style); else { int size = (int_size_in_bytes (t) / int_size_in_bytes (TREE_TYPE (t))); char buff[10]; sprintf (buff, "[%d]", size); - ret_val = gen_type (concat (ret_val, buff), + ret_val = gen_type (concat (ret_val, buff, NULL_PTR), TREE_TYPE (t), style); } break; case FUNCTION_TYPE: - ret_val = gen_type (concat (ret_val, gen_formal_list_for_type (t, style)), TREE_TYPE (t), style); + ret_val = gen_type (concat (ret_val, + gen_formal_list_for_type (t, style), + NULL_PTR), + TREE_TYPE (t), style); break; case IDENTIFIER_NODE: @@ -424,13 +441,14 @@ gen_type (ret_val, t, style) chain_p = TYPE_FIELDS (t); while (chain_p) { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); + data_type = concat (data_type, gen_decl (chain_p, 0, ansi), + NULL_PTR); chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); + data_type = concat (data_type, "; ", NULL_PTR); } - data_type = concat3 ("{ ", data_type, "}"); + data_type = concat ("{ ", data_type, "}", NULL_PTR); } - data_type = concat ("struct ", data_type); + data_type = concat ("struct ", data_type, NULL_PTR); break; case UNION_TYPE: @@ -442,13 +460,14 @@ gen_type (ret_val, t, style) chain_p = TYPE_FIELDS (t); while (chain_p) { - data_type = concat (data_type, gen_decl (chain_p, 0, ansi)); + data_type = concat (data_type, gen_decl (chain_p, 0, ansi), + NULL_PTR); chain_p = TREE_CHAIN (chain_p); - data_type = concat (data_type, "; "); + data_type = concat (data_type, "; ", NULL_PTR); } - data_type = concat3 ("{ ", data_type, "}"); + data_type = concat ("{ ", data_type, "}", NULL_PTR); } - data_type = concat ("union ", data_type); + data_type = concat ("union ", data_type, NULL_PTR); break; case ENUMERAL_TYPE: @@ -461,14 +480,14 @@ gen_type (ret_val, t, style) while (chain_p) { data_type = concat (data_type, - IDENTIFIER_POINTER (TREE_PURPOSE (chain_p))); + IDENTIFIER_POINTER (TREE_PURPOSE (chain_p)), NULL_PTR); chain_p = TREE_CHAIN (chain_p); if (chain_p) - data_type = concat (data_type, ", "); + data_type = concat (data_type, ", ", NULL_PTR); } - data_type = concat3 ("{ ", data_type, " }"); + data_type = concat ("{ ", data_type, " }", NULL_PTR); } - data_type = concat ("enum ", data_type); + data_type = concat ("enum ", data_type, NULL_PTR); break; case TYPE_DECL: @@ -478,9 +497,9 @@ gen_type (ret_val, t, style) 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 `const' or `volatile'. */ - if (TREE_UNSIGNED (t) && (TYPE_READONLY (t) || TYPE_VOLATILE (t))) - data_type = concat ("unsigned ", data_type); + with a type qualifier. */ + if (TREE_UNSIGNED (t) && TYPE_QUALS (t)) + data_type = concat ("unsigned ", data_type, NULL_PTR); break; case REAL_TYPE: @@ -500,9 +519,11 @@ gen_type (ret_val, t, style) } } if (TYPE_READONLY (t)) - ret_val = concat ("const ", ret_val); + ret_val = concat ("const ", ret_val, NULL_PTR); if (TYPE_VOLATILE (t)) - ret_val = concat ("volatile ", ret_val); + ret_val = concat ("volatile ", ret_val, NULL_PTR); + if (TYPE_RESTRICT (t)) + ret_val = concat ("restrict ", ret_val, NULL_PTR); return ret_val; } @@ -516,13 +537,13 @@ gen_type (ret_val, t, style) associated with a function definition. In this case, we can assume that an attached list of DECL nodes for function formal arguments is present. */ -static char * +static const char * gen_decl (decl, is_func_definition, style) tree decl; int is_func_definition; formals_style style; { - char *ret_val; + const char *ret_val; if (DECL_NAME (decl)) ret_val = IDENTIFIER_POINTER (DECL_NAME (decl)); @@ -544,9 +565,9 @@ gen_decl (decl, is_func_definition, style) generate the qualifiers here. */ if (TREE_THIS_VOLATILE (decl)) - ret_val = concat ("volatile ", ret_val); + ret_val = concat ("volatile ", ret_val, NULL_PTR); if (TREE_READONLY (decl)) - ret_val = concat ("const ", ret_val); + ret_val = concat ("const ", ret_val, NULL_PTR); data_type = ""; @@ -564,7 +585,8 @@ gen_decl (decl, is_func_definition, style) if (TREE_CODE (decl) == FUNCTION_DECL && is_func_definition) { - ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi)); + ret_val = concat (ret_val, gen_formal_list_for_func_def (decl, ansi), + NULL_PTR); /* Since we have already added in the formals list stuff, here we don't add the whole "type" of the function we are considering (which @@ -581,11 +603,11 @@ gen_decl (decl, is_func_definition, style) ret_val = affix_data_type (ret_val); if (TREE_CODE (decl) != FUNCTION_DECL && DECL_REGISTER (decl)) - ret_val = concat ("register ", ret_val); + ret_val = concat ("register ", ret_val, NULL_PTR); if (TREE_PUBLIC (decl)) - ret_val = concat ("extern ", ret_val); + ret_val = concat ("extern ", ret_val, NULL_PTR); if (TREE_CODE (decl) == FUNCTION_DECL && !TREE_PUBLIC (decl)) - ret_val = concat ("static ", ret_val); + ret_val = concat ("static ", ret_val, NULL_PTR); return ret_val; } diff --git a/contrib/gcc/c-common.c b/contrib/gcc/c-common.c index 61600fb..1ec3842 100644 --- a/contrib/gcc/c-common.c +++ b/contrib/gcc/c-common.c @@ -1,5 +1,5 @@ /* Subroutines shared by all languages that are variants of C. - Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -27,6 +27,8 @@ Boston, MA 02111-1307, USA. */ #include "obstack.h" #include "toplev.h" #include "output.h" +#include "c-pragma.h" +#include "rtl.h" #if USE_CPPLIB #include "cpplib.h" @@ -50,19 +52,22 @@ extern struct obstack permanent_obstack; int skip_evaluation; enum attrs {A_PACKED, A_NOCOMMON, A_COMMON, A_NORETURN, A_CONST, A_T_UNION, + A_NO_CHECK_MEMORY_USAGE, A_NO_INSTRUMENT_FUNCTION, A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED, A_UNUSED, A_FORMAT, A_FORMAT_ARG, A_WEAK, A_ALIAS}; enum format_type { printf_format_type, scanf_format_type, strftime_format_type }; -static void declare_hidden_char_array PROTO((char *, char *)); -static void add_attribute PROTO((enum attrs, char *, +static void declare_hidden_char_array PROTO((const char *, const char *)); +static void add_attribute PROTO((enum attrs, const char *, int, int, int)); static void init_attributes PROTO((void)); static void record_function_format PROTO((tree, tree, enum format_type, int, int)); static void record_international_format PROTO((tree, tree, int)); +static tree c_find_base_decl PROTO((tree)); +static int default_valid_lang_attribute PROTO ((tree, tree, 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 @@ -73,9 +78,10 @@ typedef struct { int compstmt_count; int line; - char *file; + const char *file; int needs_warning; } if_elt; +static void tfaff PROTO((void)); static if_elt *if_stack; @@ -153,12 +159,12 @@ c_expand_start_else () expand_start_else (); } -/* Make bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ +/* Make bindings for __FUNCTION__, __PRETTY_FUNCTION__, and __func__. */ void declare_function_name () { - char *name, *printable_name; + const char *name, *printable_name; if (current_function_decl == NULL) { @@ -177,11 +183,14 @@ declare_function_name () declare_hidden_char_array ("__FUNCTION__", name); declare_hidden_char_array ("__PRETTY_FUNCTION__", printable_name); + /* The ISO C people "of course" couldn't use __FUNCTION__ in the + ISO C 9x standard; instead a new variable is invented. */ + declare_hidden_char_array ("__func__", name); } static void declare_hidden_char_array (name, value) - char *name, *value; + const char *name, *value; { tree decl, type, init; int vlen; @@ -262,7 +271,7 @@ combine_strings (strings) ? wchar_bytes : 1)); if ((TREE_TYPE (t) == wchar_array_type_node) == wide_flag) { - bcopy (TREE_STRING_POINTER (t), q, len); + memcpy (q, TREE_STRING_POINTER (t), len); q += len; } else @@ -290,7 +299,6 @@ combine_strings (strings) value = make_node (STRING_CST); TREE_STRING_POINTER (value) = p; TREE_STRING_LENGTH (value) = length; - TREE_CONSTANT (value) = 1; } else { @@ -305,8 +313,9 @@ combine_strings (strings) /* Create the array type for the string constant. -Wwrite-strings says make the string constant an array of const char - so that copying it to a non-const pointer will get a warning. */ - if (warn_write_strings + so that copying it to a non-const pointer will get a warning. + For C++, this is the standard behavior. */ + if (flag_const_strings && (! flag_traditional && ! flag_writable_strings)) { tree elements @@ -320,7 +329,8 @@ combine_strings (strings) TREE_TYPE (value) = build_array_type (wide_flag ? wchar_type_node : char_type_node, build_index_type (build_int_2 (nchars - 1, 0))); - TREE_CONSTANT (value) = 1; + + TREE_READONLY (value) = TREE_CONSTANT (value) = ! flag_writable_strings; TREE_STATIC (value) = 1; return value; } @@ -339,7 +349,7 @@ static int attrtab_idx = 0; static void add_attribute (id, string, min_len, max_len, decl_req) enum attrs id; - char *string; + const char *string; int min_len, max_len; int decl_req; { @@ -382,8 +392,29 @@ init_attributes () add_attribute (A_FORMAT_ARG, "format_arg", 1, 1, 1); add_attribute (A_WEAK, "weak", 0, 0, 1); add_attribute (A_ALIAS, "alias", 1, 1, 1); + add_attribute (A_NO_INSTRUMENT_FUNCTION, "no_instrument_function", 0, 0, 1); + add_attribute (A_NO_CHECK_MEMORY_USAGE, "no_check_memory_usage", 0, 0, 1); } +/* Default implementation of valid_lang_attribute, below. By default, there + are no language-specific attributes. */ + +static int +default_valid_lang_attribute (attr_name, attr_args, decl, type) + tree attr_name ATTRIBUTE_UNUSED; + tree attr_args ATTRIBUTE_UNUSED; + tree decl ATTRIBUTE_UNUSED; + tree type ATTRIBUTE_UNUSED; +{ + return 0; +} + +/* Return a 1 if ATTR_NAME and ATTR_ARGS denote a valid language-specific + attribute for either declaration DECL or type TYPE and 0 otherwise. */ + +int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree)) + = default_valid_lang_attribute; + /* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES and install them in NODE, which is either a DECL (including a TYPE_DECL) or a TYPE. PREFIX_ATTRIBUTES can appear after the declaration specifiers @@ -409,6 +440,18 @@ decl_attributes (node, attributes, prefix_attributes) else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't') type = node, is_type = 1; +#ifdef PRAGMA_INSERT_ATTRIBUTES + /* If the code in c-pragma.c wants to insert some attributes then + allow it to do so. Do this before allowing machine back ends to + insert attributes, so that they have the opportunity to override + anything done here. */ + PRAGMA_INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes); +#endif + +#ifdef INSERT_ATTRIBUTES + INSERT_ATTRIBUTES (node, & attributes, & prefix_attributes); +#endif + attributes = chainon (prefix_attributes, attributes); for (a = attributes; a; a = TREE_CHAIN (a)) @@ -424,7 +467,8 @@ decl_attributes (node, attributes, prefix_attributes) if (i == attrtab_idx) { - if (! valid_machine_attribute (name, args, decl, type)) + if (! valid_machine_attribute (name, args, decl, type) + && ! (* valid_lang_attribute) (name, args, decl, type)) warning ("`%s' attribute directive ignored", IDENTIFIER_POINTER (name)); else if (decl != 0) @@ -491,7 +535,8 @@ decl_attributes (node, attributes, prefix_attributes) TREE_USED (type) = 1; else if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == VAR_DECL - || TREE_CODE (decl) == FUNCTION_DECL) + || TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == LABEL_DECL) TREE_USED (decl) = 1; else warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); @@ -555,7 +600,7 @@ decl_attributes (node, attributes, prefix_attributes) else { int j; - char *p = IDENTIFIER_POINTER (TREE_VALUE (args)); + const char *p = IDENTIFIER_POINTER (TREE_VALUE (args)); int len = strlen (p); enum machine_mode mode = VOIDmode; tree typefm; @@ -633,7 +678,7 @@ decl_attributes (node, attributes, prefix_attributes) = (args ? TREE_VALUE (args) : size_int (BIGGEST_ALIGNMENT / BITS_PER_UNIT)); int align; - + /* Strip any NOPs of any kind. */ while (TREE_CODE (align_expr) == NOP_EXPR || TREE_CODE (align_expr) == CONVERT_EXPR @@ -687,7 +732,7 @@ decl_attributes (node, attributes, prefix_attributes) } else { - char *p = IDENTIFIER_POINTER (format_type_id); + const char *p = IDENTIFIER_POINTER (format_type_id); if (!strcmp (p, "printf") || !strcmp (p, "__printf__")) format_type = printf_format_type; @@ -698,7 +743,7 @@ decl_attributes (node, attributes, prefix_attributes) format_type = strftime_format_type; else { - error ("`%s' is an unrecognized format function type", p); + warning ("`%s' is an unrecognized format function type", p); continue; } } @@ -864,6 +909,40 @@ decl_attributes (node, attributes, prefix_attributes) else warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); break; + + case A_NO_CHECK_MEMORY_USAGE: + if (TREE_CODE (decl) != FUNCTION_DECL) + { + error_with_decl (decl, + "`%s' attribute applies only to functions", + IDENTIFIER_POINTER (name)); + } + else if (DECL_INITIAL (decl)) + { + error_with_decl (decl, + "can't set `%s' attribute after definition", + IDENTIFIER_POINTER (name)); + } + else + DECL_NO_CHECK_MEMORY_USAGE (decl) = 1; + break; + + case A_NO_INSTRUMENT_FUNCTION: + if (TREE_CODE (decl) != FUNCTION_DECL) + { + error_with_decl (decl, + "`%s' attribute applies only to functions", + IDENTIFIER_POINTER (name)); + } + else if (DECL_INITIAL (decl)) + { + error_with_decl (decl, + "can't set `%s' attribute after definition", + IDENTIFIER_POINTER (name)); + } + else + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; + break; } } } @@ -983,7 +1062,7 @@ strip_attrs (specs_attrs) #define T_ST &sizetype typedef struct { - char *format_chars; + const char *format_chars; int pointer_count; /* Type of argument if no length modifier is used. */ tree *nolen; @@ -1006,7 +1085,7 @@ typedef struct { If NULL, then this modifier is not allowed. */ tree *zlen; /* List of other modifier characters allowed with these options. */ - char *flag_chars; + const char *flag_chars; } format_char_info; static format_char_info print_char_table[] = { @@ -1022,7 +1101,7 @@ static format_char_info print_char_table[] = { { "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "-wp" }, { "p", 1, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "-w" }, { "n", 1, T_I, NULL, T_S, T_L, T_LL, NULL, NULL, "" }, - { NULL } + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; static format_char_info scan_char_table[] = { @@ -1036,7 +1115,7 @@ static format_char_info scan_char_table[] = { { "S", 1, T_W, NULL, NULL, NULL, NULL, NULL, NULL, "*a" }, { "p", 2, T_V, NULL, NULL, NULL, NULL, NULL, NULL, "*" }, { "n", 1, T_I, T_C, T_S, T_L, T_LL, NULL, NULL, "" }, - { NULL } + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; /* Handle format characters recognized by glibc's strftime.c. @@ -1061,7 +1140,7 @@ static format_char_info time_char_table[] = { { "p", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "#" }, { "bh", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "^" }, { "CY", 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-_0EOw" }, - { NULL } + { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; typedef struct function_format_info @@ -1206,7 +1285,11 @@ record_international_format (name, assembler_name, format_num) info->format_num = format_num; } -static char tfaff[] = "too few arguments for format"; +static void +tfaff () +{ + warning ("too few arguments for format"); +} /* Check the argument list of a call to printf, scanf, etc. NAME is the function identifier. @@ -1256,7 +1339,7 @@ check_format_info (info, params) tree cur_type; tree wanted_type; tree first_fillin_param; - char *format_chars; + const char *format_chars; format_char_info *fci = NULL; char flag_chars[8]; int has_operand_number = 0; @@ -1420,7 +1503,7 @@ check_format_info (info, params) it is an operand number, so set PARAMS to that operand. */ if (*format_chars >= '0' && *format_chars <= '9') { - char *p = format_chars; + const char *p = format_chars; while (*p >= '0' && *p++ <= '9') ; @@ -1473,7 +1556,7 @@ check_format_info (info, params) ++format_chars; if (params == 0) { - warning (tfaff); + tfaff (); return; } if (info->first_arg_num != 0) @@ -1516,7 +1599,7 @@ check_format_info (info, params) ++format_chars; if (params == 0) { - warning (tfaff); + tfaff (); return; } cur_param = TREE_VALUE (params); @@ -1686,7 +1769,7 @@ check_format_info (info, params) if (precise && index (flag_chars, '0') != 0 && (format_char == 'd' || format_char == 'i' || format_char == 'o' || format_char == 'u' - || format_char == 'x' || format_char == 'x')) + || format_char == 'x' || format_char == 'X')) warning ("`0' flag ignored with precision specifier and `%c' format", format_char); switch (length_char) @@ -1711,7 +1794,7 @@ check_format_info (info, params) continue; if (params == 0) { - warning (tfaff); + tfaff (); return; } cur_param = TREE_VALUE (params); @@ -1737,9 +1820,9 @@ check_format_info (info, params) continue; } if (TREE_CODE (cur_type) != ERROR_MARK) - warning ("format argument is not a %s (arg %d)", - ((fci->pointer_count + aflag == 1) - ? "pointer" : "pointer to a pointer"), + warning ((fci->pointer_count + aflag == 1 + ? "format argument is not a pointer (arg %d)" + : "format argument is not a pointer to a pointer (arg %d)"), arg_num); break; } @@ -1779,8 +1862,8 @@ check_format_info (info, params) && (TYPE_MAIN_VARIANT (cur_type) == signed_char_type_node || TYPE_MAIN_VARIANT (cur_type) == unsigned_char_type_node))) { - register char *this; - register char *that; + register const char *this; + register const char *that; this = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (wanted_type))); that = 0; @@ -2049,8 +2132,10 @@ type_for_mode (mode, unsignedp) if (mode == TYPE_MODE (intDI_type_node)) return unsignedp ? unsigned_intDI_type_node : intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 if (mode == TYPE_MODE (intTI_type_node)) return unsignedp ? unsigned_intTI_type_node : intTI_type_node; +#endif if (mode == TYPE_MODE (float_type_node)) return float_type_node; @@ -2108,7 +2193,7 @@ void binary_op_error (code) enum tree_code code; { - register char *opname; + register const char *opname; switch (code) { @@ -2399,18 +2484,18 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr) /* This is the case of (char)x >?< 0x80, which people used to use expecting old C compilers to change the 0x80 into -0x80. */ if (val == boolean_false_node) - warning ("comparison is always 0 due to limited range of data type"); + warning ("comparison is always false due to limited range of data type"); if (val == boolean_true_node) - warning ("comparison is always 1 due to limited range of data type"); + warning ("comparison is always true due to limited range of data type"); } if (!min_lt && unsignedp0 && TREE_CODE (primop0) != INTEGER_CST) { /* This is the case of (unsigned char)x >?< -1 or < 0. */ if (val == boolean_false_node) - warning ("comparison is always 0 due to limited range of data type"); + warning ("comparison is always false due to limited range of data type"); if (val == boolean_true_node) - warning ("comparison is always 1 due to limited range of data type"); + warning ("comparison is always true due to limited range of data type"); } if (val != 0) @@ -2476,7 +2561,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr) && ! (TREE_CODE (primop0) == INTEGER_CST && ! TREE_OVERFLOW (convert (signed_type (type), primop0)))) - warning ("unsigned value >= 0 is always 1"); + warning ("comparison of unsigned expression >= 0 is always true"); value = boolean_true_node; break; @@ -2485,7 +2570,7 @@ shorten_compare (op0_ptr, op1_ptr, restype_ptr, rescode_ptr) && ! (TREE_CODE (primop0) == INTEGER_CST && ! TREE_OVERFLOW (convert (signed_type (type), primop0)))) - warning ("unsigned value < 0 is always 0"); + warning ("comparison of unsigned expression < 0 is always false"); value = boolean_false_node; break; @@ -2710,7 +2795,7 @@ truthvalue_conversion (expr) unsigned char *yy_cur, *yy_lim; #define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()) -#define UNGETC(c) ((c), yy_cur--) +#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--) int yy_get_token () @@ -2884,15 +2969,134 @@ get_directive_line (finput) down to the element type of an array. */ tree -c_build_type_variant (type, constp, volatilep) +c_build_qualified_type (type, type_quals) tree type; - int constp, volatilep; + int type_quals; { + /* 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. */ + if ((type_quals & TYPE_QUAL_RESTRICT) + && (!POINTER_TYPE_P (type) + || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type)))) + { + error ("invalid use of `restrict'"); + type_quals &= ~TYPE_QUAL_RESTRICT; + } + if (TREE_CODE (type) == ARRAY_TYPE) - return build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), + return build_array_type (c_build_qualified_type (TREE_TYPE (type), + type_quals), TYPE_DOMAIN (type)); - return build_type_variant (type, constp, volatilep); + 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; +{ + if (type_quals & TYPE_QUAL_CONST) + TREE_READONLY (decl) = 1; + if (type_quals & TYPE_QUAL_VOLATILE) + { + TREE_SIDE_EFFECTS (decl) = 1; + TREE_THIS_VOLATILE (decl) = 1; + } + 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)))) + error ("invalid use of `restrict'"); + else if (flag_strict_aliasing) + { + /* 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 + is based on the restricted pointer. So, we make the + alias set for the restricted pointer a subset of the + alias set for the type pointed to by the type of the + decl. */ + + int pointed_to_alias_set + = get_alias_set (TREE_TYPE (TREE_TYPE (decl))); + + if (!pointed_to_alias_set) + /* It's not legal to make a subset of alias set zero. */ + ; + else + { + DECL_POINTER_ALIAS_SET (decl) = new_alias_set (); + record_alias_subset (pointed_to_alias_set, + DECL_POINTER_ALIAS_SET (decl)); + } + } + } +} + +/* T is an expression with pointer type. Find the DECL on which this + expression is based. (For example, in `a[i]' this would be `a'.) + If there is no such DECL, or a unique decl cannot be determined, + NULL_TREE is retured. */ + +static tree +c_find_base_decl (t) + tree t; +{ + int i; + tree decl; + + if (t == NULL_TREE || t == error_mark_node) + return NULL_TREE; + + if (!POINTER_TYPE_P (TREE_TYPE (t))) + return NULL_TREE; + + decl = NULL_TREE; + + if (TREE_CODE (t) == FIELD_DECL + || TREE_CODE (t) == PARM_DECL + || TREE_CODE (t) == VAR_DECL) + /* Aha, we found a pointer-typed declaration. */ + return t; + + /* It would be nice to deal with COMPONENT_REFs here. If we could + tell that `a' and `b' were the same, then `a->f' and `b->f' are + also the same. */ + + /* Handle general expressions. */ + switch (TREE_CODE_CLASS (TREE_CODE (t))) + { + case '1': + case '2': + case '3': + for (i = tree_code_length [(int) TREE_CODE (t)]; --i >= 0;) + { + tree d = c_find_base_decl (TREE_OPERAND (t, i)); + if (d) + { + if (!decl) + decl = d; + else if (d && d != decl) + /* Two different declarations. That's confusing; let's + just assume we don't know what's going on. */ + decl = NULL_TREE; + } + } + break; + + default: + break; + } + + return decl; } /* Return the typed-based alias set for T, which may be an expression @@ -2902,21 +3106,20 @@ int c_get_alias_set (t) tree t; { - static int next_set = 0; tree type; + tree u; if (t == error_mark_node) return 0; type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - ? t : TREE_TYPE (t); + ? t : TREE_TYPE (t); if (type == error_mark_node) return 0; - if (TYPE_ALIAS_SET_KNOWN_P (type)) - /* If we've already calculated the value, just return it. */ - return TYPE_ALIAS_SET (type); + /* Deal with special cases first; for certain kinds of references + we're interested in more than just the type. */ if (TREE_CODE (t) == BIT_FIELD_REF) /* Perhaps reads and writes to this piece of data alias fields @@ -2924,22 +3127,48 @@ c_get_alias_set (t) let's just assume that bitfields can alias everything, which is the conservative assumption. */ return 0; - if (TREE_CODE (t) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE) - /* 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 through it. Even the type-punning allowed here is a - GCC extension, albeit a common and useful one; the C standard - says that such accesses have implementation-defined behavior. */ - return 0; - else if (TYPE_MAIN_VARIANT (type) != type) + + /* 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 + through it. Even the type-punning allowed here is a GCC + extension, albeit a common and useful one; the C standard says + that such accesses have implementation-defined behavior. */ + for (u = t; + TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; + u = TREE_OPERAND (u, 0)) + if (TREE_CODE (u) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) + return 0; + + if (TREE_CODE (t) == INDIRECT_REF) { - /* The C standard specifically allows aliasing between - cv-qualified variants of types. */ - TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type)); - return TYPE_ALIAS_SET (type); + /* Check for accesses through restrict-qualified pointers. */ + tree decl = c_find_base_decl (TREE_OPERAND (t, 0)); + + if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) + /* We use the alias set indicated in the declaration. */ + return DECL_POINTER_ALIAS_SET (decl); } + + /* From here on, only the type matters. */ + + if (TREE_CODE (t) == COMPONENT_REF + && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1))) + /* Since build_modify_expr calls get_unwidened for stores to + component references, the type of a bit field can be changed + from (say) `unsigned int : 16' to `unsigned short' or from + `enum E : 16' to `short'. We want the real type of the + bit-field in this case, not some the integral equivalent. */ + type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)); + + if (TYPE_ALIAS_SET_KNOWN_P (type)) + /* If we've already calculated the value, just return it. */ + return TYPE_ALIAS_SET (type); + else if (TYPE_MAIN_VARIANT (type) != type) + /* The C standard specifically allows aliasing between + cv-qualified variants of types. */ + TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type)); else if (TREE_CODE (type) == INTEGER_TYPE) { tree signed_variant; @@ -2950,34 +3179,37 @@ c_get_alias_set (t) signed_variant = signed_type (type); if (signed_variant != type) - { - TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant); - return TYPE_ALIAS_SET (type); - } + TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant); else if (signed_variant == signed_char_type_node) /* The C standard guarantess that any object may be accessed via an lvalue that has character type. We don't have to check for unsigned_char_type_node or char_type_node because we are specifically looking at the signed variant. */ - { - TYPE_ALIAS_SET (type) = 0; - return TYPE_ALIAS_SET (type); - } + TYPE_ALIAS_SET (type) = 0; } + else if (TREE_CODE (type) == ARRAY_TYPE) + /* Anything that can alias one of the array elements can alias + the entire array as well. */ + TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type)); + else if (TREE_CODE (type) == FUNCTION_TYPE) + /* There are no objects of FUNCTION_TYPE, so there's no point in + using up an alias set for them. (There are, of course, + pointers and references to functions, but that's + different.) */ + TYPE_ALIAS_SET (type) = 0; else if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE) - { - /* If TYPE is a struct or union type then we're reading or - writing an entire struct. Thus, we don't know anything about - aliasing. (In theory, such an access can only alias objects - whose type is the same as one of the fields, recursively, but - we don't yet make any use of that information.) */ - TYPE_ALIAS_SET (type) = 0; - return TYPE_ALIAS_SET (type); - } + /* If TYPE is a struct or union type then we're reading or + writing an entire struct. Thus, we don't know anything about + aliasing. (In theory, such an access can only alias objects + whose type is the same as one of the fields, recursively, but + we don't yet make any use of that information.) */ + TYPE_ALIAS_SET (type) = 0; + + if (!TYPE_ALIAS_SET_KNOWN_P (type)) + /* TYPE is something we haven't seen before. Put it in a new + alias set. */ + TYPE_ALIAS_SET (type) = new_alias_set (); - /* TYPE is something we haven't seen before. Put it in a new alias - set. */ - TYPE_ALIAS_SET (type) = ++next_set; return TYPE_ALIAS_SET (type); } diff --git a/contrib/gcc/c-convert.c b/contrib/gcc/c-convert.c index 6f58e76..9cb9416 100644 --- a/contrib/gcc/c-convert.c +++ b/contrib/gcc/c-convert.c @@ -1,5 +1,5 @@ /* Language-level data type conversion for GNU C. - Copyright (C) 1987, 1988, 1991 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1991, 1998 Free Software Foundation, Inc. This file is part of GNU CC. diff --git a/contrib/gcc/c-decl.c b/contrib/gcc/c-decl.c index ccaa7d2..a232217 100644 --- a/contrib/gcc/c-decl.c +++ b/contrib/gcc/c-decl.c @@ -1,5 +1,5 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -37,9 +37,7 @@ Boston, MA 02111-1307, USA. */ #if USE_CPPLIB #include "cpplib.h" -extern cpp_reader parse_in; -extern cpp_options parse_options; -static int cpp_initialized; +extern cpp_reader parse_in; #endif /* In grokdeclarator, distinguish syntactic contexts of declarators. */ @@ -151,13 +149,17 @@ tree intQI_type_node; tree intHI_type_node; tree intSI_type_node; tree intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 tree intTI_type_node; +#endif tree unsigned_intQI_type_node; tree unsigned_intHI_type_node; tree unsigned_intSI_type_node; tree unsigned_intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 tree unsigned_intTI_type_node; +#endif /* a VOID_TYPE node. */ @@ -424,7 +426,7 @@ tree static_ctors, static_dtors; static struct binding_level * make_binding_level PROTO((void)); static void clear_limbo_values PROTO((tree)); static int duplicate_decls PROTO((tree, tree, int)); -static char *redeclaration_error_message PROTO((tree, tree)); +static int redeclaration_error_message PROTO((tree, tree)); static void storedecls PROTO((tree)); static void storetags PROTO((tree)); static tree lookup_tag PROTO((enum tree_code, tree, @@ -464,6 +466,10 @@ int flag_no_nonansi_builtin; int flag_traditional; +/* Nonzero means use the ISO C9x dialect of C. */ + +int flag_isoc9x = 0; + /* Nonzero means that we have builtin functions, and main is an int */ int flag_hosted = 1; @@ -477,10 +483,6 @@ int flag_allow_single_precision = 0; int flag_signed_bitfields = 1; int explicit_flag_signed_bitfields = 0; -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident = 0; - /* Nonzero means warn about use of implicit int. */ int warn_implicit_int; @@ -498,7 +500,7 @@ int mesg_implicit_function_declaration; to get extra warnings from them. These warnings will be too numerous to be useful, except in thoroughly ANSIfied programs. */ -int warn_write_strings; +int flag_const_strings; /* Nonzero means warn about pointer casts that can drop a type qualifier from the pointer target type. */ @@ -511,6 +513,10 @@ int warn_cast_qual; int warn_bad_function_cast; +/* Warn about functions which might be candidates for attribute noreturn. */ + +int warn_missing_noreturn; + /* Warn about traditional constructs whose meanings changed in ANSI C. */ int warn_traditional; @@ -597,19 +603,12 @@ int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; int c_decode_option (argc, argv) - int argc; + int argc ATTRIBUTE_UNUSED; char **argv; { int strings_processed; char *p = argv[0]; #if USE_CPPLIB - if (! cpp_initialized) - { - cpp_reader_init (&parse_in); - parse_in.data = &parse_options; - cpp_options_init (&parse_options); - cpp_initialized = 1; - } strings_processed = cpp_handle_option (&parse_in, argc, argv); #else strings_processed = 0; @@ -640,6 +639,63 @@ c_decode_option (argc, argv) flag_traditional = 0; flag_writable_strings = 0; } + else if (!strncmp (p, "-std=", 5)) + { + /* Select the appropriate language standard. We currently + recognize: + -std=iso9899:1990 same as -ansi + -std=iso9899:199409 ISO C as modified in amend. 1 + -std=iso9899:199x ISO C 9x + -std=c89 same as -std=iso9899:1990 + -std=c9x same as -std=iso9899:199x + -std=gnu89 default, iso9899:1990 + gnu extensions + -std=gnu9x iso9899:199x + gnu extensions + */ + const char *argstart = &p[5]; + + if (!strcmp (argstart, "iso9899:1990") + || !strcmp (argstart, "c89")) + { + iso_1990: + flag_traditional = 0; + flag_writable_strings = 0; + flag_no_asm = 1; + flag_no_nonansi_builtin = 1; + flag_isoc9x = 0; + } + else if (!strcmp (argstart, "iso9899:199409")) + { + /* ??? The changes since ISO C 1990 are not supported. */ + goto iso_1990; + } + else if (!strcmp (argstart, "iso9899:199x") + || !strcmp (argstart, "c9x")) + { + flag_traditional = 0; + flag_writable_strings = 0; + flag_no_asm = 1; + flag_no_nonansi_builtin = 1; + flag_isoc9x = 1; + } + else if (!strcmp (argstart, "gnu89")) + { + flag_traditional = 0; + flag_writable_strings = 0; + flag_no_asm = 0; + flag_no_nonansi_builtin = 0; + flag_isoc9x = 0; + } + else if (!strcmp (argstart, "gnu9x")) + { + flag_traditional = 0; + flag_writable_strings = 0; + flag_no_asm = 0; + flag_no_nonansi_builtin = 0; + flag_isoc9x = 1; + } + else + error ("unknown C standard `%s'", argstart); + } else if (!strcmp (p, "-fdollars-in-identifiers")) dollars_in_ident = 1; else if (!strcmp (p, "-fno-dollars-in-identifiers")) @@ -684,12 +740,8 @@ c_decode_option (argc, argv) flag_no_builtin = 0; else if (!strcmp (p, "-fno-builtin")) flag_no_builtin = 1; - else if (!strcmp (p, "-fno-ident")) - flag_no_ident = 1; - else if (!strcmp (p, "-fident")) - flag_no_ident = 0; else if (!strcmp (p, "-ansi")) - flag_no_asm = 1, flag_no_nonansi_builtin = 1; + goto iso_1990; else if (!strcmp (p, "-Werror-implicit-function-declaration")) mesg_implicit_function_declaration = 2; else if (!strcmp (p, "-Wimplicit-function-declaration")) @@ -713,9 +765,9 @@ c_decode_option (argc, argv) else if (!strcmp (p, "-Wno-long-long")) warn_long_long = 0; else if (!strcmp (p, "-Wwrite-strings")) - warn_write_strings = 1; + flag_const_strings = 1; else if (!strcmp (p, "-Wno-write-strings")) - warn_write_strings = 0; + flag_const_strings = 0; else if (!strcmp (p, "-Wcast-qual")) warn_cast_qual = 1; else if (!strcmp (p, "-Wno-cast-qual")) @@ -724,6 +776,10 @@ c_decode_option (argc, argv) warn_bad_function_cast = 1; else if (!strcmp (p, "-Wno-bad-function-cast")) warn_bad_function_cast = 0; + else if (!strcmp (p, "-Wmissing-noreturn")) + warn_missing_noreturn = 1; + else if (!strcmp (p, "-Wno-missing-noreturn")) + warn_missing_noreturn = 0; else if (!strcmp (p, "-Wpointer-arith")) warn_pointer_arith = 1; else if (!strcmp (p, "-Wno-pointer-arith")) @@ -799,7 +855,7 @@ c_decode_option (argc, argv) else if (!strcmp (p, "-Wmain")) warn_main = 1; else if (!strcmp (p, "-Wno-main")) - warn_main = 0; + warn_main = -1; else if (!strcmp (p, "-Wsign-compare")) warn_sign_compare = 1; else if (!strcmp (p, "-Wno-sign-compare")) @@ -942,7 +998,7 @@ kept_level_p () void declare_parm_level (definition_flag) - int definition_flag; + int definition_flag ATTRIBUTE_UNUSED; { current_binding_level->parm_flag = 1; } @@ -1059,24 +1115,22 @@ poplevel (keep, reverse, functionbody) if (TYPE_SIZE (TREE_VALUE (link)) == 0) { tree type = TREE_VALUE (link); - char *errmsg; + 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: - errmsg = "`struct %s' incomplete in scope ending here"; + error ("`struct %s' incomplete in scope ending here", id); break; case UNION_TYPE: - errmsg = "`union %s' incomplete in scope ending here"; + error ("`union %s' incomplete in scope ending here", id); break; case ENUMERAL_TYPE: - errmsg = "`enum %s' incomplete in scope ending here"; + error ("`enum %s' incomplete in scope ending here", id); break; } - if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); - else - /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ - error (errmsg, IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); } #endif /* 0 */ @@ -1456,7 +1510,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) && DECL_INITIAL (newdecl) != 0); tree oldtype = TREE_TYPE (olddecl); tree newtype = TREE_TYPE (newdecl); - char *errmsg = 0; + int errmsg = 0; if (TREE_CODE_CLASS (TREE_CODE (olddecl)) == 'd') DECL_MACHINE_ATTRIBUTES (newdecl) @@ -1683,16 +1737,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level) if (TREE_CHAIN (t) == 0 && TYPE_MAIN_VARIANT (type) != void_type_node) { - error ("A parameter list with an ellipsis can't match"); - error ("an empty parameter name list declaration."); + error ("A parameter list with an ellipsis can't match an empty parameter name list declaration."); break; } if (TYPE_MAIN_VARIANT (type) == float_type_node || C_PROMOTING_INTEGER_TYPE_P (type)) { - error ("An argument type that has a default promotion"); - error ("can't match an empty parameter name list declaration."); + error ("An argument type that has a default promotion can't match an empty parameter name list declaration."); break; } } @@ -1704,7 +1756,21 @@ duplicate_decls (newdecl, olddecl, different_binding_level) errmsg = redeclaration_error_message (newdecl, olddecl); if (errmsg) { - error_with_decl (newdecl, errmsg); + 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 (); + } + error_with_decl (olddecl, ((DECL_INITIAL (olddecl) && current_binding_level == global_binding_level) @@ -1736,14 +1802,22 @@ duplicate_decls (newdecl, olddecl, different_binding_level) for (parm = TYPE_ACTUAL_ARG_TYPES (oldtype), type = TYPE_ARG_TYPES (newtype), nargs = 1; - (TYPE_MAIN_VARIANT (TREE_VALUE (parm)) != void_type_node - || TYPE_MAIN_VARIANT (TREE_VALUE (type)) != void_type_node); + ; parm = TREE_CHAIN (parm), type = TREE_CHAIN (type), nargs++) { 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) { - errmsg = "prototype for `%s' follows and number of arguments"; + 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 @@ -1755,21 +1829,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level) && TYPE_MAIN_VARIANT (TREE_VALUE (parm)) == integer_type_node && TYPE_MAIN_VARIANT (TREE_VALUE (type)) == unsigned_type_node))) { - errmsg = "prototype for `%s' follows and argument %d"; + 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 (errmsg) - { - error_with_decl (newdecl, errmsg, nargs); - error_with_decl (olddecl, - "doesn't match non-prototype definition here"); - } - else - { - warning_with_decl (newdecl, "prototype for `%s' follows"); - warning_with_decl (olddecl, "non-prototype definition here"); - } } /* Warn about mismatches in various flags. */ else @@ -1794,6 +1861,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level) && !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 + && 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 @@ -1931,6 +2006,11 @@ duplicate_decls (newdecl, olddecl, different_binding_level) { DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); + + DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl) + |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl); + DECL_NO_CHECK_MEMORY_USAGE (newdecl) + |= DECL_NO_CHECK_MEMORY_USAGE (olddecl); } pop_obstacks (); @@ -2017,7 +2097,7 @@ duplicate_decls (newdecl, olddecl, different_binding_level) DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); if (DECL_INLINE (newdecl)) - DECL_ABSTRACT_ORIGIN (newdecl) = olddecl; + DECL_ABSTRACT_ORIGIN (newdecl) = DECL_ORIGIN (olddecl); } } if (different_binding_level) @@ -2381,7 +2461,7 @@ pushdecl (x) DECL_ARGUMENTS (x) = DECL_ARGUMENTS (oldglobal); DECL_RESULT (x) = DECL_RESULT (oldglobal); TREE_ASM_WRITTEN (x) = TREE_ASM_WRITTEN (oldglobal); - DECL_ABSTRACT_ORIGIN (x) = oldglobal; + DECL_ABSTRACT_ORIGIN (x) = DECL_ORIGIN (oldglobal); } /* Inner extern decl is built-in if global one is. */ if (DECL_BUILT_IN (oldglobal)) @@ -2454,7 +2534,7 @@ pushdecl (x) /* No shadow warnings for vars made for inlining. */ && ! DECL_FROM_INLINE (x)) { - char *warnstring = 0; + char *id = IDENTIFIER_POINTER (name); if (TREE_CODE (x) == PARM_DECL && current_binding_level->level_chain->parm_flag) @@ -2465,15 +2545,12 @@ pushdecl (x) but there is no way to tell it's not a definition. */ ; else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) - warnstring = "declaration of `%s' shadows a parameter"; + warning ("declaration of `%s' shadows a parameter", id); else if (oldlocal != 0) - warnstring = "declaration of `%s' shadows previous local"; + warning ("declaration of `%s' shadows previous local", id); else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) - warnstring = "declaration of `%s' shadows global declaration"; - - if (warnstring) - warning (warnstring, IDENTIFIER_POINTER (name)); + warning ("declaration of `%s' shadows global declaration", id); } /* If storing a local value, there may already be one (inherited). @@ -2584,10 +2661,10 @@ implicitly_declare (functionid) /* 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 an error message format string with a %s - where the identifier should go. */ + Otherwise return 1 if NEWDECL is a redefinition, 2 if it is a redeclaration, + and 3 if it is a conflicting declaration. */ -static char * +static int redeclaration_error_message (newdecl, olddecl) tree newdecl, olddecl; { @@ -2606,7 +2683,7 @@ redeclaration_error_message (newdecl, olddecl) return 0; if (DECL_IN_SYSTEM_HEADER (olddecl) || DECL_IN_SYSTEM_HEADER (newdecl)) return 0; - return "redefinition of `%s'"; + return 1; } else if (TREE_CODE (newdecl) == FUNCTION_DECL) { @@ -2619,7 +2696,7 @@ redeclaration_error_message (newdecl, olddecl) time in another way is ok. */ && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl) && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl)))) - return "redefinition of `%s'"; + return 1; return 0; } else if (current_binding_level == global_binding_level) @@ -2630,11 +2707,11 @@ redeclaration_error_message (newdecl, olddecl) return 0; /* Reject two definitions. */ if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0) - return "redefinition of `%s'"; + 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 "conflicting declarations of `%s'"; + return 3; return 0; } else if (current_binding_level->parm_flag @@ -2648,7 +2725,7 @@ redeclaration_error_message (newdecl, olddecl) be an extern reference to olddecl. */ if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)) && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)) - return "redeclaration of `%s'"; + return 2; return 0; } } @@ -3038,8 +3115,10 @@ init_decl_processing () intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); +#if HOST_BITS_PER_WIDE_INT >= 64 intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node)); +#endif unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); @@ -3053,8 +3132,10 @@ init_decl_processing () unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); +#if HOST_BITS_PER_WIDE_INT >= 64 unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node)); +#endif float_type_node = make_node (REAL_TYPE); TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; @@ -3288,8 +3369,8 @@ init_decl_processing () builtin_function ("__builtin_unwind_init", build_function_type (void_type_node, endlink), BUILT_IN_UNWIND_INIT, NULL_PTR); - builtin_function ("__builtin_fp", ptr_ftype_void, BUILT_IN_FP, NULL_PTR); - builtin_function ("__builtin_sp", ptr_ftype_void, BUILT_IN_SP, NULL_PTR); + builtin_function ("__builtin_dwarf_cfa", ptr_ftype_void, + BUILT_IN_DWARF_CFA, NULL_PTR); builtin_function ("__builtin_dwarf_fp_regnum", build_function_type (unsigned_type_node, endlink), BUILT_IN_DWARF_FP_REGNUM, NULL_PTR); @@ -3299,24 +3380,16 @@ init_decl_processing () BUILT_IN_FROB_RETURN_ADDR, NULL_PTR); builtin_function ("__builtin_extract_return_addr", ptr_ftype_ptr, BUILT_IN_EXTRACT_RETURN_ADDR, NULL_PTR); - builtin_function ("__builtin_set_return_addr_reg", - build_function_type (void_type_node, - tree_cons (NULL_TREE, - ptr_type_node, - endlink)), - BUILT_IN_SET_RETURN_ADDR_REG, NULL_PTR); - builtin_function ("__builtin_eh_stub_old", ptr_ftype_void, - BUILT_IN_EH_STUB_OLD, NULL_PTR); - builtin_function ("__builtin_eh_stub", ptr_ftype_void, - BUILT_IN_EH_STUB, NULL_PTR); builtin_function - ("__builtin_set_eh_regs", + ("__builtin_eh_return", build_function_type (void_type_node, tree_cons (NULL_TREE, ptr_type_node, tree_cons (NULL_TREE, type_for_mode (ptr_mode, 0), - endlink))), - BUILT_IN_SET_EH_REGS, NULL_PTR); + tree_cons (NULL_TREE, + ptr_type_node, + endlink)))), + BUILT_IN_EH_RETURN, NULL_PTR); builtin_function ("__builtin_alloca", build_function_type (ptr_type_node, @@ -3530,7 +3603,7 @@ init_decl_processing () incomplete_decl_finalize_hook = finish_incomplete_decl; - lang_get_alias_set = &c_get_alias_set; + lang_get_alias_set = c_get_alias_set; } /* Return a definition for a builtin function named NAME and whose data type @@ -3543,10 +3616,10 @@ init_decl_processing () tree builtin_function (name, type, function_code, library_name) - char *name; + const char *name; tree type; enum built_in_function function_code; - char *library_name; + const char *library_name; { tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); DECL_EXTERNAL (decl) = 1; @@ -3718,7 +3791,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) /* The corresponding pop_obstacks is in finish_decl. */ push_obstacks_nochange (); - if (warn_main && TREE_CODE (decl) != FUNCTION_DECL + if (warn_main > 0 && TREE_CODE (decl) != FUNCTION_DECL && !strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "main")) warning_with_decl (decl, "`%s' is usually a function"); @@ -4309,13 +4382,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) tree type = NULL_TREE; int longlong = 0; int constp; + int restrictp; int volatilep; + int type_quals = TYPE_UNQUALIFIED; int inlinep; int explicit_int = 0; int explicit_char = 0; int defaulted_int = 0; tree typedef_decl = 0; - char *name; + const char *name; tree typedef_type = 0; int funcdef_flag = 0; enum tree_code innermost_code = ERROR_MARK; @@ -4471,13 +4546,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) && ! (specbits & (1 << (int) RID_TYPEDEF) && initialized) && ! (in_system_header && ! allocation_temporary_p ())) { - /* C9x will probably require a diagnostic here. - For now, issue a warning if -Wreturn-type and this is a function, - or if -Wimplicit; prefer the former warning since it is more - explicit. */ + /* Issue a warning if this is an ISO C 9x program or if -Wreturn-type + and this is a function, or if -Wimplicit; prefer the former + warning since it is more explicit. */ if ((warn_implicit_int || warn_return_type) && funcdef_flag) warn_about_return_type = 1; - else if (warn_implicit_int) + else if (warn_implicit_int || flag_isoc9x) warning ("type defaults to `int' in declaration of `%s'", name); } @@ -4619,19 +4693,26 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) type = build_complex_type (type); } - /* Set CONSTP if this declaration is `const', whether by - explicit specification or via a typedef. - Likewise for VOLATILEP. */ - + /* 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); inlinep = !! (specbits & (1 << (int) RID_INLINE)); if (constp > 1) pedwarn ("duplicate `const'"); + if (restrictp > 1) + pedwarn ("duplicate `restrict'"); if (volatilep > 1) pedwarn ("duplicate `volatile'"); - if (! flag_gen_aux_info && (TYPE_READONLY (type) || TYPE_VOLATILE (type))) + if (! flag_gen_aux_info && (TYPE_QUALS (type))) type = TYPE_MAIN_VARIANT (type); + type_quals = ((constp ? TYPE_QUAL_CONST : 0) + | (restrictp ? TYPE_QUAL_RESTRICT : 0) + | (volatilep ? TYPE_QUAL_VOLATILE : 0)); /* Warn if two storage classes are given. Default to `auto'. */ @@ -4865,13 +4946,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) is set correctly. */ type = build_array_type (type, itype); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + if (type_quals) + type = c_build_qualified_type (type, type_quals); #if 0 /* don't clear these; leave them set so that the array type or the variable is itself const or volatile. */ - constp = 0; - volatilep = 0; + type_quals = TYPE_UNQUALIFIED; #endif if (size_varies) @@ -4936,12 +5016,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) flag_traditional ? NULL_TREE : arg_types); #endif - /* ANSI seems to say that `const int foo ();' - does not make the function foo const. */ - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - constp = 0; - volatilep = 0; + /* Type qualifiers before the return type of the function + qualify the return type, not the function type. */ + if (type_quals) + type = c_build_qualified_type (type, type_quals); + type_quals = TYPE_UNQUALIFIED; type = build_function_type (type, arg_types); declarator = TREE_OPERAND (declarator, 0); @@ -4965,12 +5044,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) for the pointer. */ if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); - constp = 0; - volatilep = 0; + && type_quals) + pedwarn ("ANSI C forbids qualified function types"); + if (type_quals) + type = c_build_qualified_type (type, type_quals); + type_quals = TYPE_UNQUALIFIED; size_varies = 0; type = build_pointer_type (type); @@ -4982,13 +5060,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) { register tree typemodlist; int erred = 0; + + constp = 0; + volatilep = 0; + restrictp = 0; for (typemodlist = TREE_TYPE (declarator); typemodlist; typemodlist = TREE_CHAIN (typemodlist)) { - if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST]) + tree qualifier = TREE_VALUE (typemodlist); + + if (qualifier == ridpointers[(int) RID_CONST]) constp++; - else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE]) + else if (qualifier == ridpointers[(int) RID_VOLATILE]) volatilep++; + else if (qualifier == ridpointers[(int) RID_RESTRICT]) + restrictp++; else if (!erred) { erred = 1; @@ -4999,6 +5085,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) 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) + | (volatilep ? TYPE_QUAL_VOLATILE : 0)); } declarator = TREE_OPERAND (declarator, 0); @@ -5025,10 +5117,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) /* Note that the grammar rejects storage classes in typenames, fields or parameters */ if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + && type_quals) + pedwarn ("ANSI C forbids qualified function types"); + if (type_quals) + type = c_build_qualified_type (type, type_quals); decl = build_decl (TYPE_DECL, declarator, type); if ((specbits & (1 << (int) RID_SIGNED)) || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) @@ -5060,10 +5152,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) /* Note that the grammar rejects storage classes in typenames, fields or parameters */ if (pedantic && TREE_CODE (type) == FUNCTION_TYPE - && (constp || volatilep)) + && type_quals) pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + if (type_quals) + type = c_build_qualified_type (type, type_quals); pop_obstacks (); return type; } @@ -5103,20 +5195,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) { /* Transfer const-ness of array into that of type pointed to. */ type = TREE_TYPE (type); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + if (type_quals) + type = c_build_qualified_type (type, type_quals); type = build_pointer_type (type); - volatilep = constp = 0; + type_quals = TYPE_UNQUALIFIED; size_varies = 0; } else if (TREE_CODE (type) == FUNCTION_TYPE) { - if (pedantic && (constp || volatilep)) - pedwarn ("ANSI C forbids const or volatile function types"); - if (constp || volatilep) - type = c_build_type_variant (type, constp, volatilep); + if (pedantic && type_quals) + pedwarn ("ANSI C forbids qualified function types"); + if (type_quals) + type = c_build_qualified_type (type, type_quals); type = build_pointer_type (type); - volatilep = constp = 0; + type_quals = TYPE_UNQUALIFIED; } decl = build_decl (PARM_DECL, declarator, type); @@ -5164,13 +5256,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) type = error_mark_node; } /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) + if (TREE_CODE (type) == ARRAY_TYPE && type_quals) { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), + 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. */ - constp = volatilep = 0; + type_quals = TYPE_UNQUALIFIED; #endif } decl = build_decl (FIELD_DECL, declarator, type); @@ -5209,18 +5301,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) decl = build_decl (FUNCTION_DECL, declarator, type); decl = build_decl_attribute_variant (decl, decl_machine_attr); - if (pedantic && (constp || volatilep) - && ! DECL_IN_SYSTEM_HEADER (decl)) - pedwarn ("ANSI C forbids const or volatile functions"); + if (pedantic && type_quals && ! DECL_IN_SYSTEM_HEADER (decl)) + pedwarn ("ANSI C forbids qualified function types"); if (pedantic && TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl))) == void_type_node - && (TYPE_READONLY (TREE_TYPE (TREE_TYPE (decl))) - || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (decl)))) + && TYPE_QUALS (TREE_TYPE (TREE_TYPE (decl))) && ! DECL_IN_SYSTEM_HEADER (decl)) - pedwarn ("ANSI C forbids const or volatile void function return type"); + pedwarn ("ANSI C forbids qualified void function return type"); - if (volatilep + /* GNU C interprets a `volatile void' return type to indicate + that the function does not return. */ + if ((type_quals & TYPE_QUAL_VOLATILE) && TREE_TYPE (TREE_TYPE (decl)) != void_type_node) warning ("`noreturn' function returns non-void value"); @@ -5250,13 +5342,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) int extern_ref = !initialized && (specbits & (1 << (int) RID_EXTERN)); /* Move type qualifiers down to element of an array. */ - if (TREE_CODE (type) == ARRAY_TYPE && (constp || volatilep)) + if (TREE_CODE (type) == ARRAY_TYPE && type_quals) { - type = build_array_type (c_build_type_variant (TREE_TYPE (type), - constp, volatilep), + type = build_array_type (c_build_qualified_type (TREE_TYPE (type), + type_quals), TYPE_DOMAIN (type)); #if 0 /* Leave the variable const or volatile as well. */ - constp = volatilep = 0; + type_quals = TYPE_UNQUALIFIED; #endif } @@ -5303,14 +5395,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) DECL_REGISTER (decl) = 1; /* Record constancy and volatility. */ + c_apply_type_quals_to_decl (type_quals, decl); - if (constp) - TREE_READONLY (decl) = 1; - if (volatilep) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } /* If a type has volatile components, it should be stored in memory. Otherwise, the fact that those components are volatile will be ignored, and would even crash the compiler. */ @@ -5570,8 +5656,7 @@ parmlist_tags_warning () if (! already) { - warning ("its scope is only this definition or declaration,"); - warning ("which is probably not what you want."); + warning ("its scope is only this definition or declaration, which is probably not what you want."); already = 1; } } @@ -5685,8 +5770,8 @@ start_struct (code, name) tree grokfield (filename, line, declarator, declspecs, width) - char *filename; - int line; + const char *filename ATTRIBUTE_UNUSED; + int line ATTRIBUTE_UNUSED; tree declarator, declspecs, width; { tree value; @@ -5768,9 +5853,10 @@ finish_struct (t, fieldlist, attributes) break; if (x == 0) - pedwarn ("%s has no %smembers", - (TREE_CODE (t) == UNION_TYPE ? "union" : "structure"), - (fieldlist ? "named " : "")); + pedwarn ((fieldlist + ? "%s has no named members" + : "%s has no members"), + TREE_CODE (t) == UNION_TYPE ? "union" : "struct"); } /* Install struct as DECL_CONTEXT of each field decl. @@ -6428,6 +6514,10 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested) except for defining how to inline. So set DECL_EXTERNAL in that case. */ DECL_EXTERNAL (decl1) = current_extern_inline; +#ifdef SET_DEFAULT_DECL_ATTRIBUTES + SET_DEFAULT_DECL_ATTRIBUTES (decl1, attributes); +#endif + /* This function exists in static storage. (This does not mean `static' in the C sense!) */ TREE_STATIC (decl1) = 1; @@ -6437,7 +6527,7 @@ start_function (declspecs, declarator, prefix_attributes, attributes, nested) TREE_PUBLIC (decl1) = 0; /* Warn for unlikely, improbable, or stupid declarations of `main'. */ - if (warn_main + if (warn_main > 0 && strcmp ("main", IDENTIFIER_POINTER (DECL_NAME (decl1))) == 0) { tree args; @@ -7154,12 +7244,8 @@ finish_function (nested) if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (fndecl))) != integer_type_node) { - /* You would expect the sense of this test to be the other way - around, but if warn_main is set, we will already have warned, - so this would be a duplicate. This is the warning you get - in some environments even if you *don't* ask for it, because - these are environments where it may be more of a problem than - usual. */ + /* 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'"); } @@ -7183,6 +7269,12 @@ finish_function (nested) current_function_returns_null |= can_reach_end; + if (warn_missing_noreturn + && !TREE_THIS_VOLATILE (fndecl) + && !current_function_returns_null + && !current_function_returns_value) + warning ("function might be possible candidate for attribute `noreturn'"); + if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) warning ("`noreturn' function does return"); else if (warn_return_type && can_reach_end diff --git a/contrib/gcc/c-iterate.c b/contrib/gcc/c-iterate.c index b8f51d0..dc0cc8a 100644 --- a/contrib/gcc/c-iterate.c +++ b/contrib/gcc/c-iterate.c @@ -1,5 +1,5 @@ /* Build expressions with type checking for C compiler. - Copyright (C) 1987, 88, 89, 92, 93, 96, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92, 93, 96, 1997, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -539,10 +539,10 @@ prdecl (d) fprintf (stderr, dname); } else - fprintf (stderr, "<>"); + fprintf (stderr, "<>"); } else - fprintf (stderr, "<>"); + fprintf (stderr, "<<0>>"); } /* Print Iterator List -- names only */ diff --git a/contrib/gcc/c-lang.c b/contrib/gcc/c-lang.c index 8a5fd6b..4c55411 100644 --- a/contrib/gcc/c-lang.c +++ b/contrib/gcc/c-lang.c @@ -28,6 +28,13 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "output.h" +#if USE_CPPLIB +#include "cpplib.h" +extern char *yy_cur; +extern cpp_reader parse_in; +extern cpp_options parse_options; +#endif + /* Each of the functions defined here is an alternative to a function in objc-actions.c. */ @@ -42,17 +49,25 @@ lang_decode_option (argc, argv) void lang_init_options () { +#if USE_CPPLIB + cpp_reader_init (&parse_in); + parse_in.opts = &parse_options; + cpp_options_init (&parse_options); +#endif } void lang_init () { -#if !USE_CPPLIB /* the beginning of the file is a new line; check for # */ /* With luck, we discover the real source file's name from that and put it in input_filename. */ +#if !USE_CPPLIB ungetc (check_newline (), finput); -#endif +#else + check_newline (); + yy_cur--; +#endif } void @@ -134,7 +149,7 @@ recognize_objc_keyword () tree build_objc_string (len, str) int len ATTRIBUTE_UNUSED; - char *str ATTRIBUTE_UNUSED; + const char *str ATTRIBUTE_UNUSED; { abort (); return NULL_TREE; diff --git a/contrib/gcc/c-lex.c b/contrib/gcc/c-lex.c index f82ad76..27c65f3 100644 --- a/contrib/gcc/c-lex.c +++ b/contrib/gcc/c-lex.c @@ -20,7 +20,6 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" -#include #include "rtl.h" #include "tree.h" @@ -32,6 +31,7 @@ Boston, MA 02111-1307, USA. */ #include "c-parse.h" #include "c-pragma.h" #include "toplev.h" +#include "intl.h" /* MULTIBYTE_CHARS support only works for native compilers. ??? Ideally what we want is to model widechar support after @@ -41,8 +41,9 @@ Boston, MA 02111-1307, USA. */ #endif #ifdef MULTIBYTE_CHARS +#include "mbchar.h" #include -#endif +#endif /* MULTIBYTE_CHARS */ #if USE_CPPLIB #include "cpplib.h" @@ -65,11 +66,11 @@ tree ridpointers[(int) RID_MAX]; #if USE_CPPLIB extern unsigned char *yy_cur, *yy_lim; - + extern int yy_get_token (); - + #define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()) -#define UNGETC(c) ((c), yy_cur--) +#define UNGETC(c) ((c) == EOF ? 0 : yy_cur--) #else #define GETC() getc (finput) #define UNGETC(c) ungetc (c, finput) @@ -116,14 +117,15 @@ static int end_of_file; static int nextchar = -1; #endif -#ifdef HANDLE_SYSV_PRAGMA -static int handle_sysv_pragma PROTO((int)); -#endif /* HANDLE_SYSV_PRAGMA */ +#ifdef HANDLE_GENERIC_PRAGMAS +static int handle_generic_pragma PROTO((int)); +#endif /* HANDLE_GENERIC_PRAGMAS */ static int whitespace_cr PROTO((int)); static int skip_white_space PROTO((int)); static int skip_white_space_on_line PROTO((void)); -static char *extend_token_buffer PROTO((char *)); +static char *extend_token_buffer PROTO((const char *)); static int readescape PROTO((int *)); +static void parse_float PROTO((PTR)); /* Do not insert generated code into the source, instead, include it. This allows us to build gcc automatically even for targets that @@ -170,8 +172,10 @@ remember_protocol_qualifiers () wordlist[i].name = "inout"; else if (wordlist[i].rid == RID_BYCOPY) wordlist[i].name = "bycopy"; + else if (wordlist[i].rid == RID_BYREF) + wordlist[i].name = "byref"; else if (wordlist[i].rid == RID_ONEWAY) - wordlist[i].name = "oneway"; + wordlist[i].name = "oneway"; } char * @@ -193,19 +197,22 @@ init_parse (filename) #ifdef IO_BUFFER_SIZE setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); #endif -#endif /* !USE_CPPLIB */ - - init_lex (); - -#if USE_CPPLIB - yy_cur = "\n"; - yy_lim = yy_cur+1; - +#else /* !USE_CPPLIB */ parse_in.show_column = 1; if (! cpp_start_read (&parse_in, filename)) abort (); + + if (filename == 0 || !strcmp (filename, "-")) + filename = "stdin"; + + /* cpp_start_read always puts at least one line directive into the + token buffer. We must arrange to read it out here. */ + yy_cur = parse_in.token_buffer; + yy_lim = CPP_PWRITTEN (&parse_in); #endif + init_lex (); + return filename; } @@ -232,6 +239,7 @@ init_lex () #ifdef MULTIBYTE_CHARS /* Change to the native locale for multibyte conversions. */ setlocale (LC_CTYPE, ""); + literal_codeset = getenv ("LANG"); #endif maxtoken = 40; @@ -248,6 +256,7 @@ init_lex () ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); ridpointers[(int) RID_INLINE] = get_identifier ("inline"); ridpointers[(int) RID_CONST] = get_identifier ("const"); + ridpointers[(int) RID_RESTRICT] = get_identifier ("restrict"); ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); ridpointers[(int) RID_AUTO] = get_identifier ("auto"); ridpointers[(int) RID_STATIC] = get_identifier ("static"); @@ -261,6 +270,7 @@ init_lex () ridpointers[(int) RID_OUT] = get_identifier ("out"); ridpointers[(int) RID_INOUT] = get_identifier ("inout"); ridpointers[(int) RID_BYCOPY] = get_identifier ("bycopy"); + ridpointers[(int) RID_BYREF] = get_identifier ("byref"); ridpointers[(int) RID_ONEWAY] = get_identifier ("oneway"); forget_protocol_qualifiers(); @@ -276,6 +286,7 @@ init_lex () if (flag_traditional) { UNSET_RESERVED_WORD ("const"); + UNSET_RESERVED_WORD ("restrict"); UNSET_RESERVED_WORD ("volatile"); UNSET_RESERVED_WORD ("typeof"); UNSET_RESERVED_WORD ("signed"); @@ -283,6 +294,9 @@ init_lex () UNSET_RESERVED_WORD ("iterator"); UNSET_RESERVED_WORD ("complex"); } + else if (!flag_isoc9x) + UNSET_RESERVED_WORD ("restrict"); + if (flag_no_asm) { UNSET_RESERVED_WORD ("asm"); @@ -470,7 +484,7 @@ skip_white_space_on_line () static char * extend_token_buffer (p) - char *p; + const char *p; { int offset = p - token_buffer; @@ -480,6 +494,22 @@ extend_token_buffer (p) return token_buffer + offset; } +#if defined HANDLE_PRAGMA +/* Local versions of these macros, that can be passed as function pointers. */ +static int +pragma_getc () +{ + return GETC(); +} + +static void +pragma_ungetc (arg) + int arg; +{ + UNGETC (arg); +} +#endif + /* At the beginning of a line, increment the line number and process any #-directive on this line. If the line is a #-directive, read the entire line and return a newline. @@ -531,34 +561,46 @@ check_newline () c = GETC (); if (c == '\n') return c; -#ifdef HANDLE_SYSV_PRAGMA + +#if defined HANDLE_PRAGMA || defined HANDLE_GENERIC_PRAGMAS UNGETC (c); token = yylex (); if (token != IDENTIFIER) goto skipline; - return handle_sysv_pragma (token); -#else /* !HANDLE_SYSV_PRAGMA */ +#endif /* HANDLE_PRAGMA || HANDLE_GENERIC_PRAGMAS */ + #ifdef HANDLE_PRAGMA + /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS (if + both are defined), in order to give the back end a chance to + override the interpretation of generic style pragmas. */ #if !USE_CPPLIB - UNGETC (c); - token = yylex (); - if (token != IDENTIFIER) - goto skipline; if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = GETC (); - ungetc (c, finput); - if (HANDLE_PRAGMA (finput, yylval.ttype)) { - c = GETC (); - return c; + c = nextchar, nextchar = -1; + UNGETC (c); } -#else - ??? do not know what to do ???; #endif /* !USE_CPPLIB */ + + if (TREE_CODE (yylval.ttype) != IDENTIFIER_NODE) + goto skipline; + + if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, + IDENTIFIER_POINTER (yylval.ttype))) + return GETC (); #endif /* HANDLE_PRAGMA */ -#endif /* !HANDLE_SYSV_PRAGMA */ + +#ifdef HANDLE_GENERIC_PRAGMAS + if (handle_generic_pragma (token)) + return GETC (); +#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); + goto skipline; } } @@ -748,7 +790,7 @@ linenum: struct file_stack *p = input_file_stack; if (indent_level != p->indent_level) { - warning_with_file_and_line + warning_with_file_and_line (p->name, old_lineno, "This file contains more `%c's than `%c's.", indent_level > p->indent_level ? '{' : '}', @@ -817,17 +859,17 @@ linenum: return c; } -#ifdef HANDLE_SYSV_PRAGMA +#ifdef HANDLE_GENERIC_PRAGMAS /* Handle a #pragma directive. TOKEN is the token we read after `#pragma'. Processes the entire input - line and returns a character for the caller to reread: either \n or EOF. */ + line and return non-zero iff the pragma has been successfully parsed. */ /* This function has to be in this file, in order to get at the token types. */ static int -handle_sysv_pragma (token) +handle_generic_pragma (token) register int token; { register int c; @@ -843,7 +885,7 @@ handle_sysv_pragma (token) handle_pragma_token (token_buffer, yylval.ttype); break; default: - handle_pragma_token (token_buffer, 0); + handle_pragma_token (token_buffer, NULL); } #if !USE_CPPLIB if (nextchar >= 0) @@ -854,17 +896,16 @@ handle_sysv_pragma (token) while (c == ' ' || c == '\t') c = GETC (); - if (c == '\n' || c == EOF) - { - handle_pragma_token (0, 0); - return c; - } UNGETC (c); + + if (c == '\n' || c == EOF) + return handle_pragma_token (NULL, NULL); + token = yylex (); } } -#endif /* HANDLE_SYSV_PRAGMA */ +#endif /* HANDLE_GENERIC_PRAGMAS */ #define ENDFILE -1 /* token that represents end-of-file */ @@ -925,7 +966,7 @@ readescape (ignore_ptr) ; else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) + && (((unsigned)1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) <= firstdig))) pedwarn ("hex escape out of range"); return code; @@ -1007,30 +1048,25 @@ readescape (ignore_ptr) } void -yyerror (string) - char *string; +yyerror (msgid) + const char *msgid; { - char buf[200]; - - strcpy (buf, string); + const char *string = _(msgid); /* We can't print string and character constants well because the token_buffer contains the result of processing escapes. */ if (end_of_file) - strcat (buf, " at end of input"); + error ("%s at end of input", string); else if (token_buffer[0] == 0) - strcat (buf, " at null character"); + error ("%s at null character", string); else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); + error ("%s before string constant", string); else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); + error ("%s before character constant", string); else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); + error ("%s before character 0%o", string, (unsigned char) token_buffer[0]); else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); + error ("%s before `%s'", string, token_buffer); } #if 0 @@ -1043,7 +1079,7 @@ struct try_type char long_long_flag; }; -struct try_type type_sequence[] = +struct try_type type_sequence[] = { { &integer_type_node, 0, 0, 0}, { &unsigned_type_node, 1, 0, 0}, @@ -1054,6 +1090,120 @@ struct try_type type_sequence[] = }; #endif /* 0 */ +struct pf_args +{ + /* Input */ + int base; + char * p; + /* I/O */ + int c; + int imag; + tree type; + int conversion_errno; + /* Output */ + REAL_VALUE_TYPE value; +}; + +static void +parse_float (data) + PTR data; +{ + struct pf_args * args = (struct pf_args *) data; + int fflag = 0, lflag = 0; + /* Copy token_buffer now, while it has just the number + and not the suffixes; once we add `f' or `i', + REAL_VALUE_ATOF may not work any more. */ + char *copy = (char *) alloca (args->p - token_buffer + 1); + bcopy (token_buffer, copy, args->p - token_buffer + 1); + + while (1) + { + int lose = 0; + + /* Read the suffixes to choose a data type. */ + switch (args->c) + { + case 'f': case 'F': + if (fflag) + error ("more than one `f' in numeric constant"); + fflag = 1; + break; + + case 'l': case 'L': + if (lflag) + error ("more than one `l' in numeric constant"); + lflag = 1; + break; + + case 'i': case 'I': + if (args->imag) + error ("more than one `i' or `j' in numeric constant"); + else if (pedantic) + pedwarn ("ANSI C forbids imaginary numeric constants"); + args->imag = 1; + break; + + default: + lose = 1; + } + + if (lose) + break; + + if (args->p >= token_buffer + maxtoken - 3) + args->p = extend_token_buffer (args->p); + *(args->p++) = args->c; + *(args->p) = 0; + args->c = GETC(); + } + + /* The second argument, machine_mode, of REAL_VALUE_ATOF + tells the desired precision of the binary result + of decimal-to-binary conversion. */ + + if (fflag) + { + if (lflag) + error ("both `f' and `l' in floating constant"); + + args->type = float_type_node; + errno = 0; + if (args->base == 16) + args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); + else + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + args->conversion_errno = errno; + /* A diagnostic is required here by some ANSI C testsuites. + This is not pedwarn, because some people don't want + an error for this. */ + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `float'"); + } + else if (lflag) + { + args->type = long_double_type_node; + errno = 0; + if (args->base == 16) + args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); + else + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + args->conversion_errno = errno; + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `long double'"); + } + else + { + errno = 0; + if (args->base == 16) + args->value = REAL_VALUE_HTOF (copy, TYPE_MODE (args->type)); + else + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + args->conversion_errno = errno; + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `double'"); + } +} + int yylex () { @@ -1164,8 +1314,6 @@ yylex () while (ISALNUM (c) || c == '_' || c == '$' || c == '@') { /* Make sure this char really belongs in an identifier. */ - if (c == '@' && ! doing_objc_thang) - break; if (c == '$') { if (! dollars_in_ident) @@ -1245,7 +1393,7 @@ yylex () && TREE_CODE (DECL_INITIAL (lastiddecl)) == STRING_CST) { tree stringval = DECL_INITIAL (lastiddecl); - + /* Copy the string value so that we won't clobber anything if we put something in the TREE_CHAIN of this one. */ yylval.ttype = build_string (TREE_STRING_LENGTH (stringval), @@ -1300,8 +1448,8 @@ yylex () int parts[TOTAL_PARTS]; int overflow = 0; - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; + enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS, AFTER_EXPON} + floatflag = NOT_FLOAT; for (count = 0; count < TOTAL_PARTS; count++) parts[count] = 0; @@ -1337,12 +1485,12 @@ yylex () { if (c == '.') { - if (base == 16) + if (base == 16 && pedantic) error ("floating constant may not be in radix 16"); if (floatflag == TOO_MANY_POINTS) /* We have already emitted an error. Don't need another. */ ; - else if (floatflag == AFTER_POINT) + else if (floatflag == AFTER_POINT || floatflag == AFTER_EXPON) { error ("malformed floating constant"); floatflag = TOO_MANY_POINTS; @@ -1353,7 +1501,8 @@ yylex () else floatflag = AFTER_POINT; - base = 10; + if (base == 8) + base = 10; *p++ = c = GETC(); /* Accept '.' as the start of a floating-point number only when it is followed by a digit. @@ -1392,12 +1541,17 @@ yylex () if (c == 'e' || c == 'E') { base = 10; - floatflag = AFTER_POINT; + floatflag = AFTER_EXPON; break; /* start of exponent */ } error ("nondigits in number and not hexadecimal"); c = 0; } + else if (base == 16 && (c == 'p' || c == 'P')) + { + floatflag = AFTER_EXPON; + break; /* start of exponent */ + } else if (c >= 'a') { c = c - 'a' + 10; @@ -1450,11 +1604,12 @@ yylex () int imag = 0; int conversion_errno = 0; REAL_VALUE_TYPE value; - jmp_buf handler; + struct pf_args args; /* Read explicit exponent if any, and put it in tokenbuf. */ - if ((c == 'e') || (c == 'E')) + if ((base == 10 && ((c == 'e') || (c == 'E'))) + || (base == 16 && (c == 'p' || c == 'P'))) { if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); @@ -1465,9 +1620,10 @@ yylex () *p++ = c; c = GETC(); } + /* Exponent is decimal, even if string is a hex float. */ if (! ISDIGIT (c)) error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) + while (ISDIGIT (c)) { if (p >= token_buffer + maxtoken - 3) p = extend_token_buffer (p); @@ -1475,106 +1631,38 @@ yylex () c = GETC(); } } + if (base == 16 && floatflag != AFTER_EXPON) + error ("hexadecimal floating constant has no exponent"); *p = 0; + /* Setup input for parse_float() */ + args.base = base; + args.p = p; + args.c = c; + args.imag = imag; + args.type = type; + args.conversion_errno = conversion_errno; + /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) + if (do_float_handler (parse_float, (PTR) &args)) { - error ("floating constant out of range"); - value = dconst0; + /* Receive output from parse_float() */ + value = args.value; } else { - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (p - token_buffer + 1); - bcopy (token_buffer, copy, p - token_buffer + 1); - - set_float_handler (handler); - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C forbids imaginary numeric constants"); - imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - *p = 0; - c = GETC(); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - type = float_type_node; - errno = 0; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - conversion_errno = errno; - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, become some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - type = long_double_type_node; - errno = 0; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - conversion_errno = errno; - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - errno = 0; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - conversion_errno = errno; - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } + /* We got an exception from parse_float() */ + error ("floating constant out of range"); + value = dconst0; + } - set_float_handler (NULL_PTR); - } + /* Receive output from parse_float() */ + c = args.c; + imag = args.imag; + type = args.type; + conversion_errno = args.conversion_errno; + #ifdef ERANGE /* ERANGE is also reported for underflow, so test the value to distinguish overflow from that. */ @@ -1606,7 +1694,7 @@ yylex () int spec_long = 0; int spec_long_long = 0; int spec_imag = 0; - int bytes, warn, i; + int warn, i; traditional_type = ansi_type = type = NULL_TREE; while (1) @@ -1623,7 +1711,7 @@ yylex () { if (spec_long_long) error ("three `l's in integer constant"); - else if (pedantic) + else if (pedantic && ! in_system_header && warn_long_long) pedwarn ("ANSI C forbids long long integer constants"); spec_long_long = 1; } @@ -1645,20 +1733,10 @@ yylex () c = GETC(); } - /* If the constant won't fit in an unsigned long long, - then warn that the constant is out of range. */ - - /* ??? This assumes that long long and long integer types are - a multiple of 8 bits. This better than the original code - though which assumed that long was exactly 32 bits and long - long was exactly 64 bits. */ - - bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; + /* If it won't fit in the host's representation for integers, + then pedwarn. */ warn = overflow; - for (i = bytes; i < TOTAL_PARTS; i++) - if (parts[i]) - warn = 1; if (warn) pedwarn ("integer constant out of range"); @@ -1674,7 +1752,7 @@ yylex () << (i * HOST_BITS_PER_CHAR)); low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); } - + yylval.ttype = build_int_2 (low, high); TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; @@ -1749,7 +1827,10 @@ yylex () if (pedantic && !flag_traditional && !spec_long_long && !warn && (TYPE_PRECISION (long_integer_type_node) < TYPE_PRECISION (type))) - pedwarn ("integer constant out of range"); + { + warn = 1; + pedwarn ("integer constant out of range"); + } if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) warning ("decimal constant is so large that it is unsigned"); @@ -1777,6 +1858,15 @@ yylex () } else TREE_TYPE (yylval.ttype) = type; + + + /* If it's still an integer (not a complex), and it doesn't + fit in the type we choose for it, then pedwarn. */ + + if (! warn + && TREE_CODE (TREE_TYPE (yylval.ttype)) == INTEGER_TYPE + && ! int_fits_type_p (yylval.ttype, TREE_TYPE (yylval.ttype))) + pedwarn ("integer constant out of range"); } UNGETC (c); @@ -1795,30 +1885,27 @@ yylex () { register int result = 0; register int num_chars = 0; + int chars_seen = 0; unsigned width = TYPE_PRECISION (char_type_node); int max_chars; - - if (wide_flag) - { - width = WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); #endif - } - else - max_chars = TYPE_PRECISION (integer_type_node) / width; + + max_chars = TYPE_PRECISION (integer_type_node) / width; + if (wide_flag) + width = WCHAR_TYPE_SIZE; while (1) { tryagain: - c = GETC(); if (c == '\'' || c == EOF) break; + ++chars_seen; if (c == '\\') { int ignore = 0; @@ -1826,7 +1913,7 @@ yylex () if (ignore) goto tryagain; if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) + && (unsigned) c >= ((unsigned)1 << width)) pedwarn ("escape sequence out of range for character"); #ifdef MAP_CHARACTER if (ISPRINT (c)) @@ -1839,18 +1926,76 @@ yylex () pedwarn ("ANSI C forbids newline in character constant"); lineno++; } -#ifdef MAP_CHARACTER else - c = MAP_CHARACTER (c); + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 1; i <= longest_char; ++i) + { + if (i > maxtoken - 4) + extend_token_buffer (token_buffer); + + token_buffer[i] = c; + char_len = local_mbtowc (& wc, + token_buffer + 1, + i); + if (char_len != -1) + break; + c = GETC (); + } + if (char_len > 1) + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len < i) + UNGETC (c); + if (! wide_flag) + { + /* Merge character into result; ignore excess chars. */ + for (i = 1; i <= char_len; ++i) + { + if (i > max_chars) + break; + if (width < HOST_BITS_PER_INT) + result = (result << width) + | (token_buffer[i] + & ((1 << width) - 1)); + else + result = token_buffer[i]; + } + num_chars += char_len; + goto tryagain; + } + c = wc; + } + else + { + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + if (wide_flag) + c = wc; +#ifdef MAP_CHARACTER + else + c = MAP_CHARACTER (c); #endif + } +#else /* ! MULTIBYTE_CHARS */ +#ifdef MAP_CHARACTER + c = MAP_CHARACTER (c); +#endif +#endif /* ! MULTIBYTE_CHARS */ + } - num_chars++; - if (num_chars > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[num_chars] = c; + if (wide_flag) + { + if (chars_seen == 1) /* only keep the first one */ + result = c; + goto tryagain; + } /* Merge character into result; ignore excess chars. */ + num_chars += (width / TYPE_PRECISION (char_type_node)); if (num_chars < max_chars + 1) { if (width < HOST_BITS_PER_INT) @@ -1860,19 +2005,16 @@ yylex () } } - token_buffer[num_chars + 1] = '\''; - token_buffer[num_chars + 2] = 0; - if (c != '\'') error ("malformatted character constant"); - else if (num_chars == 0) + else if (chars_seen == 0) error ("empty character constant"); else if (num_chars > max_chars) { num_chars = max_chars; error ("character constant too long"); } - else if (num_chars != 1 && ! flag_traditional && warn_multichar) + else if (chars_seen != 1 && ! flag_traditional && warn_multichar) warning ("multi-character character constant"); /* If char type is signed, sign-extend the constant. */ @@ -1897,22 +2039,6 @@ yylex () } else { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[1] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) - result = wc; - else - warning ("Ignoring invalid multibyte character"); - } -#endif yylval.ttype = build_int_2 (result, 0); TREE_TYPE (yylval.ttype) = wchar_type_node; } @@ -1924,7 +2050,13 @@ yylex () case '"': string_constant: { - c = GETC(); + unsigned width = wide_flag ? WCHAR_TYPE_SIZE + : TYPE_PRECISION (char_type_node); +#ifdef MULTIBYTE_CHARS + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); +#endif + c = GETC (); p = token_buffer + 1; while (c != '"' && c >= 0) @@ -1935,9 +2067,8 @@ yylex () c = readescape (&ignore); if (ignore) goto skipnewline; - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && c >= (1 << TYPE_PRECISION (char_type_node))) + if (width < HOST_BITS_PER_INT + && (unsigned) c >= ((unsigned)1 << width)) pedwarn ("escape sequence out of range for character"); } else if (c == '\n') @@ -1946,15 +2077,92 @@ yylex () pedwarn ("ANSI C forbids newline in string constant"); lineno++; } + else + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 0; i < longest_char; ++i) + { + if (p + i >= token_buffer + maxtoken) + p = extend_token_buffer (p); + p[i] = c; - if (p == token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; + char_len = local_mbtowc (& wc, p, i + 1); + if (char_len != -1) + break; + c = GETC (); + } + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + else + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len <= i) + UNGETC (c); + if (! wide_flag) + { + p += (i + 1); + c = GETC (); + continue; + } + c = wc; + } +#endif /* MULTIBYTE_CHARS */ + } + + /* Add this single character into the buffer either as a wchar_t + or as a single byte. */ + if (wide_flag) + { + unsigned width = TYPE_PRECISION (char_type_node); + unsigned bytemask = (1 << width) - 1; + int byte; + + if (p + WCHAR_BYTES > token_buffer + maxtoken) + p = extend_token_buffer (p); + + for (byte = 0; byte < WCHAR_BYTES; ++byte) + { + int value; + if (byte >= (int) sizeof (c)) + value = 0; + else + value = (c >> (byte * width)) & bytemask; + if (BYTES_BIG_ENDIAN) + p[WCHAR_BYTES - byte - 1] = value; + else + p[byte] = value; + } + p += WCHAR_BYTES; + } + else + { + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); + *p++ = c; + } skipnewline: - c = GETC(); + c = GETC (); + } + + /* Terminate the string value, either with a single byte zero + or with a wide zero. */ + if (wide_flag) + { + if (p + WCHAR_BYTES > token_buffer + maxtoken) + p = extend_token_buffer (p); + bzero (p, WCHAR_BYTES); + p += WCHAR_BYTES; + } + else + { + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); + *p++ = 0; } - *p = 0; if (c < 0) error ("Unterminated string constant"); @@ -1964,52 +2172,27 @@ yylex () if (wide_flag) { - /* If this is a L"..." wide-string, convert the multibyte string - to a wide character string. */ - char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); - int len; - -#ifdef MULTIBYTE_CHARS - len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); - if (len < 0 || len >= (p - token_buffer)) - { - warning ("Ignoring invalid multibyte string"); - len = 0; - } - bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); -#else - { - char *wp, *cp; - - wp = widep + (BYTES_BIG_ENDIAN ? WCHAR_BYTES - 1 : 0); - bzero (widep, (p - token_buffer) * WCHAR_BYTES); - for (cp = token_buffer + 1; cp < p; cp++) - *wp = *cp, wp += WCHAR_BYTES; - len = p - token_buffer - 1; - } -#endif - yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); + yylval.ttype = build_string (p - (token_buffer + 1), + token_buffer + 1); TREE_TYPE (yylval.ttype) = wchar_array_type_node; value = STRING; } else if (objc_flag) { /* Return an Objective-C @"..." constant string object. */ - yylval.ttype = build_objc_string (p - token_buffer, + yylval.ttype = build_objc_string (p - (token_buffer + 1), token_buffer + 1); TREE_TYPE (yylval.ttype) = char_array_type_node; value = OBJC_STRING; } else { - yylval.ttype = build_string (p - token_buffer, token_buffer + 1); + yylval.ttype = build_string (p - (token_buffer + 1), + token_buffer + 1); TREE_TYPE (yylval.ttype) = char_array_type_node; value = STRING; } - *p++ = '"'; - *p = 0; - break; } diff --git a/contrib/gcc/c-lex.h b/contrib/gcc/c-lex.h index bd0b9d4..7d73ab5 100644 --- a/contrib/gcc/c-lex.h +++ b/contrib/gcc/c-lex.h @@ -1,5 +1,5 @@ /* Define constants for communication with c-parse.y. - Copyright (C) 1987, 1992 Free Software Foundation, Inc. + Copyright (C) 1987, 1992, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -40,6 +40,7 @@ enum rid RID_TYPEDEF, RID_SIGNED, RID_CONST, + RID_RESTRICT, RID_VOLATILE, RID_INLINE, RID_NOALIAS, @@ -50,6 +51,7 @@ enum rid RID_OUT, RID_INOUT, RID_BYCOPY, + RID_BYREF, RID_ONEWAY, RID_ID, @@ -79,7 +81,7 @@ extern void position_after_white_space PROTO((void)); extern int check_newline PROTO((void)); extern int yylex PROTO((void)); -extern void yyerror PROTO((char *)); +extern void yyerror PROTO((const char *)); extern void forget_protocol_qualifiers PROTO((void)); extern void remember_protocol_qualifiers PROTO((void)); diff --git a/contrib/gcc/c-parse.gperf b/contrib/gcc/c-parse.gperf index 90cab6a..888eee9 100644 --- a/contrib/gcc/c-parse.gperf +++ b/contrib/gcc/c-parse.gperf @@ -1,7 +1,7 @@ %{ -/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ +/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ c-parse.gperf */ %} -struct resword { char *name; short token; enum rid rid; }; +struct resword { const char *name; short token; enum rid rid; }; %% @class, CLASS, NORID @compatibility_alias, ALIAS, NORID @@ -35,6 +35,8 @@ __iterator__, SCSPEC, RID_ITERATOR __label__, LABEL, NORID __real, REALPART, NORID __real__, REALPART, NORID +__restrict, TYPE_QUAL, RID_RESTRICT +__restrict__, TYPE_QUAL, RID_RESTRICT __signed, TYPESPEC, RID_SIGNED __signed__, TYPESPEC, RID_SIGNED __typeof, TYPEOF, NORID @@ -45,6 +47,7 @@ asm, ASM_KEYWORD, NORID auto, SCSPEC, RID_AUTO break, BREAK, NORID bycopy, TYPE_QUAL, RID_BYCOPY +byref, TYPE_QUAL, RID_BYREF case, CASE, NORID char, TYPESPEC, RID_CHAR const, TYPE_QUAL, RID_CONST @@ -68,6 +71,7 @@ long, TYPESPEC, RID_LONG oneway, TYPE_QUAL, RID_ONEWAY out, TYPE_QUAL, RID_OUT register, SCSPEC, RID_REGISTER +restrict, TYPE_QUAL, RID_RESTRICT return, RETURN, NORID short, TYPESPEC, RID_SHORT signed, TYPESPEC, RID_SIGNED diff --git a/contrib/gcc/c-parse.in b/contrib/gcc/c-parse.in index 16500c5..6757c4d 100644 --- a/contrib/gcc/c-parse.in +++ b/contrib/gcc/c-parse.in @@ -1,5 +1,5 @@ /* YACC parser for C syntax and for Objective C. -*-c-*- - Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -31,7 +31,7 @@ ifobjc %expect 66 end ifobjc ifc -%expect 46 +%expect 51 /* These are the 23 conflicts you should get in parse.output; the state numbers may vary if minor changes in the grammar are made. @@ -116,7 +116,7 @@ end ifc yylval contains an IDENTIFIER_NODE which indicates which one. */ %token TYPESPEC -/* Reserved words that qualify type: "const" or "volatile". +/* Reserved words that qualify type: "const", "volatile", or "restrict". yylval contains an IDENTIFIER_NODE which indicates which one. */ %token TYPE_QUAL @@ -525,7 +525,7 @@ cast_expr: tree type = $2; finish_init (); - if (pedantic) + if (pedantic && ! flag_isoc9x) pedwarn ("ANSI C forbids constructor expressions"); if (TYPE_NAME (type) != 0) { @@ -604,12 +604,22 @@ expr_no_commas: { skip_evaluation -= $1 == boolean_true_node; $$ = build_conditional_expr ($1, $2, $5); } | expr_no_commas '=' expr_no_commas - { $$ = build_modify_expr ($1, NOP_EXPR, $3); - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } + { char class; + $$ = build_modify_expr ($1, NOP_EXPR, $3); + class = TREE_CODE_CLASS (TREE_CODE ($$)); + if (class == 'e' || class == '1' + || class == '2' || class == '<') + C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); + } | expr_no_commas ASSIGN expr_no_commas - { $$ = build_modify_expr ($1, $2, $3); + { char class; + $$ = build_modify_expr ($1, $2, $3); /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); } + class = TREE_CODE_CLASS (TREE_CODE ($$)); + if (class == 'e' || class == '1' + || class == '2' || class == '<') + C_SET_EXP_ORIGINAL_CODE ($$, ERROR_MARK); + } ; primary: @@ -1275,33 +1285,41 @@ initlist1: /* `initelt' is a single element of an initializer. It may use braces. */ initelt: - expr_no_commas - { process_init_element ($1); } - | '{' + designator_list '=' initval + | designator initval + | identifier ':' + { set_init_label ($1); } + initval + | initval + ; + +initval: + '{' { push_init_level (0); } initlist_maybe_comma '}' { process_init_element (pop_init_level (0)); } + | expr_no_commas + { process_init_element ($1); } | error + ; + +designator_list: + designator + | designator_list designator + ; + +designator: + '.' identifier + { set_init_label ($2); } /* These are for labeled elements. The syntax for an array element initializer conflicts with the syntax for an Objective-C message, so don't include these productions in the Objective-C grammar. */ ifc - | '[' expr_no_commas ELLIPSIS expr_no_commas ']' '=' + | '[' expr_no_commas ELLIPSIS expr_no_commas ']' { set_init_index ($2, $4); } - initelt - | '[' expr_no_commas ']' '=' - { set_init_index ($2, NULL_TREE); } - initelt | '[' expr_no_commas ']' { set_init_index ($2, NULL_TREE); } - initelt end ifc - | identifier ':' - { set_init_label ($1); } - initelt - | '.' identifier '=' - { set_init_label ($2); } - initelt ; nested_function: @@ -1398,6 +1416,13 @@ parm_declarator: /* | parm_declarator '(' error ')' %prec '.' { $$ = build_nt (CALL_EXPR, $1, NULL_TREE, NULL_TREE); poplevel (0, 0, 0); } */ +ifc + | parm_declarator '[' '*' ']' %prec '.' + { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); + if (! flag_isoc9x) + error ("`[*]' in parameter declaration only allowed in ISO C 9x"); + } +end ifc | parm_declarator '[' expr ']' %prec '.' { $$ = build_nt (ARRAY_REF, $1, $3); } | parm_declarator '[' ']' %prec '.' @@ -1427,6 +1452,13 @@ notype_declarator: { $$ = $2; } | '*' type_quals notype_declarator %prec UNARY { $$ = make_pointer_declarator ($2, $3); } +ifc + | notype_declarator '[' '*' ']' %prec '.' + { $$ = build_nt (ARRAY_REF, $1, NULL_TREE); + if (! flag_isoc9x) + error ("`[*]' in parameter declaration only allowed in ISO C 9x"); + } +end ifc | notype_declarator '[' expr ']' %prec '.' { $$ = build_nt (ARRAY_REF, $1, $3); } | notype_declarator '[' ']' %prec '.' @@ -1509,7 +1541,8 @@ maybecomma: maybecomma_warn: /* empty */ | ',' - { if (pedantic) pedwarn ("comma at end of enumerator list"); } + { if (pedantic && ! flag_isoc9x) + pedwarn ("comma at end of enumerator list"); } ; component_decl_list: @@ -1676,6 +1709,8 @@ absdcl1: /* a nonempty absolute declarator */ { $$ = build_nt (ARRAY_REF, NULL_TREE, NULL_TREE); } /* ??? It appears we have to support attributes here, however using prefix_attributes is wrong. */ + | attributes setattrs absdcl1 + { $$ = $3; } ; /* at least one statement, the first of which parses without error. */ @@ -2191,12 +2226,15 @@ label: CASE expr_no_commas ':' error_with_decl (duplicate, "this is the first default label"); } position_after_white_space (); } - | identifier ':' + | identifier ':' maybe_attribute { tree label = define_label (input_filename, lineno, $1); stmt_count++; emit_nop (); if (label) - expand_label (label); + { + expand_label (label); + decl_attributes (label, $3, NULL_TREE); + } position_after_white_space (); } ; diff --git a/contrib/gcc/c-pragma.c b/contrib/gcc/c-pragma.c index 3d01925..5aa8d9f 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 Free Software Foundation, Inc. + Copyright (C) 1992, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -29,147 +29,464 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "toplev.h" -#ifdef HANDLE_SYSV_PRAGMA +#ifdef HANDLE_GENERIC_PRAGMAS +#ifdef HANDLE_PRAGMA_PACK /* When structure field packing is in effect, this variable is the number of bits to use as the maximum alignment. When packing is not in effect, this is zero. */ extern int maximum_field_alignment; +#endif -/* File used for outputting assembler code. */ -extern FILE *asm_out_file; -/* Handle one token of a pragma directive. TOKEN is the - current token, and STRING is its printable form. */ +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP +typedef struct align_stack +{ + int alignment; + unsigned int num_pushes; + tree id; + struct align_stack * prev; +} align_stack; + +static struct align_stack * alignment_stack = NULL; + +static int push_alignment PROTO((int, tree)); +static int pop_alignment PROTO((tree)); + +/* Push an alignment value onto the stack. */ +static int +push_alignment (alignment, id) + int alignment; + tree id; +{ + switch (alignment) + { + case 0: + case 1: + case 2: + case 4: + case 8: + case 16: + break; + default: + warning ("\ +Alignment must be a small power of two, not %d, in #pragma pack", + alignment); + return 0; + } + + if (alignment_stack == NULL + || alignment_stack->alignment != alignment + || id != NULL_TREE) + { + align_stack * entry; + + entry = (align_stack *) xmalloc (sizeof (* entry)); + + if (entry == NULL) + { + warning ("Out of memory pushing #pragma pack"); + return 0; + } + entry->alignment = alignment; + entry->num_pushes = 1; + entry->id = id; + entry->prev = alignment_stack; + + alignment_stack = entry; + + maximum_field_alignment = alignment * 8; + } + else + alignment_stack->num_pushes ++; + + return 1; +} + +/* Undo a push of an alignment onto the stack. */ +static int +pop_alignment (id) + tree id; +{ + align_stack * entry; + + if (alignment_stack == NULL) + { + warning ("\ +#pragma pack (pop) encountered without matching #pragma pack (push, )" + ); + return 0; + } + + /* If we got an identifier, strip away everything above the target + entry so that the next step will restore the state just below it. */ + if (id) + { + for (entry = alignment_stack; entry; entry = entry->prev) + if (entry->id == id) + { + entry->num_pushes = 1; + alignment_stack = entry; + break; + } + if (entry == NULL) + warning ("\ +#pragma pack(pop, %s) encountered without matching #pragma pack(push, %s, )" + , IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id)); + } + + if (-- alignment_stack->num_pushes == 0) + { + entry = alignment_stack->prev; + + if (entry == NULL) + maximum_field_alignment = 0; + else + maximum_field_alignment = entry->alignment * 8; + + free (alignment_stack); + + alignment_stack = entry; + } + + return 1; +} + +/* Generate 'packed' and 'aligned' attributes for decls whilst a + #pragma pack(push... is in effect. */ void +insert_pack_attributes (node, attributes, prefix) + tree node; + tree * attributes; + tree * prefix; +{ + tree a; + int field_alignment; + + /* If we are not packing, then there is nothing to do. */ + if (maximum_field_alignment == 0 + || alignment_stack == NULL) + return; + + /* We are only interested in fields. */ + if (TREE_CODE_CLASS (TREE_CODE (node)) != 'd' + || TREE_CODE (node) != FIELD_DECL) + return; + + field_alignment = TYPE_ALIGN (TREE_TYPE (node)); + if (field_alignment <= 0 || field_alignment > maximum_field_alignment) + field_alignment = maximum_field_alignment; + + /* Add a 'packed' attribute. */ + * attributes = tree_cons (get_identifier ("packed"), NULL, * attributes); + + /* If the alignment is > 8 then add an alignment attribute as well. */ + if (field_alignment > 8) + { + /* If the aligned attribute is already present then do not override it. */ + for (a = * attributes; a; a = TREE_CHAIN (a)) + { + tree name = TREE_PURPOSE (a); + if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0) + break; + } + + if (a == NULL) + for (a = * prefix; a; a = TREE_CHAIN (a)) + { + tree name = TREE_PURPOSE (a); + if (strcmp (IDENTIFIER_POINTER (name), "aligned") == 0) + break; + } + + if (a == NULL) + { + * attributes = tree_cons + (get_identifier ("aligned"), + tree_cons (NULL, + build_int_2 (field_alignment / 8, 0), + NULL), + * attributes); + } + } + + return; +} +#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ + +/* Handle one token of a pragma directive. TOKEN is the current token, and + STRING is its printable form. Some front ends do not support generating + tokens, and will only pass in a STRING. Also some front ends will reuse + the buffer containing STRING, so it must be copied to a local buffer if + it needs to be preserved. + + If STRING is non-NULL, then the return value will be ignored, and there + will be futher calls to handle_pragma_token() in order to handle the rest of + the line containing the #pragma directive. If STRING is NULL, the entire + line has now been presented to handle_pragma_token() and the return value + should be zero if the pragma flawed in some way, or if the pragma was not + recognised, and non-zero if it was successfully handled. */ + +int handle_pragma_token (string, token) - char *string; + const char * string; tree token; { - static enum pragma_state state = ps_start, type; - static char *name; - static char *value; + static enum pragma_state state = ps_start; + static enum pragma_state type; + static char * name; + static char * value; static int align; + static tree id; - if (string == 0) + /* If we have reached the end of the #pragma directive then + determine what value we should return. */ + + if (string == NULL) { - if (type == ps_pack) + int ret_val = 0; + + switch (type) { + default: + abort (); + break; + + case ps_done: + /* The pragma was not recognised. */ + break; + +#ifdef HANDLE_PRAGMA_PACK + case ps_pack: if (state == ps_right) - maximum_field_alignment = align * 8; + { + maximum_field_alignment = align * 8; + ret_val = 1; + } else warning ("malformed `#pragma pack'"); - } - else if (type == ps_weak) - { + break; +#endif /* HANDLE_PRAGMA_PACK */ + +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP + case ps_push: + if (state == ps_right) + ret_val = push_alignment (align, id); + else + warning ("malformed '#pragma pack(push[,id],)'"); + break; + + case ps_pop: + if (state == ps_right) + ret_val = pop_alignment (id); + else + warning ("malformed '#pragma pack(pop[,id])'"); + break; +#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ + #ifdef HANDLE_PRAGMA_WEAK + case ps_weak: if (HANDLE_PRAGMA_WEAK) - handle_pragma_weak (state, name, value); - + { + if (state == ps_name) + ret_val = add_weak (name, NULL); + else if (state == ps_value) + ret_val = add_weak (name, value); + else + warning ("malformed `#pragma weak'"); + } + else + ret_val = 1; /* Ignore the pragma. */ + break; #endif /* HANDLE_PRAGMA_WEAK */ } type = state = ps_start; - return; + id = NULL_TREE; + + return ret_val; } + /* If we have been given a token, but it is not an identifier, + or a small constant, then something has gone wrong. */ + if (token) + { + switch (TREE_CODE (token)) + { + case IDENTIFIER_NODE: + break; + + case INTEGER_CST: + if (TREE_INT_CST_HIGH (token) != 0) + return 0; + break; + + default: + return 0; + } + } + switch (state) { case ps_start: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) + type = state = ps_done; +#ifdef HANDLE_PRAGMA_PACK + if (strcmp (string, "pack") == 0) + type = state = ps_pack; +#endif +#ifdef HANDLE_PRAGMA_WEAK + if (strcmp (string, "weak") == 0) + type = state = ps_weak; +#endif + break; + +#ifdef HANDLE_PRAGMA_WEAK + case ps_weak: + name = permalloc (strlen (string) + 1); + if (name == NULL) { - if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0) - type = state = ps_pack; - else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0) - type = state = ps_weak; - else - { - type = state = ps_done; - - /* 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", string); - } + warning ("Out of memory parsing #pragma weak"); + state = ps_bad; } else - type = state = ps_done; - break; - - case ps_weak: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) { - name = IDENTIFIER_POINTER (token); + strcpy (name, string); state = ps_name; } - else - state = ps_bad; break; - + case ps_name: state = (strcmp (string, "=") ? ps_bad : ps_equals); break; case ps_equals: - if (token && TREE_CODE (token) == IDENTIFIER_NODE) + value = permalloc (strlen (string) + 1); + if (value == NULL) { - value = IDENTIFIER_POINTER (token); - state = ps_value; + warning ("Out of memory parsing #pragma weak"); + state = ps_bad; } else - state = ps_bad; + { + strcpy (value, string); + state = ps_value; + } break; case ps_value: state = ps_bad; break; - +#endif /* HANDLE_PRAGMA_WEAK */ + +#ifdef HANDLE_PRAGMA_PACK case ps_pack: - if (strcmp (string, "(") == 0) - state = ps_left; - else - state = ps_bad; + state = (strcmp (string, "(") ? ps_bad : ps_left); break; case ps_left: - if (token && TREE_CODE (token) == INTEGER_CST - && TREE_INT_CST_HIGH (token) == 0) - switch (TREE_INT_CST_LOW (token)) - { - case 1: - case 2: - case 4: - align = TREE_INT_CST_LOW (token); - state = ps_align; - break; - default: + if (token == NULL_TREE) + { + /* #pragma pack () resets packing rules to their + defaults. */ + if (strcmp (string, ")") == 0) + { + align = 0; + state = ps_right; + } + else state = ps_bad; - } - else if (! token && strcmp (string, ")") == 0) + } + else if (TREE_CODE (token) == INTEGER_CST) + goto handle_align; + +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP + else if (TREE_CODE (token) == IDENTIFIER_NODE) { - align = 0; - state = ps_right; + if (strcmp (string, "push") == 0) + type = state = ps_push; + else if (strcmp (string, "pop") == 0) + type = state = ps_pop; + else + state = ps_bad; } +#endif else state = ps_bad; break; + handle_align: + align = TREE_INT_CST_LOW (token); + switch (align) + { + case 1: + case 2: + case 4: + case 8: + case 16: + state = ps_align; + break; + + default: + state = ps_bad; + break; + } + break; + case ps_align: - if (strcmp (string, ")") == 0) - state = ps_right; - else - state = ps_bad; + state = (strcmp (string, ")") ? ps_bad : ps_right); break; case ps_right: state = ps_bad; break; +#endif /* HANDLE_PRAGMA_PACK */ + +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP + case ps_push: + state = (strcmp (string, ",") ? ps_bad : ps_pushcomma); + break; + + case ps_pushid: + state = (strcmp (string, ",") ? ps_bad : ps_pushcomma2); + break; + + case ps_pushcomma: + if (token && TREE_CODE (token) == IDENTIFIER_NODE) + { + id = token; + state = ps_pushid; + break; + } + + /* else fall through */ + case ps_pushcomma2: + if (token && TREE_CODE (token) == INTEGER_CST) + goto handle_align; + else + state = ps_bad; + break; + case ps_pop: + if (strcmp (string, ",") == 0) + state = ps_popcomma; + else + state = (strcmp (string, ")") ? ps_bad : ps_right); + break; + + case ps_popcomma: + if (token && TREE_CODE (token) == IDENTIFIER_NODE) + { + id = token; + state = ps_align; + } + else + state = ps_bad; + break; +#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ + case ps_bad: case ps_done: break; @@ -177,5 +494,7 @@ handle_pragma_token (string, token) default: abort (); } + + return 1; } -#endif /* HANDLE_SYSV_PRAGMA */ +#endif /* HANDLE_GENERIC_PRAGMAS */ diff --git a/contrib/gcc/c-pragma.h b/contrib/gcc/c-pragma.h index 49c39fa..f94ee9f 100644 --- a/contrib/gcc/c-pragma.h +++ b/contrib/gcc/c-pragma.h @@ -1,5 +1,5 @@ /* Pragma related interfaces. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -18,29 +18,84 @@ 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 _C_PRAGMA_H +#define _C_PRAGMA_H + +#ifdef HANDLE_SYSV_PRAGMA /* Support #pragma weak iff ASM_WEAKEN_LABEL and ASM_OUTPUT_DEF are defined. */ #if defined (ASM_WEAKEN_LABEL) && defined (ASM_OUTPUT_DEF) #define HANDLE_PRAGMA_WEAK SUPPORTS_WEAK #endif +/* We always support #pragma pack for SYSV pragmas. */ +#ifndef HANDLE_PRAGMA_PACK +#define HANDLE_PRAGMA_PACK 1 +#endif +#endif /* HANDLE_SYSV_PRAGMA */ + + +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP +/* If we are supporting #pragma pack(push... then we automatically + support #pragma pack() */ +#define HANDLE_PRAGMA_PACK 1 +#define PRAGMA_INSERT_ATTRIBUTES(node, pattr, prefix_attr) \ + insert_pack_attributes (node, pattr, prefix_attr) +extern void insert_pack_attributes PROTO((tree, tree *, tree *)); +#endif /* HANDLE_PRAGMA_PACK_PUSH_POP */ + + +#ifdef HANDLE_PRAGMA_WEAK +/* This structure contains any weak symbol declarations waiting to be emitted. */ +struct weak_syms +{ + struct weak_syms * next; + char * name; + char * value; +}; + +/* Declared in varasm.c */ +extern struct weak_syms * weak_decls; + +extern int add_weak PROTO((char *, char *)); +#endif /* HANDLE_PRAGMA_WEAK */ + + +#if defined HANDLE_PRAGMA_PACK || defined HANDLE_PRAGMA_WEAK +/* Define HANDLE_GENERIC_PRAGMAS if any kind of front-end pragma + parsing is to be done. The code in GCC's generic C source files + will only look for the definition of this constant. They will + ignore definitions of HANDLE_PRAGMA_PACK and so on. */ +#define HANDLE_GENERIC_PRAGMAS 1 +#endif + + +#ifdef HANDLE_GENERIC_PRAGMAS enum pragma_state { ps_start, ps_done, - ps_bad, +#ifdef HANDLE_PRAGMA_WEAK ps_weak, ps_name, ps_equals, ps_value, +#endif +#ifdef HANDLE_PRAGMA_PACK ps_pack, ps_left, ps_align, - ps_right + ps_right, +#endif +#ifdef HANDLE_PRAGMA_PACK_PUSH_POP + ps_push, ps_pushcomma, ps_pushid, ps_pushcomma2, + ps_pop, ps_popcomma, +#endif + ps_bad }; -/* Output asm to handle ``#pragma weak'' */ -extern void handle_pragma_weak PROTO((enum pragma_state, char *, char *)); - /* Handle a C style pragma */ -extern void handle_pragma_token PROTO((char *, tree)); +extern int handle_pragma_token PROTO((const char *, tree)); + +#endif /* HANDLE_GENERIC_PRAGMAS */ +#endif /* _C_PRAGMA_H */ diff --git a/contrib/gcc/c-tree.h b/contrib/gcc/c-tree.h index 7605cfe..bcf325b 100644 --- a/contrib/gcc/c-tree.h +++ b/contrib/gcc/c-tree.h @@ -1,5 +1,5 @@ /* Definitions for C parsing and type checking. - Copyright (C) 1987, 1993, 1994, 1995, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 93, 94, 95, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -80,6 +80,22 @@ extern int pedantic; nonzero if the definition of the type has already started. */ #define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type) +/* C types are partitioned into three subsets: object, function, and + incomplete types. */ +#define C_TYPE_OBJECT_P(type) \ + (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type)) + +#define C_TYPE_FUNCTION_P(type) \ + (TREE_CODE (type) == FUNCTION_TYPE) + +#define C_TYPE_INCOMPLETE_P(type) \ + (TREE_CODE (type) != FUNCTION_TYPE && TYPE_SIZE (type) == 0) + +/* For convenience we define a single macro to identify the class of + object or incomplete types. */ +#define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \ + (!C_TYPE_FUNCTION_P (type)) + /* In a RECORD_TYPE, a sorted array of the fields of the type. */ struct lang_type { @@ -154,7 +170,7 @@ extern int maybe_objc_comptypes PROTO((tree, tree, int)); extern tree maybe_building_objc_message_expr PROTO((void)); extern tree maybe_objc_method_name PROTO((tree)); extern int recognize_objc_keyword PROTO((void)); -extern tree build_objc_string PROTO((int, char *)); +extern tree build_objc_string PROTO((int, const char *)); /* in c-aux-info.c */ extern void gen_aux_info_record PROTO((tree, int, int, int)); @@ -165,6 +181,7 @@ extern void decl_attributes PROTO((tree, tree, tree)); extern void init_function_format_info PROTO((void)); extern void check_function_format PROTO((tree, tree, tree)); extern int c_get_alias_set PROTO((tree)); +extern void c_apply_type_quals_to_decl PROTO((int, 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 PROTO((enum tree_code)); @@ -213,7 +230,9 @@ extern tree double_ftype_double; extern tree double_ftype_double_double; extern tree double_type_node; extern tree float_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 extern tree intTI_type_node; +#endif extern tree intDI_type_node; extern tree intHI_type_node; extern tree intQI_type_node; @@ -243,7 +262,9 @@ extern tree signed_wchar_type_node; extern tree string_ftype_ptr_ptr; extern tree string_type_node; extern tree unsigned_char_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 extern tree unsigned_intTI_type_node; +#endif extern tree unsigned_intDI_type_node; extern tree unsigned_intHI_type_node; extern tree unsigned_intQI_type_node; @@ -261,9 +282,13 @@ extern tree boolean_false_node; extern tree build_enumerator PROTO((tree, tree)); /* Declare a predefined function. Return the declaration. */ -extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *)); +extern tree builtin_function PROTO((const char *, tree, enum built_in_function function_, const char *)); /* Add qualifiers to a type, in the fashion for C. */ -extern tree c_build_type_variant PROTO((tree, int, int)); +extern tree c_build_qualified_type PROTO((tree, int)); +#define c_build_type_variant(TYPE, CONST_P, VOLATILE_P) \ + c_build_qualified_type (TYPE, \ + ((CONST_P) ? TYPE_QUAL_CONST : 0) | \ + ((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0)) extern int c_decode_option PROTO((int, char **)); extern void c_mark_varargs PROTO((void)); extern tree check_identifier PROTO((tree, tree)); @@ -282,7 +307,7 @@ extern tree get_parm_info PROTO((int)); extern tree getdecls PROTO((void)); extern tree gettags PROTO((void)); extern int global_bindings_p PROTO((void)); -extern tree grokfield PROTO((char *, int, tree, tree, tree)); +extern tree grokfield PROTO((const char *, int, tree, tree, tree)); extern tree groktypename PROTO((tree)); extern tree groktypename_in_parm_context PROTO((tree)); extern tree implicitly_declare PROTO((tree)); @@ -340,7 +365,7 @@ extern tree c_alignof PROTO((tree)); extern tree c_alignof_expr PROTO((tree)); extern tree default_conversion PROTO((tree)); extern tree build_component_ref PROTO((tree, tree)); -extern tree build_indirect_ref PROTO((tree, char *)); +extern tree build_indirect_ref PROTO((tree, const char *)); extern tree build_array_ref PROTO((tree, tree)); extern tree build_function_call PROTO((tree, tree)); extern tree parser_build_binary_op PROTO((enum tree_code, @@ -350,8 +375,8 @@ extern tree build_binary_op PROTO((enum tree_code, extern tree build_unary_op PROTO((enum tree_code, tree, int)); extern int lvalue_p PROTO((tree)); -extern int lvalue_or_else PROTO((tree, char *)); -extern void readonly_warning PROTO((tree, char *)); +extern int lvalue_or_else PROTO((tree, const char *)); +extern void readonly_warning PROTO((tree, const char *)); extern int mark_addressable PROTO((tree)); extern tree build_conditional_expr PROTO((tree, tree, tree)); extern tree build_compound_expr PROTO((tree)); @@ -360,10 +385,8 @@ extern tree build_modify_expr PROTO((tree, enum tree_code, tree)); extern tree initializer_constant_valid_p PROTO((tree, tree)); extern void store_init_value PROTO((tree, tree)); -extern void error_init PROTO((char *, char *, - char *)); -extern void pedwarn_init PROTO((char *, char *, - char *)); +extern void error_init PROTO((const char *)); +extern void pedwarn_init PROTO((const char *)); extern void start_init PROTO((tree, tree, int)); extern void finish_init PROTO((void)); extern void really_start_incremental_init PROTO((tree)); @@ -418,10 +441,6 @@ extern int flag_no_asm; extern int flag_hosted; -/* Nonzero means ignore `#ident' directives. */ - -extern int flag_no_ident; - /* Nonzero means warn about implicit declarations. */ extern int warn_implicit; @@ -430,7 +449,7 @@ extern int warn_implicit; to get extra warnings from them. These warnings will be too numerous to be useful, except in thoroughly ANSIfied programs. */ -extern int warn_write_strings; +extern int flag_const_strings; /* Nonzero means warn about sizeof (function) or addition/subtraction of function pointers. */ @@ -465,6 +484,10 @@ extern int warn_cast_qual; extern int warn_bad_function_cast; +/* Warn about functions which might be candidates for attribute noreturn. */ + +extern int warn_missing_noreturn; + /* Warn about traditional constructs whose meanings changed in ANSI C. */ extern int warn_traditional; @@ -489,6 +512,10 @@ extern int warn_main; extern int flag_traditional; +/* Nonzero means use the ISO C9x dialect of C. */ + +extern int flag_isoc9x; + /* Nonzero means to allow single precision math even if we're generally being traditional. */ extern int flag_allow_single_precision; @@ -509,6 +536,10 @@ extern int warn_sign_compare; extern int warn_multichar; +/* Warn about long long. */ + +extern int warn_long_long; + /* Nonzero means we are reading code that came from a system header file. */ extern int system_header_p; diff --git a/contrib/gcc/c-typeck.c b/contrib/gcc/c-typeck.c index 4ccc1a3..854baf8 100644 --- a/contrib/gcc/c-typeck.c +++ b/contrib/gcc/c-typeck.c @@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "expr.h" #include "toplev.h" +#include "intl.h" /* Nonzero if we've already printed a "missing braces around initializer" message within this initializer. */ @@ -55,18 +56,17 @@ static tree pointer_diff PROTO((tree, tree)); static tree unary_complex_lvalue PROTO((enum tree_code, tree)); static void pedantic_lvalue_warning PROTO((enum tree_code)); static tree internal_build_compound_expr PROTO((tree, int)); -static tree convert_for_assignment PROTO((tree, tree, char *, tree, +static tree convert_for_assignment PROTO((tree, tree, const char *, tree, + tree, int)); +static void warn_for_assignment PROTO((const char *, const char *, tree, int)); -static void warn_for_assignment PROTO((char *, char *, tree, int)); static tree valid_compound_expr_initializer PROTO((tree, tree)); -static void push_string PROTO((char *)); +static void push_string PROTO((const char *)); static void push_member_name PROTO((tree)); static void push_array_bounds PROTO((int)); static int spelling_length PROTO((void)); static char *print_spelling PROTO((char *)); -static char *get_spelling PROTO((char *)); -static void warning_init PROTO((char *, char *, - char *)); +static void warning_init PROTO((const char *)); static tree digest_init PROTO((tree, tree, int, int)); static void check_init_type_bitfields PROTO((tree)); static void output_init_element PROTO((tree, tree, tree, int)); @@ -83,6 +83,9 @@ require_complete_type (value) { tree type = TREE_TYPE (value); + if (TREE_CODE (value) == ERROR_MARK) + return error_mark_node; + /* First, detect a valid value with a complete type. */ if (TYPE_SIZE (type) != 0 && type != void_type_node) @@ -101,7 +104,7 @@ incomplete_type_error (value, type) tree value; tree type; { - char *errmsg; + const char *type_code_string; /* Avoid duplicate error message. */ if (TREE_CODE (type) == ERROR_MARK) @@ -119,15 +122,15 @@ incomplete_type_error (value, type) switch (TREE_CODE (type)) { case RECORD_TYPE: - errmsg = "invalid use of undefined type `struct %s'"; + type_code_string = "struct"; break; case UNION_TYPE: - errmsg = "invalid use of undefined type `union %s'"; + type_code_string = "union"; break; case ENUMERAL_TYPE: - errmsg = "invalid use of undefined type `enum %s'"; + type_code_string = "enum"; break; case VOID_TYPE: @@ -148,7 +151,8 @@ incomplete_type_error (value, type) } if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) - error (errmsg, IDENTIFIER_POINTER (TYPE_NAME (type))); + error ("invalid use of undefined type `%s %s'", + type_code_string, IDENTIFIER_POINTER (TYPE_NAME (type))); else /* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */ error ("invalid use of incomplete typedef `%s'", @@ -163,9 +167,7 @@ static tree qualify_type (type, like) tree type, like; { - int constflag = TYPE_READONLY (type) || TYPE_READONLY (like); - int volflag = TYPE_VOLATILE (type) || TYPE_VOLATILE (like); - return c_build_type_variant (type, constflag, volflag); + return c_build_qualified_type (type, TYPE_QUALS (like)); } /* Return the common type of two types. @@ -283,14 +285,14 @@ common_type (t1, t2) But ANSI C specifies doing this with the qualifiers. So I turned it on again. */ { - tree target = common_type (TYPE_MAIN_VARIANT (TREE_TYPE (t1)), - TYPE_MAIN_VARIANT (TREE_TYPE (t2))); - int constp - = TYPE_READONLY (TREE_TYPE (t1)) || TYPE_READONLY (TREE_TYPE (t2)); - int volatilep - = TYPE_VOLATILE (TREE_TYPE (t1)) || TYPE_VOLATILE (TREE_TYPE (t2)); - t1 = build_pointer_type (c_build_type_variant (target, constp, - volatilep)); + tree pointed_to_1 = TREE_TYPE (t1); + 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) | + TYPE_QUALS (pointed_to_2))); return build_type_attribute_variant (t1, attributes); } #if 0 @@ -447,9 +449,7 @@ comptypes (type1, type2) /* Qualifiers must match. */ - if (TYPE_READONLY (t1) != TYPE_READONLY (t2)) - return 0; - if (TYPE_VOLATILE (t1) != TYPE_VOLATILE (t2)) + if (TYPE_QUALS (t1) != TYPE_QUALS (t2)) return 0; /* Allow for two different type nodes which have essentially the same @@ -1084,11 +1084,12 @@ default_conversion (exp) volatilep = TREE_THIS_VOLATILE (exp); } - if (TYPE_READONLY (type) || TYPE_VOLATILE (type) - || constp || volatilep) - restype = c_build_type_variant (restype, - TYPE_READONLY (type) || constp, - TYPE_VOLATILE (type) || volatilep); + if (TYPE_QUALS (type) || constp || volatilep) + restype + = c_build_qualified_type (restype, + TYPE_QUALS (type) + | (constp * TYPE_QUAL_CONST) + | (volatilep * TYPE_QUAL_VOLATILE)); if (TREE_CODE (exp) == INDIRECT_REF) return convert (TYPE_POINTER_TO (restype), @@ -1324,7 +1325,7 @@ build_component_ref (datum, component) tree build_indirect_ref (ptr, errorstring) tree ptr; - char *errorstring; + const char *errorstring; { register tree pointer = default_conversion (ptr); register tree type = TREE_TYPE (pointer); @@ -2793,7 +2794,6 @@ build_unary_op (code, xarg, noconvert) register tree arg = xarg; register tree argtype = 0; register enum tree_code typecode = TREE_CODE (TREE_TYPE (arg)); - char *errstring = NULL; tree val; if (typecode == ERROR_MARK) @@ -2809,7 +2809,10 @@ build_unary_op (code, xarg, noconvert) associativity, but won't generate any code. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary plus"; + { + error ("wrong type argument to unary plus"); + return error_mark_node; + } else if (!noconvert) arg = default_conversion (arg); break; @@ -2817,7 +2820,10 @@ build_unary_op (code, xarg, noconvert) case NEGATE_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to unary minus"; + { + error ("wrong type argument to unary minus"); + return error_mark_node; + } else if (!noconvert) arg = default_conversion (arg); break; @@ -2830,7 +2836,10 @@ build_unary_op (code, xarg, noconvert) arg = default_conversion (arg); } else if (typecode != INTEGER_TYPE) - errstring = "wrong type argument to bit-complement"; + { + error ("wrong type argument to bit-complement"); + return error_mark_node; + } else if (!noconvert) arg = default_conversion (arg); break; @@ -2838,7 +2847,10 @@ build_unary_op (code, xarg, noconvert) case ABS_EXPR: if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to abs"; + { + error ("wrong type argument to abs"); + return error_mark_node; + } else if (!noconvert) arg = default_conversion (arg); break; @@ -2847,7 +2859,10 @@ build_unary_op (code, xarg, noconvert) /* Conjugating a real value is a no-op, but allow it anyway. */ if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE || typecode == COMPLEX_TYPE)) - errstring = "wrong type argument to conjugation"; + { + error ("wrong type argument to conjugation"); + return error_mark_node; + } else if (!noconvert) arg = default_conversion (arg); break; @@ -2859,8 +2874,8 @@ build_unary_op (code, xarg, noconvert) /* These will convert to a pointer. */ && typecode != ARRAY_TYPE && typecode != FUNCTION_TYPE) { - errstring = "wrong type argument to unary exclamation mark"; - break; + error ("wrong type argument to unary exclamation mark"); + return error_mark_node; } arg = truthvalue_conversion (arg); return invert_truthvalue (arg); @@ -2913,11 +2928,10 @@ build_unary_op (code, xarg, noconvert) if (typecode != POINTER_TYPE && typecode != INTEGER_TYPE && typecode != REAL_TYPE) { - if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - errstring ="wrong type argument to increment"; - else - errstring ="wrong type argument to decrement"; - break; + error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR + ? "wrong type argument to increment" + : "wrong type argument to decrement"); + return error_mark_node; } { @@ -2934,17 +2948,15 @@ build_unary_op (code, xarg, noconvert) /* If pointer target is an undefined struct, we just cannot know how to do the arithmetic. */ if (TYPE_SIZE (TREE_TYPE (result_type)) == 0) - error ("%s of pointer to unknown structure", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); + error (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR + ? "increment of pointer to unknown structure" + : "decrement of pointer to unknown structure"); else if ((pedantic || warn_pointer_arith) && (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE || TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)) - pedwarn ("wrong type argument to %s", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement")); + pedwarn (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR + ? "wrong type argument to increment" + : "wrong type argument to decrement"); inc = c_size_in_bytes (TREE_TYPE (result_type)); } else @@ -3001,7 +3013,8 @@ build_unary_op (code, xarg, noconvert) /* Complain about anything else that is not a true lvalue. */ if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"))) + ? "invalid lvalue in increment" + : "invalid lvalue in decrement"))) return error_mark_node; /* Report a read-only lvalue. */ @@ -3075,13 +3088,16 @@ build_unary_op (code, xarg, noconvert) ; /* Anything not already handled and not a true memory reference is an error. */ - else if (typecode != FUNCTION_TYPE && !lvalue_or_else (arg, "unary `&'")) + else if (typecode != FUNCTION_TYPE + && !lvalue_or_else (arg, "invalid lvalue in unary `&'")) return error_mark_node; /* Ordinary case; arg is a COMPONENT_REF or a decl. */ argtype = TREE_TYPE (arg); - /* If the lvalue is const or volatile, - merge that into the type that the address will point to. */ + /* If the lvalue is const or volatile, merge that into the type + to which the address will point. Note that you can't get a + restricted pointer by taking the address of something, so we + only have to deal with `const' and `volatile' here. */ if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'd' || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r') { @@ -3141,15 +3157,9 @@ build_unary_op (code, xarg, noconvert) break; } - if (!errstring) - { - if (argtype == 0) - argtype = TREE_TYPE (arg); - return fold (build1 (code, argtype, arg)); - } - - error (errstring); - return error_mark_node; + if (argtype == 0) + argtype = TREE_TYPE (arg); + return fold (build1 (code, argtype, arg)); } #if 0 @@ -3223,13 +3233,13 @@ lvalue_p (ref) otherwise, print an error message and return zero. */ int -lvalue_or_else (ref, string) +lvalue_or_else (ref, msgid) tree ref; - char *string; + const char *msgid; { int win = lvalue_p (ref); if (! win) - error ("invalid lvalue in %s", string); + error (msgid); return win; } @@ -3282,47 +3292,38 @@ pedantic_lvalue_warning (code) enum tree_code code; { if (pedantic) - pedwarn ("ANSI C forbids use of %s expressions as lvalues", - code == COND_EXPR ? "conditional" - : code == COMPOUND_EXPR ? "compound" : "cast"); + pedwarn (code == COND_EXPR + ? "ANSI C forbids use of conditional expressions as lvalues" + : code == COMPOUND_EXPR + ? "ANSI C forbids use of compound expressions as lvalues" + : "ANSI C forbids use of cast expressions as lvalues"); } /* Warn about storing in something that is `const'. */ void -readonly_warning (arg, string) +readonly_warning (arg, msgid) tree arg; - char *string; + const char *msgid; { - char buf[80]; - strcpy (buf, string); - /* Forbid assignments to iterators. */ if (TREE_CODE (arg) == VAR_DECL && ITERATOR_P (arg)) - { - strcat (buf, " of iterator `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } + pedwarn ("%s of iterator `%s'", _(msgid), + IDENTIFIER_POINTER (DECL_NAME (arg))); if (TREE_CODE (arg) == COMPONENT_REF) { if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) - readonly_warning (TREE_OPERAND (arg, 0), string); + readonly_warning (TREE_OPERAND (arg, 0), msgid); else - { - strcat (buf, " of read-only member `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); - } + pedwarn ("%s of read-only member `%s'", _(msgid), + IDENTIFIER_POINTER (DECL_NAME (TREE_OPERAND (arg, 1)))); } else if (TREE_CODE (arg) == VAR_DECL) - { - strcat (buf, " of read-only variable `%s'"); - pedwarn (buf, IDENTIFIER_POINTER (DECL_NAME (arg))); - } + pedwarn ("%s of read-only variable `%s'", _(msgid), + IDENTIFIER_POINTER (DECL_NAME (arg))); else - { - pedwarn ("%s of read-only location", buf); - } + pedwarn ("%s of read-only location", _(msgid)); } /* Mark EXP saying that we need to be able to take the @@ -3726,7 +3727,7 @@ build_c_cast (type, expr) if (field) { - char *name; + const char *name; tree t; if (pedantic) @@ -3779,11 +3780,11 @@ build_c_cast (type, expr) in_type = TREE_TYPE (in_type); while (TREE_CODE (in_otype) == POINTER_TYPE) in_otype = TREE_TYPE (in_otype); - - if (TYPE_VOLATILE (in_otype) && ! TYPE_VOLATILE (in_type)) - pedwarn ("cast discards `volatile' from pointer target type"); - if (TYPE_READONLY (in_otype) && ! TYPE_READONLY (in_type)) - pedwarn ("cast discards `const' from pointer target type"); + + if (TYPE_QUALS (in_otype) & ~TYPE_QUALS (in_type)) + /* There are qualifiers present in IN_OTYPE that are not + present in IN_TYPE. */ + pedwarn ("cast discards qualifiers from pointer target type"); } /* Warn about possible alignment problems. */ @@ -3964,7 +3965,7 @@ build_modify_expr (lhs, modifycode, rhs) /* Now we have handled acceptable kinds of LHS that are not truly lvalues. Reject anything strange now. */ - if (!lvalue_or_else (lhs, "assignment")) + if (!lvalue_or_else (lhs, "invalid lvalue in assignment")) return error_mark_node; /* Warn about storing in something that is `const'. */ @@ -3997,7 +3998,7 @@ build_modify_expr (lhs, modifycode, rhs) /* Convert new value to destination type. */ - newrhs = convert_for_assignment (lhstype, newrhs, "assignment", + newrhs = convert_for_assignment (lhstype, newrhs, _("assignment"), NULL_TREE, NULL_TREE, 0); if (TREE_CODE (newrhs) == ERROR_MARK) return error_mark_node; @@ -4012,7 +4013,7 @@ build_modify_expr (lhs, modifycode, rhs) if (olhstype == TREE_TYPE (result)) return result; - return convert_for_assignment (olhstype, result, "assignment", + return convert_for_assignment (olhstype, result, _("assignment"), NULL_TREE, NULL_TREE, 0); } @@ -4023,9 +4024,7 @@ build_modify_expr (lhs, modifycode, rhs) for assignments that are not allowed in C. ERRTYPE is a string to use in error messages: "assignment", "return", etc. If it is null, this is parameter passing - for a function call (and different error messages are output). Otherwise, - it may be a name stored in the spelling stack and interpreted by - get_spelling. + for a function call (and different error messages are output). FUNNAME is the name of the function being called, as an IDENTIFIER_NODE, or null. @@ -4034,7 +4033,7 @@ build_modify_expr (lhs, modifycode, rhs) static tree convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) tree type, rhs; - char *errtype; + const char *errtype; tree fundecl, funname; int parmnum; { @@ -4114,12 +4113,13 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) || comp_target_types (memb_type, rhstype)) { /* If this type won't generate any warnings, use it. */ - if ((TREE_CODE (ttr) == FUNCTION_TYPE - && TREE_CODE (ttl) == FUNCTION_TYPE) - ? ((! TYPE_READONLY (ttl) | TYPE_READONLY (ttr)) - & (! TYPE_VOLATILE (ttl) | TYPE_VOLATILE (ttr))) - : ((TYPE_READONLY (ttl) | ! TYPE_READONLY (ttr)) - & (TYPE_VOLATILE (ttl) | ! TYPE_VOLATILE (ttr)))) + if (TYPE_QUALS (ttl) == TYPE_QUALS (ttr) + || ((TREE_CODE (ttr) == FUNCTION_TYPE + && TREE_CODE (ttl) == FUNCTION_TYPE) + ? ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) + == TYPE_QUALS (ttr)) + : ((TYPE_QUALS (ttl) | TYPE_QUALS (ttr)) + == TYPE_QUALS (ttl)))) break; /* Keep looking for a better type, but remember this one. */ @@ -4157,26 +4157,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) certain things, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, - parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, - parmnum); - } - else - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, - parmnum); - if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, - parmnum); + if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) + warn_for_assignment ("%s makes qualified function pointer from unqualified", + errtype, funname, parmnum); } + else if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) + warn_for_assignment ("%s discards qualifiers from pointer target type", + errtype, funname, + parmnum); } if (pedantic && ! DECL_IN_SYSTEM_HEADER (fundecl)) @@ -4211,18 +4199,15 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) && (!integer_zerop (rhs) || TREE_CODE (rhs) == NOP_EXPR) && TREE_CODE (ttl) == FUNCTION_TYPE))) warn_for_assignment ("ANSI forbids %s between function pointer and `void *'", - get_spelling (errtype), funname, parmnum); + errtype, funname, parmnum); /* Const and volatile mean something different for function types, so the usual warnings are not appropriate. */ else if (TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttl) != FUNCTION_TYPE) { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - warn_for_assignment ("%s discards `const' from pointer target type", - get_spelling (errtype), funname, parmnum); - else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s discards `volatile' from pointer target type", - get_spelling (errtype), funname, parmnum); + if (TYPE_QUALS (ttr) & ~TYPE_QUALS (ttl)) + warn_for_assignment ("%s discards qualifiers from pointer target type", + errtype, funname, parmnum); /* If this is not a case of ignoring a mismatch in signedness, no warning. */ else if (TYPE_MAIN_VARIANT (ttl) == void_type_node @@ -4232,7 +4217,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) /* If there is a mismatch, do warn. */ else if (pedantic) warn_for_assignment ("pointer targets in %s differ in signedness", - get_spelling (errtype), funname, parmnum); + errtype, funname, parmnum); } else if (TREE_CODE (ttl) == FUNCTION_TYPE && TREE_CODE (ttr) == FUNCTION_TYPE) @@ -4241,17 +4226,14 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) that say the function will not do certain things, it is okay to use a const or volatile function where an ordinary one is wanted, but not vice-versa. */ - if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) - warn_for_assignment ("%s makes `const *' function pointer from non-const", - get_spelling (errtype), funname, parmnum); - if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) - warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", - get_spelling (errtype), funname, parmnum); + if (TYPE_QUALS (ttl) & ~TYPE_QUALS (ttr)) + warn_for_assignment ("%s makes qualified function pointer from unqualified", + errtype, funname, parmnum); } } else warn_for_assignment ("%s from incompatible pointer type", - get_spelling (errtype), funname, parmnum); + errtype, funname, parmnum); return convert (type, rhs); } else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) @@ -4267,7 +4249,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) && integer_zerop (TREE_OPERAND (rhs, 0)))) { warn_for_assignment ("%s makes pointer from integer without a cast", - get_spelling (errtype), funname, parmnum); + errtype, funname, parmnum); return convert (type, rhs); } return null_pointer_node; @@ -4275,7 +4257,7 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) else if (codel == INTEGER_TYPE && coder == POINTER_TYPE) { warn_for_assignment ("%s makes integer from pointer without a cast", - get_spelling (errtype), funname, parmnum); + errtype, funname, parmnum); return convert (type, rhs); } @@ -4297,30 +4279,28 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) parmnum); } else - error ("incompatible types in %s", get_spelling (errtype)); + error ("incompatible types in %s", errtype); return error_mark_node; } -/* Print a warning using MSG. +/* Print a warning using MSGID. It gets OPNAME as its one parameter. If OPNAME is null, it is replaced by "passing arg ARGNUM of `FUNCTION'". FUNCTION and ARGNUM are handled specially if we are building an Objective-C selector. */ static void -warn_for_assignment (msg, opname, function, argnum) - char *msg; - char *opname; +warn_for_assignment (msgid, opname, function, argnum) + const char *msgid; + const char *opname; tree function; int argnum; { - static char argstring[] = "passing arg %d of `%s'"; - static char argnofun[] = "passing arg %d"; - if (opname == 0) { tree selector = maybe_building_objc_message_expr (); + char * new_opname; if (selector && argnum > 2) { @@ -4330,18 +4310,23 @@ warn_for_assignment (msg, opname, function, argnum) if (function) { /* Function name is known; supply it. */ - opname = (char *) alloca (IDENTIFIER_LENGTH (function) - + sizeof (argstring) + 25 /*%d*/ + 1); - sprintf (opname, argstring, argnum, IDENTIFIER_POINTER (function)); + const char *argstring = _("passing arg %d of `%s'"); + new_opname = (char *) alloca (IDENTIFIER_LENGTH (function) + + strlen (argstring) + 1 + 25 + /*%d*/ + 1); + sprintf (new_opname, argstring, argnum, + IDENTIFIER_POINTER (function)); } else { - /* Function name unknown (call through ptr); just give arg number. */ - opname = (char *) alloca (sizeof (argnofun) + 25 /*%d*/ + 1); - sprintf (opname, argnofun, argnum); + /* Function name unknown (call through ptr); just give arg number.*/ + const char *argnofun = _("passing arg %d of pointer to function"); + new_opname = (char *) alloca (strlen (argnofun) + 1 + 25 /*%d*/ + 1); + sprintf (new_opname, argnofun, argnum); } + opname = new_opname; } - pedwarn (msg, opname); + pedwarn (msgid, opname); } /* Return nonzero if VALUE is a valid constant-valued expression @@ -4423,13 +4408,18 @@ initializer_constant_valid_p (value, endtype) return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - /* Likewise conversions from int to pointers. */ + /* Likewise conversions from int to pointers, but also allow + conversions from 0. */ if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); + && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) + { + if (integer_zerop (TREE_OPERAND (value, 0))) + return null_pointer_node; + else if (TYPE_PRECISION (TREE_TYPE (value)) + <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) + return initializer_constant_valid_p (TREE_OPERAND (value, 0), + endtype); + } /* Allow conversions to union types if the value inside is okay. */ if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) @@ -4575,7 +4565,7 @@ struct spelling union { int i; - char *s; + const char *s; } u; }; @@ -4631,7 +4621,7 @@ static int spelling_size; /* Size of the spelling stack. */ static void push_string (string) - char *string; + const char *string; { PUSH_SPELLING (SPELLING_STRING, string, u.s); } @@ -4643,7 +4633,7 @@ push_member_name (decl) tree decl; { - char *string + const char *string = DECL_NAME (decl) ? IDENTIFIER_POINTER (DECL_NAME (decl)) : ""; PUSH_SPELLING (SPELLING_MEMBER, string, u.s); } @@ -4683,7 +4673,6 @@ print_spelling (buffer) register char *buffer; { register char *d = buffer; - register char *s; register struct spelling *p; for (p = spelling_base; p < spelling; p++) @@ -4694,6 +4683,7 @@ print_spelling (buffer) } else { + register const char *s; if (p->kind == SPELLING_MEMBER) *d++ = '.'; for (s = p->u.s; (*d = *s++); d++) @@ -4703,115 +4693,52 @@ print_spelling (buffer) return buffer; } -/* Provide a means to pass component names derived from the spelling stack. */ - -char initialization_message; - -/* Interpret the spelling of the given ERRTYPE message. */ - -static char * -get_spelling (errtype) - char *errtype; -{ - static char *buffer; - static int size = -1; - - if (errtype == &initialization_message) - { - /* Avoid counting chars */ - static char message[] = "initialization of `%s'"; - register int needed = sizeof (message) + spelling_length () + 1; - char *temp; - - if (size < 0) - buffer = (char *) xmalloc (size = needed); - if (needed > size) - buffer = (char *) xrealloc (buffer, size = needed); - - temp = (char *) alloca (needed); - sprintf (buffer, message, print_spelling (temp)); - return buffer; - } - - return errtype; -} - /* Issue an error message for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ + MSGID identifies the message. + The component name is taken from the spelling stack. */ void -error_init (format, local, ofwhat) - char *format, *local, *ofwhat; +error_init (msgid) + const char *msgid; { - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); + char *ofwhat; + error (msgid); + ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - error (format, buffer); + error ("(near initialization for `%s')", ofwhat); } /* Issue a pedantic warning for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ + MSGID identifies the message. + The component name is taken from the spelling stack. */ void -pedwarn_init (format, local, ofwhat) - char *format, *local, *ofwhat; +pedwarn_init (msgid) + const char *msgid; { - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); + char *ofwhat; + pedwarn (msgid); + ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - pedwarn (format, buffer); + pedwarn ("(near initialization for `%s')", ofwhat); } /* Issue a warning for a bad initializer component. - FORMAT describes the message. OFWHAT is the name for the component. - LOCAL is a format string for formatting the insertion of the name - into the message. - - If OFWHAT is null, the component name is stored on the spelling stack. - If the component name is a null string, then LOCAL is omitted entirely. */ + MSGID identifies the message. + The component name is taken from the spelling stack. */ static void -warning_init (format, local, ofwhat) - char *format, *local, *ofwhat; +warning_init (msgid) + const char *msgid; { - char *buffer; - - if (ofwhat == 0) - ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); - buffer = (char *) alloca (strlen (local) + strlen (ofwhat) + 2); + char *ofwhat; + warning (msgid); + ofwhat = print_spelling ((char *) alloca (spelling_length () + 1)); if (*ofwhat) - sprintf (buffer, local, ofwhat); - else - buffer[0] = 0; - - warning (format, buffer); + warning ("(near initialization for `%s')", ofwhat); } /* Digest the parser output INIT as an initializer for type TYPE. @@ -4859,16 +4786,14 @@ digest_init (type, init, require_constant, constructor_constant) != char_type_node) && TYPE_PRECISION (typ1) == TYPE_PRECISION (char_type_node)) { - error_init ("char-array%s initialized from wide string", - " `%s'", NULL); + error_init ("char-array initialized from wide string"); return error_mark_node; } if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))) == char_type_node) && TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node)) { - error_init ("int-array%s initialized from non-wide string", - " `%s'", NULL); + error_init ("int-array initialized from non-wide string"); return error_mark_node; } @@ -4885,9 +4810,7 @@ digest_init (type, init, require_constant, constructor_constant) - (TYPE_PRECISION (typ1) != TYPE_PRECISION (char_type_node) ? TYPE_PRECISION (wchar_type_node) / BITS_PER_UNIT : 1)) - pedwarn_init ( - "initializer-string for array of chars%s is too long", - " `%s'", NULL); + pedwarn_init ("initializer-string for array of chars is too long"); } return inside_init; } @@ -4914,8 +4837,7 @@ digest_init (type, init, require_constant, constructor_constant) else if (code == ARRAY_TYPE && TREE_CODE (inside_init) != STRING_CST && TREE_CODE (inside_init) != CONSTRUCTOR) { - error_init ("array%s initialized from non-constant array expression", - " `%s'", NULL); + error_init ("array initialized from non-constant array expression"); return error_mark_node; } @@ -4932,25 +4854,21 @@ digest_init (type, init, require_constant, constructor_constant) = valid_compound_expr_initializer (inside_init, TREE_TYPE (inside_init)); if (inside_init == error_mark_node) - error_init ("initializer element%s is not constant", - " for `%s'", NULL); + error_init ("initializer element is not constant"); else - pedwarn_init ("initializer element%s is not constant", - " for `%s'", NULL); + pedwarn_init ("initializer element is not constant"); if (flag_pedantic_errors) inside_init = error_mark_node; } else if (require_constant && ! TREE_CONSTANT (inside_init)) { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); + error_init ("initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); + error_init ("initializer element is not computable at load time"); inside_init = error_mark_node; } @@ -4966,20 +4884,18 @@ digest_init (type, init, require_constant, constructor_constant) for arrays and functions. We must not call it in the case where inside_init is a null pointer constant. */ inside_init - = convert_for_assignment (type, init, "initialization", + = convert_for_assignment (type, init, _("initialization"), NULL_TREE, NULL_TREE, 0); if (require_constant && ! TREE_CONSTANT (inside_init)) { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); + error_init ("initializer element is not constant"); inside_init = error_mark_node; } else if (require_constant && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0) { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); + error_init ("initializer element is not computable at load time"); inside_init = error_mark_node; } @@ -4990,8 +4906,7 @@ digest_init (type, init, require_constant, constructor_constant) if (TYPE_SIZE (type) && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { - error_init ("variable-sized object%s may not be initialized", - " `%s'", NULL); + error_init ("variable-sized object may not be initialized"); return error_mark_node; } @@ -5017,7 +4932,7 @@ digest_init (type, init, require_constant, constructor_constant) type = TREE_TYPE (TYPE_FIELDS (type)); else { - error_init ("invalid initializer%s", " for `%s'", NULL); + error_init ("invalid initializer"); return error_mark_node; } } @@ -5033,7 +4948,7 @@ digest_init (type, init, require_constant, constructor_constant) else return error_mark_node; } - error_init ("invalid initializer%s", " for `%s'", NULL); + error_init ("invalid initializer"); return error_mark_node; } @@ -5196,7 +5111,7 @@ start_init (decl, asmspec_tree, top_level) tree asmspec_tree; int top_level; { - char *locus; + const char *locus; struct initializer_stack *p = (struct initializer_stack *) xmalloc (sizeof (struct initializer_stack)); char *asmspec = 0; @@ -5510,8 +5425,7 @@ push_init_level (implicit) if (constructor_type == 0) { - error_init ("extra brace group at end of initializer%s", - " for `%s'", NULL); + error_init ("extra brace group at end of initializer"); constructor_fields = 0; constructor_unfilled_fields = 0; return; @@ -5523,7 +5437,7 @@ push_init_level (implicit) if (implicit && warn_missing_braces && !missing_braces_mentioned) { missing_braces_mentioned = 1; - warning_init ("missing braces around initializer%s", " for `%s'", NULL); + warning_init ("missing braces around initializer"); } if (TREE_CODE (constructor_type) == RECORD_TYPE @@ -5554,7 +5468,7 @@ push_init_level (implicit) } else { - warning_init ("braces around scalar initializer%s", " for `%s'", NULL); + warning_init ("braces around scalar initializer"); constructor_fields = constructor_type; constructor_unfilled_fields = constructor_type; } @@ -5574,9 +5488,7 @@ check_init_type_bitfields (type) for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) { - if (DECL_C_BIT_FIELD (tail) - /* This catches cases like `int foo : 8;'. */ - || DECL_MODE (tail) != TYPE_MODE (TREE_TYPE (tail))) + if (DECL_C_BIT_FIELD (tail)) { constructor_incremental = 0; break; @@ -5586,6 +5498,17 @@ check_init_type_bitfields (type) } } + else if (TREE_CODE (type) == UNION_TYPE) + { + tree tail = TYPE_FIELDS (type); + if (tail && DECL_C_BIT_FIELD (tail)) + /* We also use the nonincremental algorithm for initiliazation + of unions whose first member is a bitfield, becuase the + incremental algorithm has no code for dealing with + bitfields. */ + constructor_incremental = 0; + } + else if (TREE_CODE (type) == ARRAY_TYPE) check_init_type_bitfields (TREE_TYPE (type)); } @@ -5626,7 +5549,7 @@ pop_init_level (implicit) && constructor_unfilled_fields) { push_member_name (constructor_unfilled_fields); - warning_init ("missing initializer%s", " for `%s'", NULL); + warning_init ("missing initializer"); RESTORE_SPELLING_DEPTH (constructor_depth); } @@ -5639,7 +5562,7 @@ pop_init_level (implicit) && (TREE_CODE (constructor_type) == ARRAY_TYPE ? integer_zerop (constructor_unfilled_index) : constructor_unfilled_fields == TYPE_FIELDS (constructor_type))) - pedwarn_init ("empty braces in initializer%s", " for `%s'", NULL); + pedwarn_init ("empty braces in initializer"); #endif /* Pad out the end of the structure. */ @@ -5703,14 +5626,12 @@ pop_init_level (implicit) the element, after verifying there is just one. */ if (constructor_elements == 0) { - error_init ("empty scalar initializer%s", - " for `%s'", NULL); + error_init ("empty scalar initializer"); constructor = error_mark_node; } else if (TREE_CHAIN (constructor_elements) != 0) { - error_init ("extra elements in scalar initializer%s", - " for `%s'", NULL); + error_init ("extra elements in scalar initializer"); constructor = TREE_VALUE (constructor_elements); } else @@ -5844,20 +5765,20 @@ set_init_index (first, last) (last) = TREE_OPERAND (last, 0); if (TREE_CODE (first) != INTEGER_CST) - error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); + error_init ("nonconstant array index in initializer"); else if (last != 0 && TREE_CODE (last) != INTEGER_CST) - error_init ("nonconstant array index in initializer%s", " for `%s'", NULL); + error_init ("nonconstant array index in initializer"); else if (! constructor_unfilled_index) - error_init ("array index in non-array initializer%s", " for `%s'", NULL); + error_init ("array index in non-array initializer"); else if (tree_int_cst_lt (first, constructor_unfilled_index)) - error_init ("duplicate array index in initializer%s", " for `%s'", NULL); + error_init ("duplicate array index in initializer"); else { TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (first); TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (first); if (last != 0 && tree_int_cst_lt (last, first)) - error_init ("empty index range in initializer%s", " for `%s'", NULL); + error_init ("empty index range in initializer"); else { if (pedantic) @@ -6188,15 +6109,13 @@ output_init_element (value, type, field, pending) if (require_constant_value && ! TREE_CONSTANT (value)) { - error_init ("initializer element%s is not constant", - " for `%s'", NULL); + error_init ("initializer element is not constant"); value = error_mark_node; } else if (require_constant_elements && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0) { - error_init ("initializer element%s is not computable at load time", - " for `%s'", NULL); + error_init ("initializer element is not computable at load time"); value = error_mark_node; } @@ -6212,7 +6131,7 @@ output_init_element (value, type, field, pending) { if (pending_init_member (field)) { - error_init ("duplicate initializer%s", " for `%s'", NULL); + error_init ("duplicate initializer"); duplicate = 1; } } @@ -6565,8 +6484,7 @@ process_init_element (value) if (constructor_stack->replacement_value != 0) { - error_init ("excess elements in struct initializer%s", - " after `%s'", NULL_PTR); + error_init ("excess elements in struct initializer"); return; } @@ -6601,8 +6519,7 @@ process_init_element (value) if (constructor_fields == 0) { - pedwarn_init ("excess elements in struct initializer%s", - " after `%s'", NULL_PTR); + pedwarn_init ("excess elements in struct initializer"); break; } @@ -6666,8 +6583,7 @@ process_init_element (value) if (constructor_fields == 0) { - pedwarn_init ("excess elements in union initializer%s", - " after `%s'", NULL_PTR); + pedwarn_init ("excess elements in union initializer"); break; } @@ -6741,8 +6657,7 @@ process_init_element (value) if (constructor_max_index != 0 && tree_int_cst_lt (constructor_max_index, constructor_index)) { - pedwarn_init ("excess elements in array initializer%s", - " after `%s'", NULL_PTR); + pedwarn_init ("excess elements in array initializer"); break; } @@ -6753,8 +6668,7 @@ process_init_element (value) && tree_int_cst_lt (constructor_max_index, constructor_range_end)) { - pedwarn_init ("excess elements in array initializer%s", - " after `%s'", NULL_PTR); + pedwarn_init ("excess elements in array initializer"); TREE_INT_CST_HIGH (constructor_range_end) = TREE_INT_CST_HIGH (constructor_max_index); TREE_INT_CST_LOW (constructor_range_end) @@ -6805,8 +6719,7 @@ process_init_element (value) for a scalar variable. */ if (constructor_fields == 0) { - pedwarn_init ("excess elements in scalar initializer%s", - " after `%s'", NULL_PTR); + pedwarn_init ("excess elements in scalar initializer"); break; } @@ -6923,7 +6836,7 @@ c_expand_return (retval) } else { - tree t = convert_for_assignment (valtype, retval, "return", + tree t = convert_for_assignment (valtype, retval, _("return"), NULL_TREE, NULL_TREE, 0); tree res = DECL_RESULT (current_function_decl); tree inner; diff --git a/contrib/gcc/caller-save.c b/contrib/gcc/caller-save.c index 4a2deb6..7c390a5 100644 --- a/contrib/gcc/caller-save.c +++ b/contrib/gcc/caller-save.c @@ -1,5 +1,5 @@ /* Save and restore call-clobbered registers which are live across a call. - Copyright (C) 1989, 1992, 94-95, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 1992, 94-95, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -39,6 +39,8 @@ Boston, MA 02111-1307, USA. */ #define MIN_UNITS_PER_WORD UNITS_PER_WORD #endif +#define MOVE_MAX_WORDS (MOVE_MAX / UNITS_PER_WORD) + /* Modes for each hard register that we can save. The smallest mode is wide enough to save the entire contents of the register. When saving the register because it is live we first try to save in multi-register modes. @@ -64,27 +66,31 @@ static enum insn_code static enum insn_code reg_restore_code[FIRST_PSEUDO_REGISTER][MAX_MOVE_MAX / MIN_UNITS_PER_WORD + 1]; -/* Set of hard regs currently live (during scan of all insns). */ - -static HARD_REG_SET hard_regs_live; - /* Set of hard regs currently residing in save area (during insn scan). */ static HARD_REG_SET hard_regs_saved; -/* Set of hard regs which need to be restored before referenced. */ +/* Number of registers currently in hard_regs_saved. */ -static HARD_REG_SET hard_regs_need_restore; +static int n_regs_saved; -/* Number of registers currently in hard_regs_saved. */ +/* Computed by mark_referenced_regs, all regs referenced in a given + insn. */ +static HARD_REG_SET referenced_regs; -int n_regs_saved; +/* Computed in mark_set_regs, holds all registers set by the current + instruction. */ +static HARD_REG_SET this_insn_sets; -static void set_reg_live PROTO((rtx, rtx)); -static void clear_reg_live PROTO((rtx)); -static void restore_referenced_regs PROTO((rtx, rtx, enum machine_mode)); -static int insert_save_restore PROTO((rtx, int, int, - enum machine_mode, int)); + +static void mark_set_regs PROTO((rtx, rtx)); +static void mark_referenced_regs PROTO((rtx)); +static int insert_save PROTO((struct insn_chain *, int, int, + HARD_REG_SET *)); +static int insert_restore PROTO((struct insn_chain *, int, int, + int)); +static void insert_one_insn PROTO((struct insn_chain *, int, + enum insn_code, rtx)); /* Initialize for caller-save. @@ -113,9 +119,9 @@ init_caller_save () { if (call_used_regs[i] && ! call_fixed_regs[i]) { - for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++) + for (j = 1; j <= MOVE_MAX_WORDS; j++) { - regno_save_mode[i][j] = choose_hard_reg_mode (i, j); + regno_save_mode[i][j] = HARD_REGNO_CALLER_SAVE_MODE (i, j); if (regno_save_mode[i][j] == VOIDmode && j == 1) { call_fixed_regs[i] = 1; @@ -170,7 +176,7 @@ init_caller_save () start_sequence (); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++) + for (j = 1; j <= MOVE_MAX_WORDS; j++) if (regno_save_mode[i][j] != VOIDmode) { rtx mem = gen_rtx_MEM (regno_save_mode[i][j], address); @@ -186,13 +192,14 @@ init_caller_save () /* Now extract both insns and see if we can meet their constraints. */ - ok = (reg_save_code[i][j] != -1 && reg_restore_code[i][j] != -1); + ok = (reg_save_code[i][j] != (enum insn_code)-1 + && reg_restore_code[i][j] != (enum insn_code)-1); if (ok) { - insn_extract (saveinsn); - ok = constrain_operands (reg_save_code[i][j], 1); - insn_extract (restinsn); - ok &= constrain_operands (reg_restore_code[i][j], 1); + extract_insn (saveinsn); + ok = constrain_operands (1); + extract_insn (restinsn); + ok &= constrain_operands (1); } if (! ok) @@ -219,7 +226,7 @@ init_save_areas () int i, j; for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++) + for (j = 1; j <= MOVE_MAX_WORDS; j++) regno_save_mem[i][j] = 0; } @@ -229,13 +236,6 @@ init_save_areas () overestimate slightly (especially if some of these registers are later used as spill registers), but it should not be significant. - Then perform register elimination in the addresses of the save area - locations; return 1 if all eliminated addresses are strictly valid. - We assume that our caller has set up the elimination table to the - worst (largest) possible offsets. - - Set *PCHANGED to 1 if we had to allocate some memory for the save area. - Future work: In the fallback case we should iterate backwards across all possible @@ -248,14 +248,11 @@ init_save_areas () machine independent since they might be saving non-consecutive registers. (imagine caller-saving d0,d1,a0,a1 on the 68k) */ -int -setup_save_areas (pchanged) - int *pchanged; +void +setup_save_areas () { int i, j, k; HARD_REG_SET hard_regs_used; - int ok = 1; - /* Allocate space in the save area for the largest multi-register pseudos first, then work backwards to single register @@ -283,10 +280,9 @@ setup_save_areas (pchanged) in a manner which allows multi-register saves/restores to be done. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - for (j = MOVE_MAX / UNITS_PER_WORD; j > 0; j--) + for (j = MOVE_MAX_WORDS; j > 0; j--) { - int ok = 1; - int do_save; + int do_save = 1; /* If no mode exists for this size, try another. Also break out if we have already saved this hard register. */ @@ -294,7 +290,6 @@ setup_save_areas (pchanged) continue; /* See if any register in this group has been saved. */ - do_save = 1; for (k = 0; k < j; k++) if (regno_save_mem[i + k][1]) { @@ -305,207 +300,171 @@ setup_save_areas (pchanged) continue; for (k = 0; k < j; k++) + if (! TEST_HARD_REG_BIT (hard_regs_used, i + k)) { - int regno = i + k; - ok &= (TEST_HARD_REG_BIT (hard_regs_used, regno) != 0); + do_save = 0; + break; } + if (! do_save) + continue; /* We have found an acceptable mode to store in. */ - if (ok) + regno_save_mem[i][j] + = assign_stack_local (regno_save_mode[i][j], + GET_MODE_SIZE (regno_save_mode[i][j]), 0); + + /* Setup single word save area just in case... */ + for (k = 0; k < j; k++) { + /* This should not depend on WORDS_BIG_ENDIAN. + The order of words in regs is the same as in memory. */ + rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1], + XEXP (regno_save_mem[i][j], 0)); - regno_save_mem[i][j] - = assign_stack_local (regno_save_mode[i][j], - GET_MODE_SIZE (regno_save_mode[i][j]), 0); - - /* Setup single word save area just in case... */ - for (k = 0; k < j; k++) - { - /* This should not depend on WORDS_BIG_ENDIAN. - The order of words in regs is the same as in memory. */ - rtx temp = gen_rtx_MEM (regno_save_mode[i+k][1], - XEXP (regno_save_mem[i][j], 0)); - - regno_save_mem[i+k][1] - = adj_offsettable_operand (temp, k * UNITS_PER_WORD); - } - *pchanged = 1; + regno_save_mem[i+k][1] + = adj_offsettable_operand (temp, k * UNITS_PER_WORD); } } - - for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) - for (j = 1; j <= MOVE_MAX / UNITS_PER_WORD; j++) - if (regno_save_mem[i][j] != 0) - ok &= strict_memory_address_p (GET_MODE (regno_save_mem[i][j]), - XEXP (eliminate_regs (regno_save_mem[i][j], 0, NULL_RTX), 0)); - - return ok; } -/* Find the places where hard regs are live across calls and save them. - - INSN_MODE is the mode to assign to any insns that we add. This is used - by reload to determine whether or not reloads or register eliminations - need be done on these insns. */ - +/* Find the places where hard regs are live across calls and save them. */ void -save_call_clobbered_regs (insn_mode) - enum machine_mode insn_mode; +save_call_clobbered_regs () { - rtx insn; - int b; + struct insn_chain *chain, *next; + + CLEAR_HARD_REG_SET (hard_regs_saved); + n_regs_saved = 0; - for (b = 0; b < n_basic_blocks; b++) + for (chain = reload_insn_chain; chain != 0; chain = next) { - regset regs_live = basic_block_live_at_start[b]; - rtx prev_block_last = PREV_INSN (basic_block_head[b]); - int i, j; - int regno; - - /* Compute hard regs live at start of block -- this is the - real hard regs marked live, plus live pseudo regs that - have been renumbered to hard regs. No registers have yet been - saved because we restore all of them before the end of the basic - block. */ - - REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live); - CLEAR_HARD_REG_SET (hard_regs_saved); - CLEAR_HARD_REG_SET (hard_regs_need_restore); - n_regs_saved = 0; - - EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i, - { - if ((regno = reg_renumber[i]) >= 0) - for (j = regno; - j < regno + HARD_REGNO_NREGS (regno, - PSEUDO_REGNO_MODE (i)); - j++) - SET_HARD_REG_BIT (hard_regs_live, j); - }); - - /* Now scan the insns in the block, keeping track of what hard - regs are live as we go. When we see a call, save the live - call-clobbered hard regs. */ - - for (insn = basic_block_head[b]; ; insn = NEXT_INSN (insn)) + rtx insn = chain->insn; + enum rtx_code code = GET_CODE (insn); + + next = chain->next; + + if (chain->is_caller_save_insn) + abort (); + + if (GET_RTX_CLASS (code) == 'i') { - RTX_CODE code = GET_CODE (insn); + /* If some registers have been saved, see if INSN references + any of them. We must restore them before the insn if so. */ - if (GET_RTX_CLASS (code) == 'i') + if (n_regs_saved) { - rtx link; - - /* If some registers have been saved, see if INSN references - any of them. We must restore them before the insn if so. */ - - if (n_regs_saved) - restore_referenced_regs (PATTERN (insn), insn, insn_mode); - - /* NB: the normal procedure is to first enliven any - registers set by insn, then deaden any registers that - had their last use at insn. This is incorrect now, - since multiple pseudos may have been mapped to the - same hard reg, and the death notes are ambiguous. So - it must be done in the other, safe, order. */ - - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) == REG_DEAD) - clear_reg_live (XEXP (link, 0)); - - /* When we reach a call, we need to save all registers that are - live, call-used, not fixed, and not already saved. We must - test at this point because registers that die in a CALL_INSN - are not live across the call and likewise for registers that - are born in the CALL_INSN. - - If registers are filled with parameters for this function, - and some of these are also being set by this function, then - they will not appear to die (no REG_DEAD note for them), - to check if in fact they do, collect the set registers in - hard_regs_live first. */ - - if (code == CALL_INSN) - { - HARD_REG_SET this_call_sets; - { - HARD_REG_SET old_hard_regs_live; - - /* Save the hard_regs_live information. */ - COPY_HARD_REG_SET (old_hard_regs_live, hard_regs_live); - - /* Now calculate hard_regs_live for this CALL_INSN - only. */ - CLEAR_HARD_REG_SET (hard_regs_live); - note_stores (PATTERN (insn), set_reg_live); - COPY_HARD_REG_SET (this_call_sets, hard_regs_live); - - /* Restore the hard_regs_live information. */ - COPY_HARD_REG_SET (hard_regs_live, old_hard_regs_live); - } - - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (call_used_regs[regno] && ! call_fixed_regs[regno] - && TEST_HARD_REG_BIT (hard_regs_live, regno) - /* It must not be set by this instruction. */ - && ! TEST_HARD_REG_BIT (this_call_sets, regno) - && ! TEST_HARD_REG_BIT (hard_regs_saved, regno)) - regno += insert_save_restore (insn, 1, regno, - insn_mode, 0); - - /* Put the information for this CALL_INSN on top of what - we already had. */ - IOR_HARD_REG_SET (hard_regs_live, this_call_sets); - COPY_HARD_REG_SET (hard_regs_need_restore, hard_regs_saved); - - /* Must recompute n_regs_saved. */ - n_regs_saved = 0; - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) - n_regs_saved++; - } + int regno; + + if (code == JUMP_INSN) + /* Restore all registers if this is a JUMP_INSN. */ + COPY_HARD_REG_SET (referenced_regs, hard_regs_saved); else { - note_stores (PATTERN (insn), set_reg_live); -#ifdef AUTO_INC_DEC - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) == REG_INC) - set_reg_live (XEXP (link, 0), NULL_RTX); -#endif + CLEAR_HARD_REG_SET (referenced_regs); + mark_referenced_regs (PATTERN (insn)); + AND_HARD_REG_SET (referenced_regs, hard_regs_saved); } - for (link = REG_NOTES (insn); link; link = XEXP (link, 1)) - if (REG_NOTE_KIND (link) == REG_UNUSED) - clear_reg_live (XEXP (link, 0)); + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (referenced_regs, regno)) + regno += insert_restore (chain, 1, regno, MOVE_MAX_WORDS); } - if (insn == basic_block_end[b]) - break; - } - - /* At the end of the basic block, we must restore any registers that - remain saved. If the last insn in the block is a JUMP_INSN, put - the restore before the insn, otherwise, put it after the insn. */ + if (code == CALL_INSN) + { + rtx x; + int regno, nregs; + HARD_REG_SET hard_regs_to_save; + + /* Use the register life information in CHAIN to compute which + regs are live before the call. */ + REG_SET_TO_HARD_REG_SET (hard_regs_to_save, chain->live_before); + compute_use_by_pseudos (&hard_regs_to_save, chain->live_before); + + /* Record all registers set in this call insn. These don't need + to be saved. */ + CLEAR_HARD_REG_SET (this_insn_sets); + note_stores (PATTERN (insn), mark_set_regs); + + /* Compute which hard regs must be saved before this call. */ + AND_COMPL_HARD_REG_SET (hard_regs_to_save, call_fixed_reg_set); + AND_COMPL_HARD_REG_SET (hard_regs_to_save, this_insn_sets); + AND_COMPL_HARD_REG_SET (hard_regs_to_save, hard_regs_saved); + AND_HARD_REG_SET (hard_regs_to_save, call_used_reg_set); + + /* Registers used for function parameters need not be saved. */ + for (x = CALL_INSN_FUNCTION_USAGE (insn); x != 0; + x = XEXP (x, 1)) + { + rtx y; + + if (GET_CODE (XEXP (x, 0)) != USE) + continue; + y = XEXP (XEXP (x, 0), 0); + if (GET_CODE (y) != REG) + abort (); + regno = REGNO (y); + if (REGNO (y) >= FIRST_PSEUDO_REGISTER) + abort (); + nregs = HARD_REGNO_NREGS (regno, GET_MODE (y)); + while (nregs-- > 0) + CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs); + } - if (n_regs_saved) - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (TEST_HARD_REG_BIT (hard_regs_need_restore, regno)) - regno += insert_save_restore ((GET_CODE (insn) == JUMP_INSN - ? insn : NEXT_INSN (insn)), 0, - regno, insn_mode, MOVE_MAX / UNITS_PER_WORD); + /* Neither do registers for which we find a death note. */ + for (x = REG_NOTES (insn); x != 0; x = XEXP (x, 1)) + { + rtx y = XEXP (x, 0); + + if (REG_NOTE_KIND (x) != REG_DEAD) + continue; + if (GET_CODE (y) != REG) + abort (); + regno = REGNO (y); + + if (regno >= FIRST_PSEUDO_REGISTER) + regno = reg_renumber[regno]; + if (regno < 0) + continue; + nregs = HARD_REGNO_NREGS (regno, GET_MODE (y)); + while (nregs-- > 0) + CLEAR_HARD_REG_BIT (hard_regs_to_save, regno + nregs); + } + + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (hard_regs_to_save, regno)) + regno += insert_save (chain, 1, regno, &hard_regs_to_save); + + /* Must recompute n_regs_saved. */ + n_regs_saved = 0; + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) + n_regs_saved++; + } + } - /* If we added any insns at the start of the block, update the start - of the block to point at those insns. */ - basic_block_head[b] = NEXT_INSN (prev_block_last); - } + if (chain->next == 0 || chain->next->block > chain->block) + { + int regno; + /* At the end of the basic block, we must restore any registers that + remain saved. If the last insn in the block is a JUMP_INSN, put + the restore before the insn, otherwise, put it after the insn. */ + + if (n_regs_saved) + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (TEST_HARD_REG_BIT (hard_regs_saved, regno)) + regno += insert_restore (chain, GET_CODE (insn) == JUMP_INSN, + regno, MOVE_MAX_WORDS); + } + } } /* Here from note_stores when an insn stores a value in a register. - Set the proper bit or bits in hard_regs_live. All pseudos that have + Set the proper bit or bits in this_insn_sets. All pseudos that have been assigned hard regs have had their register number changed already, so we can ignore pseudos. */ - static void -set_reg_live (reg, setter) +mark_set_regs (reg, setter) rtx reg; rtx setter ATTRIBUTE_UNUSED; { @@ -526,105 +485,71 @@ set_reg_live (reg, setter) endregno = regno + HARD_REGNO_NREGS (regno, mode); for (i = regno; i < endregno; i++) - { - SET_HARD_REG_BIT (hard_regs_live, i); - CLEAR_HARD_REG_BIT (hard_regs_saved, i); - CLEAR_HARD_REG_BIT (hard_regs_need_restore, i); - } + SET_HARD_REG_BIT (this_insn_sets, i); } -/* Here when a REG_DEAD note records the last use of a reg. Clear - the appropriate bit or bits in hard_regs_live. Again we can ignore - pseudos. */ - -static void -clear_reg_live (reg) - rtx reg; -{ - register int regno, endregno, i; - - if (GET_CODE (reg) != REG || REGNO (reg) >= FIRST_PSEUDO_REGISTER) - return; - - regno = REGNO (reg); - endregno= regno + HARD_REGNO_NREGS (regno, GET_MODE (reg)); - - for (i = regno; i < endregno; i++) - { - CLEAR_HARD_REG_BIT (hard_regs_live, i); - CLEAR_HARD_REG_BIT (hard_regs_need_restore, i); - CLEAR_HARD_REG_BIT (hard_regs_saved, i); - } -} - -/* If any register currently residing in the save area is referenced in X, - which is part of INSN, emit code to restore the register in front of INSN. - INSN_MODE is the mode to assign to any insns that we add. */ - +/* Walk X and record all referenced registers in REFERENCED_REGS. */ static void -restore_referenced_regs (x, insn, insn_mode) +mark_referenced_regs (x) rtx x; - rtx insn; - enum machine_mode insn_mode; { enum rtx_code code = GET_CODE (x); char *fmt; int i, j; - if (code == CLOBBER) - return; + if (code == SET) + mark_referenced_regs (SET_SRC (x)); + if (code == SET || code == CLOBBER) + { + x = SET_DEST (x); + code = GET_CODE (x); + if (code == REG || code == PC || code == CC0 + || (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG)) + return; + } + if (code == MEM || code == SUBREG) + { + x = XEXP (x, 0); + code = GET_CODE (x); + } if (code == REG) { int regno = REGNO (x); + int hardregno = (regno < FIRST_PSEUDO_REGISTER ? regno + : reg_renumber[regno]); - /* If this is a pseudo, scan its memory location, since it might - involve the use of another register, which might be saved. */ - - if (regno >= FIRST_PSEUDO_REGISTER - && reg_equiv_mem[regno] != 0) - restore_referenced_regs (XEXP (reg_equiv_mem[regno], 0), - insn, insn_mode); - else if (regno >= FIRST_PSEUDO_REGISTER - && reg_equiv_address[regno] != 0) - restore_referenced_regs (reg_equiv_address[regno], - insn, insn_mode); - - /* Otherwise if this is a hard register, restore any piece of it that - is currently saved. */ - - else if (regno < FIRST_PSEUDO_REGISTER) + if (hardregno >= 0) { - int numregs = HARD_REGNO_NREGS (regno, GET_MODE (x)); - /* Save at most SAVEREGS at a time. This can not be larger than - MOVE_MAX, because that causes insert_save_restore to fail. */ - int saveregs = MIN (numregs, MOVE_MAX / UNITS_PER_WORD); - int endregno = regno + numregs; - - for (i = regno; i < endregno; i++) - if (TEST_HARD_REG_BIT (hard_regs_need_restore, i)) - i += insert_save_restore (insn, 0, i, insn_mode, saveregs); + int nregs = HARD_REGNO_NREGS (hardregno, GET_MODE (x)); + while (nregs-- > 0) + SET_HARD_REG_BIT (referenced_regs, hardregno + nregs); } - + /* If this is a pseudo that did not get a hard register, scan its + memory location, since it might involve the use of another + register, which might be saved. */ + else if (reg_equiv_mem[regno] != 0) + mark_referenced_regs (XEXP (reg_equiv_mem[regno], 0)); + else if (reg_equiv_address[regno] != 0) + mark_referenced_regs (reg_equiv_address[regno]); return; } - + fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - restore_referenced_regs (XEXP (x, i), insn, insn_mode); + mark_referenced_regs (XEXP (x, i)); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) - restore_referenced_regs (XVECEXP (x, i, j), insn, insn_mode); + mark_referenced_regs (XVECEXP (x, i, j)); } } -/* Insert a sequence of insns to save or restore, SAVE_P says which, - REGNO. Place these insns in front of INSN. INSN_MODE is the mode - to assign to these insns. MAXRESTORE is the maximum number of registers - which should be restored during this call (when SAVE_P == 0). It should - never be less than 1 since we only work with entire registers. +/* Insert a sequence of insns to restore. Place these insns in front of + CHAIN if BEFORE_P is nonzero, behind the insn otherwise. MAXRESTORE is + the maximum number of registers which should be restored during this call. + It should never be less than 1 since we only work with entire registers. Note that we have verified in init_caller_save that we can do this with a simple SET, so use it. Set INSN_CODE to what we save there @@ -635,13 +560,13 @@ restore_referenced_regs (x, insn, insn_mode) Return the extra number of registers saved. */ static int -insert_save_restore (insn, save_p, regno, insn_mode, maxrestore) - rtx insn; - int save_p; +insert_restore (chain, before_p, regno, maxrestore) + struct insn_chain *chain; + int before_p; int regno; - enum machine_mode insn_mode; int maxrestore; { + int i; rtx pat = NULL_RTX; enum insn_code code = CODE_FOR_nothing; int numregs = 0; @@ -656,108 +581,177 @@ insert_save_restore (insn, save_p, regno, insn_mode, maxrestore) if (regno_save_mem[regno][1] == 0) abort (); -#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 - insn that references CC0 is for a restore, and doing a restore earlier - isn't a problem. We do, however, assume here that CALL_INSNs don't - reference CC0. Guard against non-INSN's like CODE_LABEL. */ - - if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) - && reg_referenced_p (cc0_rtx, PATTERN (insn))) - insn = prev_nonnote_insn (insn); -#endif + /* Get the pattern to emit and update our status. - /* Get the pattern to emit and update our status. */ - if (save_p) + See if we can restore `maxrestore' registers at once. Work + backwards to the single register case. */ + for (i = maxrestore; i > 0; i--) { - int i, j, k; - int ok; + int j, k; + int ok = 1; - /* See if we can save several registers with a single instruction. - Work backwards to the single register case. */ - for (i = MOVE_MAX / UNITS_PER_WORD; i > 0; i--) - { - ok = 1; - if (regno_save_mem[regno][i] != 0) - for (j = 0; j < i; j++) - { - if (! call_used_regs[regno + j] || call_fixed_regs[regno + j] - || ! TEST_HARD_REG_BIT (hard_regs_live, regno + j) - || TEST_HARD_REG_BIT (hard_regs_saved, regno + j)) - ok = 0; - } - else - continue; - - /* Must do this one save at a time */ - if (! ok) - continue; + if (regno_save_mem[regno][i] == 0) + continue; - pat = gen_rtx_SET (VOIDmode, regno_save_mem[regno][i], - gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]), - regno)); - code = reg_save_code[regno][i]; + for (j = 0; j < i; j++) + if (! TEST_HARD_REG_BIT (hard_regs_saved, regno + j)) + { + ok = 0; + break; + } + /* Must do this one restore at a time */ + if (! ok) + continue; - /* Set hard_regs_saved for all the registers we saved. */ - for (k = 0; k < i; k++) - { - SET_HARD_REG_BIT (hard_regs_saved, regno + k); - SET_HARD_REG_BIT (hard_regs_need_restore, regno + k); - n_regs_saved++; - } + pat = gen_rtx_SET (VOIDmode, + gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]), + regno), + regno_save_mem[regno][i]); + code = reg_restore_code[regno][i]; - numregs = i; - break; - } + /* Clear status for all registers we restored. */ + for (k = 0; k < i; k++) + { + CLEAR_HARD_REG_BIT (hard_regs_saved, regno + k); + n_regs_saved--; + } + + numregs = i; + break; } - else + + insert_one_insn (chain, before_p, code, pat); + + /* 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) + struct insn_chain *chain; + int before_p; + int regno; + HARD_REG_SET *to_save; +{ + int i; + rtx pat = NULL_RTX; + enum insn_code code = CODE_FOR_nothing; + int numregs = 0; + + /* A common failure mode if register status is not correct in the RTL + is for this routine to be called with a REGNO we didn't expect to + save. That will cause us to write an insn with a (nil) SET_DEST + or SET_SRC. Instead of doing so and causing a crash later, check + for this common case and abort here instead. This will remove one + step in debugging such problems. */ + + if (regno_save_mem[regno][1] == 0) + abort (); + + /* Get the pattern to emit and update our status. + + 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--) { - int i, j, k; - int ok; + int j, k; + int ok = 1; + if (regno_save_mem[regno][i] == 0) + continue; - /* See if we can restore `maxrestore' registers at once. Work - backwards to the single register case. */ - for (i = maxrestore; i > 0; i--) - { - ok = 1; - if (regno_save_mem[regno][i]) - for (j = 0; j < i; j++) - { - if (! TEST_HARD_REG_BIT (hard_regs_need_restore, regno + j)) - ok = 0; - } - else - continue; - - /* Must do this one restore at a time */ - if (! ok) - continue; - - pat = gen_rtx_SET (VOIDmode, - gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]), - regno), - regno_save_mem[regno][i]); - code = reg_restore_code[regno][i]; + for (j = 0; j < i; j++) + if (! TEST_HARD_REG_BIT (*to_save, regno + j)) + { + ok = 0; + break; + } + /* Must do this one save at a time */ + if (! ok) + continue; + pat = gen_rtx_SET (VOIDmode, regno_save_mem[regno][i], + gen_rtx_REG (GET_MODE (regno_save_mem[regno][i]), + regno)); + code = reg_save_code[regno][i]; - /* Clear status for all registers we restored. */ - for (k = 0; k < i; k++) - { - CLEAR_HARD_REG_BIT (hard_regs_need_restore, regno + k); - n_regs_saved--; - } + /* Set hard_regs_saved for all the registers we saved. */ + for (k = 0; k < i; k++) + { + SET_HARD_REG_BIT (hard_regs_saved, regno + k); + n_regs_saved++; + } - numregs = i; - break; - } + numregs = i; + break; } - /* Emit the insn and set the code and mode. */ - insn = emit_insn_before (pat, insn); - PUT_MODE (insn, insn_mode); - INSN_CODE (insn) = code; + insert_one_insn (chain, before_p, code, pat); /* Tell our callers how many extra registers we saved/restored */ return numregs - 1; } + +/* Emit a new caller-save insn and set the code. */ +static void +insert_one_insn (chain, before_p, code, pat) + struct insn_chain *chain; + int before_p; + enum insn_code 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 + insn that references CC0 is for a restore, and doing a restore earlier + isn't a problem. We do, however, assume here that CALL_INSNs don't + reference CC0. Guard against non-INSN's like CODE_LABEL. */ + + if ((GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN) + && before_p + && reg_referenced_p (cc0_rtx, PATTERN (insn))) + chain = chain->prev, insn = chain->insn; +#endif + + new = new_insn_chain (); + if (before_p) + { + new->prev = chain->prev; + if (new->prev != 0) + new->prev->next = new; + else + reload_insn_chain = new; + + chain->prev = new; + new->next = chain; + new->insn = emit_insn_before (pat, insn); + /* ??? It would be nice if we could exclude the already / still saved + registers from the live sets. */ + COPY_REG_SET (new->live_before, chain->live_before); + COPY_REG_SET (new->live_after, chain->live_before); + if (chain->insn == BLOCK_HEAD (chain->block)) + BLOCK_HEAD (chain->block) = new->insn; + } + else + { + new->next = chain->next; + if (new->next != 0) + new->next->prev = new; + chain->next = new; + new->prev = chain; + new->insn = emit_insn_after (pat, insn); + /* ??? It would be nice if we could exclude the already / still saved + registers from the live sets, and observe REG_UNUSED notes. */ + COPY_REG_SET (new->live_before, chain->live_after); + COPY_REG_SET (new->live_after, chain->live_after); + if (chain->insn == BLOCK_END (chain->block)) + BLOCK_END (chain->block) = new->insn; + } + new->block = chain->block; + new->is_caller_save_insn = 1; + + INSN_CODE (new->insn) = code; +} diff --git a/contrib/gcc/calls.c b/contrib/gcc/calls.c index 8b14019..d0153a3 100644 --- a/contrib/gcc/calls.c +++ b/contrib/gcc/calls.c @@ -1,5 +1,5 @@ /* Convert function calls to rtl insns, for GNU C compiler. - Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 92-97, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -19,11 +19,6 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" -#ifdef __STDC__ -#include -#else -#include -#endif #include "system.h" #include "rtl.h" #include "tree.h" @@ -34,6 +29,10 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "output.h" +#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY +#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY +#endif + /* Decide whether a function's arguments should be processed from first to last or from last to first. @@ -48,8 +47,8 @@ Boston, MA 02111-1307, USA. */ #endif -/* Like STACK_BOUNDARY but in units of bytes, not bits. */ -#define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT) +/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */ +#define STACK_BYTES (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT) /* Data structure and subroutines used within expand_call. */ @@ -125,13 +124,44 @@ static int highest_outgoing_arg_in_use; int stack_arg_under_construction; #endif -static int calls_function PROTO((tree, int)); -static int calls_function_1 PROTO((tree, int)); -static void emit_call_1 PROTO((rtx, tree, tree, HOST_WIDE_INT, - HOST_WIDE_INT, rtx, rtx, - int, rtx, int)); +static int calls_function PROTO ((tree, int)); +static int calls_function_1 PROTO ((tree, int)); +static void emit_call_1 PROTO ((rtx, tree, tree, HOST_WIDE_INT, + HOST_WIDE_INT, HOST_WIDE_INT, rtx, + rtx, int, rtx, int)); +static void special_function_p PROTO ((char *, tree, int *, int *, + int *, int *)); +static void precompute_register_parameters PROTO ((int, struct arg_data *, + int *)); static void store_one_arg PROTO ((struct arg_data *, rtx, int, int, - tree, int)); + int)); +static void store_unaligned_arguments_into_pseudos PROTO ((struct arg_data *, + int)); +static int finalize_must_preallocate PROTO ((int, int, + struct arg_data *, + struct args_size *)); +static void precompute_arguments PROTO ((int, int, int, + struct arg_data *, + struct args_size *)); +static int compute_argument_block_size PROTO ((int, + struct args_size *)); +static void initialize_argument_information PROTO ((int, + struct arg_data *, + struct args_size *, + int, tree, tree, + CUMULATIVE_ARGS *, + int, rtx *, int *, + int *, int *)); +static void compute_argument_addresses PROTO ((struct arg_data *, + rtx, int)); +static rtx rtx_for_function_call PROTO ((tree, tree)); +static void load_register_parameters PROTO ((struct arg_data *, + int, rtx *)); + +#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE) +static rtx save_fixed_argument_area PROTO ((int, rtx, int *, int *)); +static void restore_fixed_argument_area PROTO ((rtx, rtx, int, int)); +#endif /* If WHICH is 1, return 1 if EXP contains a call to the built-in function `alloca'. @@ -316,7 +346,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen) says that the pointer to this aggregate is to be popped by the callee. STACK_SIZE is the number of bytes of arguments on the stack, - rounded up to STACK_BOUNDARY; zero if the size is variable. + rounded up to PREFERRED_STACK_BOUNDARY; zero if the size is variable. This is both to put into the call insn and to generate explicit popping code if necessary. @@ -344,13 +374,14 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen) IS_CONST is true if this is a `const' call. */ static void -emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, - next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage, - is_const) +emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size, + struct_value_size, next_arg_reg, valreg, old_inhibit_defer_pop, + call_fusage, is_const) rtx funexp; - tree fndecl; - tree funtype; + tree fndecl ATTRIBUTE_UNUSED; + tree funtype ATTRIBUTE_UNUSED; HOST_WIDE_INT stack_size; + HOST_WIDE_INT rounded_stack_size; HOST_WIDE_INT struct_value_size; rtx next_arg_reg; rtx valreg; @@ -358,11 +389,12 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, rtx call_fusage; int is_const; { - rtx stack_size_rtx = GEN_INT (stack_size); + rtx rounded_stack_size_rtx = GEN_INT (rounded_stack_size); rtx struct_value_size_rtx = GEN_INT (struct_value_size); rtx call_insn; #ifndef ACCUMULATE_OUTGOING_ARGS int already_popped = 0; + HOST_WIDE_INT n_popped = RETURN_POPS_ARGS (fndecl, funtype, stack_size); #endif /* Ensure address is valid. SYMBOL_REF is already valid, so no need, @@ -373,11 +405,9 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, #ifndef ACCUMULATE_OUTGOING_ARGS #if defined (HAVE_call_pop) && defined (HAVE_call_value_pop) - if (HAVE_call_pop && HAVE_call_value_pop - && (RETURN_POPS_ARGS (fndecl, funtype, stack_size) > 0 - || stack_size == 0)) + if (HAVE_call_pop && HAVE_call_value_pop && n_popped > 0) { - rtx n_pop = GEN_INT (RETURN_POPS_ARGS (fndecl, funtype, stack_size)); + rtx n_pop = GEN_INT (n_popped); rtx pat; /* If this subroutine pops its own args, record that in the call insn @@ -386,10 +416,10 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, if (valreg) pat = gen_call_value_pop (valreg, gen_rtx_MEM (FUNCTION_MODE, funexp), - stack_size_rtx, next_arg_reg, n_pop); + rounded_stack_size_rtx, next_arg_reg, n_pop); else pat = gen_call_pop (gen_rtx_MEM (FUNCTION_MODE, funexp), - stack_size_rtx, next_arg_reg, n_pop); + rounded_stack_size_rtx, next_arg_reg, n_pop); emit_call_insn (pat); already_popped = 1; @@ -404,11 +434,11 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, if (valreg) emit_call_insn (gen_call_value (valreg, gen_rtx_MEM (FUNCTION_MODE, funexp), - stack_size_rtx, next_arg_reg, + rounded_stack_size_rtx, next_arg_reg, NULL_RTX)); else emit_call_insn (gen_call (gen_rtx_MEM (FUNCTION_MODE, funexp), - stack_size_rtx, next_arg_reg, + rounded_stack_size_rtx, next_arg_reg, struct_value_size_rtx)); } else @@ -455,590 +485,444 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, struct_value_size, If returning from the subroutine does pop the args, indicate that the stack pointer will be changed. */ - if (stack_size != 0 && RETURN_POPS_ARGS (fndecl, funtype, stack_size) > 0) + if (n_popped > 0) { if (!already_popped) CALL_INSN_FUNCTION_USAGE (call_insn) = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_CLOBBER (VOIDmode, stack_pointer_rtx), CALL_INSN_FUNCTION_USAGE (call_insn)); - stack_size -= RETURN_POPS_ARGS (fndecl, funtype, stack_size); - stack_size_rtx = GEN_INT (stack_size); + rounded_stack_size -= n_popped; + rounded_stack_size_rtx = GEN_INT (rounded_stack_size); } - if (stack_size != 0) + if (rounded_stack_size != 0) { if (flag_defer_pop && inhibit_defer_pop == 0 && !is_const) - pending_stack_adjust += stack_size; + pending_stack_adjust += rounded_stack_size; else - adjust_stack (stack_size_rtx); + adjust_stack (rounded_stack_size_rtx); } #endif } -/* 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. - If the value is stored in TARGET then TARGET is returned. - 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; -{ - /* List of actual parameters. */ - tree actparms = TREE_OPERAND (exp, 1); - /* RTX for the function to be called. */ - rtx funexp; - /* Data type of the function. */ - tree funtype; - /* Declaration of the function being called, - or 0 if the function is computed (not known by name). */ - tree fndecl = 0; - char *name = 0; +/* Determine if the function identified by NAME and FNDECL is one with + special properties we wish to know about. - /* Register in which non-BLKmode value will be returned, - or 0 if no value or if value is BLKmode. */ - rtx valreg; - /* Address where we should return a BLKmode value; - 0 if value not BLKmode. */ - rtx structure_value_addr = 0; - /* Nonzero if that address is being passed by treating it as - an extra, implicit first parameter. Otherwise, - it is passed by being copied directly into struct_value_rtx. */ - int structure_value_addr_parm = 0; - /* Size of aggregate value wanted, or zero if none wanted - or if we are using the non-reentrant PCC calling convention - or expecting the value in registers. */ - HOST_WIDE_INT struct_value_size = 0; - /* 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; + For example, if the function might return more than one time (setjmp), then + set RETURNS_TWICE to a nonzero value. - /* Number of actual parameters in this call, including struct value addr. */ - int num_actuals; - /* Number of named args. Args after this are anonymous ones - and they must all go on the stack. */ - int n_named_args; - /* Count arg position in order args appear. */ - int argpos; + Similarly set IS_LONGJMP for if the function is in the longjmp family. - /* Vector of information about each argument. - Arguments are numbered in the order they will be pushed, - not the order they are written. */ - struct arg_data *args; + Set IS_MALLOC for any of the standard memory allocation functions which + allocate from the heap. - /* Total size in bytes of all the stack-parms scanned so far. */ - struct args_size args_size; - /* Size of arguments before any adjustments (such as rounding). */ - struct args_size original_args_size; - /* Data on reg parms scanned so far. */ - CUMULATIVE_ARGS args_so_far; - /* Nonzero if a reg parm has been scanned. */ - int reg_parm_seen; - /* Nonzero if this is an indirect function call. */ + Set MAY_BE_ALLOCA for any memory allocation function that might allocate + space from the stack such as alloca. */ - /* Nonzero if we must avoid push-insns in the args for this call. - If stack space is allocated for register parameters, but not by the - caller, then it is preallocated in the fixed part of the stack frame. - So the entire argument block must then be preallocated (i.e., we - ignore PUSH_ROUNDING in that case). */ +static void +special_function_p (name, fndecl, returns_twice, is_longjmp, + is_malloc, may_be_alloca) + char *name; + tree fndecl; + int *returns_twice; + int *is_longjmp; + int *is_malloc; + int *may_be_alloca; +{ + *returns_twice = 0; + *is_longjmp = 0; + *is_malloc = 0; + *may_be_alloca = 0; -#ifdef PUSH_ROUNDING - int must_preallocate = 0; -#else - int must_preallocate = 1; -#endif + if (name != 0 && 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)) + { + char *tname = name; - /* Size of the stack reserved for parameter registers. */ - int reg_parm_stack_space = 0; + /* We assume that alloca will always be called by name. It + makes no sense to pass it as a pointer-to-function to + anything that does not understand its behavior. */ + *may_be_alloca + = (((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6 + && name[0] == 'a' + && ! strcmp (name, "alloca")) + || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16 + && name[0] == '_' + && ! strcmp (name, "__builtin_alloca")))); - /* 1 if scanning parms front to back, -1 if scanning back to front. */ - int inc; - /* Address of space preallocated for stack parms - (on machines that lack push insns), or 0 if space not preallocated. */ - rtx argblock = 0; + /* Disregard prefix _, __ or __x. */ + if (name[0] == '_') + { + if (name[1] == '_' && name[2] == 'x') + tname += 3; + else if (name[1] == '_') + tname += 2; + else + tname += 1; + } - /* Nonzero if it is plausible that this is a call to alloca. */ - int may_be_alloca; - /* Nonzero if this is a call to malloc or a related function. */ - int is_malloc; - /* Nonzero if this is a call to setjmp or a related function. */ - int returns_twice; - /* Nonzero if this is a call to `longjmp'. */ - int is_longjmp; - /* Nonzero if this is a call to an inline function. */ - int is_integrable = 0; - /* Nonzero if this is a call to a `const' function. - Note that only explicitly named functions are handled as `const' here. */ - int is_const = 0; - /* Nonzero if this is a call to a `volatile' function. */ - int is_volatile = 0; -#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(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; - rtx save_area = 0; /* Place that it is saved */ -#endif + if (tname[0] == 's') + { + *returns_twice + = ((tname[1] == 'e' + && (! strcmp (tname, "setjmp") + || ! strcmp (tname, "setjmp_syscall"))) + || (tname[1] == 'i' + && ! strcmp (tname, "sigsetjmp")) + || (tname[1] == 'a' + && ! strcmp (tname, "savectx"))); + if (tname[1] == 'i' + && ! strcmp (tname, "siglongjmp")) + *is_longjmp = 1; + } + else if ((tname[0] == 'q' && tname[1] == 's' + && ! strcmp (tname, "qsetjmp")) + || (tname[0] == 'v' && tname[1] == 'f' + && ! strcmp (tname, "vfork"))) + *returns_twice = 1; -#ifdef ACCUMULATE_OUTGOING_ARGS - int initial_highest_arg_in_use = highest_outgoing_arg_in_use; - char *initial_stack_usage_map = stack_usage_map; - int old_stack_arg_under_construction; -#endif + else if (tname[0] == 'l' && tname[1] == 'o' + && ! strcmp (tname, "longjmp")) + *is_longjmp = 1; + /* XXX should have "malloc" attribute on functions instead + of recognizing them by name. */ + else if (! strcmp (tname, "malloc") + || ! strcmp (tname, "calloc") + || ! strcmp (tname, "realloc") + /* Note use of NAME rather than TNAME here. These functions + are only reserved when preceded with __. */ + || ! strcmp (name, "__vn") /* mangled __builtin_vec_new */ + || ! strcmp (name, "__nw") /* mangled __builtin_new */ + || ! strcmp (name, "__builtin_new") + || ! strcmp (name, "__builtin_vec_new")) + *is_malloc = 1; + } +} - rtx old_stack_level = 0; - int old_pending_adj = 0; - int old_inhibit_defer_pop = inhibit_defer_pop; - rtx call_fusage = 0; - register tree p; - register int i, j; +/* Precompute all register parameters as described by ARGS, storing values + into fields within the ARGS array. - /* The value of the function call can be put in a hard register. But - if -fcheck-memory-usage, code which invokes functions (and thus - damages some hard registers) can be inserted before using the value. - So, target is always a pseudo-register in that case. */ - if (flag_check_memory_usage) - target = 0; + NUM_ACTUALS indicates the total number elements in the ARGS array. - /* See if we can find a DECL-node for the actual function. - As a result, decide whether this is a call to an integrable function. */ + Set REG_PARM_SEEN if we encounter a register parameter. */ - p = TREE_OPERAND (exp, 0); - if (TREE_CODE (p) == ADDR_EXPR) - { - fndecl = TREE_OPERAND (p, 0); - if (TREE_CODE (fndecl) != FUNCTION_DECL) - fndecl = 0; - else - { - if (!flag_no_inline - && fndecl != current_function_decl - && DECL_INLINE (fndecl) - && DECL_SAVED_INSNS (fndecl) - && RTX_INTEGRATED_P (DECL_SAVED_INSNS (fndecl))) - is_integrable = 1; - else if (! TREE_ADDRESSABLE (fndecl)) - { - /* In case this function later becomes inlinable, - record that there was already a non-inline call to it. +static void +precompute_register_parameters (num_actuals, args, reg_parm_seen) + int num_actuals; + struct arg_data *args; + int *reg_parm_seen; +{ + int i; - Use abstraction instead of setting TREE_ADDRESSABLE - directly. */ - if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline - && optimize > 0) - { - warning_with_decl (fndecl, "can't inline call to `%s'"); - warning ("called from here"); - } - mark_addressable (fndecl); - } + *reg_parm_seen = 0; - if (TREE_READONLY (fndecl) && ! TREE_THIS_VOLATILE (fndecl) - && TYPE_MODE (TREE_TYPE (exp)) != VOIDmode) - is_const = 1; + for (i = 0; i < num_actuals; i++) + if (args[i].reg != 0 && ! args[i].pass_on_stack) + { + *reg_parm_seen = 1; - if (TREE_THIS_VOLATILE (fndecl)) - is_volatile = 1; - } - } + if (args[i].value == 0) + { + push_temp_slots (); + args[i].value = expand_expr (args[i].tree_value, NULL_RTX, + VOIDmode, 0); + preserve_temp_slots (args[i].value); + pop_temp_slots (); - /* If we don't have specific function to call, see if we have a - constant or `noreturn' function from the type. */ - if (fndecl == 0) - { - is_const = TREE_READONLY (TREE_TYPE (TREE_TYPE (p))); - is_volatile = TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (p))); - } + /* ANSI doesn't require a sequence point here, + but PCC has one, so this will avoid some problems. */ + emit_queue (); + } -#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 + /* If we are to promote the function arg to a wider mode, + do it now. */ -#if defined(PUSH_ROUNDING) && ! defined(OUTGOING_REG_PARM_STACK_SPACE) - if (reg_parm_stack_space > 0) - must_preallocate = 1; -#endif + if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value))) + args[i].value + = convert_modes (args[i].mode, + TYPE_MODE (TREE_TYPE (args[i].tree_value)), + args[i].value, args[i].unsignedp); - /* 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 value is expensive, and we are inside an appropriately + short loop, put the value into a pseudo and then put the pseudo + into the hard reg. - /* Set up a place to return a structure. */ + For small register classes, also do this if this call uses + register parameters. This is to avoid reload conflicts while + loading the parameters registers. */ - /* Cater to broken compilers. */ - if (aggregate_value_p (exp)) - { - /* This call returns a big structure. */ - is_const = 0; - -#ifdef PCC_STATIC_STRUCT_RETURN - { - pcc_struct_value = 1; - /* Easier than making that case work right. */ - if (is_integrable) - { - /* In case this is a static function, note that it has been - used. */ - if (! TREE_ADDRESSABLE (fndecl)) - mark_addressable (fndecl); - is_integrable = 0; - } + if ((! (GET_CODE (args[i].value) == REG + || (GET_CODE (args[i].value) == SUBREG + && GET_CODE (SUBREG_REG (args[i].value)) == REG))) + && args[i].mode != BLKmode + && rtx_cost (args[i].value, SET) > 2 + && ((SMALL_REGISTER_CLASSES && *reg_parm_seen) + || preserve_subexpressions_p ())) + args[i].value = copy_to_mode_reg (args[i].mode, args[i].value); } -#else /* not PCC_STATIC_STRUCT_RETURN */ - { - struct_value_size = int_size_in_bytes (TREE_TYPE (exp)); +} - if (target && GET_CODE (target) == MEM) - structure_value_addr = XEXP (target, 0); - else - { - /* Assign a temporary to hold the value. */ - tree d; +#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE) - /* For variable-sized objects, we must be called with a target - specified. If we were to allocate space on the stack here, - we would have no way of knowing when to free it. */ + /* 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. */ +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; +{ + int i; + rtx save_area = NULL_RTX; - if (struct_value_size < 0) - abort (); + /* Compute the boundary of the that needs to be saved, if any. */ +#ifdef ARGS_GROW_DOWNWARD + for (i = 0; i < reg_parm_stack_space + 1; i++) +#else + for (i = 0; i < reg_parm_stack_space; i++) +#endif + { + if (i >= highest_outgoing_arg_in_use + || stack_usage_map[i] == 0) + continue; - /* This DECL is just something to feed to mark_addressable; - it doesn't get pushed. */ - d = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); - DECL_RTL (d) = assign_temp (TREE_TYPE (exp), 1, 0, 1); - mark_addressable (d); - structure_value_addr = XEXP (DECL_RTL (d), 0); - TREE_USED (d) = 1; - target = 0; - } - } -#endif /* not PCC_STATIC_STRUCT_RETURN */ - } + if (*low_to_save == -1) + *low_to_save = i; - /* If called function is inline, try to integrate it. */ + *high_to_save = i; + } - if (is_integrable) + if (*low_to_save >= 0) { - rtx temp; -#ifdef ACCUMULATE_OUTGOING_ARGS - rtx before_call = get_last_insn (); -#endif + 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; - temp = expand_inline_function (fndecl, actparms, target, - ignore, TREE_TYPE (exp), - structure_value_addr); + /* 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 inlining succeeded, return. */ - if (temp != (rtx) (HOST_WIDE_INT) -1) +#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) { -#ifdef ACCUMULATE_OUTGOING_ARGS - /* If the outgoing argument list must be preserved, push - the stack before executing the inlined function if it - makes any calls. */ + save_area = assign_stack_temp (BLKmode, num_to_save, 0); + emit_block_move (validize_mem (save_area), stack_area, + GEN_INT (num_to_save), + PARM_BOUNDARY / BITS_PER_UNIT); + } + else + { + save_area = gen_reg_rtx (save_mode); + emit_move_insn (save_area, stack_area); + } + } + return save_area; +} - for (i = reg_parm_stack_space - 1; i >= 0; i--) - if (i < highest_outgoing_arg_in_use && stack_usage_map[i] != 0) - break; +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; +{ + 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 - if (stack_arg_under_construction || i >= 0) - { - rtx first_insn - = before_call ? NEXT_INSN (before_call) : get_insns (); - rtx insn, seq; + if (save_mode != BLKmode) + emit_move_insn (stack_area, save_area); + else + emit_block_move (stack_area, validize_mem (save_area), + GEN_INT (high_to_save - low_to_save + 1), + PARM_BOUNDARY / BITS_PER_UNIT); +} +#endif + +/* If any elements in ARGS refer to parameters that are to be passed in + registers, but not in memory, and whose alignment does not permit a + direct copy into registers. Copy the values into a group of pseudos + which we will later copy into the appropriate hard registers. - /* Look for a call in the inline function code. - If OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) is - nonzero then there is a call and it is not necessary - to scan the insns. */ + Pseudos for each unaligned argument will be stored into the array + args[argnum].aligned_regs. The caller is responsible for deallocating + the aligned_regs array if it is nonzero. */ - if (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) == 0) - for (insn = first_insn; insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == CALL_INSN) - break; +static void +store_unaligned_arguments_into_pseudos (args, num_actuals) + struct arg_data *args; + int num_actuals; +{ + int i, j; + + for (i = 0; i < num_actuals; i++) + if (args[i].reg != 0 && ! args[i].pass_on_stack + && args[i].mode == BLKmode + && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value)) + < (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; - if (insn) - { - /* Reserve enough stack space so that the largest - argument list of any function call in the inline - function does not overlap the argument list being - evaluated. This is usually an overestimate because - allocate_dynamic_stack_space reserves space for an - outgoing argument list in addition to the requested - space, but there is no way to ask for stack space such - that an argument list of a certain length can be - safely constructed. + args[i].n_aligned_regs + = args[i].partial ? args[i].partial + : (bytes + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD; - Add the stack space reserved for register arguments, if - any, in the inline function. What is really needed is the - largest value of reg_parm_stack_space in the inline - function, but that is not available. Using the current - value of reg_parm_stack_space is wrong, but gives - correct results on all supported machines. */ + args[i].aligned_regs = (rtx *) xmalloc (sizeof (rtx) + * args[i].n_aligned_regs); - int adjust = (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) - + reg_parm_stack_space); + /* Structures smaller than 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 * BITS_PER_UNIT)); - start_sequence (); - emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); - allocate_dynamic_stack_space (GEN_INT (adjust), - NULL_RTX, BITS_PER_UNIT); - seq = get_insns (); - end_sequence (); - emit_insns_before (seq, first_insn); - emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); - } - } -#endif + for (j = 0; j < args[i].n_aligned_regs; j++) + { + rtx reg = gen_reg_rtx (word_mode); + rtx word = operand_subword_force (args[i].value, j, BLKmode); + int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD); + int bitalign = TYPE_ALIGN (TREE_TYPE (args[i].tree_value)); + + args[i].aligned_regs[j] = reg; + + /* There is no need to restrict this code to loading items + in TYPE_ALIGN sized hunks. The bitfield instructions can + load up entire word sized registers efficiently. + + ??? This may not be needed anymore. + We use to emit a clobber here but that doesn't let later + passes optimize the instructions we emit. By storing 0 into + the register later passes know the first AND to zero out the + bitfield being set in the register is unnecessary. The store + of 0 will be deleted as will at least the first AND. */ + + 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, + bitalign / BITS_PER_UNIT, + BITS_PER_WORD), + bitalign / BITS_PER_UNIT, BITS_PER_WORD); + } + } +} - /* If the result is equivalent to TARGET, return TARGET to simplify - checks in store_expr. They can be equivalent but not equal in the - case of a function that returns BLKmode. */ - if (temp != target && rtx_equal_p (temp, target)) - return target; - return temp; - } +/* Fill in ARGS_SIZE and ARGS array based on the parameters found in + ACTPARMS. - /* If inlining failed, mark FNDECL as needing to be compiled - separately after all. If function was declared inline, - give a warning. */ - 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 ("called from here"); - } - mark_addressable (fndecl); - } + NUM_ACTUALS is the total number of parameters. - /* When calling a const function, we must pop the stack args right away, - so that the pop is deleted or moved with the call. */ - if (is_const) - NO_DEFER_POP; + N_NAMED_ARGS is the total number of named arguments. - function_call_count++; + FNDECL is the tree code for the target of this call (if known) - if (fndecl && DECL_NAME (fndecl)) - name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); + ARGS_SO_FAR holds state needed by the target to know where to place + the next argument. -#if 0 - /* Unless it's a call to a specific function that isn't alloca, - if it has one argument, we must assume it might be alloca. */ + REG_PARM_STACK_SPACE is the number of bytes of stack space reserved + for arguments which are passed in registers. + + OLD_STACK_LEVEL is a pointer to an rtx which olds the old stack level + and may be modified by this routine. + + OLD_PENDING_ADJ, MUST_PREALLOCATE and IS_CONST are pointers to integer + flags which may may be modified by this routine. */ + +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, is_const) + 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 *is_const; +{ + /* 1 if scanning parms front to back, -1 if scanning back to front. */ + int inc; + + /* Count arg position in order args appear. */ + int argpos; + + int i; + tree p; + + args_size->constant = 0; + args_size->var = 0; + + /* In this loop, we consider args in the order they are written. + We fill up ARGS from the front or from the back if necessary + so that in any case the first arg to be pushed ends up at the front. */ - may_be_alloca - = (!(fndecl != 0 && strcmp (name, "alloca")) - && actparms != 0 - && TREE_CHAIN (actparms) == 0); +#ifdef PUSH_ARGS_REVERSED + i = num_actuals - 1, inc = -1; + /* In this case, must reverse order of args + so that we compute and push the last arg first. */ #else - /* We assume that alloca will always be called by name. It - makes no sense to pass it as a pointer-to-function to - anything that does not understand its behavior. */ - may_be_alloca - = (name && ((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6 - && name[0] == 'a' - && ! strcmp (name, "alloca")) - || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16 - && name[0] == '_' - && ! strcmp (name, "__builtin_alloca")))); + i = 0, inc = 1; #endif - /* See if this is a call to a function that can return more than once - or a call to longjmp. */ + /* I counts args in order (to be) pushed; ARGPOS counts in order written. */ + for (p = actparms, argpos = 0; p; p = TREE_CHAIN (p), i += inc, argpos++) + { + tree type = TREE_TYPE (TREE_VALUE (p)); + int unsignedp; + enum machine_mode mode; - returns_twice = 0; - is_longjmp = 0; - is_malloc = 0; + args[i].tree_value = TREE_VALUE (p); - if (name != 0 && 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)) - { - char *tname = name; + /* Replace erroneous argument with constant zero. */ + if (type == error_mark_node || TYPE_SIZE (type) == 0) + args[i].tree_value = integer_zero_node, type = integer_type_node; - /* Disregard prefix _, __ or __x. */ - if (name[0] == '_') - { - if (name[1] == '_' && name[2] == 'x') - tname += 3; - else if (name[1] == '_') - tname += 2; - else - tname += 1; - } - - if (tname[0] == 's') - { - returns_twice - = ((tname[1] == 'e' - && (! strcmp (tname, "setjmp") - || ! strcmp (tname, "setjmp_syscall"))) - || (tname[1] == 'i' - && ! strcmp (tname, "sigsetjmp")) - || (tname[1] == 'a' - && ! strcmp (tname, "savectx"))); - if (tname[1] == 'i' - && ! strcmp (tname, "siglongjmp")) - is_longjmp = 1; - } - else if ((tname[0] == 'q' && tname[1] == 's' - && ! strcmp (tname, "qsetjmp")) - || (tname[0] == 'v' && tname[1] == 'f' - && ! strcmp (tname, "vfork"))) - returns_twice = 1; - - else if (tname[0] == 'l' && tname[1] == 'o' - && ! strcmp (tname, "longjmp")) - is_longjmp = 1; - /* XXX should have "malloc" attribute on functions instead - of recognizing them by name. */ - else if (! strcmp (tname, "malloc") - || ! strcmp (tname, "calloc") - || ! strcmp (tname, "realloc") - /* Note use of NAME rather than TNAME here. These functions - are only reserved when preceded with __. */ - || ! strcmp (name, "__vn") /* mangled __builtin_vec_new */ - || ! strcmp (name, "__nw") /* mangled __builtin_new */ - || ! strcmp (name, "__builtin_new") - || ! strcmp (name, "__builtin_vec_new")) - is_malloc = 1; - } - - if (may_be_alloca) - current_function_calls_alloca = 1; - - /* Don't let pending stack adjusts add up to too much. - Also, do all pending adjustments now - if there is any chance this might be a call to alloca. */ - - if (pending_stack_adjust >= 32 - || (pending_stack_adjust > 0 && may_be_alloca)) - do_pending_stack_adjust (); - - /* Operand 0 is a pointer-to-function; get the type of the function. */ - funtype = TREE_TYPE (TREE_OPERAND (exp, 0)); - if (TREE_CODE (funtype) != POINTER_TYPE) - abort (); - funtype = TREE_TYPE (funtype); - - /* Push the temporary stack slot level so that we can free any temporaries - we make. */ - push_temp_slots (); - - /* 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 - 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)); - - /* 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 is a REG other than - virtual_outgoing_args_rtx, we can use always use it. If it - is not a REG, we must always copy it into a register. - If it is virtual_outgoing_args_rtx, we must copy it to another - register in some cases. */ - rtx temp = (GET_CODE (structure_value_addr) != REG -#ifdef ACCUMULATE_OUTGOING_ARGS - || (stack_arg_under_construction - && structure_value_addr == virtual_outgoing_args_rtx) -#endif - ? copy_addr_to_reg (structure_value_addr) - : structure_value_addr); - - actparms - = tree_cons (error_mark_node, - make_tree (build_pointer_type (TREE_TYPE (funtype)), - temp), - actparms); - structure_value_addr_parm = 1; - } - - /* Count the arguments and set NUM_ACTUALS. */ - for (p = actparms, i = 0; p; p = TREE_CHAIN (p)) i++; - num_actuals = i; - - /* 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 SETUP_INCOMING_VARARGS is defined 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 SETUP_INCOMING_VARARGS is not defined, we do not have any reliable - way to pass unnamed args in registers, so we must force them into - memory. */ - - if ((STRICT_ARGUMENT_NAMING -#ifndef SETUP_INCOMING_VARARGS - || 1 -#endif - ) - && TYPE_ARG_TYPES (funtype) != 0) - n_named_args - = (list_length (TYPE_ARG_TYPES (funtype)) - /* Don't include the last named arg. */ - - (STRICT_ARGUMENT_NAMING ? 0 : 1) - /* Count the struct value address, if it is passed as a parm. */ - + structure_value_addr_parm); - else - /* If we know nothing, 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)); - bzero ((char *) args, num_actuals * sizeof (struct arg_data)); - - args_size.constant = 0; - args_size.var = 0; - - /* In this loop, we consider args in the order they are written. - We fill up ARGS from the front or from the back if necessary - so that in any case the first arg to be pushed ends up at the front. */ - -#ifdef PUSH_ARGS_REVERSED - i = num_actuals - 1, inc = -1; - /* In this case, must reverse order of args - so that we compute and push the last arg first. */ -#else - i = 0, inc = 1; -#endif - - /* I counts args in order (to be) pushed; ARGPOS counts in order written. */ - for (p = actparms, argpos = 0; p; p = TREE_CHAIN (p), i += inc, argpos++) - { - tree type = TREE_TYPE (TREE_VALUE (p)); - int unsignedp; - enum machine_mode mode; - - args[i].tree_value = TREE_VALUE (p); - - /* Replace erroneous argument with constant zero. */ - if (type == error_mark_node || TYPE_SIZE (type) == 0) - args[i].tree_value = integer_zero_node, type = integer_type_node; - - /* If TYPE is a transparent union, pass things the way we would - pass the first field of the union. We have already verified that - the modes are the same. */ - if (TYPE_TRANSPARENT_UNION (type)) - type = TREE_TYPE (TYPE_FIELDS (type)); + /* If TYPE is a transparent union, pass things the way we would + pass the first field of the union. We have already verified that + the modes are the same. */ + if (TYPE_TRANSPARENT_UNION (type)) + type = TREE_TYPE (TYPE_FIELDS (type)); /* Decide where to pass this arg. @@ -1059,7 +943,7 @@ expand_call (exp, target, ignore) && 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), + || FUNCTION_ARG_PASS_BY_REFERENCE (*args_so_far, TYPE_MODE (type), type, argpos < n_named_args) #endif ) @@ -1068,7 +952,7 @@ expand_call (exp, target, ignore) references instead of making a copy. */ if (current_function_is_thunk #ifdef FUNCTION_ARG_CALLEE_COPIES - || (FUNCTION_ARG_CALLEE_COPIES (args_so_far, TYPE_MODE (type), + || (FUNCTION_ARG_CALLEE_COPIES (*args_so_far, TYPE_MODE (type), type, argpos < n_named_args) /* If it's in a register, we must make a copy of it too. */ /* ??? Is this a sufficient test? Is there a better one? */ @@ -1078,6 +962,22 @@ expand_call (exp, target, ignore) #endif ) { + /* C++ uses a TARGET_EXPR to indicate that we want to make a + new object from the argument. If we are passing by + invisible reference, the callee will do that for us, so we + can strip off the TARGET_EXPR. This is not always safe, + but it is safe in the only case where this is a useful + optimization; namely, when the argument is a plain object. + In that case, the frontend is just asking the backend to + make a bitwise copy of the argument. */ + + if (TREE_CODE (args[i].tree_value) == TARGET_EXPR + && (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND + (args[i].tree_value, 1))) + == 'd') + && ! REG_P (DECL_RTL (TREE_OPERAND (args[i].tree_value, 1)))) + args[i].tree_value = TREE_OPERAND (args[i].tree_value, 1); + args[i].tree_value = build1 (ADDR_EXPR, build_pointer_type (type), args[i].tree_value); @@ -1100,10 +1000,10 @@ expand_call (exp, target, ignore) for it. */ rtx size_rtx = expr_size (TREE_VALUE (p)); - if (old_stack_level == 0) + if (*old_stack_level == 0) { - emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); - old_pending_adj = pending_stack_adjust; + emit_stack_save (SAVE_BLOCK, old_stack_level, NULL_RTX); + *old_pending_adj = pending_stack_adjust; pending_stack_adjust = 0; } @@ -1118,10 +1018,10 @@ expand_call (exp, target, ignore) copy = assign_stack_temp (TYPE_MODE (type), size, 0); } - MEM_IN_STRUCT_P (copy) = AGGREGATE_TYPE_P (type); + MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type)); store_expr (args[i].tree_value, copy, 0); - is_const = 0; + *is_const = 0; args[i].tree_value = build1 (ADDR_EXPR, build_pointer_type (type), @@ -1139,99 +1039,935 @@ expand_call (exp, target, ignore) args[i].unsignedp = unsignedp; args[i].mode = mode; - args[i].reg = FUNCTION_ARG (args_so_far, mode, type, + args[i].reg = FUNCTION_ARG (*args_so_far, mode, type, argpos < n_named_args); #ifdef FUNCTION_ARG_PARTIAL_NREGS if (args[i].reg) args[i].partial - = FUNCTION_ARG_PARTIAL_NREGS (args_so_far, mode, type, + = FUNCTION_ARG_PARTIAL_NREGS (*args_so_far, mode, type, argpos < n_named_args); #endif args[i].pass_on_stack = MUST_PASS_IN_STACK (mode, type); - /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]), - it means that we are to pass this arg in the register(s) designated - by the PARALLEL, but also to pass it in the stack. */ - if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL - && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0) - args[i].pass_on_stack = 1; + /* If FUNCTION_ARG returned a (parallel [(expr_list (nil) ...) ...]), + it means that we are to pass this arg in the register(s) designated + by the PARALLEL, but also to pass it in the stack. */ + if (args[i].reg && GET_CODE (args[i].reg) == PARALLEL + && XEXP (XVECEXP (args[i].reg, 0, 0), 0) == 0) + args[i].pass_on_stack = 1; + + /* If this is an addressable type, we must preallocate the stack + since we must evaluate the object into its final location. + + If this is to be passed in both registers and the stack, it is simpler + to preallocate. */ + if (TREE_ADDRESSABLE (type) + || (args[i].pass_on_stack && args[i].reg != 0)) + *must_preallocate = 1; + + /* If this is an addressable type, we cannot pre-evaluate it. Thus, + we cannot consider this function call constant. */ + if (TREE_ADDRESSABLE (type)) + *is_const = 0; + + /* Compute the stack-size of this argument. */ + if (args[i].reg == 0 || args[i].partial != 0 + || reg_parm_stack_space > 0 + || args[i].pass_on_stack) + locate_and_pad_parm (mode, type, +#ifdef STACK_PARMS_IN_REG_PARM_AREA + 1, +#else + args[i].reg != 0, +#endif + fndecl, args_size, &args[i].offset, + &args[i].size); + +#ifndef ARGS_GROW_DOWNWARD + args[i].slot_offset = *args_size; +#endif + + /* 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 + + /* Increment ARGS_SO_FAR, which has info about which arg-registers + have been used, etc. */ + + FUNCTION_ARG_ADVANCE (*args_so_far, TYPE_MODE (type), type, + argpos < n_named_args); + } +} + +/* Update ARGS_SIZE to contain the total size for the argument block. + Return the original constant component of the argument block's size. + + REG_PARM_STACK_SPACE holds the number of bytes of stack space reserved + for arguments passed in registers. */ + +static int +compute_argument_block_size (reg_parm_stack_space, args_size) + int reg_parm_stack_space; + struct args_size *args_size; +{ + int unadjusted_args_size = args_size->constant; + + /* Compute the actual size of the argument block required. The variable + and constant sizes must be combined, the size may have to be rounded, + and there may be a minimum required size. */ + + if (args_size->var) + { + args_size->var = ARGS_SIZE_TREE (*args_size); + args_size->constant = 0; + +#ifdef PREFERRED_STACK_BOUNDARY + if (PREFERRED_STACK_BOUNDARY != BITS_PER_UNIT) + args_size->var = round_up (args_size->var, STACK_BYTES); +#endif + + if (reg_parm_stack_space > 0) + { + args_size->var + = size_binop (MAX_EXPR, args_size->var, + size_int (reg_parm_stack_space)); + +#ifndef OUTGOING_REG_PARM_STACK_SPACE + /* The area corresponding to register parameters is not to count in + the size of the block we need. So make the adjustment. */ + args_size->var + = size_binop (MINUS_EXPR, args_size->var, + size_int (reg_parm_stack_space)); +#endif + } + } + else + { +#ifdef PREFERRED_STACK_BOUNDARY + args_size->constant = (((args_size->constant + + pending_stack_adjust + + STACK_BYTES - 1) + / STACK_BYTES * STACK_BYTES) + - pending_stack_adjust); +#endif + + args_size->constant = MAX (args_size->constant, + reg_parm_stack_space); + +#ifdef MAYBE_REG_PARM_STACK_SPACE + if (reg_parm_stack_space == 0) + args_size->constant = 0; +#endif + +#ifndef OUTGOING_REG_PARM_STACK_SPACE + args_size->constant -= reg_parm_stack_space; +#endif + } + return unadjusted_args_size; +} + +/* Precompute parameters has needed for a function call. + + IS_CONST indicates the target function is a pure function. + + MUST_PREALLOCATE indicates that we must preallocate stack space for + any stack arguments. + + NUM_ACTUALS is the number of arguments. + + ARGS is an array containing information for each argument; this routine + fills in the INITIAL_VALUE and VALUE fields for each precomputed argument. + + ARGS_SIZE contains information about the size of the arg list. */ + +static void +precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size) + int is_const; + int must_preallocate; + int num_actuals; + struct arg_data *args; + struct args_size *args_size; +{ + int i; + + /* If this function call is cse'able, precompute all the parameters. + Note that if the parameter is constructed into a temporary, this will + cause an additional copy because the parameter will be constructed + into a temporary location and then copied into the outgoing arguments. + If a parameter contains a call to alloca and this function uses the + stack, precompute the parameter. */ + + /* If we preallocated the stack space, and some arguments must be passed + on the stack, then we must precompute any parameter which contains a + function call which will store arguments on the stack. + Otherwise, evaluating the parameter may clobber previous parameters + which have already been stored into the stack. */ + + for (i = 0; i < num_actuals; i++) + if (is_const + || ((args_size->var != 0 || args_size->constant != 0) + && calls_function (args[i].tree_value, 1)) + || (must_preallocate + && (args_size->var != 0 || args_size->constant != 0) + && calls_function (args[i].tree_value, 0))) + { + /* If this is an addressable type, we cannot pre-evaluate it. */ + if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))) + abort (); + + push_temp_slots (); + + args[i].initial_value = args[i].value + = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); + + preserve_temp_slots (args[i].value); + pop_temp_slots (); + + /* ANSI doesn't require a sequence point here, + but PCC has one, so this will avoid some problems. */ + emit_queue (); + + args[i].initial_value = args[i].value + = protect_from_queue (args[i].initial_value, 0); + + if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode) + args[i].value + = convert_modes (args[i].mode, + TYPE_MODE (TREE_TYPE (args[i].tree_value)), + args[i].value, args[i].unsignedp); + } +} + +/* Given the current state of MUST_PREALLOCATE and information about + arguments to a function call in NUM_ACTUALS, ARGS and ARGS_SIZE, + 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; +{ + /* See if we have or want to preallocate stack space. + + If we would have to push a partially-in-regs parm + before other stack parms, preallocate stack space instead. + + If the size of some parm is not a multiple of the required stack + alignment, we must preallocate. + + If the total size of arguments that would otherwise create a copy in + a temporary (such as a CALL) is more than half the total argument list + size, preallocation is faster. + + Another reason to preallocate is if we have a machine (like the m88k) + where stack alignment is required to be maintained between every + pair of insns, not just when the call is made. However, we assume here + that such machines either do not have push insns (and hence preallocation + would occur anyway) or the problem is taken care of with + PUSH_ROUNDING. */ + + if (! must_preallocate) + { + int partial_seen = 0; + int copy_to_evaluate_size = 0; + int i; + + for (i = 0; i < num_actuals && ! must_preallocate; i++) + { + if (args[i].partial > 0 && ! args[i].pass_on_stack) + partial_seen = 1; + else if (partial_seen && args[i].reg == 0) + must_preallocate = 1; + + if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode + && (TREE_CODE (args[i].tree_value) == CALL_EXPR + || TREE_CODE (args[i].tree_value) == TARGET_EXPR + || TREE_CODE (args[i].tree_value) == COND_EXPR + || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))) + copy_to_evaluate_size + += int_size_in_bytes (TREE_TYPE (args[i].tree_value)); + } + + if (copy_to_evaluate_size * 2 >= args_size->constant + && args_size->constant > 0) + must_preallocate = 1; + } + return must_preallocate; +} + +/* If we preallocated stack space, compute the address of each argument + and store it into the ARGS array. + + We need not ensure it is a valid memory address here; it will be + validized when it is used. + + 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; +{ + if (argblock) + { + rtx arg_reg = argblock; + int i, arg_offset = 0; + + if (GET_CODE (argblock) == PLUS) + arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1)); + + 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 addr; + + /* Skip this parm if it will not be passed on the stack. */ + if (! args[i].pass_on_stack && args[i].reg != 0) + continue; + + if (GET_CODE (offset) == CONST_INT) + addr = plus_constant (arg_reg, INTVAL (offset)); + else + addr = gen_rtx_PLUS (Pmode, arg_reg, offset); + + addr = plus_constant (addr, arg_offset); + args[i].stack = gen_rtx_MEM (args[i].mode, addr); + MEM_SET_IN_STRUCT_P + (args[i].stack, + AGGREGATE_TYPE_P (TREE_TYPE (args[i].tree_value))); + + if (GET_CODE (slot_offset) == CONST_INT) + addr = plus_constant (arg_reg, INTVAL (slot_offset)); + else + addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset); + + addr = plus_constant (addr, arg_offset); + args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr); + } + } +} + +/* Given a FNDECL and EXP, return an rtx suitable for use as a target address + in a call instruction. + + FNDECL is the tree node for the target function. For an indirect call + FNDECL will be NULL_TREE. + + EXP is the CALL_EXPR for this call. */ + +static rtx +rtx_for_function_call (fndecl, exp) + tree fndecl; + tree exp; +{ + rtx funexp; + + /* Get the function to call, in the form of RTL. */ + if (fndecl) + { + /* If this is the first use of the function, see if we need to + make an external definition for it. */ + if (! TREE_USED (fndecl)) + { + assemble_external (fndecl); + TREE_USED (fndecl) = 1; + } + + /* Get a SYMBOL_REF rtx for the function address. */ + funexp = XEXP (DECL_RTL (fndecl), 0); + } + else + /* Generate an rtx (probably a pseudo-register) for the address. */ + { + rtx funaddr; + push_temp_slots (); + funaddr = funexp = + expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0); + pop_temp_slots (); /* FUNEXP can't be BLKmode */ + + /* Check the function is executable. */ + if (current_function_check_memory_usage) + { +#ifdef POINTERS_EXTEND_UNSIGNED + /* It might be OK to convert funexp in place, but there's + a lot going on between here and when it happens naturally + that this seems safer. */ + funaddr = convert_memory_address (Pmode, funexp); +#endif + emit_library_call (chkr_check_exec_libfunc, 1, + VOIDmode, 1, + funaddr, Pmode); + } + emit_queue (); + } + return funexp; +} + +/* Do the register loads required for any wholly-register parms or any + parms which are passed both on the stack and in a register. Their + expressions were already evaluated. + + Mark all register-parms as living through the call, putting these USE + insns in the CALL_INSN_FUNCTION_USAGE field. */ + +static void +load_register_parameters (args, num_actuals, call_fusage) + struct arg_data *args; + int num_actuals; + rtx *call_fusage; +{ + 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 = args[i].reg; + int partial = args[i].partial; + int nregs; + + if (reg) + { + /* 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)); + + /* 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)), + (TYPE_ALIGN (TREE_TYPE (args[i].tree_value)) + / BITS_PER_UNIT)); + } + + /* 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); + + /* If we have pre-computed the values to put in the registers in + the case of non-aligned structures, copy them in now. */ + + else if (args[i].n_aligned_regs != 0) + for (j = 0; j < args[i].n_aligned_regs; j++) + emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j), + 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); + + /* Handle calls that pass values in multiple non-contiguous + locations. The Irix 6 ABI has examples of this. */ + if (GET_CODE (reg) == PARALLEL) + use_group_regs (call_fusage, reg); + else if (nregs == -1) + use_reg (call_fusage, reg); + else + use_regs (call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs); + } + } +} + +/* 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. + If the value is stored in TARGET then TARGET is returned. + 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; +{ + /* List of actual parameters. */ + tree actparms = TREE_OPERAND (exp, 1); + /* RTX for the function to be called. */ + rtx funexp; + /* Data type of the function. */ + tree funtype; + /* Declaration of the function being called, + or 0 if the function is computed (not known by name). */ + tree fndecl = 0; + char *name = 0; + + /* Register in which non-BLKmode value will be returned, + or 0 if no value or if value is BLKmode. */ + rtx valreg; + /* Address where we should return a BLKmode value; + 0 if value not BLKmode. */ + rtx structure_value_addr = 0; + /* Nonzero if that address is being passed by treating it as + an extra, implicit first parameter. Otherwise, + it is passed by being copied directly into struct_value_rtx. */ + int structure_value_addr_parm = 0; + /* Size of aggregate value wanted, or zero if none wanted + or if we are using the non-reentrant PCC calling convention + or expecting the value in registers. */ + HOST_WIDE_INT struct_value_size = 0; + /* 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; + + /* Number of actual parameters in this call, including struct value addr. */ + int num_actuals; + /* Number of named args. Args after this are anonymous ones + and they must all go on the stack. */ + int n_named_args; + + /* Vector of information about each argument. + Arguments are numbered in the order they will be pushed, + not the order they are written. */ + struct arg_data *args; + + /* Total size in bytes of all the stack-parms scanned so far. */ + struct args_size args_size; + /* Size of arguments before any adjustments (such as rounding). */ + int unadjusted_args_size; + /* Data on reg parms scanned so far. */ + CUMULATIVE_ARGS args_so_far; + /* Nonzero if a reg parm has been scanned. */ + int reg_parm_seen; + /* Nonzero if this is an indirect function call. */ + + /* Nonzero if we must avoid push-insns in the args for this call. + If stack space is allocated for register parameters, but not by the + caller, then it is preallocated in the fixed part of the stack frame. + So the entire argument block must then be preallocated (i.e., we + ignore PUSH_ROUNDING in that case). */ + +#ifdef PUSH_ROUNDING + int must_preallocate = 0; +#else + int must_preallocate = 1; +#endif + + /* Size of the stack reserved for parameter registers. */ + int reg_parm_stack_space = 0; + + /* Address of space preallocated for stack parms + (on machines that lack push insns), or 0 if space not preallocated. */ + rtx argblock = 0; + + /* Nonzero if it is plausible that this is a call to alloca. */ + int may_be_alloca; + /* Nonzero if this is a call to malloc or a related function. */ + int is_malloc; + /* Nonzero if this is a call to setjmp or a related function. */ + int returns_twice; + /* Nonzero if this is a call to `longjmp'. */ + int is_longjmp; + /* Nonzero if this is a call to an inline function. */ + int is_integrable = 0; + /* Nonzero if this is a call to a `const' function. + Note that only explicitly named functions are handled as `const' here. */ + int is_const = 0; + /* Nonzero if this is a call to a `volatile' function. */ + int is_volatile = 0; +#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(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; + rtx save_area = 0; /* Place that it is saved */ +#endif + +#ifdef ACCUMULATE_OUTGOING_ARGS + int initial_highest_arg_in_use = highest_outgoing_arg_in_use; + char *initial_stack_usage_map = stack_usage_map; + int old_stack_arg_under_construction; +#endif + + rtx old_stack_level = 0; + int old_pending_adj = 0; + int old_inhibit_defer_pop = inhibit_defer_pop; + rtx call_fusage = 0; + register tree p; + register int i; + + /* The value of the function call can be put in a hard register. But + if -fcheck-memory-usage, code which invokes functions (and thus + damages some hard registers) can be inserted before using the value. + So, target is always a pseudo-register in that case. */ + if (current_function_check_memory_usage) + target = 0; + + /* See if we can find a DECL-node for the actual function. + As a result, decide whether this is a call to an integrable function. */ + + p = TREE_OPERAND (exp, 0); + if (TREE_CODE (p) == ADDR_EXPR) + { + fndecl = TREE_OPERAND (p, 0); + if (TREE_CODE (fndecl) != FUNCTION_DECL) + fndecl = 0; + else + { + if (!flag_no_inline + && fndecl != current_function_decl + && DECL_INLINE (fndecl) + && DECL_SAVED_INSNS (fndecl) + && RTX_INTEGRATED_P (DECL_SAVED_INSNS (fndecl))) + is_integrable = 1; + else if (! TREE_ADDRESSABLE (fndecl)) + { + /* In case this function later becomes inlinable, + record that there was already a non-inline call to it. + + Use abstraction instead of setting TREE_ADDRESSABLE + directly. */ + if (DECL_INLINE (fndecl) && warn_inline && !flag_no_inline + && optimize > 0) + { + warning_with_decl (fndecl, "can't inline call to `%s'"); + warning ("called from here"); + } + mark_addressable (fndecl); + } + + if (TREE_READONLY (fndecl) && ! TREE_THIS_VOLATILE (fndecl) + && TYPE_MODE (TREE_TYPE (exp)) != VOIDmode) + is_const = 1; + + if (TREE_THIS_VOLATILE (fndecl)) + is_volatile = 1; + } + } + + /* If we don't have specific function to call, see if we have a + constant or `noreturn' function from the type. */ + if (fndecl == 0) + { + is_const = TREE_READONLY (TREE_TYPE (TREE_TYPE (p))); + is_volatile = TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (p))); + } + +#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 + +#if defined(PUSH_ROUNDING) && ! defined(OUTGOING_REG_PARM_STACK_SPACE) + if (reg_parm_stack_space > 0) + 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)) + { + /* This call returns a big structure. */ + is_const = 0; + +#ifdef PCC_STATIC_STRUCT_RETURN + { + pcc_struct_value = 1; + /* Easier than making that case work right. */ + if (is_integrable) + { + /* In case this is a static function, note that it has been + used. */ + if (! TREE_ADDRESSABLE (fndecl)) + mark_addressable (fndecl); + is_integrable = 0; + } + } +#else /* not PCC_STATIC_STRUCT_RETURN */ + { + struct_value_size = int_size_in_bytes (TREE_TYPE (exp)); + + if (target && GET_CODE (target) == MEM) + structure_value_addr = XEXP (target, 0); + else + { + /* Assign a temporary to hold the value. */ + tree d; + + /* For variable-sized objects, we must be called with a target + specified. If we were to allocate space on the stack here, + we would have no way of knowing when to free it. */ + + if (struct_value_size < 0) + abort (); + + /* This DECL is just something to feed to mark_addressable; + it doesn't get pushed. */ + d = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); + DECL_RTL (d) = assign_temp (TREE_TYPE (exp), 1, 0, 1); + mark_addressable (d); + structure_value_addr = XEXP (DECL_RTL (d), 0); + TREE_USED (d) = 1; + target = 0; + } + } +#endif /* not PCC_STATIC_STRUCT_RETURN */ + } + + /* If called function is inline, try to integrate it. */ + + if (is_integrable) + { + rtx temp; +#ifdef ACCUMULATE_OUTGOING_ARGS + rtx before_call = get_last_insn (); +#endif + + temp = expand_inline_function (fndecl, actparms, target, + ignore, TREE_TYPE (exp), + structure_value_addr); + + /* If inlining succeeded, return. */ + if (temp != (rtx) (HOST_WIDE_INT) -1) + { +#ifdef ACCUMULATE_OUTGOING_ARGS + /* If the outgoing argument list must be preserved, push + 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; + + if (stack_arg_under_construction || i >= 0) + { + rtx first_insn + = before_call ? NEXT_INSN (before_call) : get_insns (); + rtx insn, seq; + + /* Look for a call in the inline function code. + If OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) is + nonzero then there is a call and it is not necessary + to scan the insns. */ + + if (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) == 0) + for (insn = first_insn; insn; insn = NEXT_INSN (insn)) + if (GET_CODE (insn) == CALL_INSN) + break; + + if (insn) + { + /* Reserve enough stack space so that the largest + argument list of any function call in the inline + function does not overlap the argument list being + evaluated. This is usually an overestimate because + allocate_dynamic_stack_space reserves space for an + outgoing argument list in addition to the requested + space, but there is no way to ask for stack space such + that an argument list of a certain length can be + safely constructed. + + Add the stack space reserved for register arguments, if + any, in the inline function. What is really needed is the + largest value of reg_parm_stack_space in the inline + function, but that is not available. Using the current + value of reg_parm_stack_space is wrong, but gives + correct results on all supported machines. */ + + int adjust = (OUTGOING_ARGS_SIZE (DECL_SAVED_INSNS (fndecl)) + + reg_parm_stack_space); + + start_sequence (); + emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX); + allocate_dynamic_stack_space (GEN_INT (adjust), + NULL_RTX, BITS_PER_UNIT); + seq = get_insns (); + end_sequence (); + emit_insns_before (seq, first_insn); + emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX); + } + } +#endif + + /* If the result is equivalent to TARGET, return TARGET to simplify + checks in store_expr. They can be equivalent but not equal in the + case of a function that returns BLKmode. */ + if (temp != target && rtx_equal_p (temp, target)) + return target; + return temp; + } + + /* If inlining failed, mark FNDECL as needing to be compiled + separately after all. If function was declared inline, + give a warning. */ + 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 ("called from here"); + } + mark_addressable (fndecl); + } + + function_call_count++; + + if (fndecl && DECL_NAME (fndecl)) + name = IDENTIFIER_POINTER (DECL_NAME (fndecl)); + + /* See if this is a call to a function that can return more than once + or a call to longjmp or malloc. */ + special_function_p (name, fndecl, &returns_twice, &is_longjmp, + &is_malloc, &may_be_alloca); + + if (may_be_alloca) + current_function_calls_alloca = 1; + + /* Operand 0 is a pointer-to-function; get the type of the function. */ + funtype = TREE_TYPE (TREE_OPERAND (exp, 0)); + if (! POINTER_TYPE_P (funtype)) + abort (); + funtype = TREE_TYPE (funtype); + + /* When calling a const function, we must pop the stack args right away, + so that the pop is deleted or moved with the call. */ + if (is_const) + NO_DEFER_POP; + + /* Don't let pending stack adjusts add up to too much. + Also, do all pending adjustments now + if there is any chance this might be a call to alloca. */ + + if (pending_stack_adjust >= 32 + || (pending_stack_adjust > 0 && may_be_alloca)) + do_pending_stack_adjust (); - /* If this is an addressable type, we must preallocate the stack - since we must evaluate the object into its final location. + /* Push the temporary stack slot level so that we can free any temporaries + we make. */ + push_temp_slots (); - If this is to be passed in both registers and the stack, it is simpler - to preallocate. */ - if (TREE_ADDRESSABLE (type) - || (args[i].pass_on_stack && args[i].reg != 0)) - must_preallocate = 1; + /* Start updating where the next arg would go. - /* If this is an addressable type, we cannot pre-evaluate it. Thus, - we cannot consider this function call constant. */ - if (TREE_ADDRESSABLE (type)) - is_const = 0; + On some machines (such as the PA) indirect calls have a different + calling convention than normal calls. The last 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)); - /* Compute the stack-size of this argument. */ - if (args[i].reg == 0 || args[i].partial != 0 - || reg_parm_stack_space > 0 - || args[i].pass_on_stack) - locate_and_pad_parm (mode, type, -#ifdef STACK_PARMS_IN_REG_PARM_AREA - 1, -#else - args[i].reg != 0, + /* 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 is a REG other than + virtual_outgoing_args_rtx, we can use always use it. If it + is not a REG, we must always copy it into a register. + If it is virtual_outgoing_args_rtx, we must copy it to another + register in some cases. */ + rtx temp = (GET_CODE (structure_value_addr) != REG +#ifdef ACCUMULATE_OUTGOING_ARGS + || (stack_arg_under_construction + && structure_value_addr == virtual_outgoing_args_rtx) #endif - fndecl, &args_size, &args[i].offset, - &args[i].size); + ? copy_addr_to_reg (structure_value_addr) + : structure_value_addr); -#ifndef ARGS_GROW_DOWNWARD - args[i].slot_offset = args_size; -#endif + actparms + = tree_cons (error_mark_node, + make_tree (build_pointer_type (TREE_TYPE (funtype)), + temp), + actparms); + structure_value_addr_parm = 1; + } - /* 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. */ + /* Count the arguments and set NUM_ACTUALS. */ + for (p = actparms, i = 0; p; p = TREE_CHAIN (p)) i++; + num_actuals = i; - args_size.constant += args[i].size.constant; - if (args[i].size.var) - { - ADD_PARM_SIZE (args_size, args[i].size.var); - } + /* 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.) - /* 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; + 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. - args[i].slot_offset.constant = -args_size.constant; - if (args_size.var) - { - SUB_PARM_SIZE (args[i].slot_offset, args_size.var); - } -#endif + 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. */ - /* Increment ARGS_SO_FAR, which has info about which arg-registers - have been used, etc. */ + if ((STRICT_ARGUMENT_NAMING + || ! PRETEND_OUTGOING_VARARGS_NAMED) + && TYPE_ARG_TYPES (funtype) != 0) + n_named_args + = (list_length (TYPE_ARG_TYPES (funtype)) + /* Don't include the last named arg. */ + - (STRICT_ARGUMENT_NAMING ? 0 : 1) + /* Count the struct value address, if it is passed as a parm. */ + + structure_value_addr_parm); + else + /* If we know nothing, treat all args as named. */ + n_named_args = num_actuals; - FUNCTION_ARG_ADVANCE (args_so_far, TYPE_MODE (type), type, - argpos < n_named_args); - } + /* Make a vector to hold all the information about each arg. */ + args = (struct arg_data *) alloca (num_actuals * sizeof (struct arg_data)); + bzero ((char *) args, num_actuals * sizeof (struct arg_data)); + + /* Build up entries inthe ARGS array, compute the size of the arguments + into ARGS_SIZE, etc. */ + 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, + &is_const); #ifdef FINAL_REG_PARM_STACK_SPACE reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant, args_size.var); #endif - /* Compute the actual size of the argument block required. The variable - and constant sizes must be combined, the size may have to be rounded, - and there may be a minimum required size. */ - - original_args_size = args_size; if (args_size.var) { /* If this function requires a variable-sized argument list, don't try to @@ -1241,94 +1977,17 @@ expand_call (exp, target, ignore) is_const = 0; must_preallocate = 1; - - args_size.var = ARGS_SIZE_TREE (args_size); - args_size.constant = 0; - -#ifdef STACK_BOUNDARY - if (STACK_BOUNDARY != BITS_PER_UNIT) - args_size.var = round_up (args_size.var, STACK_BYTES); -#endif - - if (reg_parm_stack_space > 0) - { - args_size.var - = size_binop (MAX_EXPR, args_size.var, - size_int (reg_parm_stack_space)); - -#ifndef OUTGOING_REG_PARM_STACK_SPACE - /* The area corresponding to register parameters is not to count in - the size of the block we need. So make the adjustment. */ - args_size.var - = size_binop (MINUS_EXPR, args_size.var, - size_int (reg_parm_stack_space)); -#endif - } - } - else - { -#ifdef STACK_BOUNDARY - args_size.constant = (((args_size.constant + (STACK_BYTES - 1)) - / STACK_BYTES) * STACK_BYTES); -#endif - - args_size.constant = MAX (args_size.constant, - reg_parm_stack_space); - -#ifdef MAYBE_REG_PARM_STACK_SPACE - if (reg_parm_stack_space == 0) - args_size.constant = 0; -#endif - -#ifndef OUTGOING_REG_PARM_STACK_SPACE - args_size.constant -= reg_parm_stack_space; -#endif } - /* See if we have or want to preallocate stack space. - - If we would have to push a partially-in-regs parm - before other stack parms, preallocate stack space instead. - - If the size of some parm is not a multiple of the required stack - alignment, we must preallocate. - - If the total size of arguments that would otherwise create a copy in - a temporary (such as a CALL) is more than half the total argument list - size, preallocation is faster. - - Another reason to preallocate is if we have a machine (like the m88k) - where stack alignment is required to be maintained between every - pair of insns, not just when the call is made. However, we assume here - that such machines either do not have push insns (and hence preallocation - would occur anyway) or the problem is taken care of with - PUSH_ROUNDING. */ - - if (! must_preallocate) - { - int partial_seen = 0; - int copy_to_evaluate_size = 0; - - for (i = 0; i < num_actuals && ! must_preallocate; i++) - { - if (args[i].partial > 0 && ! args[i].pass_on_stack) - partial_seen = 1; - else if (partial_seen && args[i].reg == 0) - must_preallocate = 1; - - if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode - && (TREE_CODE (args[i].tree_value) == CALL_EXPR - || TREE_CODE (args[i].tree_value) == TARGET_EXPR - || TREE_CODE (args[i].tree_value) == COND_EXPR - || TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value)))) - copy_to_evaluate_size - += int_size_in_bytes (TREE_TYPE (args[i].tree_value)); - } + /* Compute the actual size of the argument block required. The variable + and constant sizes must be combined, the size may have to be rounded, + and there may be a minimum required size. */ + unadjusted_args_size + = compute_argument_block_size (reg_parm_stack_space, &args_size); - if (copy_to_evaluate_size * 2 >= args_size.constant - && args_size.constant > 0) - must_preallocate = 1; - } + /* Now make final decision about preallocating stack space. */ + must_preallocate = finalize_must_preallocate (must_preallocate, + num_actuals, args, &args_size); /* If the structure value address will reference the stack pointer, we must stabilize it. We don't need to do this if we know that we are not going @@ -1344,51 +2003,9 @@ expand_call (exp, target, ignore) )) structure_value_addr = copy_to_reg (structure_value_addr); - /* If this function call is cse'able, precompute all the parameters. - Note that if the parameter is constructed into a temporary, this will - cause an additional copy because the parameter will be constructed - into a temporary location and then copied into the outgoing arguments. - If a parameter contains a call to alloca and this function uses the - stack, precompute the parameter. */ - - /* If we preallocated the stack space, and some arguments must be passed - on the stack, then we must precompute any parameter which contains a - function call which will store arguments on the stack. - Otherwise, evaluating the parameter may clobber previous parameters - which have already been stored into the stack. */ - - for (i = 0; i < num_actuals; i++) - if (is_const - || ((args_size.var != 0 || args_size.constant != 0) - && calls_function (args[i].tree_value, 1)) - || (must_preallocate && (args_size.var != 0 || args_size.constant != 0) - && calls_function (args[i].tree_value, 0))) - { - /* If this is an addressable type, we cannot pre-evaluate it. */ - if (TREE_ADDRESSABLE (TREE_TYPE (args[i].tree_value))) - abort (); - - push_temp_slots (); - - args[i].initial_value = args[i].value - = expand_expr (args[i].tree_value, NULL_RTX, VOIDmode, 0); - - preserve_temp_slots (args[i].value); - pop_temp_slots (); - - /* ANSI doesn't require a sequence point here, - but PCC has one, so this will avoid some problems. */ - emit_queue (); - - args[i].initial_value = args[i].value - = protect_from_queue (args[i].initial_value, 0); - - if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) != args[i].mode) - args[i].value - = convert_modes (args[i].mode, - TYPE_MODE (TREE_TYPE (args[i].tree_value)), - args[i].value, args[i].unsignedp); - } + /* Precompute any arguments as needed. */ + precompute_arguments (is_const, must_preallocate, num_actuals, + args, &args_size); /* Now we are about to start emitting insns that can be deleted if a libcall is deleted. */ @@ -1551,55 +2168,14 @@ expand_call (exp, target, ignore) } #endif + compute_argument_addresses (args, argblock, num_actuals); - /* If we preallocated stack space, compute the address of each argument. - We need not ensure it is a valid memory address here; it will be - validized when it is used. */ - if (argblock) - { - rtx arg_reg = argblock; - int arg_offset = 0; - - if (GET_CODE (argblock) == PLUS) - arg_reg = XEXP (argblock, 0), arg_offset = INTVAL (XEXP (argblock, 1)); - - 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 addr; - - /* Skip this parm if it will not be passed on the stack. */ - if (! args[i].pass_on_stack && args[i].reg != 0) - continue; - - if (GET_CODE (offset) == CONST_INT) - addr = plus_constant (arg_reg, INTVAL (offset)); - else - addr = gen_rtx_PLUS (Pmode, arg_reg, offset); - - addr = plus_constant (addr, arg_offset); - args[i].stack = gen_rtx_MEM (args[i].mode, addr); - MEM_IN_STRUCT_P (args[i].stack) - = AGGREGATE_TYPE_P (TREE_TYPE (args[i].tree_value)); - - if (GET_CODE (slot_offset) == CONST_INT) - addr = plus_constant (arg_reg, INTVAL (slot_offset)); - else - addr = gen_rtx_PLUS (Pmode, arg_reg, slot_offset); - - addr = plus_constant (addr, arg_offset); - args[i].stack_slot = gen_rtx_MEM (args[i].mode, addr); - } - } - #ifdef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we push args individually in reverse order, perform stack alignment before the first push (the last arg). */ if (argblock == 0) - anti_adjust_stack (GEN_INT (args_size.constant - - original_args_size.constant)); + anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size)); #endif #endif @@ -1608,34 +2184,7 @@ expand_call (exp, target, ignore) if (argblock) NO_DEFER_POP; - /* Get the function to call, in the form of RTL. */ - if (fndecl) - { - /* If this is the first use of the function, see if we need to - make an external definition for it. */ - if (! TREE_USED (fndecl)) - { - assemble_external (fndecl); - TREE_USED (fndecl) = 1; - } - - /* Get a SYMBOL_REF rtx for the function address. */ - funexp = XEXP (DECL_RTL (fndecl), 0); - } - else - /* Generate an rtx (probably a pseudo-register) for the address. */ - { - push_temp_slots (); - funexp = expand_expr (TREE_OPERAND (exp, 0), NULL_RTX, VOIDmode, 0); - pop_temp_slots (); /* FUNEXP can't be BLKmode */ - - /* Check the function is executable. */ - if (flag_check_memory_usage) - emit_library_call (chkr_check_exec_libfunc, 1, - VOIDmode, 1, - funexp, ptr_mode); - emit_queue (); - } + funexp = rtx_for_function_call (fndecl, exp); /* Figure out the register where the value, if any, will come back. */ valreg = 0; @@ -1651,115 +2200,16 @@ expand_call (exp, target, ignore) /* Precompute all register parameters. It isn't safe to compute anything once we have started filling any specific hard regs. */ - reg_parm_seen = 0; - for (i = 0; i < num_actuals; i++) - if (args[i].reg != 0 && ! args[i].pass_on_stack) - { - reg_parm_seen = 1; - - if (args[i].value == 0) - { - push_temp_slots (); - args[i].value = expand_expr (args[i].tree_value, NULL_RTX, - VOIDmode, 0); - preserve_temp_slots (args[i].value); - pop_temp_slots (); - - /* ANSI doesn't require a sequence point here, - but PCC has one, so this will avoid some problems. */ - emit_queue (); - } - - /* If we are to promote the function arg to a wider mode, - do it now. */ - - if (args[i].mode != TYPE_MODE (TREE_TYPE (args[i].tree_value))) - args[i].value - = convert_modes (args[i].mode, - TYPE_MODE (TREE_TYPE (args[i].tree_value)), - args[i].value, args[i].unsignedp); - - /* If the value is expensive, and we are inside an appropriately - short loop, put the value into a pseudo and then put the pseudo - into the hard reg. - - For small register classes, also do this if this call uses - register parameters. This is to avoid reload conflicts while - loading the parameters registers. */ - - if ((! (GET_CODE (args[i].value) == REG - || (GET_CODE (args[i].value) == SUBREG - && GET_CODE (SUBREG_REG (args[i].value)) == REG))) - && args[i].mode != BLKmode - && rtx_cost (args[i].value, SET) > 2 - && ((SMALL_REGISTER_CLASSES && reg_parm_seen) - || preserve_subexpressions_p ())) - args[i].value = copy_to_mode_reg (args[i].mode, args[i].value); - } + precompute_register_parameters (num_actuals, args, ®_parm_seen); #if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE) - /* 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 (i = 0; i < reg_parm_stack_space + 1; i++) -#else - for (i = 0; i < reg_parm_stack_space; i++) -#endif - { - if (i >= highest_outgoing_arg_in_use - || stack_usage_map[i] == 0) - continue; - - if (low_to_save == -1) - low_to_save = i; - - high_to_save = i; - } - - 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); - MEM_IN_STRUCT_P (save_area) = 0; - emit_block_move (validize_mem (save_area), stack_area, - GEN_INT (num_to_save), - PARM_BOUNDARY / BITS_PER_UNIT); - } - else - { - save_area = gen_reg_rtx (save_mode); - emit_move_insn (save_area, stack_area); - } - } + /* Save the fixed argument area if it's part of the caller's frame and + is clobbered by argument setup for this call. */ + save_area = save_fixed_argument_area (reg_parm_stack_space, argblock, + &low_to_save, &high_to_save); #endif - + /* Now store (and compute if necessary) all non-register parms. These come before register parms, since they can require block-moves, @@ -1770,75 +2220,14 @@ expand_call (exp, target, ignore) for (i = 0; i < num_actuals; i++) if (args[i].reg == 0 || args[i].pass_on_stack) store_one_arg (&args[i], argblock, may_be_alloca, - args_size.var != 0, fndecl, reg_parm_stack_space); + args_size.var != 0, reg_parm_stack_space); /* If we have a parm that is passed in registers but not in memory and whose alignment does not permit a direct copy into registers, make a group of pseudos that correspond to each register that we will later fill. */ - if (STRICT_ALIGNMENT) - for (i = 0; i < num_actuals; i++) - if (args[i].reg != 0 && ! args[i].pass_on_stack - && args[i].mode == BLKmode - && (TYPE_ALIGN (TREE_TYPE (args[i].tree_value)) - < 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; - - args[i].aligned_regs = (rtx *) alloca (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, - 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)); - - for (j = 0; j < args[i].n_aligned_regs; j++) - { - rtx reg = gen_reg_rtx (word_mode); - rtx word = operand_subword_force (args[i].value, j, BLKmode); - int bitsize = TYPE_ALIGN (TREE_TYPE (args[i].tree_value)); - int bitpos; - - args[i].aligned_regs[j] = reg; - - /* Clobber REG and move each partword into it. Ensure we don't - go past the end of the structure. Note that the loop below - works because we've already verified that padding - and endianness are compatible. - - We use to emit a clobber here but that doesn't let later - passes optimize the instructions we emit. By storing 0 into - the register later passes know the first AND to zero out the - bitfield being set in the register is unnecessary. The store - of 0 will be deleted as will at least the first AND. */ - - emit_move_insn (reg, const0_rtx); - - for (bitpos = 0; - bitpos < BITS_PER_WORD && bytes > 0; - bitpos += bitsize, bytes -= bitsize / BITS_PER_UNIT) - { - int xbitpos = bitpos + big_endian_correction; - - store_bit_field (reg, bitsize, xbitpos, word_mode, - extract_bit_field (word, bitsize, bitpos, 1, - NULL_RTX, word_mode, - word_mode, - bitsize / BITS_PER_UNIT, - BITS_PER_WORD), - bitsize / BITS_PER_UNIT, BITS_PER_WORD); - } - } - } + store_unaligned_arguments_into_pseudos (args, num_actuals); /* Now store any partially-in-registers parm. This is the last place a block-move can happen. */ @@ -1846,15 +2235,14 @@ expand_call (exp, target, ignore) for (i = 0; i < num_actuals; i++) if (args[i].partial != 0 && ! args[i].pass_on_stack) store_one_arg (&args[i], argblock, may_be_alloca, - args_size.var != 0, fndecl, reg_parm_stack_space); + args_size.var != 0, reg_parm_stack_space); #ifndef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we pushed args in forward order, perform stack alignment after pushing the last arg. */ if (argblock == 0) - anti_adjust_stack (GEN_INT (args_size.constant - - original_args_size.constant)); + anti_adjust_stack (GEN_INT (args_size.constant - unadjusted_args_size)); #endif #endif @@ -1875,10 +2263,10 @@ expand_call (exp, target, ignore) NULL_RTX))); /* Mark the memory for the aggregate as write-only. */ - if (flag_check_memory_usage) + if (current_function_check_memory_usage) emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, - structure_value_addr, ptr_mode, + structure_value_addr, Pmode, GEN_INT (struct_value_size), TYPE_MODE (sizetype), GEN_INT (MEMORY_USE_WO), TYPE_MODE (integer_type_node)); @@ -1889,76 +2277,7 @@ expand_call (exp, target, ignore) funexp = prepare_call_address (funexp, fndecl, &call_fusage, reg_parm_seen); - /* Now do the register loads required for any wholly-register parms or any - parms which are passed both on the stack and in a register. Their - expressions were already evaluated. - - Mark all register-parms as living through the call, putting these USE - insns in the CALL_INSN_FUNCTION_USAGE field. */ - -#ifdef LOAD_ARGS_REVERSED - for (i = num_actuals - 1; i >= 0; i--) -#else - for (i = 0; i < num_actuals; i++) -#endif - { - rtx reg = args[i].reg; - int partial = args[i].partial; - int nregs; - - if (reg) - { - /* 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)); - - /* 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)), - (TYPE_ALIGN (TREE_TYPE (args[i].tree_value)) - / BITS_PER_UNIT)); - } - - /* 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); - - /* If we have pre-computed the values to put in the registers in - the case of non-aligned structures, copy them in now. */ - - else if (args[i].n_aligned_regs != 0) - for (j = 0; j < args[i].n_aligned_regs; j++) - emit_move_insn (gen_rtx_REG (word_mode, REGNO (reg) + j), - 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); - - /* Handle calls that pass values in multiple non-contiguous - locations. The Irix 6 ABI has examples of this. */ - if (GET_CODE (reg) == PARALLEL) - use_group_regs (&call_fusage, reg); - else if (nregs == -1) - use_reg (&call_fusage, reg); - else - use_regs (&call_fusage, REGNO (reg), nregs == 0 ? 1 : nregs); - } - } + load_register_parameters (args, num_actuals, &call_fusage); /* Perform postincrements before actually calling the function. */ emit_queue (); @@ -1966,7 +2285,8 @@ expand_call (exp, target, ignore) /* All arguments and registers used for the call must be set up by now! */ /* Generate the actual call instruction. */ - emit_call_1 (funexp, fndecl, funtype, args_size.constant, struct_value_size, + emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size, + args_size.constant, struct_value_size, FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), valreg, old_inhibit_defer_pop, call_fusage, is_const); @@ -2078,7 +2398,8 @@ expand_call (exp, target, ignore) target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), memory_address (TYPE_MODE (TREE_TYPE (exp)), structure_value_addr)); - MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp)); + MEM_SET_IN_STRUCT_P (target, + AGGREGATE_TYPE_P (TREE_TYPE (exp))); } } else if (pcc_struct_value) @@ -2088,7 +2409,7 @@ expand_call (exp, target, ignore) never use this value more than once in one expression. */ target = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (exp)), copy_to_reg (valreg)); - MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp)); + MEM_SET_IN_STRUCT_P (target, AGGREGATE_TYPE_P (TREE_TYPE (exp))); } /* Handle calls that return values in multiple non-contiguous locations. The Irix 6 ABI has examples of this. */ @@ -2099,7 +2420,7 @@ expand_call (exp, target, ignore) if (target == 0) { target = assign_stack_temp (TYPE_MODE (TREE_TYPE (exp)), bytes, 0); - MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp)); + MEM_SET_IN_STRUCT_P (target, AGGREGATE_TYPE_P (TREE_TYPE (exp))); preserve_temp_slots (target); } @@ -2116,75 +2437,7 @@ expand_call (exp, target, ignore) when function inlining is being done. */ emit_move_insn (target, valreg); else if (TYPE_MODE (TREE_TYPE (exp)) == BLKmode) - { - /* Some machines (the PA for example) want to return all small - structures in registers regardless of the structure's alignment. - - Deal with them explicitly by copying from the return registers - into the target MEM locations. */ - int bytes = int_size_in_bytes (TREE_TYPE (exp)); - rtx src = NULL, dst = NULL; - int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (exp)), BITS_PER_WORD); - int bitpos, xbitpos, big_endian_correction = 0; - - if (target == 0) - { - target = assign_stack_temp (BLKmode, bytes, 0); - MEM_IN_STRUCT_P (target) = AGGREGATE_TYPE_P (TREE_TYPE (exp)); - preserve_temp_slots (target); - } - - /* This code assumes valreg is at least a full word. If it isn't, - copy it into a new pseudo which is a full word. */ - if (GET_MODE (valreg) != BLKmode - && GET_MODE_SIZE (GET_MODE (valreg)) < UNITS_PER_WORD) - valreg = convert_to_mode (word_mode, valreg, - TREE_UNSIGNED (TREE_TYPE (exp))); - - /* 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)); - - /* Copy the structure BITSIZE bites at a time. - - 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; - 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 - (the first time through). */ - if (xbitpos % BITS_PER_WORD == 0 - || xbitpos == big_endian_correction) - src = operand_subword_force (valreg, - xbitpos / BITS_PER_WORD, - BLKmode); - - /* We need a new destination operand each time bitpos is on - a word boundary. */ - if (bitpos % BITS_PER_WORD == 0) - dst = operand_subword (target, bitpos / BITS_PER_WORD, 1, BLKmode); - - /* Use xbitpos for the source extraction (right justified) and - xbitpos for the destination store (left justified). */ - store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, word_mode, - extract_bit_field (src, bitsize, - xbitpos % BITS_PER_WORD, 1, - NULL_RTX, word_mode, - word_mode, - bitsize / BITS_PER_UNIT, - BITS_PER_WORD), - bitsize / BITS_PER_UNIT, BITS_PER_WORD); - } - } + target = copy_blkmode_from_reg (target, valreg, TREE_TYPE (exp)); else target = copy_to_reg (valreg); @@ -2227,31 +2480,10 @@ expand_call (exp, target, ignore) { #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))); + restore_fixed_argument_area (save_area, argblock, + high_to_save, low_to_save); #endif - if (save_mode != BLKmode) - emit_move_insn (stack_area, save_area); - else - emit_block_move (stack_area, validize_mem (save_area), - GEN_INT (high_to_save - low_to_save + 1), - PARM_BOUNDARY / BITS_PER_UNIT); - } -#endif - /* If we saved any argument areas, restore them. */ for (i = 0; i < num_actuals; i++) if (args[i].save_area) @@ -2279,11 +2511,16 @@ expand_call (exp, target, ignore) Check for the handler slots since we might not have a save area for non-local gotos. */ - if (may_be_alloca && nonlocal_goto_handler_slot != 0) + if (may_be_alloca && nonlocal_goto_handler_slots != 0) emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX); pop_temp_slots (); + /* Free up storage we no longer need. */ + for (i = 0; i < num_actuals; ++i) + if (args[i].aligned_regs) + free (args[i].aligned_regs); + return target; } @@ -2311,7 +2548,7 @@ void emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, int nargs, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES rtx orgfun; int no_queue; enum machine_mode outmode; @@ -2352,13 +2589,13 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, #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); + reg_parm_stack_space = REG_PARM_STACK_SPACE ((tree) 0); #endif #endif VA_START (p, nargs); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES orgfun = va_arg (p, rtx); no_queue = va_arg (p, int); outmode = va_arg (p, enum machine_mode); @@ -2465,7 +2702,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, assemble_external_libcall (fun); original_args_size = args_size; -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY args_size.constant = (((args_size.constant + (STACK_BYTES - 1)) / STACK_BYTES) * STACK_BYTES); #endif @@ -2533,7 +2770,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, #endif #ifdef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we push args individually in reverse order, perform stack alignment before the first push (the last arg). */ if (argblock == 0) @@ -2599,7 +2836,6 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, if (save_mode == BLKmode) { save_area = assign_stack_temp (BLKmode, num_to_save, 0); - MEM_IN_STRUCT_P (save_area) = 0; emit_block_move (validize_mem (save_area), stack_area, GEN_INT (num_to_save), PARM_BOUNDARY / BITS_PER_UNIT); @@ -2678,7 +2914,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, } #ifndef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we pushed args in forward order, perform stack alignment after pushing the last arg. */ if (argblock == 0) @@ -2735,7 +2971,7 @@ emit_library_call VPROTO((rtx orgfun, int no_queue, enum machine_mode outmode, get_identifier (XSTR (orgfun, 0)), build_function_type (outmode == VOIDmode ? void_type_node : type_for_mode (outmode, 0), NULL_TREE), - args_size.constant, 0, + original_args_size.constant, args_size.constant, 0, FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX, old_inhibit_defer_pop + 1, call_fusage, no_queue); @@ -2802,7 +3038,7 @@ rtx emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, enum machine_mode outmode, int nargs, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES rtx orgfun; rtx value; int no_queue; @@ -2851,13 +3087,13 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, #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); + reg_parm_stack_space = REG_PARM_STACK_SPACE ((tree) 0); #endif #endif VA_START (p, nargs); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES orgfun = va_arg (p, rtx); value = va_arg (p, rtx); no_queue = va_arg (p, int); @@ -3029,7 +3265,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, assemble_external_libcall (fun); original_args_size = args_size; -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY args_size.constant = (((args_size.constant + (STACK_BYTES - 1)) / STACK_BYTES) * STACK_BYTES); #endif @@ -3097,7 +3333,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, #endif #ifdef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we push args individually in reverse order, perform stack alignment before the first push (the last arg). */ if (argblock == 0) @@ -3163,7 +3399,6 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, if (save_mode == BLKmode) { save_area = assign_stack_temp (BLKmode, num_to_save, 0); - MEM_IN_STRUCT_P (save_area) = 0; emit_block_move (validize_mem (save_area), stack_area, GEN_INT (num_to_save), PARM_BOUNDARY / BITS_PER_UNIT); @@ -3243,7 +3478,7 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, } #ifndef PUSH_ARGS_REVERSED -#ifdef STACK_BOUNDARY +#ifdef PREFERRED_STACK_BOUNDARY /* If we pushed args in forward order, perform stack alignment after pushing the last arg. */ if (argblock == 0) @@ -3309,7 +3544,8 @@ emit_library_call_value VPROTO((rtx orgfun, rtx value, int no_queue, emit_call_1 (fun, get_identifier (XSTR (orgfun, 0)), build_function_type (type_for_mode (outmode, 0), NULL_TREE), - args_size.constant, struct_value_size, + original_args_size.constant, args_size.constant, + struct_value_size, FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1), mem_value == 0 ? hard_libcall_value (outmode) : NULL_RTX, old_inhibit_defer_pop + 1, call_fusage, is_const); @@ -3436,13 +3672,12 @@ target_for_arg (type, size, args_addr, offset) FNDECL is the declaration of the function we are calling. */ static void -store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, +store_one_arg (arg, argblock, may_be_alloca, variable_size, reg_parm_stack_space) struct arg_data *arg; rtx argblock; int may_be_alloca; - int variable_size; - tree fndecl; + int variable_size ATTRIBUTE_UNUSED; int reg_parm_stack_space; { register tree pval = arg->tree_value; @@ -3504,8 +3739,9 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, { arg->save_area = assign_stack_temp (BLKmode, arg->size.constant, 0); - MEM_IN_STRUCT_P (arg->save_area) - = AGGREGATE_TYPE_P (TREE_TYPE (arg->tree_value)); + MEM_SET_IN_STRUCT_P (arg->save_area, + AGGREGATE_TYPE_P (TREE_TYPE + (arg->tree_value))); preserve_temp_slots (arg->save_area); emit_block_move (validize_mem (arg->save_area), stack_area, GEN_INT (arg->size.constant), @@ -3518,6 +3754,14 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, } } } + + /* Now that we have saved any slots that will be overwritten by this + store, mark all slots this store will use. We must do this before + we actually expand the argument since the expansion itself may + trigger library calls which might need to use the same stack slot. */ + if (argblock && ! variable_size && arg->stack) + for (i = lower_bound; i < upper_bound; i++) + stack_usage_map[i] = 1; #endif /* If this isn't going to be placed on both the stack and in registers, @@ -3587,15 +3831,13 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, if (arg->value == arg->stack) { - /* If the value is already in the stack slot, we are done. */ - if (flag_check_memory_usage && GET_CODE (arg->stack) == MEM) + /* If the value is already in the stack slot, we are done moving + data. */ + if (current_function_check_memory_usage && GET_CODE (arg->stack) == MEM) { - if (arg->mode == BLKmode) - abort (); - emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, - XEXP (arg->stack, 0), ptr_mode, - GEN_INT (GET_MODE_SIZE (arg->mode)), + XEXP (arg->stack, 0), Pmode, + ARGS_SIZE_RTX (arg->size), TYPE_MODE (sizetype), GEN_INT (MEMORY_USE_RW), TYPE_MODE (integer_type_node)); @@ -3695,11 +3937,4 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size, fndecl, preserve_temp_slots (NULL_RTX); free_temp_slots (); pop_temp_slots (); - -#ifdef ACCUMULATE_OUTGOING_ARGS - /* Now mark the segment we just used. */ - if (argblock && ! variable_size && arg->stack) - for (i = lower_bound; i < upper_bound; i++) - stack_usage_map[i] = 1; -#endif } diff --git a/contrib/gcc/cccp.c b/contrib/gcc/cccp.c index 2e87c36..6e2d519 100644 --- a/contrib/gcc/cccp.c +++ b/contrib/gcc/cccp.c @@ -1,5 +1,5 @@ /* C Compatible Compiler Preprocessor (CCCP) - Copyright (C) 1986, 87, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1986, 87, 89, 92-98, 1999 Free Software Foundation, Inc. Written by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -19,21 +19,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" -#ifdef __STDC__ -# include -#else -# include -#endif - -#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n) - -#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2) -#define PRINTF_PROTO_2(ARGS) PRINTF_PROTO(ARGS, 2, 3) -#define PRINTF_PROTO_3(ARGS) PRINTF_PROTO(ARGS, 3, 4) -#define PRINTF_PROTO_4(ARGS) PRINTF_PROTO(ARGS, 4, 5) #include "system.h" -#include #include #ifdef HAVE_SYS_RESOURCE_H @@ -42,11 +29,17 @@ Boston, MA 02111-1307, USA. */ typedef unsigned char U_CHAR; -#include "gansidecl.h" #include "pcp.h" +#include "intl.h" +#include "prefix.h" + +#ifdef MULTIBYTE_CHARS +#include "mbchar.h" +#include +#endif /* MULTIBYTE_CHARS */ -#ifndef GET_ENVIRONMENT -#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME) +#ifndef GET_ENV_PATH_LIST +#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) #endif #ifndef STANDARD_INCLUDE_DIR @@ -58,6 +51,11 @@ typedef unsigned char U_CHAR; # define PATH_SEPARATOR ':' #endif +/* By default, a slash separates directory names. */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +#endif + /* By default, the suffix for object files is ".o". */ #ifdef OBJECT_SUFFIX # define HAVE_OBJECT_SUFFIX @@ -85,43 +83,11 @@ static int hack_vms_include_specification (); #endif /* VMS */ /* Windows does not natively support inodes, and neither does MSDOS. */ -#if (defined (_WIN32) && ! defined (CYGWIN32)) || defined (__MSDOS__) +#if (defined (_WIN32) && ! defined (__CYGWIN__) && ! defined (_UWIN)) \ + || defined (__MSDOS__) #define INO_T_EQ(a, b) 0 #endif -#undef MIN -#undef MAX -#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) -#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) - -/* Find the largest host integer type and set its size and type. - Watch out: on some crazy hosts `long' is shorter than `int'. */ - -#ifndef HOST_WIDE_INT -# if HAVE_INTTYPES_H -# include -# define HOST_WIDE_INT intmax_t -# else -# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT) -# define HOST_WIDE_INT int -# else -# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX)) -# define HOST_WIDE_INT long -# else -# define HOST_WIDE_INT long long -# endif -# endif -# endif -#endif - -#ifndef S_ISREG -#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -#ifndef S_ISDIR -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - #ifndef INO_T_EQ #define INO_T_EQ(a, b) ((a) == (b)) #endif @@ -137,9 +103,8 @@ static int hack_vms_include_specification (); /* External declarations. */ extern char *version_string; -extern char *update_path PROTO((char *, char *)); -HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT)); -HOST_WIDE_INT parse_c_expression PROTO((char *, int)); +HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT)); +HOST_WIDEST_INT parse_c_expression PROTO((char *, int)); /* Name under which this program was invoked. */ @@ -294,6 +259,10 @@ int traditional; int c89; +/* Nonzero for the 199x C Standard. */ + +int c9x; + /* Nonzero causes output not to be done, but directives such as #define that have side effects are still obeyed. */ @@ -414,49 +383,49 @@ static struct default_include { int cxx_aware; /* Includes in this directory don't need to be wrapped in extern "C" when compiling C++. */ + int included; /* Set if the directory is acceptable. */ } include_defaults_array[] #ifdef INCLUDE_DEFAULTS = INCLUDE_DEFAULTS; #else = { /* Pick up GNU C++ specific include files. */ - { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1 }, - { OLD_GPLUSPLUS_INCLUDE_DIR, 0, 1, 1 }, + { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0 }, #ifdef CROSS_COMPILE /* This is the dir for fixincludes. Put it just before the files that we fix. */ - { GCC_INCLUDE_DIR, "GCC", 0, 0 }, + { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 }, /* For cross-compilation, this dir name is generated automatically in Makefile.in. */ - { CROSS_INCLUDE_DIR, "GCC", 0, 0 }, + { CROSS_INCLUDE_DIR, "GCC", 0, 0, 0 }, #ifdef TOOL_INCLUDE_DIR /* This is another place that the target system's headers might be. */ - { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 }, + { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 }, #endif #else /* not CROSS_COMPILE */ #ifdef LOCAL_INCLUDE_DIR /* This should be /usr/local/include and should come before the fixincludes-fixed header files. */ - { LOCAL_INCLUDE_DIR, 0, 0, 1 }, + { LOCAL_INCLUDE_DIR, 0, 0, 1, 0 }, #endif #ifdef TOOL_INCLUDE_DIR /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here. Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */ - { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0 }, + { TOOL_INCLUDE_DIR, "BINUTILS", 0, 0, 0 }, #endif /* This is the dir for fixincludes. Put it just before the files that we fix. */ - { GCC_INCLUDE_DIR, "GCC", 0, 0 }, + { GCC_INCLUDE_DIR, "GCC", 0, 0, 0 }, /* Some systems have an extra dir of include files. */ #ifdef SYSTEM_INCLUDE_DIR - { SYSTEM_INCLUDE_DIR, 0, 0, 0 }, + { SYSTEM_INCLUDE_DIR, 0, 0, 0, 0 }, #endif #ifndef STANDARD_INCLUDE_COMPONENT #define STANDARD_INCLUDE_COMPONENT 0 #endif - { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0 }, + { STANDARD_INCLUDE_DIR, STANDARD_INCLUDE_COMPONENT, 0, 0, 0 }, #endif /* not CROSS_COMPILE */ - { 0, 0, 0, 0 } + { 0, 0, 0, 0, 0 } }; #endif /* no INCLUDE_DEFAULTS */ @@ -614,6 +583,11 @@ union hashval { static char rest_extension[] = "..."; #define REST_EXTENSION_LENGTH (sizeof (rest_extension) - 1) +/* This is the implicit parameter name when using variable number of + parameters for macros using the ISO C 9x extension. */ +static char va_args_name[] = "__VA_ARGS__"; +#define VA_ARGS_NAME_LENGTH (sizeof (va_args_name) - 1) + /* The structure of a node in the hash table. The hash table has entries for all tokens defined by #define directives (type T_MACRO), plus some special tokens like __LINE__ (these each have their own @@ -689,13 +663,6 @@ static HASHNODE *hashtab[HASHSIZE]; #define HASHSTEP(old, c) ((old << 2) + c) #define MAKE_POS(v) (v & 0x7fffffff) /* make number positive */ -/* Symbols to predefine. */ - -#ifdef CPP_PREDEFINES -static char *predefs = CPP_PREDEFINES; -#else -static char *predefs = ""; -#endif /* We let tm.h override the types used here, to handle trivial differences such as the choice of unsigned int or long unsigned int for size_t. @@ -728,6 +695,8 @@ char * wchar_type = WCHAR_TYPE; #ifndef USER_LABEL_PREFIX #define USER_LABEL_PREFIX "" #endif +char * user_label_prefix = USER_LABEL_PREFIX; +#undef USER_LABEL_PREFIX /* The string value for __REGISTER_PREFIX__ */ @@ -856,8 +825,6 @@ U_CHAR is_idstart[256]; static U_CHAR is_hor_space[256]; /* table to tell if c is horizontal or vertical space. */ U_CHAR is_space[256]; -/* names of some characters */ -static char *char_name[256]; #define SKIP_WHITE_SPACE(p) do { while (is_hor_space[*p]) p++; } while (0) #define SKIP_ALL_WHITE_SPACE(p) do { while (is_space[*p]) p++; } while (0) @@ -867,6 +834,10 @@ static int errors = 0; /* Error counter for exit code */ /* Name of output file, for error messages. */ static char *out_fname; +/* Nonzero to ignore \ in string constants. Use to treat #line 1 "A:\file.h + as a non-form feed. If you want it to be a form feed, you must use + # 1 "\f". */ +static int ignore_escape_flag = 1; /* Stack of conditionals currently in progress (including both successful and failing conditionals). */ @@ -903,7 +874,7 @@ static int ignore_srcdir; static int safe_read PROTO((int, char *, int)); static void safe_write PROTO((int, char *, int)); -static void eprint_string PROTO((char *, size_t)); +static void eprint_string PROTO((const char *, size_t)); int main PROTO((int, char **)); @@ -943,14 +914,14 @@ static void record_control_macro PROTO((struct include_file *, U_CHAR *)); static char *check_precompiled PROTO((int, struct stat *, char *, char **)); static int check_preconditions PROTO((char *)); -static void pcfinclude PROTO((U_CHAR *, U_CHAR *, U_CHAR *, FILE_BUF *)); +static void pcfinclude PROTO((U_CHAR *, U_CHAR *, FILE_BUF *)); static void pcstring_used PROTO((HASHNODE *)); static void write_output PROTO((void)); static void pass_thru_directive PROTO((U_CHAR *, U_CHAR *, FILE_BUF *, struct directive *)); static MACRODEF create_definition PROTO((U_CHAR *, U_CHAR *, FILE_BUF *)); -static int check_macro_name PROTO((U_CHAR *, char *)); +static int check_macro_name PROTO((U_CHAR *, int)); static int compare_defs PROTO((DEFINITION *, DEFINITION *)); static int comp_def_part PROTO((int, U_CHAR *, int, U_CHAR *, int, int)); @@ -968,7 +939,7 @@ static void delete_assertion PROTO((ASSERTION_HASHNODE *)); static void do_once PROTO((void)); -static HOST_WIDE_INT eval_if_expression PROTO((U_CHAR *, int)); +static HOST_WIDEST_INT eval_if_expression PROTO((U_CHAR *, int)); static void conditional_skip PROTO((FILE_BUF *, int, enum node_type, U_CHAR *, FILE_BUF *)); static void skip_if_group PROTO((FILE_BUF *, int, FILE_BUF *)); static void validate_else PROTO((U_CHAR *, U_CHAR *)); @@ -985,7 +956,7 @@ static void output_line_directive PROTO((FILE_BUF *, FILE_BUF *, int, enum file_ static void macroexpand PROTO((HASHNODE *, FILE_BUF *)); struct argdata; -static char *macarg PROTO((struct argdata *, int)); +static int macarg PROTO((struct argdata *, int)); static U_CHAR *macarg1 PROTO((U_CHAR *, U_CHAR *, struct hashnode *, int *, int *, int *, int)); @@ -994,18 +965,21 @@ static int discard_comments PROTO((U_CHAR *, int, int)); static int change_newlines PROTO((U_CHAR *, int)); static char *my_strerror PROTO((int)); -void error PRINTF_PROTO_1((char *, ...)); -static void verror PROTO((char *, va_list)); +static void notice PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +static void vnotice PROTO((const char *, va_list)); +void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void verror PROTO((const char *, va_list)); static void error_from_errno PROTO((char *)); -void warning PRINTF_PROTO_1((char *, ...)); -static void vwarning PROTO((char *, va_list)); -static void error_with_line PRINTF_PROTO_2((int, char *, ...)); -static void verror_with_line PROTO((int, char *, va_list)); -static void vwarning_with_line PROTO((int, char *, va_list)); -static void warning_with_line PRINTF_PROTO_2((int, char *, ...)); -void pedwarn PRINTF_PROTO_1((char *, ...)); -void pedwarn_with_line PRINTF_PROTO_2((int, char *, ...)); -static void pedwarn_with_file_and_line PRINTF_PROTO_4((char *, size_t, int, char *, ...)); +void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +static void vwarning PROTO((const char *, va_list)); +static void error_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2; +static void verror_with_line PROTO((int, const char *, va_list)); +static void vwarning_with_line PROTO((int, const char *, va_list)); +static void warning_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2; +void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void pedwarn_with_line PVPROTO((int, const char *, ...)) ATTRIBUTE_PRINTF_2; +static void pedwarn_with_file_and_line PVPROTO((const char *, size_t, int, const char *, ...)) ATTRIBUTE_PRINTF_4; +static void pedwarn_strange_white_space PROTO((int)); static void print_containing_files PROTO((void)); @@ -1025,28 +999,24 @@ static void dump_arg_n PROTO((DEFINITION *, int, FILE *)); static void initialize_char_syntax PROTO((void)); static void initialize_builtins PROTO((FILE_BUF *, FILE_BUF *)); -static void make_definition PROTO((char *, FILE_BUF *)); +static void make_definition PROTO((char *)); static void make_undef PROTO((char *, FILE_BUF *)); -static void make_assertion PROTO((char *, char *)); +static void make_assertion PROTO((const char *, const char *)); -static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, char *, char *, char *)); +static struct file_name_list *new_include_prefix PROTO((struct file_name_list *, const char *, const char *, const char *)); static void append_include_chain PROTO((struct file_name_list *, struct file_name_list *)); -static int quote_string_for_make PROTO((char *, char *)); -static void deps_output PROTO((char *, int)); +static int quote_string_for_make PROTO((char *, const char *)); +static void deps_output PROTO((const char *, int)); -static void fatal PRINTF_PROTO_1((char *, ...)) __attribute__ ((noreturn)); -void fancy_abort PROTO((void)) __attribute__ ((noreturn)); +void fatal PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; +void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; static void perror_with_name PROTO((char *)); -static void pfatal_with_name PROTO((char *)) __attribute__ ((noreturn)); -static void pipe_closed PROTO((int)) __attribute__ ((noreturn)); - -static void memory_full PROTO((void)) __attribute__ ((noreturn)); -GENERIC_PTR xmalloc PROTO((size_t)); -static GENERIC_PTR xrealloc PROTO((GENERIC_PTR, size_t)); -static GENERIC_PTR xcalloc PROTO((size_t, size_t)); -static char *savestring PROTO((char *)); +static void pfatal_with_name PROTO((char *)) ATTRIBUTE_NORETURN; +static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN; + +static void memory_full PROTO((void)) ATTRIBUTE_NORETURN; static void print_help PROTO((void)); /* Read LEN bytes at PTR from descriptor DESC, for file FILENAME, @@ -1128,7 +1098,7 @@ safe_write (desc, ptr, len) static void eprint_string (string, length) - char *string; + const char *string; size_t length; { size_t segment_length; @@ -1167,12 +1137,15 @@ print_help () printf (" -traditional Follow K&R pre-processor behaviour\n"); printf (" -trigraphs Support ANSI C trigraphs\n"); printf (" -lang-c Assume that the input sources are in C\n"); - printf (" -lang-c89 Assume that the input sources are in C89\n"); + printf (" -lang-c89 Assume that the input is C89; depricated\n"); printf (" -lang-c++ Assume that the input sources are in C++\n"); printf (" -lang-objc Assume that the input sources are in ObjectiveC\n"); printf (" -lang-objc++ Assume that the input sources are in ObjectiveC++\n"); printf (" -lang-asm Assume that the input sources are in assembler\n"); printf (" -lang-chill Assume that the input sources are in Chill\n"); + printf (" -std= Specify the conformance standard; one of:\n"); + printf (" gnu89, gnu9x, c89, c9x, iso9899:1990,\n"); + printf (" iso9899:199409, iso9899:199x\n"); printf (" -+ Allow parsing of C++ style features\n"); printf (" -w Inhibit warning messages\n"); printf (" -Wtrigraphs Warn if trigraphs are encountered\n"); @@ -1180,10 +1153,10 @@ print_help () printf (" -Wcomment{s} Warn if one comment starts inside another\n"); printf (" -Wno-comment{s} Do not warn about comments\n"); printf (" -Wtraditional Warn if a macro argument is/would be turned into\n"); - printf (" a string if -tradtional is specified\n"); + printf (" a string if -traditional is specified\n"); printf (" -Wno-traditional Do not warn about stringification\n"); printf (" -Wundef Warn if an undefined macro is used by #if\n"); - printf (" -Wno-undef Do not warn about testing udefined macros\n"); + printf (" -Wno-undef Do not warn about testing undefined macros\n"); printf (" -Wimport Warn about the use of the #import directive\n"); printf (" -Wno-import Do not warn about the use of #import\n"); printf (" -Werror Treat all warnings as errors\n"); @@ -1224,17 +1197,17 @@ main (argc, argv) char *cp; int f, i; FILE_BUF *fp; - char **pend_files = (char **) xmalloc (argc * sizeof (char *)); - char **pend_defs = (char **) xmalloc (argc * sizeof (char *)); - char **pend_undefs = (char **) xmalloc (argc * sizeof (char *)); - char **pend_assertions = (char **) xmalloc (argc * sizeof (char *)); - char **pend_includes = (char **) xmalloc (argc * sizeof (char *)); + + char **pend_files; + char **pend_defs; + char **pend_undefs; + char **pend_assertions; + char **pend_includes; /* Record the option used with each element of pend_assertions. This is preparation for supporting more than one option for making an assertion. */ - char **pend_assertion_options = (char **) xmalloc (argc * sizeof (char *)); - int inhibit_predefs = 0; + char **pend_assertion_options; int no_standard_includes = 0; int no_standard_cplusplus_includes = 0; int missing_newline = 0; @@ -1271,13 +1244,19 @@ main (argc, argv) signal (SIGPIPE, pipe_closed); #endif +#ifdef HAVE_LC_MESSAGES + setlocale (LC_MESSAGES, ""); +#endif + (void) bindtextdomain (PACKAGE, localedir); + (void) textdomain (PACKAGE); + progname = base_name (argv[0]); #ifdef VMS { /* Remove extension from PROGNAME. */ char *p; - char *s = progname = savestring (progname); + char *s = progname = xstrdup (progname); if ((p = rindex (s, ';')) != 0) *p = '\0'; /* strip version number */ if ((p = rindex (s, '.')) != 0 /* strip type iff ".exe" */ @@ -1289,6 +1268,16 @@ main (argc, argv) } #endif + /* Do not invoke xmalloc before this point, since locale and + progname need to be set first, in case a diagnostic is issued. */ + + pend_files = (char **) xmalloc (argc * sizeof (char *)); + pend_defs = (char **) xmalloc (argc * sizeof (char *)); + pend_undefs = (char **) xmalloc (argc * sizeof (char *)); + pend_assertions = (char **) xmalloc (argc * sizeof (char *)); + pend_includes = (char **) xmalloc (argc * sizeof (char *)); + pend_assertion_options = (char **) xmalloc (argc * sizeof (char *)); + in_fname = NULL; out_fname = NULL; @@ -1308,6 +1297,12 @@ main (argc, argv) bzero ((char *) pend_assertions, argc * sizeof (char *)); bzero ((char *) pend_includes, argc * sizeof (char *)); +#ifdef MULTIBYTE_CHARS + /* Change to the native locale for multibyte conversions. */ + setlocale (LC_CTYPE, ""); + literal_codeset = getenv ("LANG"); +#endif + /* Process switches and find input file name. */ for (i = 1; i < argc; i++) { @@ -1373,7 +1368,7 @@ main (argc, argv) if (include_prefix != 0) prefix = include_prefix; else { - prefix = savestring (GCC_INCLUDE_DIR); + prefix = xstrdup (GCC_INCLUDE_DIR); /* Remove the `include' from /usr/local/lib/gcc.../include. */ if (!strcmp (prefix + strlen (prefix) - 8, "/include")) prefix[strlen (prefix) - 7] = 0; @@ -1398,7 +1393,7 @@ main (argc, argv) if (include_prefix != 0) prefix = include_prefix; else { - prefix = savestring (GCC_INCLUDE_DIR); + prefix = xstrdup (GCC_INCLUDE_DIR); /* Remove the `include' from /usr/local/lib/gcc.../include. */ if (!strcmp (prefix + strlen (prefix) - 8, "/include")) prefix[strlen (prefix) - 7] = 0; @@ -1465,18 +1460,18 @@ main (argc, argv) case 'l': if (! strcmp (argv[i], "-lang-c")) - cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 0; - if (! strcmp (argv[i], "-lang-c89")) - cplusplus = 0, cplusplus_comments = 0, c89 = 1, objc = 0; - if (! strcmp (argv[i], "-lang-c++")) - cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 0; - if (! strcmp (argv[i], "-lang-objc")) - cplusplus = 0, cplusplus_comments = 1, c89 = 0, objc = 1; - if (! strcmp (argv[i], "-lang-objc++")) - cplusplus = 1, cplusplus_comments = 1, c89 = 0, objc = 1; - if (! strcmp (argv[i], "-lang-asm")) + cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0; + else if (! strcmp (argv[i], "-lang-c89")) + cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0; + else if (! strcmp (argv[i], "-lang-c++")) + cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 0; + else if (! strcmp (argv[i], "-lang-objc")) + cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1; + else if (! strcmp (argv[i], "-lang-objc++")) + cplusplus = 1, cplusplus_comments = 1, c89 = 0, c9x = 0, objc = 1; + else if (! strcmp (argv[i], "-lang-asm")) lang_asm = 1; - if (! strcmp (argv[i], "-lint")) + else if (! strcmp (argv[i], "-lint")) for_lint = 1; break; @@ -1484,6 +1479,18 @@ main (argc, argv) cplusplus = 1, cplusplus_comments = 1; break; + case 's': + if (!strcmp (argv[i], "-std=iso9899:1990") + || !strcmp (argv[i], "-std=iso9899:199409") + || !strcmp (argv[i], "-std=c89") + || !strcmp (argv[i], "-std=gnu89")) + cplusplus = 0, cplusplus_comments = 0, c89 = 1, c9x = 0, objc = 0; + else if (!strcmp (argv[i], "-std=iso9899:199x") + || !strcmp (argv[i], "-std=c9x") + || !strcmp (argv[i], "-std=gnu9x")) + cplusplus = 0, cplusplus_comments = 1, c89 = 0, c9x = 1, objc = 0; + break; + case 'w': inhibit_warnings = 1; break; @@ -1524,6 +1531,13 @@ main (argc, argv) } break; + case 'f': + if (!strcmp (argv[i], "-fleading-underscore")) + user_label_prefix = "_"; + else if (!strcmp (argv[i], "-fno-leading-underscore")) + user_label_prefix = ""; + break; + case 'M': /* The style of the choices here is a bit mixed. The chosen scheme is a hybrid of keeping all options in one string @@ -1604,7 +1618,7 @@ main (argc, argv) break; case 'v': - fprintf (stderr, "GNU CPP version %s", version_string); + notice ("GNU CPP version %s", version_string); #ifdef TARGET_VERSION TARGET_VERSION; #endif @@ -1642,7 +1656,6 @@ main (argc, argv) on the command line. That way we can get rid of any that were passed automatically in from GCC. */ int j; - inhibit_predefs = 1; for (j = 0; j < i; j++) pend_defs[j] = pend_assertions[j] = 0; } else { @@ -1710,12 +1723,6 @@ main (argc, argv) remap = 1; break; - case 'u': - /* Sun compiler passes undocumented switch "-undef". - Let's assume it means to inhibit the predefined symbols. */ - inhibit_predefs = 1; - break; - case '\0': /* JF handle '-' as file name meaning stdin or stdout */ if (in_fname == NULL) { in_fname = ""; @@ -1737,7 +1744,7 @@ main (argc, argv) /* Some people say that CPATH should replace the standard include dirs, but that seems pointless: it comes before them, so it overrides them anyway. */ - GET_ENVIRONMENT (cp, "CPATH"); + GET_ENV_PATH_LIST (cp, "CPATH"); if (cp && ! no_standard_includes) path_include (cp); @@ -1766,135 +1773,6 @@ main (argc, argv) and option processing. */ initialize_builtins (fp, &outbuf); - /* Do standard #defines and assertions - that identify system and machine type. */ - - if (!inhibit_predefs) { - char *p = (char *) alloca (strlen (predefs) + 1); - -#ifdef VMS - struct dsc$descriptor_s lcl_name; - struct item_list { - unsigned short length; /* input length */ - unsigned short code; /* item code */ - unsigned long dptr; /* data ptr */ - unsigned long lptr; /* output length ptr */ - }; - - unsigned long syi_length; - char syi_data[16]; - - struct item_list items[] = { - { 16, SYI$_VERSION, 0, 0 }, - { 0, 0, 0, 0 } - }; - - items[0].dptr = (unsigned long)syi_data; - items[0].lptr = (unsigned long)(&syi_length); - - if (SYS$GETSYIW (0, 0, 0, items, NULL, NULL, NULL, NULL) == SS$_NORMAL) - { - unsigned long vms_version_value; - char *vers; - - vers = syi_data; - vms_version_value = 0; - - if (*vers == 'V') - vers++; - if (ISDIGIT (*vers)) - { - vms_version_value = (*vers - '0') * 10000000; - } - vers++; - if (*vers == '.') - { - vers++; - if (ISDIGIT (*vers)) - { - vms_version_value += (*vers - '0') * 100000; - } - } - - if (vms_version_value > 0) - { - char versbuf[32]; - - sprintf (versbuf, "__VMS_VER=%08ld", vms_version_value); - if (debug_output) - output_line_directive (fp, &outbuf, 0, same_file); - make_definition (versbuf, &outbuf); - } - } -#endif - - strcpy (p, predefs); - while (*p) { - char *q; - while (*p == ' ' || *p == '\t') - p++; - /* Handle -D options. */ - if (p[0] == '-' && p[1] == 'D') { - q = &p[2]; - while (*p && *p != ' ' && *p != '\t') - p++; - if (*p != 0) - *p++= 0; - if (debug_output) - output_line_directive (fp, &outbuf, 0, same_file); - make_definition (q, &outbuf); - while (*p == ' ' || *p == '\t') - p++; - } else if (p[0] == '-' && p[1] == 'A') { - /* Handle -A options (assertions). */ - char *assertion; - char *past_name; - char *value; - char *past_value; - char *termination; - int save_char; - - assertion = &p[2]; - past_name = assertion; - /* Locate end of name. */ - while (*past_name && *past_name != ' ' - && *past_name != '\t' && *past_name != '(') - past_name++; - /* Locate `(' at start of value. */ - value = past_name; - while (*value && (*value == ' ' || *value == '\t')) - value++; - if (*value++ != '(') - abort (); - while (*value && (*value == ' ' || *value == '\t')) - value++; - past_value = value; - /* Locate end of value. */ - while (*past_value && *past_value != ' ' - && *past_value != '\t' && *past_value != ')') - past_value++; - termination = past_value; - while (*termination && (*termination == ' ' || *termination == '\t')) - termination++; - if (*termination++ != ')') - abort (); - if (*termination && *termination != ' ' && *termination != '\t') - abort (); - /* Temporarily null-terminate the value. */ - save_char = *termination; - *termination = '\0'; - /* Install the assertion. */ - make_assertion ("-A", assertion); - *termination = (char) save_char; - p = termination; - while (*p == ' ' || *p == '\t') - p++; - } else { - abort (); - } - } - } - /* Now handle the command line options. */ /* Do -U's, -D's and -A's in the order they were seen. */ @@ -1907,7 +1785,7 @@ main (argc, argv) if (pend_defs[i]) { if (debug_output) output_line_directive (fp, &outbuf, 0, same_file); - make_definition (pend_defs[i], &outbuf); + make_definition (pend_defs[i]); } if (pend_assertions[i]) make_assertion (pend_assertion_options[i], pend_assertions[i]); @@ -1921,16 +1799,16 @@ main (argc, argv) switch ((objc << 1) + cplusplus) { case 0: - GET_ENVIRONMENT (epath, "C_INCLUDE_PATH"); + GET_ENV_PATH_LIST (epath, "C_INCLUDE_PATH"); break; case 1: - GET_ENVIRONMENT (epath, "CPLUS_INCLUDE_PATH"); + GET_ENV_PATH_LIST (epath, "CPLUS_INCLUDE_PATH"); break; case 2: - GET_ENVIRONMENT (epath, "OBJC_INCLUDE_PATH"); + GET_ENV_PATH_LIST (epath, "OBJC_INCLUDE_PATH"); break; case 3: - GET_ENVIRONMENT (epath, "OBJCPLUS_INCLUDE_PATH"); + GET_ENV_PATH_LIST (epath, "OBJCPLUS_INCLUDE_PATH"); break; } /* If the environment var for this language is set, @@ -1953,7 +1831,7 @@ main (argc, argv) if (c == PATH_SEPARATOR || !c) { endp[-1] = 0; include_defaults[num_dirs].fname - = startp == endp ? "." : savestring (startp); + = startp == endp ? "." : xstrdup (startp); endp[-1] = c; include_defaults[num_dirs].component = 0; include_defaults[num_dirs].cplusplus = cplusplus; @@ -1979,7 +1857,7 @@ main (argc, argv) if (!no_standard_includes) { struct default_include *p = include_defaults; char *specd_prefix = include_prefix; - char *default_prefix = savestring (GCC_INCLUDE_DIR); + char *default_prefix = xstrdup (GCC_INCLUDE_DIR); int default_len = 0; /* Remove the `include' from /usr/local/lib/gcc.../include. */ if (!strcmp (default_prefix + strlen (default_prefix) - 8, "/include")) { @@ -2003,6 +1881,7 @@ main (argc, argv) append_include_chain (new, new); if (first_system_include == 0) first_system_include = new; + p->included = 1; } } } @@ -2018,6 +1897,7 @@ main (argc, argv) append_include_chain (new, new); if (first_system_include == 0) first_system_include = new; + p->included = 1; } } } @@ -2031,10 +1911,10 @@ main (argc, argv) /* With -v, print the list of dirs to search. */ if (verbose) { struct file_name_list *p; - fprintf (stderr, "#include \"...\" search starts here:\n"); + notice ("#include \"...\" search starts here:\n"); for (p = include; p; p = p->next) { if (p == first_bracket_include) - fprintf (stderr, "#include <...> search starts here:\n"); + notice ("#include <...> search starts here:\n"); if (!p->fname[0]) fprintf (stderr, " .\n"); else if (!strcmp (p->fname, "/") || !strcmp (p->fname, "//")) @@ -2043,7 +1923,15 @@ main (argc, argv) /* Omit trailing '/'. */ fprintf (stderr, " %.*s\n", (int) strlen (p->fname) - 1, p->fname); } - fprintf (stderr, "End of search list.\n"); + notice ("End of search list.\n"); + { + struct default_include * d; + notice ("The following default directories have been omitted from the search path:\n"); + for (d = include_defaults; d->fname; d++) + if (! d->included) + fprintf (stderr, " %s\n", d->fname); + notice ("End of omitted list.\n"); + } } /* -MG doesn't select the form of output and must be specified with one of @@ -2528,7 +2416,7 @@ get_lintcmd (ibp, limit, argstart, arglen, cmdlen) U_CHAR **argstart; /* point to command arg */ int *arglen, *cmdlen; /* how long they are */ { - HOST_WIDE_INT linsize; + HOST_WIDEST_INT linsize; register U_CHAR *numptr; /* temp for arg parsing */ *arglen = 0; @@ -2774,9 +2662,27 @@ do { ip = &instack[indepth]; \ bp += 2; else if (*bp == '/' && bp[1] == '*') { bp += 2; - while (!(*bp == '*' && bp[1] == '/')) - bp++; - bp += 2; + while (1) + { + if (*bp == '*') + { + if (bp[1] == '/') + { + bp += 2; + break; + } + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, limit - bp); + if (length > 1) + bp += (length - 1); +#endif + } + bp++; + } } /* There is no point in trying to deal with C++ // comments here, because if there is one, then this # must be part of the @@ -2937,6 +2843,24 @@ do { ip = &instack[indepth]; \ if (ibp[-1] == c) goto while2end; break; +#ifdef MULTIBYTE_CHARS + default: + { + int length; + --ibp; + length = local_mblen (ibp, limit - ibp); + if (length > 0) + { + --obp; + bcopy (ibp, obp, length); + obp += length; + ibp += length; + } + else + ++ibp; + } + break; +#endif } } while2end: @@ -2965,24 +2889,39 @@ do { ip = &instack[indepth]; \ U_CHAR *before_bp = ibp; while (++ibp < limit) { - if (*ibp == '\n') { - if (ibp[-1] != '\\') { + if (*ibp == '\n') + { if (put_out_comments) { bcopy ((char *) before_bp, (char *) obp, ibp - before_bp); obp += ibp - before_bp; } break; } - if (warn_comments) - warning ("multiline `//' comment"); - ++ip->lineno; - /* Copy the newline into the output buffer, in order to - avoid the pain of a #line every time a multiline comment - is seen. */ - if (!put_out_comments) - *obp++ = '\n'; - ++op->lineno; - } + if (*ibp == '\\') + { + if (ibp + 1 < limit && ibp[1] == '\n') + { + if (warn_comments) + warning ("multiline `//' comment"); + ++ip->lineno; + /* Copy the newline into the output buffer, in order to + avoid the pain of a #line every time a multiline comment + is seen. */ + if (!put_out_comments) + *obp++ = '\n'; + ++op->lineno; + ++ibp; + } + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + ibp += (length - 1); +#endif + } } break; } @@ -3071,6 +3010,16 @@ do { ip = &instack[indepth]; \ goto limit_reached; } break; +#ifdef MULTIBYTE_CHARS + default: + { + int length; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + ibp += (length - 1); + } + break; +#endif } } comment_end: @@ -3433,11 +3382,27 @@ randomchar: break; } } - if (*ibp == '\n') { + else if (*ibp == '\n') { /* Newline in a file. Count it. */ ++ip->lineno; ++op->lineno; } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + { + if (put_out_comments) + { + bcopy (ibp, obp, length - 1); + obp += length - 1; + } + ibp += (length - 1); + } +#endif + } if (put_out_comments) *obp++ = *ibp; } @@ -3448,9 +3413,34 @@ randomchar: } else if (! traditional) { *obp++ = ' '; } - for (ibp += 2; *ibp != '\n' || ibp[-1] == '\\'; ibp++) - if (put_out_comments) - *obp++ = *ibp; + for (ibp += 2; ; ibp++) + { + if (*ibp == '\n') + break; + if (*ibp == '\\' && ibp[1] == '\n') + { + if (put_out_comments) + *obp++ = *ibp++; + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + { + if (put_out_comments) + { + bcopy (ibp, obp, length - 1); + obp += length - 1; + } + ibp += (length - 1); + } +#endif + } + if (put_out_comments) + *obp++ = *ibp; + } } else break; } @@ -3679,11 +3669,13 @@ handle_directive (ip, op) /* Record where the directive started. do_xifdef needs this. */ directive_start = bp - 1; + ignore_escape_flag = 1; + /* Skip whitespace and \-newline. */ while (1) { if (is_hor_space[*bp]) { if (*bp != ' ' && *bp != '\t' && pedantic) - pedwarn ("%s in preprocessing directive", char_name[*bp]); + pedwarn_strange_white_space (*bp); bp++; } else if (*bp == '/') { if (bp[1] == '\\' && bp[2] == '\n') @@ -3741,6 +3733,7 @@ handle_directive (ip, op) pedwarn ("`#' followed by integer"); after_ident = ident; kt = line_directive_table; + ignore_escape_flag = 0; goto old_linenum; } @@ -3885,7 +3878,7 @@ handle_directive (ip, op) case '\r': case '\v': if (pedantic) - pedwarn ("%s in preprocessing directive", char_name[c]); + pedwarn_strange_white_space (c); break; case '\n': @@ -3905,7 +3898,8 @@ handle_directive (ip, op) /* If a directive should be copied through, and -C was given, pass it through before removing comments. */ if (!no_output && put_out_comments - && (kt->type == T_DEFINE ? dump_macros == dump_definitions + && ((kt->type == T_DEFINE || kt->type == T_UNDEF) + ? dump_macros == dump_definitions : IS_INCLUDE_DIRECTIVE_TYPE (kt->type) ? dump_includes : kt->type == T_PRAGMA)) { int len; @@ -3987,11 +3981,33 @@ handle_directive (ip, op) case '\'': case '\"': { + int backslash_newlines_p; + register U_CHAR *bp1 = skip_quoted_string (xp - 1, bp, ip->lineno, - NULL_PTR, NULL_PTR, NULL_PTR); - while (xp != bp1) - *cp++ = *xp++; + NULL_PTR, &backslash_newlines_p, + NULL_PTR); + if (backslash_newlines_p) + while (xp != bp1) + { + /* With something like: + + #define X "a\ + b" + + we should still remove the backslash-newline + pair as part of phase two. */ + if (xp[0] == '\\' && xp[1] == '\n') + xp += 2; + else + *cp++ = *xp++; + } + else + /* This is the same as the loop above, but taking + advantage of the fact that we know there are no + backslash-newline pairs. */ + while (xp != bp1) + *cp++ = *xp++; } break; @@ -4175,7 +4191,7 @@ special_symbol (hp, op) break; case T_USER_LABEL_PREFIX_TYPE: - buf = USER_LABEL_PREFIX; + buf = user_label_prefix; break; case T_REGISTER_PREFIX_TYPE: @@ -4326,16 +4342,18 @@ do_include (buf, limit, op, keyword) && !instack[indepth].system_header_p && !import_warning) { import_warning = 1; warning ("using `#import' is not recommended"); - fprintf (stderr, "The fact that a certain header file need not be processed more than once\n"); - fprintf (stderr, "should be indicated in the header file, not where it is used.\n"); - fprintf (stderr, "The best way to do this is with a conditional of this form:\n\n"); - fprintf (stderr, " #ifndef _FOO_H_INCLUDED\n"); - fprintf (stderr, " #define _FOO_H_INCLUDED\n"); - fprintf (stderr, " ... ...\n"); - fprintf (stderr, " #endif /* Not _FOO_H_INCLUDED */\n\n"); - fprintf (stderr, "Then users can use `#include' any number of times.\n"); - fprintf (stderr, "GNU C automatically avoids processing the file more than once\n"); - fprintf (stderr, "when it is equipped with such a conditional.\n"); + notice ("The fact that a certain header file need not be processed more than once\n\ +should be indicated in the header file, not where it is used.\n\ +The best way to do this is with a conditional of this form:\n\ +\n\ + #ifndef _FOO_H_INCLUDED\n\ + #define _FOO_H_INCLUDED\n\ + ... ...\n\ + #endif /* Not _FOO_H_INCLUDED */\n\ +\n\ +Then users can use `#include' any number of times.\n\ +GNU C automatically avoids processing the file more than once\n\ +when it is equipped with such a conditional.\n"); } get_filename: @@ -4707,8 +4725,7 @@ get_filename: if (pcfbuf) { pcfname = xmalloc (strlen (pcftry) + 1); strcpy (pcfname, pcftry); - pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) pcfbuflimit, - (U_CHAR *) fname, op); + pcfinclude ((U_CHAR *) pcfbuf, (U_CHAR *) fname, op); } else finclude (f, inc, op, is_system_include (fname), searchptr); @@ -4774,10 +4791,11 @@ static int absolute_filename (filename) char *filename; { -#if defined (__MSDOS__) || (defined (_WIN32) && !defined (__CYGWIN32__)) +#if defined (__MSDOS__) \ + || (defined (_WIN32) && !defined (__CYGWIN__) && !defined (_UWIN)) if (ISALPHA (filename[0]) && filename[1] == ':') filename += 2; #endif -#if defined (__CYGWIN32__) +#if defined (__CYGWIN__) /* At present, any path that begins with a drive spec is absolute. */ if (ISALPHA (filename[0]) && filename[1] == ':') return 1; #endif @@ -4791,6 +4809,20 @@ absolute_filename (filename) return 0; } +/* Returns whether or not a given character is a directory separator. + Used by simplify_filename. */ +static inline +int +is_dir_separator(ch) + char ch; +{ + return (ch == DIR_SEPARATOR) +#if defined (DIR_SEPARATOR_2) + || (ch == DIR_SEPARATOR_2) +#endif + ; +} + /* Remove unnecessary characters from FILENAME in place, to avoid unnecessary filename aliasing. Return the length of the resulting string. @@ -4808,55 +4840,59 @@ simplify_filename (filename) char *to0; /* Remove redundant initial /s. */ - if (*from == '/') { - *to++ = '/'; - if (*++from == '/') { - if (*++from == '/') { - /* 3 or more initial /s are equivalent to 1 /. */ - while (*++from == '/') - continue; - } else { - /* On some hosts // differs from /; Posix allows this. */ - static int slashslash_vs_slash; - if (slashslash_vs_slash == 0) { - struct stat s1, s2; - slashslash_vs_slash = ((stat ("/", &s1) == 0 && stat ("//", &s2) == 0 - && INO_T_EQ (s1.st_ino, s2.st_ino) - && s1.st_dev == s2.st_dev) - ? 1 : -1); - } - if (slashslash_vs_slash < 0) - *to++ = '/'; - } + if (is_dir_separator (*from)) + { + *to++ = DIR_SEPARATOR; + if (is_dir_separator (*++from)) + { + if (is_dir_separator (*++from)) + { + /* 3 or more initial /s are equivalent to 1 /. */ + while (is_dir_separator (*++from)) + continue; + } + else + { + /* On some hosts // differs from /; Posix allows this. */ + *to++ = DIR_SEPARATOR; + } + } } - } + to0 = to; - for (;;) { + for (;;) + { #ifndef VMS - if (from[0] == '.' && from[1] == '/') - from += 2; - else + if (from[0] == '.' && from[1] == '/') + from += 2; + else #endif - { - /* Copy this component and trailing /, if any. */ - while ((*to++ = *from++) != '/') { - if (!to[-1]) { - /* Trim . component at end of nonempty name. */ - to -= filename <= to - 3 && to[-3] == '/' && to[-2] == '.'; - - /* Trim unnecessary trailing /s. */ - while (to0 < --to && to[-1] == '/') - continue; - - *to = 0; - return to - filename; - } - } - } + { + /* Copy this component and trailing DIR_SEPARATOR, if any. */ + while (!is_dir_separator (*to++ = *from++)) + { + if (!to[-1]) + { + /* Trim . component at end of nonempty name. */ + to -= filename <= to - 3 && to[-3] == DIR_SEPARATOR && to[-2] == '.'; + + /* Trim unnecessary trailing /s. */ + while (to0 < --to && to[-1] == DIR_SEPARATOR) + continue; + + *to = 0; + return to - filename; + } + } +#if defined(DIR_SEPARATOR_2) + /* Simplify to one directory separator. */ + to[-1] = DIR_SEPARATOR; +#endif + } /* Skip /s after a /. */ - while (*from == '/') + while (is_dir_separator (*from)) from++; } } @@ -4939,7 +4975,7 @@ read_name_map (dirname) map_list_ptr = ((struct file_name_map_list *) xmalloc (sizeof (struct file_name_map_list))); - map_list_ptr->map_list_name = savestring (dirname); + map_list_ptr->map_list_name = xstrdup (dirname); map_list_ptr->map_list_map = NULL; dirlen = strlen (dirname); @@ -5415,8 +5451,8 @@ check_preconditions (prec) in. OP is the main output buffer. */ static void -pcfinclude (buf, limit, name, op) - U_CHAR *buf, *limit, *name; +pcfinclude (buf, name, op) + U_CHAR *buf, *name; FILE_BUF *op; { FILE_BUF tmpbuf; @@ -5603,7 +5639,7 @@ pass_thru_directive (buf, limit, op, keyword) FILE_BUF *op; struct directive *keyword; { - register unsigned keyword_length = keyword->length; + register int keyword_length = keyword->length; check_expand (op, 1 + keyword_length + (limit - buf)); *op->bufp++ = '#'; @@ -5667,7 +5703,7 @@ create_definition (buf, limit, op) bp++; symname = bp; /* remember where it starts */ - sym_length = check_macro_name (bp, "macro"); + sym_length = check_macro_name (bp, 0); bp += sym_length; /* Lossage will occur if identifiers or control keywords are broken @@ -5697,13 +5733,24 @@ create_definition (buf, limit, op) rest_extension); if (!is_idstart[*bp]) + { + if (c9x && limit - bp > (long) REST_EXTENSION_LENGTH + && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) + { + /* This is the ISO C 9x way to write macros with variable + number of arguments. */ + rest_args = 1; + temp->rest_args = 1; + } + else pedwarn ("invalid character in macro parameter name"); + } /* Find the end of the arg name. */ while (is_idchar[*bp]) { bp++; /* do we have a "special" rest-args extension here? */ - if (limit - bp > REST_EXTENSION_LENGTH + if (limit - bp > (long) REST_EXTENSION_LENGTH && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0) { if (pedantic && !instack[indepth].system_header_p) pedwarn ("ANSI C does not allow macro with variable arguments"); @@ -5712,6 +5759,13 @@ create_definition (buf, limit, op) break; } } + if (bp == temp->name && rest_args == 1) + { + /* This is the ISO C 9x style. */ + temp->name = (U_CHAR *) va_args_name; + temp->length = VA_ARGS_NAME_LENGTH; + } + else temp->length = bp - temp->name; if (rest_args == 1) bp += REST_EXTENSION_LENGTH; @@ -5725,7 +5779,9 @@ create_definition (buf, limit, op) bp++; SKIP_WHITE_SPACE (bp); /* A comma at this point can only be followed by an identifier. */ - if (!is_idstart[*bp]) { + if (!is_idstart[*bp] + && !(c9x && limit - bp > (long) REST_EXTENSION_LENGTH + && bcmp (rest_extension, bp, REST_EXTENSION_LENGTH) == 0)) { error ("badly punctuated parameter list in `#define'"); goto nope; } @@ -5739,11 +5795,19 @@ create_definition (buf, limit, op) for (otemp = temp->next; otemp != NULL; otemp = otemp->next) if (temp->length == otemp->length - && bcmp (temp->name, otemp->name, temp->length) == 0) { + && bcmp (temp->name, otemp->name, temp->length) == 0) + { error ("duplicate argument name `%.*s' in `#define'", temp->length, temp->name); goto nope; } + if (rest_args == 0 && temp->length == VA_ARGS_NAME_LENGTH + && bcmp (temp->name, va_args_name, VA_ARGS_NAME_LENGTH) == 0) + { + error ("\ +reserved name `%s' used as argument name in `#define'", va_args_name); + goto nope; + } } } @@ -5890,12 +5954,12 @@ nope: } /* Check a purported macro name SYMNAME, and yield its length. - USAGE is the kind of name this is intended for. */ + ASSERTION is nonzero if this is really for an assertion name. */ static int -check_macro_name (symname, usage) +check_macro_name (symname, assertion) U_CHAR *symname; - char *usage; + int assertion; { U_CHAR *p; int sym_length; @@ -5905,10 +5969,13 @@ check_macro_name (symname, usage) sym_length = p - symname; if (sym_length == 0 || (sym_length == 1 && *symname == 'L' && (*p == '\'' || *p == '"'))) - error ("invalid %s name", usage); + error (assertion ? "invalid assertion name" : "invalid macro name"); else if (!is_idstart[*symname] || (sym_length == 7 && ! bcmp (symname, "defined", 7))) - error ("invalid %s name `%.*s'", usage, sym_length, symname); + error ((assertion + ? "invalid assertion name `%.*s'" + : "invalid macro name `%.*s'"), + sym_length, symname); return sym_length; } @@ -6186,6 +6253,25 @@ collect_expansion (buf, end, nargs, arglist) } } +#ifdef MULTIBYTE_CHARS + /* Handle multibyte characters inside string and character literals. */ + if (expected_delimiter != '\0') + { + int length; + --p; + length = local_mblen (p, limit - p); + if (length > 1) + { + --exp_p; + bcopy (p, exp_p, length); + p += length; + exp_p += length; + continue; + } + ++p; + } +#endif + /* Handle the start of a symbol. */ if (is_idchar[c] && nargs > 0) { U_CHAR *id_beg = p - 1; @@ -6315,7 +6401,7 @@ do_assert (buf, limit, op, keyword) bp++; symname = bp; /* remember where it starts */ - sym_length = check_macro_name (bp, "assertion"); + sym_length = check_macro_name (bp, 1); bp += sym_length; /* #define doesn't do this, but we should. */ SKIP_WHITE_SPACE (bp); @@ -6394,7 +6480,7 @@ do_unassert (buf, limit, op, keyword) bp++; symname = bp; /* remember where it starts */ - sym_length = check_macro_name (bp, "assertion"); + sym_length = check_macro_name (bp, 1); bp += sym_length; /* #define doesn't do this, but we should. */ SKIP_WHITE_SPACE (bp); @@ -6767,15 +6853,16 @@ do_line (buf, limit, op, keyword) return 0; case '\\': - { - char *bpc = (char *) bp; - HOST_WIDE_INT c = parse_escape (&bpc, (HOST_WIDE_INT) (U_CHAR) (-1)); - bp = (U_CHAR *) bpc; - if (c < 0) - p--; - else - p[-1] = c; - } + if (! ignore_escape_flag) + { + char *bpc = (char *) bp; + HOST_WIDEST_INT c = parse_escape (&bpc, (HOST_WIDEST_INT) (U_CHAR) (-1)); + bp = (U_CHAR *) bpc; + if (c < 0) + p--; + else + p[-1] = c; + } break; case '\"': @@ -6868,7 +6955,7 @@ do_undef (buf, limit, op, keyword) pass_thru_directive (buf, limit, op, keyword); SKIP_WHITE_SPACE (buf); - sym_length = check_macro_name (buf, "macro"); + sym_length = check_macro_name (buf, 0); while ((hp = lookup (buf, sym_length, -1)) != NULL) { /* If we are generating additional info for debugging (with -g) we @@ -7082,7 +7169,7 @@ do_if (buf, limit, op, keyword) FILE_BUF *op; struct directive *keyword ATTRIBUTE_UNUSED; { - HOST_WIDE_INT value; + HOST_WIDEST_INT value; FILE_BUF *ip = &instack[indepth]; value = eval_if_expression (buf, limit - buf); @@ -7099,7 +7186,7 @@ do_elif (buf, limit, op, keyword) FILE_BUF *op; struct directive *keyword ATTRIBUTE_UNUSED; { - HOST_WIDE_INT value; + HOST_WIDEST_INT value; FILE_BUF *ip = &instack[indepth]; if (if_stack == instack[indepth].if_stack) { @@ -7137,14 +7224,14 @@ do_elif (buf, limit, op, keyword) /* Evaluate a #if expression in BUF, of length LENGTH, then parse the result as a C expression and return the value as an int. */ -static HOST_WIDE_INT +static HOST_WIDEST_INT eval_if_expression (buf, length) U_CHAR *buf; int length; { FILE_BUF temp_obuf; HASHNODE *save_defined; - HOST_WIDE_INT value; + HOST_WIDEST_INT value; save_defined = install ((U_CHAR *) "defined", -1, T_SPEC_DEFINED, NULL_PTR, -1); @@ -7412,9 +7499,27 @@ skip_if_group (ip, any, op) bp += 2; else if (*bp == '/' && bp[1] == '*') { bp += 2; - while (!(*bp == '*' && bp[1] == '/')) - bp++; - bp += 2; + while (1) + { + if (*bp == '*') + { + if (bp[1] == '/') + { + bp += 2; + break; + } + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, endb - bp); + if (length > 1) + bp += (length - 1); +#endif + } + bp++; + } } /* There is no point in trying to deal with C++ // comments here, because if there is one, then this # must be part of the @@ -7458,17 +7563,37 @@ skip_if_group (ip, any, op) if (bp[1] == '/') break; } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, endb - bp); + if (length > 1) + bp += (length - 1); +#endif + } } bp += 2; } else if (bp[1] == '/' && cplusplus_comments) { for (bp += 2; ; bp++) { - if (*bp == '\n') { - if (bp[-1] != '\\') - break; - if (warn_comments) - warning ("multiline `//' comment"); - ip->lineno++; - } + if (*bp == '\n') + break; + if (*bp == '\\' && bp[1] == '\n') + { + if (warn_comments) + warning ("multiline `//' comment"); + ip->lineno++; + bp++; + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, endb - bp); + if (length > 1) + bp += (length - 1); +#endif + } } } else break; @@ -7764,6 +7889,15 @@ validate_else (p, limit) break; } } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (p, limit - p); + if (length > 1) + p += (length - 1); +#endif + } } } else if (cplusplus_comments && p[1] == '/') @@ -7807,16 +7941,37 @@ skip_to_end_of_comment (ip, line_counter, nowarn) } if (cplusplus_comments && bp[-1] == '/') { for (; bp < limit; bp++) { - if (*bp == '\n') { - if (bp[-1] != '\\') - break; - if (!nowarn && warn_comments) - warning ("multiline `//' comment"); - if (line_counter) - ++*line_counter; - if (op) - ++op->lineno; - } + if (*bp == '\n') + break; + if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n') + { + if (!nowarn && warn_comments) + warning ("multiline `//' comment"); + if (line_counter) + ++*line_counter; + if (op) + { + ++op->lineno; + *op->bufp++ = *bp; + } + ++bp; + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, limit - bp); + if (length > 1) + { + if (op) + { + bcopy (bp, op->bufp, length - 1); + op->bufp += (length - 1); + } + bp += (length - 1); + } +#endif + } if (op) *op->bufp++ = *bp; } @@ -7854,6 +8009,23 @@ skip_to_end_of_comment (ip, line_counter, nowarn) return bp; } break; +#ifdef MULTIBYTE_CHARS + default: + { + int length; + bp--; + length = local_mblen (bp, limit - bp); + if (length <= 0) + length = 1; + if (op) + { + op->bufp--; + bcopy (bp, op->bufp, length); + op->bufp += length; + } + bp += length; + } +#endif } } @@ -7944,6 +8116,16 @@ skip_quoted_string (bp, limit, start_line, count_newlines, backslash_newlines_p, } } else if (c == match) break; +#ifdef MULTIBYTE_CHARS + { + int length; + --bp; + length = local_mblen (bp, limit - bp); + if (length <= 0) + length = 1; + bp += length; + } +#endif } return bp; } @@ -8171,7 +8353,7 @@ macroexpand (hp, op) if (nargs >= 0) { register int i; struct argdata *args; - char *parse_error = 0; + int parse_error = 0; args = (struct argdata *) alloca ((nargs + 1) * sizeof (struct argdata)); @@ -8205,7 +8387,8 @@ macroexpand (hp, op) else parse_error = macarg (NULL_PTR, 0); if (parse_error) { - error_with_line (line_for_error (start_line), parse_error); + error_with_line (line_for_error (start_line), + "unterminated macro call"); break; } i++; @@ -8381,9 +8564,23 @@ macroexpand (hp, op) else { if (c == '\\') escaped = 1; - if (in_string) { + else if (in_string) { if (c == in_string) in_string = 0; + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (arg->raw + i, arglen - i); + if (length > 1) + { + bcopy (arg->raw + i, xbuf + totlen, length); + i += length - 1; + totlen += length; + continue; + } +#endif + } } else if (c == '\"' || c == '\'') in_string = c; } @@ -8536,7 +8733,7 @@ macroexpand (hp, op) REST_ARGS is passed to macarg1 to make it absorb the rest of the args. Return nonzero to indicate a syntax error. */ -static char * +static int macarg (argptr, rest_args) register struct argdata *argptr; int rest_args; @@ -8545,7 +8742,7 @@ macarg (argptr, rest_args) int paren = 0; int newlines = 0; int comments = 0; - char *result = 0; + int result = 0; /* Try to parse as much of the argument as exists at this input stack level. */ @@ -8578,7 +8775,7 @@ macarg (argptr, rest_args) while (bp == ip->buf + ip->length) { if (instack[indepth].macro == 0) { - result = "unterminated macro call"; + result = 1; break; } ip->macro->type = T_MACRO; @@ -8717,17 +8914,39 @@ macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args) break; } } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, limit - bp); + if (length > 1) + bp += (length - 1); +#endif + } } } else if (bp[1] == '/' && cplusplus_comments) { *comments = 1; for (bp += 2; bp < limit; bp++) { if (*bp == '\n') { ++*newlines; - if (bp[-1] != '\\') - break; - if (warn_comments) - warning ("multiline `//' comment"); + break; } + if (*bp == '\\' && bp + 1 < limit && bp[1] == '\n') + { + ++*newlines; + if (warn_comments) + warning ("multiline `//' comment"); + ++bp; + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, limit - bp); + if (length > 1) + bp += (length - 1); +#endif + } } } break; @@ -8751,6 +8970,15 @@ macarg1 (start, limit, macro, depthptr, newlines, comments, rest_args) if (quotec == '\'') break; } + else + { +#ifdef MULTIBYTE_CHARS + int length; + length = local_mblen (bp, limit - bp); + if (length > 1) + bp += (length - 1); +#endif + } } } break; @@ -8828,8 +9056,22 @@ discard_comments (start, length, newlines) /* Comments are equivalent to spaces. */ obp[-1] = ' '; ibp++; - while (ibp < limit && (*ibp != '\n' || ibp[-1] == '\\')) - ibp++; + while (ibp < limit) + { + if (*ibp == '\n') + break; + if (*ibp == '\\' && ibp + 1 < limit && ibp[1] == '\n') + ibp++; + else + { +#ifdef MULTIBYTE_CHARS + int length = local_mblen (ibp, limit - ibp); + if (length > 1) + ibp += (length - 1); +#endif + } + ibp++; + } break; } if (ibp[0] != '*' || ibp + 1 >= limit) @@ -8849,6 +9091,14 @@ discard_comments (start, length, newlines) break; } } + else + { +#ifdef MULTIBYTE_CHARS + int length = local_mblen (ibp, limit - ibp); + if (length > 1) + ibp += (length - 1); +#endif + } } break; @@ -8863,9 +9113,12 @@ discard_comments (start, length, newlines) *obp++ = c = *ibp++; if (c == quotec) break; - if (c == '\n' && quotec == '\'') - break; - if (c == '\\') { + if (c == '\n') + { + if (quotec == '\'') + break; + } + else if (c == '\\') { if (ibp < limit && *ibp == '\n') { ibp++; obp--; @@ -8876,6 +9129,23 @@ discard_comments (start, length, newlines) *obp++ = *ibp++; } } + else + { +#ifdef MULTIBYTE_CHARS + int length; + ibp--; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + { + obp--; + bcopy (ibp, obp, length); + ibp += length; + obp += length; + } + else + ibp++; +#endif + } } } break; @@ -8925,10 +9195,32 @@ change_newlines (start, length) int quotec = c; while (ibp < limit) { *obp++ = c = *ibp++; - if (c == quotec && ibp[-2] != '\\') - break; - if (c == '\n' && quotec == '\'') + if (c == quotec) break; + else if (c == '\\' && ibp < limit && *ibp == '\n') + *obp++ = *ibp++; + else if (c == '\n') + { + if (quotec == '\'') + break; + } + else + { +#ifdef MULTIBYTE_CHARS + int length; + ibp--; + length = local_mblen (ibp, limit - ibp); + if (length > 1) + { + obp--; + bcopy (ibp, obp, length); + ibp += length; + obp += length; + } + else + ibp++; +#endif + } } } break; @@ -8965,34 +9257,62 @@ my_strerror (errnum) #endif if (!result) - result = "undocumented I/O error"; + result = "errno = ?"; return result; } +/* notice - output message to stderr */ + +static void +notice VPROTO ((const char * msgid, ...)) +{ +#ifndef ANSI_PROTOTYPES + const char * msgid; +#endif + va_list args; + + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); +#endif + + vnotice (msgid, args); + va_end (args); +} + +static void +vnotice (msgid, args) + const char *msgid; + va_list args; +{ + vfprintf (stderr, _(msgid), args); +} + /* error - print error message and increment count of errors. */ void -error VPROTO ((char * msg, ...)) +error VPROTO ((const char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + const char * msgid; #endif va_list args; - VA_START (args, msg); + VA_START (args, msgid); -#ifndef __STDC__ - msg = va_arg (args, char *); +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); #endif - - verror (msg, args); + + verror (msgid, args); va_end (args); } -static void -verror (msg, args) - char *msg; +void +verror (msgid, args) + const char *msgid; va_list args; { int i; @@ -9010,7 +9330,7 @@ verror (msg, args) eprint_string (ip->nominal_fname, ip->nominal_fname_len); fprintf (stderr, ":%d: ", ip->lineno); } - vfprintf (stderr, msg, args); + vnotice (msgid, args); fprintf (stderr, "\n"); errors++; } @@ -9046,26 +9366,26 @@ error_from_errno (name) /* Print error message but don't count it. */ void -warning VPROTO ((char * msg, ...)) +warning VPROTO ((const char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + const char * msgid; #endif va_list args; - VA_START (args, msg); + VA_START (args, msgid); -#ifndef __STDC__ - msg = va_arg (args, char *); +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); #endif - vwarning (msg, args); + vwarning (msgid, args); va_end (args); } static void -vwarning (msg, args) - char *msg; +vwarning (msgid, args) + const char *msgid; va_list args; { int i; @@ -9089,35 +9409,36 @@ vwarning (msg, args) eprint_string (ip->nominal_fname, ip->nominal_fname_len); fprintf (stderr, ":%d: ", ip->lineno); } - fprintf (stderr, "warning: "); - vfprintf (stderr, msg, args); + notice ("warning: "); + vnotice (msgid, args); fprintf (stderr, "\n"); } static void -error_with_line VPROTO ((int line, char * msg, ...)) +error_with_line VPROTO ((int line, const char * msgid, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES int line; - char * msg; + const char * msgid; #endif va_list args; - VA_START (args, msg); + VA_START (args, msgid); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES line = va_arg (args, int); - msg = va_arg (args, char *); + msgid = va_arg (args, const char *); #endif - verror_with_line (line, msg, args); + verror_with_line (line, msgid, args); va_end (args); } + static void -verror_with_line (line, msg, args) +verror_with_line (line, msgid, args) int line; - char *msg; + const char *msgid; va_list args; { int i; @@ -9135,35 +9456,35 @@ verror_with_line (line, msg, args) eprint_string (ip->nominal_fname, ip->nominal_fname_len); fprintf (stderr, ":%d: ", line); } - vfprintf (stderr, msg, args); + vnotice (msgid, args); fprintf (stderr, "\n"); errors++; } static void -warning_with_line VPROTO ((int line, char * msg, ...)) +warning_with_line VPROTO ((int line, const char * msgid, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES int line; - char * msg; + const char * msgid; #endif va_list args; - VA_START (args, msg); + VA_START (args, msgid); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES line = va_arg (args, int); - msg = va_arg (args, char *); + msgid = va_arg (args, const char *); #endif - vwarning_with_line (line, msg, args); + vwarning_with_line (line, msgid, args); va_end (args); } static void -vwarning_with_line (line, msg, args) +vwarning_with_line (line, msgid, args) int line; - char *msg; + const char *msgid; va_list args; { int i; @@ -9187,54 +9508,54 @@ vwarning_with_line (line, msg, args) eprint_string (ip->nominal_fname, ip->nominal_fname_len); fprintf (stderr, line ? ":%d: " : ": ", line); } - fprintf (stderr, "warning: "); - vfprintf (stderr, msg, args); + notice ("warning: "); + vnotice (msgid, args); fprintf (stderr, "\n"); } /* Print an error message and maybe count it. */ void -pedwarn VPROTO ((char * msg, ...)) +pedwarn VPROTO ((const char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + const char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); #endif - + if (pedantic_errors) - verror (msg, args); + verror (msgid, args); else - vwarning (msg, args); + vwarning (msgid, args); va_end (args); } void -pedwarn_with_line VPROTO ((int line, char * msg, ...)) +pedwarn_with_line VPROTO ((int line, const char * msgid, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES int line; - char * msg; + const char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES line = va_arg (args, int); - msg = va_arg (args, char *); + msgid = va_arg (args, const char *); #endif - + if (pedantic_errors) - verror_with_line (line, msg, args); + verror_with_line (line, msgid, args); else - vwarning_with_line (line, msg, args); + vwarning_with_line (line, msgid, args); va_end (args); } @@ -9242,19 +9563,29 @@ pedwarn_with_line VPROTO ((int line, char * msg, ...)) giving specified file name and line number, not current. */ static void -pedwarn_with_file_and_line VPROTO ((char *file, size_t file_len, int line, - char * msg, ...)) +pedwarn_with_file_and_line VPROTO ((const char *file, size_t file_len, int line, + const char * msgid, ...)) { -#ifndef __STDC__ - char *file; +#ifndef ANSI_PROTOTYPES + const char *file; size_t file_len; int line; - char * msg; + const char * msgid; #endif va_list args; if (!pedantic_errors && inhibit_warnings) return; + + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + file = va_arg (args, const char *); + file_len = va_arg (args, size_t); + line = va_arg (args, int); + msgid = va_arg (args, const char *); +#endif + if (file) { eprint_string (file, file_len); fprintf (stderr, ":%d: ", line); @@ -9262,20 +9593,24 @@ pedwarn_with_file_and_line VPROTO ((char *file, size_t file_len, int line, if (pedantic_errors) errors++; if (!pedantic_errors) - fprintf (stderr, "warning: "); - VA_START (args, msg); - -#ifndef __STDC__ - file = va_arg (args, char *); - file_len = va_arg (args, size_t); - line = va_arg (args, int); - msg = va_arg (args, char *); -#endif - - vfprintf (stderr, msg, args); + notice ("warning: "); + vnotice (msgid, args); va_end (args); fprintf (stderr, "\n"); } + +static void +pedwarn_strange_white_space (ch) + int ch; +{ + switch (ch) + { + case '\f': pedwarn ("formfeed in preprocessing directive"); break; + case '\r': pedwarn ("carriage return in preprocessing directive"); break; + case '\v': pedwarn ("vertical tab in preprocessing directive"); break; + default: abort (); + } +} /* Print the file names and line numbers of the #include directives which led to the current file. */ @@ -9308,12 +9643,11 @@ print_containing_files () ip = &instack[i]; if (first) { first = 0; - fprintf (stderr, "In file included"); + notice ( "In file included from "); } else { - fprintf (stderr, ",\n "); + notice (",\n from "); } - fprintf (stderr, " from "); eprint_string (ip->nominal_fname, ip->nominal_fname_len); fprintf (stderr, ":%d", ip->lineno); } @@ -9751,10 +10085,6 @@ initialize_char_syntax () is_space['\f'] = 1; is_space['\n'] = 1; is_space['\r'] = 1; - - char_name['\v'] = "vertical tab"; - char_name['\f'] = "formfeed"; - char_name['\r'] = "carriage return"; } /* Initialize the built-in macros. */ @@ -9788,8 +10118,6 @@ initialize_builtins (inp, outp) install ((U_CHAR *) "__STDC__", -1, T_CONST, "1", -1); install ((U_CHAR *) "__STDC_VERSION__", -1, T_CONST, "199409L", -1); } - if (objc) - install ((U_CHAR *) "__OBJC__", -1, T_CONST, "1", -1); /* This is supplied using a -D by the compiler driver so that it is present only when truly compiling with GNU C. */ /* install ((U_CHAR *) "__GNUC__", -1, T_CONST, "2", -1); */ @@ -9870,9 +10198,8 @@ initialize_builtins (inp, outp) */ static void -make_definition (str, op) +make_definition (str) char *str; - FILE_BUF *op; { FILE_BUF *ip; struct directive *kt; @@ -9986,8 +10313,8 @@ make_undef (str, op) static void make_assertion (option, str) - char *option; - char *str; + const char *option; + const char *str; { FILE_BUF *ip; struct directive *kt; @@ -10040,10 +10367,6 @@ make_assertion (option, str) --indepth; } -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - /* The previous include prefix, if any, is PREV_FILE_NAME. Translate any pathnames with COMPONENT. Allocate a new include prefix whose name is the @@ -10055,9 +10378,9 @@ make_assertion (option, str) static struct file_name_list * new_include_prefix (prev_file_name, component, prefix, name) struct file_name_list *prev_file_name; - char *component; - char *prefix; - char *name; + const char *component; + const char *prefix; + const char *name; { if (name == 0) fatal ("Directory name missing after command line option"); @@ -10182,9 +10505,9 @@ append_include_chain (first, last) static int quote_string_for_make (dst, src) char *dst; - char *src; + const char *src; { - char *p = src; + const char *p = src; int i = 0; for (;;) { @@ -10201,7 +10524,7 @@ quote_string_for_make (dst, src) preceded by 2N backslashes represents N backslashes at the end of a file name; and backslashes in other contexts should not be doubled. */ - char *q; + const char *q; for (q = p - 1; src < q && q[-1] == '\\'; q--) { if (dst) @@ -10244,7 +10567,7 @@ quote_string_for_make (dst, src) static void deps_output (string, spacer) - char *string; + const char *string; int spacer; { int size = quote_string_for_make ((char *) 0, string); @@ -10282,22 +10605,21 @@ deps_output (string, spacer) deps_buffer[deps_size] = 0; } -static void -fatal VPROTO ((char * msg, ...)) +void +fatal VPROTO ((const char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + const char * msgid; #endif va_list args; fprintf (stderr, "%s: ", progname); - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); #endif - - vfprintf (stderr, msg, args); + vnotice (msgid, args); va_end (args); fprintf (stderr, "\n"); exit (FATAL_EXIT_CODE); @@ -10348,47 +10670,50 @@ memory_full () fatal ("Memory exhausted."); } - -GENERIC_PTR +PTR xmalloc (size) - size_t size; + size_t size; { - register GENERIC_PTR ptr = (GENERIC_PTR) malloc (size); + register PTR ptr = (PTR) malloc (size); if (!ptr) memory_full (); return ptr; } -static GENERIC_PTR +PTR xrealloc (old, size) - GENERIC_PTR old; - size_t size; + PTR old; + size_t size; { - register GENERIC_PTR ptr = (GENERIC_PTR) realloc (old, size); + register PTR ptr; + if (old) + ptr = (PTR) realloc (old, size); + else + ptr = (PTR) malloc (size); if (!ptr) memory_full (); return ptr; } -static GENERIC_PTR +PTR xcalloc (number, size) - size_t number, size; + size_t number, size; { register size_t total = number * size; - register GENERIC_PTR ptr = (GENERIC_PTR) malloc (total); + register PTR ptr = (PTR) malloc (total); if (!ptr) memory_full (); bzero (ptr, total); return ptr; } -static char * -savestring (input) - char *input; +char * +xstrdup (input) + const char *input; { - size_t size = strlen (input); - char *output = xmalloc (size + 1); - strcpy (output, input); + register size_t len = strlen (input) + 1; + register char *output = xmalloc (len); + memcpy (output, input, len); return output; } diff --git a/contrib/gcc/cexp.y b/contrib/gcc/cexp.y index 6280aed..9364ac3 100644 --- a/contrib/gcc/cexp.y +++ b/contrib/gcc/cexp.y @@ -1,5 +1,5 @@ /* Parse C expressions for CCCP. - Copyright (C) 1987, 1992, 94 - 97, 1998 Free Software Foundation. + Copyright (C) 1987, 92, 94-98, 1999 Free Software Foundation. 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,25 +26,16 @@ Boston, MA 02111-1307, USA. %{ #include "config.h" -#ifdef __STDC__ -# include -#else -# include -#endif - -#define PRINTF_PROTO(ARGS, m, n) PVPROTO (ARGS) ATTRIBUTE_PRINTF(m, n) - -#define PRINTF_PROTO_1(ARGS) PRINTF_PROTO(ARGS, 1, 2) #include "system.h" +#include "intl.h" #include /* #define YYDEBUG 1 */ #ifdef MULTIBYTE_CHARS +#include "mbchar.h" #include -#endif - -#include "gansidecl.h" +#endif /* MULTIBYTE_CHARS */ typedef unsigned char U_CHAR; @@ -56,44 +47,12 @@ struct arglist { int argno; }; -/* Find the largest host integer type and set its size and type. - Watch out: on some crazy hosts `long' is shorter than `int'. */ - -#ifndef HOST_WIDE_INT -# if HAVE_INTTYPES_H -# include -# define HOST_WIDE_INT intmax_t -# define unsigned_HOST_WIDE_INT uintmax_t -# else -# if (HOST_BITS_PER_LONG <= HOST_BITS_PER_INT && HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_INT) -# define HOST_WIDE_INT int -# else -# if (HOST_BITS_PER_LONGLONG <= HOST_BITS_PER_LONG || ! (defined LONG_LONG_MAX || defined LLONG_MAX)) -# define HOST_WIDE_INT long -# else -# define HOST_WIDE_INT long long -# endif -# endif -# endif -#endif - -#ifndef unsigned_HOST_WIDE_INT -#define unsigned_HOST_WIDE_INT unsigned HOST_WIDE_INT -#endif - -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif - -#ifndef HOST_BITS_PER_WIDE_INT -#define HOST_BITS_PER_WIDE_INT (CHAR_BIT * sizeof (HOST_WIDE_INT)) -#endif - -HOST_WIDE_INT parse_c_expression PROTO((char *, int)); +HOST_WIDEST_INT parse_c_expression PROTO((char *, int)); static int yylex PROTO((void)); -static void yyerror PROTO((char *)) __attribute__ ((noreturn)); -static HOST_WIDE_INT expression_value; +static void yyerror PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; +static HOST_WIDEST_INT expression_value; #ifdef TEST_EXP_READER static int expression_signedp; #endif @@ -154,13 +113,13 @@ extern int c89; #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE #endif -#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \ - ? (~ (~ (HOST_WIDE_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ - : ~ (HOST_WIDE_INT) 0) +#define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? (~ (~ (HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ + : ~ (HOST_WIDEST_INT) 0) -#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDE_INT \ - ? ~ (~ (HOST_WIDE_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ - : ~ (HOST_WIDE_INT) 0) +#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ + ? ~ (~ (HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ + : ~ (HOST_WIDEST_INT) 0) /* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow. Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1. @@ -174,17 +133,17 @@ extern int c89; struct constant; -GENERIC_PTR xmalloc PROTO((size_t)); -HOST_WIDE_INT parse_escape PROTO((char **, HOST_WIDE_INT)); +HOST_WIDEST_INT parse_escape PROTO((char **, HOST_WIDEST_INT)); int check_assertion PROTO((U_CHAR *, int, int, struct arglist *)); struct hashnode *lookup PROTO((U_CHAR *, int, int)); -void error PRINTF_PROTO_1((char *, ...)); -void pedwarn PRINTF_PROTO_1((char *, ...)); -void warning PRINTF_PROTO_1((char *, ...)); +void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void verror PROTO((const char *, va_list)); +void pedwarn PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void warning PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; static int parse_number PROTO((int)); -static HOST_WIDE_INT left_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT)); -static HOST_WIDE_INT right_shift PROTO((struct constant *, unsigned_HOST_WIDE_INT)); +static HOST_WIDEST_INT left_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT)); +static HOST_WIDEST_INT right_shift PROTO((struct constant *, unsigned HOST_WIDEST_INT)); static void integer_overflow PROTO((void)); /* `signedp' values */ @@ -193,7 +152,7 @@ static void integer_overflow PROTO((void)); %} %union { - struct constant {HOST_WIDE_INT value; int signedp;} integer; + struct constant {HOST_WIDEST_INT value; int signedp;} integer; struct name {U_CHAR *address; int length;} name; struct arglist *keywords; } @@ -280,7 +239,7 @@ exp : exp '*' exp integer_overflow (); } else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value * $3.value); } | exp '/' exp { if ($3.value == 0) @@ -297,7 +256,7 @@ exp : exp '*' exp integer_overflow (); } else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value / $3.value); } | exp '%' exp { if ($3.value == 0) @@ -310,7 +269,7 @@ exp : exp '*' exp if ($$.signedp) $$.value = $1.value % $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value % $3.value); } | exp '+' exp { $$.value = $1.value + $3.value; @@ -347,28 +306,28 @@ exp : exp '*' exp if ($1.signedp & $3.signedp) $$.value = $1.value <= $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value <= $3.value); } | exp GEQ exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value >= $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value >= $3.value); } | exp '<' exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value < $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value < $3.value); } | exp '>' exp { $$.signedp = SIGNED; if ($1.signedp & $3.signedp) $$.value = $1.value > $3.value; else - $$.value = ((unsigned_HOST_WIDE_INT) $1.value + $$.value = ((unsigned HOST_WIDEST_INT) $1.value > $3.value); } | exp '&' exp { $$.value = $1.value & $3.value; @@ -451,7 +410,7 @@ parse_number (olen) { register char *p = lexptr; register int c; - register unsigned_HOST_WIDE_INT n = 0, nd, max_over_base; + register unsigned HOST_WIDEST_INT n = 0, nd, max_over_base; register int base = 10; register int len = olen; register int overflow = 0; @@ -469,7 +428,7 @@ parse_number (olen) } } - max_over_base = (unsigned_HOST_WIDE_INT) -1 / base; + max_over_base = (unsigned HOST_WIDEST_INT) -1 / base; for (; len > 0; len--) { c = *p++; @@ -498,12 +457,9 @@ parse_number (olen) else { if (c == '.' || c == 'e' || c == 'E' || c == 'p' || c == 'P') yyerror ("Floating point numbers not allowed in #if expressions"); - else { - char *buf = (char *) alloca (p - lexptr + 40); - sprintf (buf, "missing white space after number `%.*s'", + else + yyerror ("missing white space after number `%.*s'", (int) (p - lexptr - 1), lexptr); - yyerror (buf); - } } if (--len == 0) @@ -527,7 +483,7 @@ parse_number (olen) pedwarn ("integer constant out of range"); /* If too big to be signed, consider it unsigned. */ - if (((HOST_WIDE_INT) n & yylval.integer.signedp) < 0) + if (((HOST_WIDEST_INT) n & yylval.integer.signedp) < 0) { if (base == 10) warning ("integer constant is so large that it is unsigned"); @@ -540,7 +496,7 @@ parse_number (olen) } struct token { - char *operator; + const char *operator; int token; }; @@ -568,7 +524,7 @@ yylex () register unsigned char *tokstart; register struct token *toktab; int wide_flag; - HOST_WIDE_INT mask; + HOST_WIDEST_INT mask; retry: @@ -580,11 +536,7 @@ yylex () if (c == *toktab->operator && tokstart[1] == toktab->operator[1]) { lexptr += 2; if (toktab->token == ERROR) - { - char *buf = (char *) alloca (40); - sprintf (buf, "`%s' not allowed in operand of `#if'", toktab->operator); - yyerror (buf); - } + yyerror ("`%s' not allowed in operand of `#if'", toktab->operator); return toktab->token; } @@ -639,25 +591,20 @@ yylex () handles multicharacter constants and wide characters. It is mostly copied from c-lex.c. */ { - register HOST_WIDE_INT result = 0; + register HOST_WIDEST_INT result = 0; register int num_chars = 0; + int chars_seen = 0; unsigned width = MAX_CHAR_TYPE_SIZE; int max_chars; - char *token_buffer; - - if (wide_flag) - { - width = MAX_WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; + int longest_char = local_mb_cur_max (); + char *token_buffer = (char *) alloca (longest_char); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); #endif - } - else - max_chars = MAX_LONG_TYPE_SIZE / width; - token_buffer = (char *) alloca (max_chars + 1); + max_chars = MAX_LONG_TYPE_SIZE / width; + if (wide_flag) + width = MAX_WCHAR_TYPE_SIZE; while (1) { @@ -666,72 +613,108 @@ yylex () if (c == '\'' || c == EOF) break; + ++chars_seen; if (c == '\\') { c = parse_escape (&lexptr, mask); } + else + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 1; i <= longest_char; ++i) + { + token_buffer[i - 1] = c; + char_len = local_mbtowc (& wc, token_buffer, i); + if (char_len != -1) + break; + c = *lexptr++; + } + if (char_len > 1) + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len < i) + lexptr--; + if (! wide_flag) + { + /* Merge character into result; ignore excess chars. */ + for (i = 1; i <= char_len; ++i) + { + if (i > max_chars) + break; + if (width < HOST_BITS_PER_INT) + result = (result << width) + | (token_buffer[i - 1] + & ((1 << width) - 1)); + else + result = token_buffer[i - 1]; + } + num_chars += char_len; + continue; + } + } + else + { + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + } + if (wide_flag) + c = wc; +#endif /* ! MULTIBYTE_CHARS */ + } - num_chars++; + if (wide_flag) + { + if (chars_seen == 1) /* only keep the first one */ + result = c; + continue; + } /* Merge character into result; ignore excess chars. */ + num_chars++; if (num_chars <= max_chars) { - if (width < HOST_BITS_PER_WIDE_INT) - result = (result << width) | c; + if (width < HOST_BITS_PER_INT) + result = (result << width) | (c & ((1 << width) - 1)); else result = c; - token_buffer[num_chars - 1] = c; } } - token_buffer[num_chars] = 0; - if (c != '\'') error ("malformatted character constant"); - else if (num_chars == 0) + else if (chars_seen == 0) error ("empty character constant"); else if (num_chars > max_chars) { num_chars = max_chars; error ("character constant too long"); } - else if (num_chars != 1 && ! traditional) + else if (chars_seen != 1 && ! traditional) warning ("multi-character character constant"); /* If char type is signed, sign-extend the constant. */ if (! wide_flag) { int num_bits = num_chars * width; - - if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__", + if (num_bits == 0) + /* We already got an error; avoid invalid shift. */ + yylval.integer.value = 0; + else if (lookup ((U_CHAR *) "__CHAR_UNSIGNED__", sizeof ("__CHAR_UNSIGNED__") - 1, -1) || ((result >> (num_bits - 1)) & 1) == 0) yylval.integer.value - = result & (~ (unsigned_HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)); + = result & (~ (unsigned HOST_WIDEST_INT) 0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); else yylval.integer.value - = result | ~(~ (unsigned_HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)); + = result | ~(~ (unsigned HOST_WIDEST_INT) 0 + >> (HOST_BITS_PER_WIDEST_INT - num_bits)); } else { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[0] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL_PTR, NULL_PTR, 0); - if (mbtowc (& wc, token_buffer, num_chars) == num_chars) - result = wc; - else - pedwarn ("Ignoring invalid multibyte character"); - } -#endif yylval.integer.value = result; } } @@ -854,10 +837,10 @@ yylex () If \ is followed by 000, we return 0 and leave the string pointer after the zeros. A value of 0 does not mean end of string. */ -HOST_WIDE_INT +HOST_WIDEST_INT parse_escape (string_ptr, result_mask) char **string_ptr; - HOST_WIDE_INT result_mask; + HOST_WIDEST_INT result_mask; { register int c = *(*string_ptr)++; switch (c) @@ -896,7 +879,7 @@ parse_escape (string_ptr, result_mask) case '6': case '7': { - register HOST_WIDE_INT i = c - '0'; + register HOST_WIDEST_INT i = c - '0'; register int count = 0; while (++count < 3) { @@ -918,7 +901,7 @@ parse_escape (string_ptr, result_mask) } case 'x': { - register unsigned_HOST_WIDE_INT i = 0, overflow = 0; + register unsigned HOST_WIDEST_INT i = 0, overflow = 0; register int digits_found = 0, digit; for (;;) { @@ -953,46 +936,37 @@ parse_escape (string_ptr, result_mask) } static void -yyerror (s) - char *s; -{ - error ("%s", s); - skip_evaluation = 0; - longjmp (parse_return_error, 1); -} - -static void integer_overflow () { if (!skip_evaluation && pedantic) pedwarn ("integer overflow in preprocessor expression"); } -static HOST_WIDE_INT +static HOST_WIDEST_INT left_shift (a, b) struct constant *a; - unsigned_HOST_WIDE_INT b; + unsigned HOST_WIDEST_INT b; { /* It's unclear from the C standard whether shifts can overflow. The following code ignores overflow; perhaps a C standard interpretation ruling is needed. */ - if (b >= HOST_BITS_PER_WIDE_INT) + if (b >= HOST_BITS_PER_WIDEST_INT) return 0; else - return (unsigned_HOST_WIDE_INT) a->value << b; + return (unsigned HOST_WIDEST_INT) a->value << b; } -static HOST_WIDE_INT +static HOST_WIDEST_INT right_shift (a, b) struct constant *a; - unsigned_HOST_WIDE_INT b; + unsigned HOST_WIDEST_INT b; { - if (b >= HOST_BITS_PER_WIDE_INT) - return a->signedp ? a->value >> (HOST_BITS_PER_WIDE_INT - 1) : 0; + if (b >= HOST_BITS_PER_WIDEST_INT) + return a->signedp ? a->value >> (HOST_BITS_PER_WIDEST_INT - 1) : 0; else if (a->signedp) return a->value >> b; else - return (unsigned_HOST_WIDE_INT) a->value >> b; + return (unsigned HOST_WIDEST_INT) a->value >> b; } /* This page contains the entry point to this file. */ @@ -1005,7 +979,7 @@ right_shift (a, b) We do not support C comments. They should be removed before this function is called. */ -HOST_WIDE_INT +HOST_WIDEST_INT parse_c_expression (string, warn_undefined) char *string; int warn_undefined; @@ -1027,6 +1001,27 @@ parse_c_expression (string, warn_undefined) return expression_value; /* set by yyparse () */ } + +static void +yyerror VPROTO ((const char * msgid, ...)) +{ +#ifndef ANSI_PROTOTYPES + const char * msgid; +#endif + va_list args; + + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, const char *); +#endif + + verror (msgid, args); + va_end (args); + skip_evaluation = 0; + longjmp (parse_return_error, 1); +} + #ifdef TEST_EXP_READER @@ -1036,10 +1031,11 @@ extern int yydebug; int pedantic; int traditional; +int c89; int main PROTO((int, char **)); static void initialize_random_junk PROTO((void)); -static void print_unsigned_host_wide_int PROTO((unsigned_HOST_WIDE_INT)); +static void print_unsigned_host_widest_int PROTO((unsigned HOST_WIDEST_INT)); /* Main program for testing purposes. */ int @@ -1049,12 +1045,13 @@ main (argc, argv) { int n, c; char buf[1024]; - unsigned_HOST_WIDE_INT u; + unsigned HOST_WIDEST_INT u; pedantic = 1 < argc; traditional = 2 < argc; + c89 = 3 < argc; #if YYDEBUG - yydebug = 3 < argc; + yydebug = 4 < argc; #endif initialize_random_junk (); @@ -1067,7 +1064,7 @@ main (argc, argv) break; parse_c_expression (buf, 1); printf ("parser returned "); - u = (unsigned_HOST_WIDE_INT) expression_value; + u = (unsigned HOST_WIDEST_INT) expression_value; if (expression_value < 0 && expression_signedp) { u = -u; printf ("-"); @@ -1075,7 +1072,7 @@ main (argc, argv) if (u == 0) printf ("0"); else - print_unsigned_host_wide_int (u); + print_unsigned_host_widest_int (u); if (! expression_signedp) printf("u"); printf ("\n"); @@ -1085,11 +1082,11 @@ main (argc, argv) } static void -print_unsigned_host_wide_int (u) - unsigned_HOST_WIDE_INT u; +print_unsigned_host_widest_int (u) + unsigned HOST_WIDEST_INT u; { if (u) { - print_unsigned_host_wide_int (u / 10); + print_unsigned_host_widest_int (u / 10); putchar ('0' + (int) (u % 10)); } } @@ -1137,65 +1134,66 @@ initialize_random_junk () } void -error VPROTO ((char * msg, ...)) +error VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "error: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } void -pedwarn VPROTO ((char * msg, ...)) +pedwarn VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "pedwarn: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } void -warning VPROTO ((char * msg, ...)) +warning VPROTO ((char * msgid, ...)) { -#ifndef __STDC__ - char * msg; +#ifndef ANSI_PROTOTYPES + char * msgid; #endif va_list args; - VA_START (args, msg); - -#ifndef __STDC__ - msg = va_arg (args, char *); + VA_START (args, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (args, char *); #endif - + fprintf (stderr, "warning: "); - vfprintf (stderr, msg, args); + vfprintf (stderr, _(msgid), args); fprintf (stderr, "\n"); va_end (args); } + int check_assertion (name, sym_length, tokens_specified, tokens) U_CHAR *name; @@ -1215,10 +1213,10 @@ lookup (name, len, hash) return (DEFAULT_SIGNED_CHAR) ? 0 : ((struct hashnode *) -1); } -GENERIC_PTR +PTR xmalloc (size) - size_t size; + size_t size; { - return (GENERIC_PTR) malloc (size); + return (PTR) malloc (size); } #endif diff --git a/contrib/gcc/collect2.c b/contrib/gcc/collect2.c index 4fcbe73..121ad39 100644 --- a/contrib/gcc/collect2.c +++ b/contrib/gcc/collect2.c @@ -1,6 +1,6 @@ /* Collect static initialization info into data structures that can be traversed by C++ initialization and finalization routines. - Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 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,38 +28,31 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" #include -#include + +#ifdef vfork /* Autoconf may define this to fork for us. */ +# define VFORK_STRING "fork" +#else +# define VFORK_STRING "vfork" +#endif +#ifdef HAVE_VFORK_H +#include +#endif +#ifdef VMS +#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ + lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) +#endif /* VMS */ #define COLLECT +#include "collect2.h" #include "demangle.h" #include "obstack.h" -#include "gansidecl.h" -#ifdef __CYGWIN32__ -#include -#endif +#include "intl.h" /* Obstack allocation and deallocation routines. */ #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free -#ifdef USG -#define vfork fork -#endif - -#ifndef WIFSIGNALED -#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f) -#endif -#ifndef WTERMSIG -#define WTERMSIG(S) ((S) & 0x7f) -#endif -#ifndef WIFEXITED -#define WIFEXITED(S) (((S) & 0xff) == 0) -#endif -#ifndef WEXITSTATUS -#define WEXITSTATUS(S) (((S) & 0xff00) >> 8) -#endif - extern char *make_temp_file PROTO ((char *)); /* On certain systems, we have code that works by scanning the object file @@ -137,7 +130,7 @@ extern char *make_temp_file PROTO ((char *)); /* Default flags to pass to nm. */ #ifndef NM_FLAGS -#define NM_FLAGS "-p" +#define NM_FLAGS "-n" #endif #endif /* OBJECT_FORMAT_NONE */ @@ -151,6 +144,9 @@ extern char *make_temp_file PROTO ((char *)); #define SYMBOL__MAIN __main #endif +/* This must match tree.h. */ +#define DEFAULT_INIT_PRIORITY 65535 + #if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES #define SCAN_LIBRARIES #endif @@ -186,11 +182,6 @@ enum pass { PASS_SECOND /* with constructors linked in */ }; -#ifndef NO_SYS_SIGLIST -#ifndef SYS_SIGLIST_DECLARED -extern char *sys_siglist[]; -#endif -#endif extern char *version_string; int vflag; /* true if -v */ @@ -234,14 +225,16 @@ struct obstack temporary_obstack; struct obstack permanent_obstack; char * temporary_firstobj; +/* Holds the return value of pexecute. */ +int pexecute_pid; + /* Defined in the automatically-generated underscore.c. */ extern int prepends_underscore; -extern char *mktemp (); extern FILE *fdopen (); -#ifndef GET_ENVIRONMENT -#define GET_ENVIRONMENT(ENV_VALUE,ENV_NAME) ENV_VALUE = getenv (ENV_NAME) +#ifndef GET_ENV_PATH_LIST +#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) #endif /* Structure to hold all the directories in which to search for files to @@ -270,7 +263,13 @@ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */ #endif +void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; +void fatal PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; +void fatal_perror PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; static char *my_strerror PROTO((int)); +static const char *my_strsignal PROTO((int)); static void handler PROTO((int)); static int is_ctor_dtor PROTO((char *)); static char *find_a_file PROTO((struct path_prefix *, char *)); @@ -281,6 +280,8 @@ static void do_wait PROTO((char *)); static void fork_execute PROTO((char *, char **)); static void maybe_unlink PROTO((char *)); static void add_to_list PROTO((struct head *, char *)); +static int extract_init_priority PROTO((char *)); +static void sort_ids PROTO((struct head *)); static void write_list PROTO((FILE *, char *, struct id *)); #ifdef COLLECT_EXPORT_LIST static void dump_list PROTO((FILE *, char *, struct id *)); @@ -302,10 +303,6 @@ static char *resolve_lib_name PROTO((char *)); static int use_import_list PROTO((char *)); static int ignore_library PROTO((char *)); #endif - -char *xcalloc (); -char *xmalloc (); - #ifdef NO_DUP2 int @@ -339,17 +336,38 @@ my_strerror (e) #else - static char buffer[30]; if (!e) return ""; if (e > 0 && e < sys_nerr) return sys_errlist[e]; - sprintf (buffer, "Unknown error %d", e); - return buffer; + return "errno = ?"; #endif } + +static const char * +my_strsignal (s) + int s; +{ +#ifdef HAVE_STRSIGNAL + return strsignal (s); +#else + if (s >= 0 && s < NSIG) + { +# ifdef NO_SYS_SIGLIST + static char buffer[30]; + + sprintf (buffer, "Unknown signal %d", s); + return buffer; +# else + return sys_siglist[s]; +# endif + } + else + return NULL; +#endif /* HAVE_STRSIGNAL */ +} /* Delete tempfiles and exit function. */ @@ -384,41 +402,94 @@ collect_exit (status) } +/* Notify user of a non-error. */ +void +notice VPROTO((char *msgid, ...)) +{ +#ifndef ANSI_PROTOTYPES + char *msgid; +#endif + va_list ap; + + VA_START (ap, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (ap, char *); +#endif + + vfprintf (stderr, _(msgid), ap); + va_end (ap); +} + /* Die when sys call fails. */ void -fatal_perror (string, arg1, arg2, arg3) - char *string, *arg1, *arg2, *arg3; +fatal_perror VPROTO((const char * msgid, ...)) { +#ifndef ANSI_PROTOTYPES + const char *msgid; +#endif int e = errno; + va_list ap; + + VA_START (ap, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (ap, const char *); +#endif fprintf (stderr, "collect2: "); - fprintf (stderr, string, arg1, arg2, arg3); + vfprintf (stderr, _(msgid), ap); fprintf (stderr, ": %s\n", my_strerror (e)); + va_end (ap); + collect_exit (FATAL_EXIT_CODE); } /* Just die. */ void -fatal (string, arg1, arg2, arg3) - char *string, *arg1, *arg2, *arg3; +fatal VPROTO((const char * msgid, ...)) { +#ifndef ANSI_PROTOTYPES + const char *msgid; +#endif + va_list ap; + + VA_START (ap, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (ap, const char *); +#endif + fprintf (stderr, "collect2: "); - fprintf (stderr, string, arg1, arg2, arg3); + vfprintf (stderr, _(msgid), ap); fprintf (stderr, "\n"); + va_end (ap); + collect_exit (FATAL_EXIT_CODE); } /* Write error message. */ void -error (string, arg1, arg2, arg3, arg4) - char *string, *arg1, *arg2, *arg3, *arg4; +error VPROTO((const char * msgid, ...)) { +#ifndef ANSI_PROTOTYPES + const char * msgid; +#endif + va_list ap; + + VA_START (ap, msgid); + +#ifndef ANSI_PROTOTYPES + msgid = va_arg (ap, const char *); +#endif + fprintf (stderr, "collect2: "); - fprintf (stderr, string, arg1, arg2, arg3, arg4); + vfprintf (stderr, _(msgid), ap); fprintf (stderr, "\n"); + va_end(ap); } /* In case obstack is linked in, and abort is defined to fancy_abort, @@ -429,7 +500,6 @@ fancy_abort () { fatal ("internal error"); } - static void handler (signo) @@ -457,39 +527,39 @@ handler (signo) } -char * +PTR xcalloc (size1, size2) - int size1, size2; + size_t size1, size2; { - char *ptr = (char *) calloc (size1, size2); - if (ptr) - return ptr; - - fatal ("out of memory"); - return (char *) 0; + PTR ptr = (PTR) calloc (size1, size2); + if (!ptr) + fatal ("out of memory"); + return ptr; } -char * +PTR xmalloc (size) - unsigned size; + size_t size; { - char *ptr = (char *) malloc (size); - if (ptr) - return ptr; - - fatal ("out of memory"); - return (char *) 0; + PTR ptr = (PTR) malloc (size); + if (!ptr) + fatal ("out of memory"); + return ptr; } -char * -xrealloc (ptr, size) - char *ptr; - unsigned size; +PTR +xrealloc (old, size) + PTR old; + size_t size; { - register char *value = (char *) realloc (ptr, size); - if (value == 0) + register PTR ptr; + if (old) + ptr = (PTR) realloc (old, size); + else + ptr = (PTR) malloc (size); + if (ptr == 0) fatal ("virtual memory exhausted"); - return value; + return ptr; } int @@ -502,13 +572,12 @@ file_exists (name) /* Make a copy of a string INPUT with size SIZE. */ char * -savestring (input, size) - char *input; - int size; +xstrdup (input) + const char *input; { - char *output = (char *) xmalloc (size + 1); - bcopy (input, output, size); - output[size] = 0; + register size_t len = strlen (input) + 1; + register char *output = xmalloc (len); + memcpy (output, input, len); return output; } @@ -754,9 +823,8 @@ find_a_file (pprefix, name) /* Determine the filename to execute (special case for absolute paths). */ if (*name == '/' -#ifdef DIR_SEPARATOR - || (DIR_SEPARATOR == '\\' && name[1] == ':' - && (name[2] == DIR_SEPARATOR || name[2] == '/')) +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + || (*name && name[1] == ':') #endif ) { @@ -770,6 +838,16 @@ find_a_file (pprefix, name) return temp; } +#ifdef EXECUTABLE_SUFFIX + /* Some systems have a suffix for executable files. + So try appending that. */ + strcpy (temp, name); + strcat (temp, EXECUTABLE_SUFFIX); + + if (access (temp, X_OK) == 0) + return temp; +#endif + if (debug) fprintf (stderr, " - failed to locate using absolute path\n"); } @@ -825,7 +903,7 @@ add_prefix (pprefix, prefix) pprefix->max_len = len; pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); - pl->prefix = savestring (prefix, len); + pl->prefix = xstrdup (prefix); if (*prev) pl->next = *prev; @@ -843,7 +921,7 @@ prefix_from_env (env, pprefix) struct path_prefix *pprefix; { char *p; - GET_ENVIRONMENT (p, env); + GET_ENV_PATH_LIST (p, env); if (p) prefix_from_string (p, pprefix); @@ -924,15 +1002,33 @@ main (argc, argv) char *p; char **c_argv; char **c_ptr; - char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3); - char **ld1 = ld1_argv; - char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6); - char **ld2 = ld2_argv; - char **object_lst = (char **) xcalloc (sizeof (char *), argc); - char **object = object_lst; + char **ld1_argv; + char **ld1; + char **ld2_argv; + char **ld2; + char **object_lst; + char **object; int first_file; int num_c_args = argc+9; +#if defined (COLLECT2_HOST_INITIALIZATION) + /* Perform system dependant initialization, if neccessary. */ + COLLECT2_HOST_INITIALIZATION; +#endif + +#ifdef HAVE_LC_MESSAGES + setlocale (LC_MESSAGES, ""); +#endif + (void) bindtextdomain (PACKAGE, localedir); + (void) textdomain (PACKAGE); + + /* Do not invoke xcalloc before this point, since locale needs to be + set first, in case a diagnostic is issued. */ + + ld1 = ld1_argv = (char **) xcalloc (sizeof (char *), argc+3); + ld2 = ld2_argv = (char **) xcalloc (sizeof (char *), argc+6); + object = object_lst = (char **) xcalloc (sizeof (char *), argc); + #ifdef DEBUG debug = 1; #endif @@ -1056,6 +1152,12 @@ main (argc, argv) /* Try to discover a valid linker/nm/strip to use. */ /* Maybe we know the right file to use (if not cross). */ + ld_file_name = 0; +#ifdef DEFAULT_LINKER + if (access (DEFAULT_LINKER, X_OK) == 0) + ld_file_name = DEFAULT_LINKER; + if (ld_file_name == 0) +#endif #ifdef REAL_LD_FILE_NAME ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); if (ld_file_name == 0) @@ -1164,6 +1266,8 @@ main (argc, argv) char *q = extract_string (&p); if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); + if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0) + *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0) shared_obj = 1; } @@ -1195,7 +1299,7 @@ main (argc, argv) case 'b': if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0) export_flag = 1; - if (arg[2] == '6' && arg[3] == '4') + else if (arg[2] == '6' && arg[3] == '4') aix64_flag = 1; break; #endif @@ -1342,16 +1446,16 @@ main (argc, argv) *ld2++ = buf2; exportf = fopen (export_file, "w"); if (exportf == (FILE *) 0) - fatal_perror ("%s", export_file); + fatal_perror ("fopen %s", export_file); write_export_file (exportf); if (fclose (exportf)) - fatal_perror ("closing %s", export_file); + fatal_perror ("fclose %s", export_file); importf = fopen (import_file, "w"); if (importf == (FILE *) 0) fatal_perror ("%s", import_file); write_import_file (importf); if (fclose (importf)) - fatal_perror ("closing %s", import_file); + fatal_perror ("fclose %s", import_file); } #endif @@ -1360,7 +1464,7 @@ main (argc, argv) if (vflag) { - fprintf (stderr, "collect2 version %s", version_string); + notice ("collect2 version %s", version_string); #ifdef TARGET_VERSION TARGET_VERSION; #endif @@ -1449,8 +1553,9 @@ main (argc, argv) if (debug) { - fprintf (stderr, "%d constructor(s) found\n", constructors.number); - fprintf (stderr, "%d destructor(s) found\n", destructors.number); + notice ("%d constructor(s) found\n", constructors.number); + notice ("%d destructor(s) found\n", destructors.number); + notice ("%d frame table(s) found\n", frame_tables.number); } if (constructors.number == 0 && destructors.number == 0 @@ -1486,15 +1591,19 @@ main (argc, argv) return 0; } + /* Sort ctor and dtor lists by priority. */ + sort_ids (&constructors); + sort_ids (&destructors); + maybe_unlink(output_file); outf = fopen (c_file, "w"); if (outf == (FILE *) 0) - fatal_perror ("%s", c_file); + fatal_perror ("fopen %s", c_file); write_c_file (outf, c_file); if (fclose (outf)) - fatal_perror ("closing %s", c_file); + fatal_perror ("fclose %s", c_file); /* Tell the linker that we have initializer and finalizer functions. */ #ifdef LD_INIT_SWITCH @@ -1514,10 +1623,10 @@ main (argc, argv) add_to_list (&exports, "_GLOBAL__DD"); exportf = fopen (export_file, "w"); if (exportf == (FILE *) 0) - fatal_perror ("%s", export_file); + fatal_perror ("fopen %s", export_file); write_export_file (exportf); if (fclose (exportf)) - fatal_perror ("closing %s", export_file); + fatal_perror ("fclose %s", export_file); } #endif @@ -1570,25 +1679,18 @@ collect_wait (prog) { int status; - wait (&status); + pwait (pexecute_pid, &status, 0); if (status) { if (WIFSIGNALED (status)) { int sig = WTERMSIG (status); -#ifdef NO_SYS_SIGLIST - error ("%s terminated with signal %d %s", + error ((status & 0200 + ? "%s terminated with signal %d [%s]" + : "%s terminated with signal %d [%s], core dumped"), prog, sig, - (status & 0200) ? ", core dumped" : ""); -#else - error ("%s terminated with signal %d [%s]%s", - prog, - sig, - sys_siglist[sig], - (status & 0200) ? ", core dumped" : ""); -#endif - + my_strsignal(sig)); collect_exit (FATAL_EXIT_CODE); } @@ -1611,7 +1713,7 @@ do_wait (prog) } -/* Fork and execute a program, and wait for the reply. */ +/* Execute a program, and wait for the reply. */ void collect_execute (prog, argv, redir) @@ -1619,7 +1721,11 @@ collect_execute (prog, argv, redir) char **argv; char *redir; { - int pid; + char *errmsg_fmt; + char *errmsg_arg; + int redir_handle = -1; + int stdout_save = -1; + int stderr_save = -1; if (vflag || debug) { @@ -1629,7 +1735,7 @@ collect_execute (prog, argv, redir) if (argv[0]) fprintf (stderr, "%s", argv[0]); else - fprintf (stderr, "[cannot find %s]", prog); + notice ("[cannot find %s]", prog); for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) fprintf (stderr, " %s", str); @@ -1646,36 +1752,41 @@ collect_execute (prog, argv, redir) if (argv[0] == 0) fatal ("cannot find `%s'", prog); -#ifndef __CYGWIN32__ - pid = vfork (); - if (pid == -1) + if (redir) { -#ifdef vfork - fatal_perror ("fork"); -#else - fatal_perror ("vfork"); -#endif + /* Open response file. */ + redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT); + + /* Duplicate the stdout and stderr file handles + so they can be restored later. */ + stdout_save = dup (STDOUT_FILENO); + if (stdout_save == -1) + fatal_perror ("redirecting stdout: %s", redir); + stderr_save = dup (STDERR_FILENO); + if (stderr_save == -1) + fatal_perror ("redirecting stdout: %s", redir); + + /* Redirect stdout & stderr to our response file. */ + dup2 (redir_handle, STDOUT_FILENO); + dup2 (redir_handle, STDERR_FILENO); } - if (pid == 0) /* child context */ + pexecute_pid = pexecute (argv[0], argv, argv[0], NULL, + &errmsg_fmt, &errmsg_arg, + (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH)); + + if (redir) { - if (redir) - { - unlink (redir); - if (freopen (redir, "a", stdout) == NULL) - fatal_perror ("redirecting stdout: %s", redir); - if (freopen (redir, "a", stderr) == NULL) - fatal_perror ("redirecting stderr: %s", redir); - } + /* Restore stdout and stderr to their previous settings. */ + dup2 (stdout_save, STDOUT_FILENO); + dup2 (stderr_save, STDERR_FILENO); - execvp (argv[0], argv); - fatal_perror ("executing %s", prog); + /* Close reponse file. */ + close (redir_handle); } -#else - pid = _spawnvp (_P_NOWAIT, argv[0], argv); - if (pid == -1) - fatal ("spawnvp failed"); -#endif + + if (pexecute_pid == -1) + fatal_perror (errmsg_fmt, errmsg_arg); } static void @@ -1696,10 +1807,12 @@ maybe_unlink (file) if (!debug) unlink (file); else - fprintf (stderr, "[Leaving %s]\n", file); + notice ("[Leaving %s]\n", file); } +static long sequence_number = 0; + /* Add a name to a linked list. */ static void @@ -1710,7 +1823,6 @@ add_to_list (head_ptr, name) struct id *newid = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); struct id *p; - static long sequence_number = 0; strcpy (newid->name, name); if (head_ptr->first) @@ -1735,6 +1847,67 @@ add_to_list (head_ptr, name) head_ptr->number++; } +/* Grab the init priority number from an init function name that + looks like "_GLOBAL_.I.12345.foo". */ + +static int +extract_init_priority (name) + char *name; +{ + int pos = 0, pri; + + while (name[pos] == '_') + ++pos; + pos += 10; /* strlen ("GLOBAL__X_") */ + + /* Extract init_p number from ctor/dtor name. */ + pri = atoi (name + pos); + return pri ? pri : DEFAULT_INIT_PRIORITY; +} + +/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. + ctors will be run from right to left, dtors from left to right. */ + +static void +sort_ids (head_ptr) + 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 + looking for the place to insert id. */ + struct id *id, *id_next, **id_ptr; + + id = head_ptr->first; + + /* We don't have any sorted elements yet. */ + head_ptr->first = NULL; + + for (; id; id = id_next) + { + id_next = id->next; + id->sequence = extract_init_priority (id->name); + + for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) + if (*id_ptr == NULL + /* If the sequence numbers are the same, we put the id from the + file later on the command line later in the list. */ + || id->sequence > (*id_ptr)->sequence + /* Hack: do lexical compare, too. + || (id->sequence == (*id_ptr)->sequence + && strcmp (id->name, (*id_ptr)->name) > 0) */ + ) + { + id->next = *id_ptr; + *id_ptr = id; + break; + } + } + + /* Now set the sequence numbers properly so write_c_file works. */ + for (id = head_ptr->first; id; id = id->next) + id->sequence = ++sequence_number; +} + /* Write: `prefix', the names on list LIST, `suffix'. */ static void @@ -1853,11 +2026,11 @@ write_c_file_stat (stream, name) strncpy (prefix, p, q - p); prefix[q - p] = 0; for (q = prefix; *q; q++) - if (!ISALNUM (*q)) + if (!ISALNUM ((unsigned char)*q)) *q = '_'; if (debug) - fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n", - output_file, prefix); + notice ("\nwrite_c_file - output name is %s, prefix is %s\n", + output_file, prefix); #define INIT_NAME_FORMAT "_GLOBAL__FI_%s" initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2); @@ -2114,28 +2287,22 @@ scan_prog_file (prog_name, which_pass) /* Spawn child nm on pipe */ pid = vfork (); if (pid == -1) - { -#ifdef vfork - fatal_perror ("fork"); -#else - fatal_perror ("vfork"); -#endif - } + fatal_perror (VFORK_STRING); if (pid == 0) /* child context */ { /* setup stdout */ if (dup2 (pipe_fd[1], 1) < 0) - fatal_perror ("dup2 (%d, 1)", pipe_fd[1]); + fatal_perror ("dup2 %d 1", pipe_fd[1]); if (close (pipe_fd[0]) < 0) - fatal_perror ("close (%d)", pipe_fd[0]); + fatal_perror ("close %d", pipe_fd[0]); if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); + fatal_perror ("close %d", pipe_fd[1]); execv (nm_file_name, nm_argv); - fatal_perror ("executing %s", nm_file_name); + fatal_perror ("execvp %s", nm_file_name); } /* Parent context from here on. */ @@ -2145,7 +2312,7 @@ scan_prog_file (prog_name, which_pass) #endif if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); + fatal_perror ("close %d", pipe_fd[1]); if (debug) fprintf (stderr, "\nnm output with constructors/destructors.\n"); @@ -2206,6 +2373,7 @@ scan_prog_file (prog_name, which_pass) case 5: if (which_pass != PASS_LIB) add_to_list (&frame_tables, name); + break; default: /* not a constructor or destructor */ continue; @@ -2219,7 +2387,7 @@ scan_prog_file (prog_name, which_pass) fprintf (stderr, "\n"); if (fclose (inf) != 0) - fatal_perror ("fclose of pipe"); + fatal_perror ("fclose"); do_wait (nm_file_name); @@ -2421,7 +2589,7 @@ locatelib (name) if (*pp == 0) { if (debug) - fprintf (stderr, "not found\n"); + notice ("not found\n"); else fatal ("dynamic dependency %s not found", name); } @@ -2465,7 +2633,7 @@ scan_libraries (prog_name) } if (debug) - fprintf (stderr, "dynamic dependencies.\n"); + notice ("dynamic dependencies.\n"); ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base); for (lo = (struct link_object *) ld_2->ld_need; lo; @@ -2556,28 +2724,22 @@ scan_libraries (prog_name) /* Spawn child ldd on pipe */ pid = vfork (); if (pid == -1) - { -#ifdef vfork - fatal_perror ("fork"); -#else - fatal_perror ("vfork"); -#endif - } + fatal_perror (VFORK_STRING); if (pid == 0) /* child context */ { /* setup stdout */ if (dup2 (pipe_fd[1], 1) < 0) - fatal_perror ("dup2 (%d, 1)", pipe_fd[1]); + fatal_perror ("dup2 %d 1", pipe_fd[1]); if (close (pipe_fd[0]) < 0) - fatal_perror ("close (%d)", pipe_fd[0]); + fatal_perror ("close %d", pipe_fd[0]); if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); + fatal_perror ("close %d", pipe_fd[1]); execv (ldd_file_name, ldd_argv); - fatal_perror ("executing %s", ldd_file_name); + fatal_perror ("execv %s", ldd_file_name); } /* Parent context from here on. */ @@ -2587,10 +2749,10 @@ scan_libraries (prog_name) #endif if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); + fatal_perror ("close %d", pipe_fd[1]); if (debug) - fprintf (stderr, "\nldd output with constructors/destructors.\n"); + notice ("\nldd output with constructors/destructors.\n"); /* Read each line of ldd output. */ while (fgets (buf, sizeof buf, inf) != (char *) 0) @@ -2626,7 +2788,7 @@ scan_libraries (prog_name) fprintf (stderr, "\n"); if (fclose (inf) != 0) - fatal_perror ("fclose of pipe"); + fatal_perror ("fclose"); do_wait (ldd_file_name); @@ -2656,7 +2818,7 @@ scan_libraries (prog_name) #if defined(EXTENDED_COFF) # define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) # define GCC_SYMENT SYMR -# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText) +# define GCC_OK_SYMBOL(X) ((X).st == stProc || (X).st == stGlobal) # define GCC_SYMINC(X) (1) # define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) # define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) @@ -2796,6 +2958,11 @@ scan_prog_file (prog_name, which_pass) break; #endif + case 5: + if (! is_shared) + add_to_list (&frame_tables, name); + break; + default: /* not a constructor or destructor */ #ifdef COLLECT_EXPORT_LIST /* If we are building a shared object on AIX we need @@ -3059,7 +3226,7 @@ scan_prog_file (prog_name, which_pass) prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY); if (prog_fd < 0) - fatal_perror ("cannot read %s", prog_name); + fatal_perror ("open %s", prog_name); obj_file = read_file (prog_name, prog_fd, rw); obj = obj_file->start; @@ -3155,8 +3322,8 @@ scan_prog_file (prog_name, which_pass) case SYMC_STABS: kind = "stabs"; break; } - fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n", - symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind); + 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) @@ -3240,15 +3407,15 @@ scan_prog_file (prog_name, which_pass) add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION); if (debug) - fprintf (stderr, "\nUpdating header and load commands.\n\n"); + 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) - fprintf (stderr, "load command map, %d cmds, new size %ld.\n", - (int)hdr.moh_n_load_cmds, (long)size); + 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; @@ -3278,7 +3445,7 @@ scan_prog_file (prog_name, which_pass) bad_header (status); if (debug) - fprintf (stderr, "writing load commands.\n\n"); + notice ("writing load commands.\n\n"); /* Write load commands */ offset = hdr.moh_first_cmd_off; @@ -3298,7 +3465,7 @@ scan_prog_file (prog_name, which_pass) end_file (obj_file); if (close (prog_fd)) - fatal_perror ("closing %s", prog_name); + fatal_perror ("close %s", prog_name); if (debug) fprintf (stderr, "\n"); @@ -3376,12 +3543,11 @@ add_func_table (hdr_p, load_array, sym, type) } if (debug) - fprintf (stderr, - "%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); + 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); } @@ -3502,22 +3668,17 @@ static void bad_header (status) int status; { - char *msg = (char *) 0; - switch (status) { - case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break; - case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break; - case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break; - case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break; - case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break; - case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break; + 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); } - - if (msg == (char *) 0) - fatal ("unknown {de,en}code_mach_o_hdr return value %d", status); - else - fatal ("%s", msg); } @@ -3573,7 +3734,7 @@ read_file (name, fd, rw) p->use_mmap = 0; p->start = xmalloc (p->size); if (lseek (fd, 0L, SEEK_SET) < 0) - fatal_perror ("lseek to 0 on %s", name); + fatal_perror ("lseek %s 0", name); len = read (fd, p->start, p->size); if (len < 0) @@ -3621,7 +3782,7 @@ end_file (ptr) fprintf (stderr, "write %s\n", ptr->name); if (lseek (ptr->fd, 0L, SEEK_SET) < 0) - fatal_perror ("lseek to 0 on %s", ptr->name); + fatal_perror ("lseek %s 0", ptr->name); len = write (ptr->fd, ptr->start, ptr->size); if (len < 0) diff --git a/contrib/gcc/collect2.h b/contrib/gcc/collect2.h new file mode 100644 index 0000000..04844bc --- /dev/null +++ b/contrib/gcc/collect2.h @@ -0,0 +1,36 @@ +/* Header file for collect/tlink routines. + Copyright (C) 1998 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. */ + +#ifndef __COLLECT2_H__ +#define __COLLECT2_H__ + +extern void do_tlink PARAMS ((char **, char **)); + +extern void collect_execute PARAMS ((char *, char **, char *)); + +extern void collect_exit PARAMS ((int)) ATTRIBUTE_NORETURN; + +extern int collect_wait PARAMS ((char *)); + +extern void dump_file PARAMS ((char *)); + +extern int file_exists PARAMS ((char *)); + +#endif /* ! __COLLECT2_H__ */ diff --git a/contrib/gcc/combine.c b/contrib/gcc/combine.c index db9bb38..0b64a86 100644 --- a/contrib/gcc/combine.c +++ b/contrib/gcc/combine.c @@ -75,16 +75,8 @@ Boston, MA 02111-1307, USA. */ combine anyway. */ #include "config.h" -#ifdef __STDC__ -#include -#else -#include -#endif - -/* stdio.h must precede rtl.h for FFS. */ #include "system.h" - -#include "rtl.h" +#include "rtl.h" /* stdio.h must precede rtl.h for FFS. */ #include "flags.h" #include "regs.h" #include "hard-reg-set.h" @@ -434,7 +426,7 @@ static int merge_outer_ops PROTO((enum rtx_code *, HOST_WIDE_INT *, enum machine_mode, int *)); static rtx simplify_shift_const PROTO((rtx, enum rtx_code, enum machine_mode, rtx, int)); -static int recog_for_combine PROTO((rtx *, rtx, rtx *, int *)); +static int recog_for_combine PROTO((rtx *, rtx, rtx *)); static rtx gen_lowpart_for_combine PROTO((enum machine_mode, rtx)); static rtx gen_rtx_combine PVPROTO((enum rtx_code code, enum machine_mode mode, ...)); @@ -581,7 +573,7 @@ combine_instructions (f, nregs) /* If INSN starts a new basic block, update our basic block number. */ if (this_basic_block + 1 < n_basic_blocks - && basic_block_head[this_basic_block + 1] == insn) + && BLOCK_HEAD (this_basic_block + 1) == insn) this_basic_block++; if (GET_CODE (insn) == CODE_LABEL) @@ -682,6 +674,9 @@ combine_instructions (f, nregs) total_successes += combine_successes; nonzero_sign_valid = 0; + + /* Make recognizer allow volatile MEMs again. */ + init_recog (); } /* Wipe the reg_last_xxx arrays in preparation for another pass. */ @@ -749,7 +744,7 @@ set_nonzero_bits_and_sign_copies (x, set) && REGNO (x) >= FIRST_PSEUDO_REGISTER /* If this register is undefined at the start of the file, we can't say what its contents were. */ - && ! REGNO_REG_SET_P (basic_block_live_at_start[0], REGNO (x)) + && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, REGNO (x)) && GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT) { if (set == 0 || GET_CODE (set) == CLOBBER) @@ -824,7 +819,8 @@ static int can_combine_p (insn, i3, pred, succ, pdest, psrc) rtx insn; rtx i3; - rtx pred, succ; + rtx pred ATTRIBUTE_UNUSED; + rtx succ; rtx *pdest, *psrc; { int i; @@ -958,8 +954,14 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc) /* Don't substitute into an incremented register. */ || FIND_REG_INC_NOTE (i3, dest) || (succ && FIND_REG_INC_NOTE (succ, dest)) +#if 0 /* Don't combine the end of a libcall into anything. */ + /* ??? This gives worse code, and appears to be unnecessary, since no + pass after flow uses REG_LIBCALL/REG_RETVAL notes. Local-alloc does + use REG_RETVAL notes for noconflict blocks, but other code here + makes sure that those insns don't disappear. */ || find_reg_note (insn, REG_RETVAL, NULL_RTX) +#endif /* Make sure that DEST is not used after SUCC but before I3. */ || (succ && ! all_adjacent && reg_used_between_p (dest, succ, i3)) @@ -1354,8 +1356,6 @@ try_combine (i3, i2, i1) int i3_subst_into_i2 = 0; /* Notes that I1, I2 or I3 is a MULT operation. */ int have_mult = 0; - /* Number of clobbers of SCRATCH we had to add. */ - int i3_scratches = 0, i2_scratches = 0, other_scratches = 0; int maxreg; rtx temp; @@ -1371,7 +1371,12 @@ try_combine (i3, i2, i1) if (GET_RTX_CLASS (GET_CODE (i3)) != 'i' || GET_RTX_CLASS (GET_CODE (i2)) != 'i' || (i1 && GET_RTX_CLASS (GET_CODE (i1)) != 'i') - || find_reg_note (i3, REG_LIBCALL, NULL_RTX)) +#if 0 + /* ??? This gives worse code, and appears to be unnecessary, since no + pass after flow uses REG_LIBCALL/REG_RETVAL notes. */ + || find_reg_note (i3, REG_LIBCALL, NULL_RTX) +#endif +) return 0; combine_attempts++; @@ -1827,8 +1832,7 @@ try_combine (i3, i2, i1) mark_used_regs_combine (newpat); /* Is the result of combination a valid instruction? */ - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + 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, @@ -1849,8 +1853,7 @@ try_combine (i3, i2, i1) && asm_noperands (newpat) < 0) { newpat = XVECEXP (newpat, 0, 0); - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); } else if (insn_code_number < 0 && GET_CODE (newpat) == PARALLEL @@ -1863,8 +1866,7 @@ try_combine (i3, i2, i1) && asm_noperands (newpat) < 0) { newpat = XVECEXP (newpat, 0, 1); - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); } /* If we were combining three insns and the result is a simple SET @@ -1933,8 +1935,7 @@ try_combine (i3, i2, i1) if (REGNO (i2dest) >= FIRST_PSEUDO_REGISTER) SUBST (regno_reg_rtx[REGNO (i2dest)], ni2dest); - i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes, - &i2_scratches); + i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); /* If I2 or I3 has multiple SETs, we won't know how to track register status, so don't use these insns. If I2's destination @@ -1943,8 +1944,8 @@ try_combine (i3, i2, i1) if (i2_code_number >= 0 && i2set && i3set && (next_real_insn (i2) == i3 || ! reg_used_between_p (SET_DEST (i2set), i2, i3))) - insn_code_number = recog_for_combine (&newi3pat, i3, &new_i3_notes, - &i3_scratches); + insn_code_number = recog_for_combine (&newi3pat, i3, + &new_i3_notes); if (insn_code_number >= 0) newpat = newi3pat; @@ -2031,14 +2032,12 @@ try_combine (i3, i2, i1) newi2pat = gen_rtx_combine (SET, VOIDmode, newdest, *split); SUBST (*split, newdest); - i2_code_number - = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches); + i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); /* If the split point was a MULT and we didn't have one before, don't use one now. */ if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult)) - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); } } @@ -2092,12 +2091,10 @@ try_combine (i3, i2, i1) newpat = XVECEXP (newpat, 0, 1); SUBST (SET_SRC (newpat), gen_lowpart_for_combine (GET_MODE (SET_SRC (newpat)), ni2dest)); - i2_code_number - = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches); + i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); if (i2_code_number >= 0) - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); if (insn_code_number >= 0) { @@ -2127,7 +2124,7 @@ try_combine (i3, i2, i1) for (insn = NEXT_INSN (i3); insn && (this_basic_block == n_basic_blocks - 1 - || insn != basic_block_head[this_basic_block + 1]); + || insn != BLOCK_HEAD (this_basic_block + 1)); insn = NEXT_INSN (insn)) { if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' @@ -2184,12 +2181,10 @@ try_combine (i3, i2, i1) newpat = XVECEXP (newpat, 0, 0); } - i2_code_number - = recog_for_combine (&newi2pat, i2, &new_i2_notes, &i2_scratches); + i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes); if (i2_code_number >= 0) - insn_code_number - = recog_for_combine (&newpat, i3, &new_i3_notes, &i3_scratches); + insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes); } /* If it still isn't recognized, fail and change things back the way they @@ -2211,9 +2206,8 @@ try_combine (i3, i2, i1) CLEAR_HARD_REG_SET (newpat_used_regs); - other_code_number - = recog_for_combine (&other_pat, undobuf.other_insn, - &new_other_notes, &other_scratches); + other_code_number = recog_for_combine (&other_pat, undobuf.other_insn, + &new_other_notes); if (other_code_number < 0 && ! check_asm_operands (other_pat)) { @@ -2316,7 +2310,7 @@ try_combine (i3, i2, i1) SET_DEST (XVECEXP (PATTERN (i2), 0, i)))) for (temp = NEXT_INSN (i2); temp && (this_basic_block == n_basic_blocks - 1 - || basic_block_head[this_basic_block] != temp); + || BLOCK_HEAD (this_basic_block) != temp); temp = NEXT_INSN (temp)) if (temp != i3 && GET_RTX_CLASS (GET_CODE (temp)) == 'i') for (link = LOG_LINKS (temp); link; link = XEXP (link, 1)) @@ -2496,7 +2490,8 @@ try_combine (i3, i2, i1) regno = REGNO (i2dest); REG_N_SETS (regno)--; if (REG_N_SETS (regno) == 0 - && ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno)) + && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, + regno)) REG_N_REFS (regno) = 0; } } @@ -2518,7 +2513,8 @@ try_combine (i3, i2, i1) { REG_N_SETS (regno)--; if (REG_N_SETS (regno) == 0 - && ! REGNO_REG_SET_P (basic_block_live_at_start[0], regno)) + && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, + regno)) REG_N_REFS (regno) = 0; } } @@ -2530,12 +2526,6 @@ try_combine (i3, i2, i1) if (newi2pat) note_stores (newi2pat, set_nonzero_bits_and_sign_copies); - /* If we added any (clobber (scratch)), add them to the max for a - block. This is a very pessimistic calculation, since we might - have had them already and this might not be the worst block, but - it's not worth doing any better. */ - max_scratch += i3_scratches + i2_scratches + other_scratches; - /* If I3 is now an unconditional jump, ensure that it has a BARRIER following it since it may have initially been a conditional jump. It may also be the last nonnote insn. */ @@ -2747,7 +2737,7 @@ find_split_point (loc, insn) if (BITS_BIG_ENDIAN) pos = GET_MODE_BITSIZE (mode) - len - pos; - if (src == mask) + if ((unsigned HOST_WIDE_INT) src == mask) SUBST (SET_SRC (x), gen_binary (IOR, mode, dest, GEN_INT (src << pos))); else @@ -3514,9 +3504,8 @@ simplify_rtx (x, op0_mode, last, in_dest) plus_constant (XEXP (inner, 0), (SUBREG_WORD (x) * UNITS_PER_WORD + endian_offset))); - MEM_VOLATILE_P (x) = MEM_VOLATILE_P (inner); RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (inner); - MEM_IN_STRUCT_P (x) = MEM_IN_STRUCT_P (inner); + MEM_COPY_ATTRIBUTES (x, inner); return x; } @@ -3821,9 +3810,12 @@ simplify_rtx (x, op0_mode, last, in_dest) return SUBREG_REG (XEXP (x, 0)); /* If we know that the value is already truncated, we can - replace the TRUNCATE with a SUBREG. */ - if (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) - >= GET_MODE_BITSIZE (mode) + 1) + replace the TRUNCATE with a SUBREG if TRULY_NOOP_TRUNCATION is + nonzero for the corresponding modes. */ + if (TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode), + GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))) + && num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))) + >= GET_MODE_BITSIZE (mode) + 1) return gen_lowpart_for_combine (mode, XEXP (x, 0)); /* A truncate of a comparison can be replaced with a subreg if @@ -4164,7 +4156,7 @@ 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)) - == (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) @@ -4692,9 +4684,8 @@ simplify_set (x) && exact_log2 (mask = nonzero_bits (op0, GET_MODE (op0))) >= 0) { rtx pat = PATTERN (other_insn), note = 0; - int scratches; - if ((recog_for_combine (&pat, other_insn, ¬e, &scratches) < 0 + if ((recog_for_combine (&pat, other_insn, ¬e) < 0 && ! check_asm_operands (pat))) { PUT_CODE (*cc_use, old_code); @@ -5131,7 +5122,7 @@ simplify_logical (x, last) when STORE_FLAG_VALUE is the sign bit. */ if (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)) && op1 == const_true_rtx && GET_RTX_CLASS (GET_CODE (op0)) == '<' && reversible_comparison_p (op0)) @@ -5432,6 +5423,24 @@ expand_field_assignment (x) compute_mode = GET_MODE (inner); + /* Don't attempt bitwise arithmetic on non-integral modes. */ + if (! INTEGRAL_MODE_P (compute_mode)) + { + enum machine_mode imode; + + /* Something is probably seriously wrong if this matches. */ + if (! FLOAT_MODE_P (compute_mode)) + break; + + /* Try to find an integral mode to pun with. */ + imode = mode_for_size (GET_MODE_BITSIZE (compute_mode), MODE_INT, 0); + if (imode == BLKmode) + break; + + compute_mode = imode; + inner = gen_lowpart_for_combine (imode, inner); + } + /* Compute a mask of LEN bits, if we can do this on the host machine. */ if (len < HOST_BITS_PER_WIDE_INT) mask = GEN_INT (((HOST_WIDE_INT) 1 << len) - 1); @@ -5588,8 +5597,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, new = gen_rtx_MEM (tmode, plus_constant (XEXP (inner, 0), offset)); RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (inner); - MEM_VOLATILE_P (new) = MEM_VOLATILE_P (inner); - MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (inner); + MEM_COPY_ATTRIBUTES (new, inner); } else if (GET_CODE (inner) == REG) { @@ -5653,27 +5661,45 @@ make_extraction (mode, inner, pos, pos_rtx, len, #ifdef HAVE_insv if (in_dest) { - wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_insv][0]; - pos_mode = insn_operand_mode[(int) CODE_FOR_insv][2]; - extraction_mode = insn_operand_mode[(int) CODE_FOR_insv][3]; + wanted_inner_reg_mode + = (insn_operand_mode[(int) CODE_FOR_insv][0] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_insv][0]); + pos_mode = (insn_operand_mode[(int) CODE_FOR_insv][2] == VOIDmode + ? word_mode : insn_operand_mode[(int) CODE_FOR_insv][2]); + extraction_mode = (insn_operand_mode[(int) CODE_FOR_insv][3] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_insv][3]); } #endif #ifdef HAVE_extzv if (! in_dest && unsignedp) { - wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; - pos_mode = insn_operand_mode[(int) CODE_FOR_extzv][3]; - extraction_mode = insn_operand_mode[(int) CODE_FOR_extzv][0]; + wanted_inner_reg_mode + = (insn_operand_mode[(int) CODE_FOR_extzv][1] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_extzv][1]); + pos_mode = (insn_operand_mode[(int) CODE_FOR_extzv][3] == VOIDmode + ? word_mode : insn_operand_mode[(int) CODE_FOR_extzv][3]); + extraction_mode = (insn_operand_mode[(int) CODE_FOR_extzv][0] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_extzv][0]); } #endif #ifdef HAVE_extv if (! in_dest && ! unsignedp) { - wanted_inner_reg_mode = insn_operand_mode[(int) CODE_FOR_extv][1]; - pos_mode = insn_operand_mode[(int) CODE_FOR_extv][3]; - extraction_mode = insn_operand_mode[(int) CODE_FOR_extv][0]; + wanted_inner_reg_mode + = (insn_operand_mode[(int) CODE_FOR_extv][1] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_extv][1]); + pos_mode = (insn_operand_mode[(int) CODE_FOR_extv][3] == VOIDmode + ? word_mode : insn_operand_mode[(int) CODE_FOR_extv][3]); + extraction_mode = (insn_operand_mode[(int) CODE_FOR_extv][0] == VOIDmode + ? word_mode + : insn_operand_mode[(int) CODE_FOR_extv][0]); } #endif @@ -5763,8 +5789,7 @@ make_extraction (mode, inner, pos, pos_rtx, len, rtx newmem = gen_rtx_MEM (wanted_inner_mode, plus_constant (XEXP (inner, 0), offset)); RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (inner); - MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (inner); - MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (inner); + MEM_COPY_ATTRIBUTES (newmem, inner); inner = newmem; } } @@ -6328,7 +6353,7 @@ force_to_mode (x, mode, mask, reg, just_select) need it. */ if (GET_CODE (x) == AND && GET_CODE (XEXP (x, 1)) == CONST_INT - && INTVAL (XEXP (x, 1)) == mask) + && (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) == mask) x = XEXP (x, 0); /* If it remains an AND, try making another AND with the bits @@ -6390,20 +6415,21 @@ force_to_mode (x, mode, mask, reg, just_select) unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode); sp_mask &= ~ (sp_alignment - 1); - if ((sp_mask & ~ mask) == 0 - && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) != 0) + if ((sp_mask & ~ smask) == 0 + && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ smask) != 0) return force_to_mode (plus_constant (XEXP (x, 0), ((INTVAL (XEXP (x, 1)) - - STACK_BIAS) & mask) + STACK_BIAS) & smask) + STACK_BIAS), - mode, mask, reg, next_select); + mode, smask, reg, next_select); } #endif - if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0 - && (INTVAL (XEXP (x, 1)) & ~ mask) != 0) + if ((nonzero_bits (XEXP (x, 0), mode) & ~ smask) == 0 + && (INTVAL (XEXP (x, 1)) & ~ smask) != 0) return force_to_mode (plus_constant (XEXP (x, 0), - INTVAL (XEXP (x, 1)) & mask), - mode, mask, reg, next_select); + (INTVAL (XEXP (x, 1)) + & smask)), + mode, smask, reg, next_select); } } @@ -6549,7 +6575,7 @@ force_to_mode (x, mode, mask, reg, just_select) /* If we are just looking for the sign bit, we don't need this shift at all, even if it has a variable count. */ if (GET_MODE_BITSIZE (GET_MODE (x)) <= HOST_BITS_PER_WIDE_INT - && (mask == ((HOST_WIDE_INT) 1 + && (mask == ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (GET_MODE (x)) - 1)))) return force_to_mode (XEXP (x, 0), mode, mask, reg, next_select); @@ -7376,7 +7402,7 @@ simplify_and_const_int (x, mode, varop, constop) else { if (GET_CODE (XEXP (x, 1)) != CONST_INT - || INTVAL (XEXP (x, 1)) != constop) + || (unsigned HOST_WIDE_INT) INTVAL (XEXP (x, 1)) != constop) SUBST (XEXP (x, 1), GEN_INT (constop)); SUBST (XEXP (x, 0), varop); @@ -8292,7 +8318,8 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p) op0 = NIL; else if (const0 == 0 && op0 == AND) op0 = SET; - else if (const0 == GET_MODE_MASK (mode) && op0 == AND) + else if ((unsigned HOST_WIDE_INT) const0 == GET_MODE_MASK (mode) + && op0 == AND) op0 = NIL; /* If this would be an entire word for the target, but is not for @@ -8475,8 +8502,7 @@ simplify_shift_const (x, code, result_mode, varop, count) plus_constant (XEXP (varop, 0), count / BITS_PER_UNIT)); RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (varop); - MEM_VOLATILE_P (new) = MEM_VOLATILE_P (varop); - MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (varop); + MEM_COPY_ATTRIBUTES (new, varop); varop = gen_rtx_combine (code == ASHIFTRT ? SIGN_EXTEND : ZERO_EXTEND, mode, new); count = 0; @@ -9066,18 +9092,14 @@ simplify_shift_const (x, code, result_mode, varop, count) PNOTES is a pointer to a location where any REG_UNUSED notes added for the CLOBBERs are placed. - PADDED_SCRATCHES is set to the number of (clobber (scratch)) patterns - we had to add. - The value is the final insn code from the pattern ultimately matched, or -1. */ static int -recog_for_combine (pnewpat, insn, pnotes, padded_scratches) +recog_for_combine (pnewpat, insn, pnotes) rtx *pnewpat; rtx insn; rtx *pnotes; - int *padded_scratches; { register rtx pat = *pnewpat; int insn_code_number; @@ -9085,8 +9107,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches) int i; rtx notes = 0; - *padded_scratches = 0; - /* 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 thing, force rejection. */ @@ -9148,8 +9168,6 @@ recog_for_combine (pnewpat, insn, pnotes, padded_scratches) if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == REG && ! reg_dead_at_p (XEXP (XVECEXP (newpat, 0, i), 0), insn)) return -1; - else if (GET_CODE (XEXP (XVECEXP (newpat, 0, i), 0)) == SCRATCH) - (*padded_scratches)++; notes = gen_rtx_EXPR_LIST (REG_UNUSED, XEXP (XVECEXP (newpat, 0, i), 0), notes); } @@ -9243,8 +9261,7 @@ gen_lowpart_for_combine (mode, x) } new = gen_rtx_MEM (mode, plus_constant (XEXP (x, 0), offset)); RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (x); - MEM_VOLATILE_P (new) = MEM_VOLATILE_P (x); - MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (x); + MEM_COPY_ATTRIBUTES (new, x); return new; } @@ -9279,7 +9296,7 @@ gen_lowpart_for_combine (mode, x) static rtx gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...)) { -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES enum rtx_code code; enum machine_mode mode; #endif @@ -9293,7 +9310,7 @@ gen_rtx_combine VPROTO((enum rtx_code code, enum machine_mode mode, ...)) VA_START (p, mode); -#ifndef __STDC__ +#ifndef ANSI_PROTOTYPES code = va_arg (p, enum rtx_code); mode = va_arg (p, enum machine_mode); #endif @@ -9553,7 +9570,7 @@ simplify_comparison (code, pop0, pop1) for (tmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (GET_MODE (op0))); tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode)) - if (c0 == GET_MODE_MASK (tmode)) + if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode)) { op0 = gen_lowpart_for_combine (tmode, inner_op0); op1 = gen_lowpart_for_combine (tmode, inner_op1); @@ -9628,7 +9645,7 @@ simplify_comparison (code, pop0, pop1) || code == LT || code == LTU) && mode_width <= HOST_BITS_PER_WIDE_INT && exact_log2 (const_op) >= 0 - && nonzero_bits (op0, mode) == const_op) + && nonzero_bits (op0, mode) == (unsigned HOST_WIDE_INT) const_op) { code = (code == EQ || code == GE || code == GEU ? NE : EQ); op1 = const0_rtx, const_op = 0; @@ -9820,12 +9837,16 @@ simplify_comparison (code, pop0, pop1) && (i = exact_log2 (INTVAL (XEXP (op0, 0)))) >= 0) { if (BITS_BIG_ENDIAN) + { #ifdef HAVE_extzv - i = (GET_MODE_BITSIZE - (insn_operand_mode[(int) CODE_FOR_extzv][1]) - 1 - i); + mode = insn_operand_mode[(int) CODE_FOR_extzv][1]; + if (mode == VOIDmode) + mode = word_mode; + i = (GET_MODE_BITSIZE (mode) - 1 - i); #else - i = BITS_PER_WORD - 1 - i; + i = BITS_PER_WORD - 1 - i; #endif + } op0 = XEXP (op0, 2); op1 = GEN_INT (i); @@ -9953,7 +9974,7 @@ simplify_comparison (code, pop0, pop1) && (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) <= HOST_BITS_PER_WIDE_INT) && ((unsigned HOST_WIDE_INT) const_op - < (((HOST_WIDE_INT) 1 + < (((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (op0, 0))) - 1))))) { op0 = XEXP (op0, 0); @@ -9977,7 +9998,7 @@ simplify_comparison (code, pop0, pop1) && GET_CODE (XEXP (SUBREG_REG (op0), 1)) == CONST_INT && INTVAL (XEXP (SUBREG_REG (op0), 1)) < 0 && (- INTVAL (XEXP (SUBREG_REG (op0), 1)) - < GET_MODE_MASK (mode) / 2) + < (HOST_WIDE_INT)(GET_MODE_MASK (mode) / 2)) && (unsigned HOST_WIDE_INT) const_op < GET_MODE_MASK (mode) / 2 && (0 == (nonzero_bits (XEXP (SUBREG_REG (op0), 0), GET_MODE (SUBREG_REG (op0))) @@ -10181,7 +10202,7 @@ simplify_comparison (code, pop0, pop1) && GET_CODE (XEXP (op0, 1)) == CONST_INT && mode_width <= HOST_BITS_PER_WIDE_INT && ((INTVAL (XEXP (op0, 1)) & GET_MODE_MASK (mode)) - == (HOST_WIDE_INT) 1 << (mode_width - 1))) + == (unsigned HOST_WIDE_INT) 1 << (mode_width - 1))) { op0 = XEXP (op0, 0); code = (code == EQ ? GE : LT); @@ -10232,8 +10253,8 @@ simplify_comparison (code, pop0, pop1) && (INTVAL (XEXP (op0, 1)) & ~ mask) == 0 && 0 == (~ GET_MODE_MASK (GET_MODE (SUBREG_REG (XEXP (op0, 0)))) & INTVAL (XEXP (op0, 1))) - && INTVAL (XEXP (op0, 1)) != mask - && (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)))))) { @@ -11012,7 +11033,7 @@ reg_dead_at_p (reg, insn) else { for (block = 0; block < n_basic_blocks; block++) - if (insn == basic_block_head[block]) + if (insn == BLOCK_HEAD (block)) break; if (block == n_basic_blocks) @@ -11020,7 +11041,7 @@ reg_dead_at_p (reg, insn) } for (i = reg_dead_regno; i < reg_dead_endregno; i++) - if (REGNO_REG_SET_P (basic_block_live_at_start[block], i)) + if (REGNO_REG_SET_P (BASIC_BLOCK (block)->global_live_at_start, i)) return 0; return 1; @@ -11413,6 +11434,17 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) place = i3; break; + case REG_EH_REGION: + /* This note must remain with the call. It should not be possible + for both I2 and I3 to be a call. */ + if (GET_CODE (i3) == CALL_INSN) + place = i3; + else if (i2 && GET_CODE (i2) == CALL_INSN) + place = i2; + else + abort (); + break; + case REG_UNUSED: /* Any clobbers for i3 may still exist, and so we must process REG_UNUSED notes from that insn. @@ -11476,7 +11508,6 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) case REG_INC: case REG_NO_CONFLICT: - case REG_LABEL: /* These notes say something about how a register is used. They must be present on any use of the register in I2 or I3. */ if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3))) @@ -11491,6 +11522,30 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) } break; + case REG_LABEL: + /* This can show up in several ways -- either directly in the + pattern, or hidden off in the constant pool with (or without?) + a REG_EQUAL note. */ + /* ??? Ignore the without-reg_equal-note problem for now. */ + if (reg_mentioned_p (XEXP (note, 0), PATTERN (i3)) + || ((tem = find_reg_note (i3, REG_EQUAL, NULL_RTX)) + && GET_CODE (XEXP (tem, 0)) == LABEL_REF + && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0))) + place = i3; + + if (i2 + && (reg_mentioned_p (XEXP (note, 0), PATTERN (i2)) + || ((tem = find_reg_note (i2, REG_EQUAL, NULL_RTX)) + && GET_CODE (XEXP (tem, 0)) == LABEL_REF + && XEXP (XEXP (tem, 0), 0) == XEXP (note, 0)))) + { + if (place) + place2 = i2; + else + place = i2; + } + break; + case REG_WAS_0: /* It is too much trouble to try to see if this note is still correct in all situations. It is better to simply delete it. */ @@ -11578,6 +11633,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) { rtx set = single_set (tem); rtx inner_dest = 0; +#ifdef HAVE_cc0 + rtx cc0_setter = NULL_RTX; +#endif if (set != 0) for (inner_dest = SET_DEST (set); @@ -11588,10 +11646,21 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) ; /* Verify that it was the set, and not a clobber that - modified the register. */ + modified the register. + + CC0 targets must be careful to maintain setter/user + pairs. If we cannot delete the setter due to side + effects, mark the user with an UNUSED note instead + of deleting it. */ if (set != 0 && ! side_effects_p (SET_SRC (set)) - && rtx_equal_p (XEXP (note, 0), inner_dest)) + && rtx_equal_p (XEXP (note, 0), inner_dest) +#ifdef HAVE_cc0 + && (! reg_mentioned_p (cc0_rtx, SET_SRC (set)) + || ((cc0_setter = prev_cc0_setter (tem)) != NULL + && sets_cc0_p (PATTERN (cc0_setter)) > 0)) +#endif + ) { /* Move the notes and links of TEM elsewhere. This might delete other dead insns recursively. @@ -11607,6 +11676,23 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) PUT_CODE (tem, NOTE); NOTE_LINE_NUMBER (tem) = NOTE_INSN_DELETED; NOTE_SOURCE_FILE (tem) = 0; + +#ifdef HAVE_cc0 + /* Delete the setter too. */ + if (cc0_setter) + { + PATTERN (cc0_setter) = pc_rtx; + + distribute_notes (REG_NOTES (cc0_setter), + cc0_setter, cc0_setter, + NULL_RTX, NULL_RTX, NULL_RTX); + distribute_links (LOG_LINKS (cc0_setter)); + + PUT_CODE (cc0_setter, NOTE); + NOTE_LINE_NUMBER (cc0_setter) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (cc0_setter) = 0; + } +#endif } /* If the register is both set and used here, put the REG_DEAD note here, but place a REG_UNUSED note @@ -11672,9 +11758,9 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1) tem); /* If this insn was emitted between blocks, then update - basic_block_head of the current block to include it. */ - if (basic_block_end[this_basic_block - 1] == tem) - basic_block_head[this_basic_block] = place; + BLOCK_HEAD of the current block to include it. */ + if (BLOCK_END (this_basic_block - 1) == tem) + BLOCK_HEAD (this_basic_block) = place; } } @@ -11873,7 +11959,7 @@ distribute_links (links) for (insn = NEXT_INSN (XEXP (link, 0)); (insn && (this_basic_block == n_basic_blocks - 1 - || basic_block_head[this_basic_block + 1] != insn)); + || BLOCK_HEAD (this_basic_block + 1) != insn)); insn = NEXT_INSN (insn)) if (GET_RTX_CLASS (GET_CODE (insn)) == 'i' && reg_overlap_mentioned_p (reg, PATTERN (insn))) @@ -11935,7 +12021,7 @@ void dump_combine_stats (file) FILE *file; { - fprintf + fnotice (file, ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n", combine_attempts, combine_merges, combine_extras, combine_successes); @@ -11945,7 +12031,7 @@ void dump_combine_total_stats (file) FILE *file; { - fprintf + fnotice (file, "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", total_attempts, total_merges, total_extras, total_successes); diff --git a/contrib/gcc/config.in b/contrib/gcc/config.in index b4e9898..c804a2b 100644 --- a/contrib/gcc/config.in +++ b/contrib/gcc/config.in @@ -1,10 +1,22 @@ /* config.in. Generated automatically from configure.in by autoheader. */ +/* Define if you can safely include both and . */ +#undef STRING_WITH_STRINGS + /* Define if printf supports "%p". */ #undef HAVE_PRINTF_PTR /* Define if you want expensive run-time checks. */ #undef ENABLE_CHECKING +/* Define to 1 if NLS is requested. */ +#undef ENABLE_NLS + +/* Define as 1 if you have catgets and don't want to use GNU gettext. */ +#undef HAVE_CATGETS + +/* Define as 1 if you have gettext and don't want to use GNU gettext. */ +#undef HAVE_GETTEXT + /* Define if your cpp understands the stringify operator. */ #undef HAVE_CPP_STRINGIFY @@ -18,9 +30,22 @@ /* Define if your assembler supports .balign and .p2align. */ #undef HAVE_GAS_BALIGN_AND_P2ALIGN +/* 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 uses the old HImode fild and fist notation. */ +#undef HAVE_GAS_FILDS_FISTS + /* Define if you have a working header file. */ #undef HAVE_INTTYPES_H +/* Define if your locale.h file contains LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define as 1 if you have the stpcpy function. */ +#undef HAVE_STPCPY + /* Whether malloc must be declared even if is included. */ #undef NEED_DECLARATION_MALLOC @@ -54,6 +79,9 @@ /* Whether atol must be declared even if is included. */ #undef NEED_DECLARATION_ATOL +/* Whether atof must be declared even if is included. */ +#undef NEED_DECLARATION_ATOF + /* Whether sbrk must be declared even if is included. */ #undef NEED_DECLARATION_SBRK @@ -63,6 +91,12 @@ /* Whether strerror must be declared even if is included. */ #undef NEED_DECLARATION_STRERROR +/* Whether strsignal must be declared even if is included. */ +#undef NEED_DECLARATION_STRSIGNAL + +/* Whether strstr must be declared even if is included. */ +#undef NEED_DECLARATION_STRSTR + /* Whether getcwd must be declared even if is included. */ #undef NEED_DECLARATION_GETCWD @@ -75,15 +109,79 @@ /* Whether setrlimit must be declared even if is included. */ #undef NEED_DECLARATION_SETRLIMIT -/* Define if you want expensive run-time checks. */ -#undef ENABLE_CHECKING +/* Whether putc_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_PUTC_UNLOCKED + +/* Whether fputs_unlocked must be declared even if is included. */ +#undef NEED_DECLARATION_FPUTS_UNLOCKED + +/* Define to enable the use of a default assembler. */ +#undef DEFAULT_ASSEMBLER + +/* Define to enable the use of a default linker. */ +#undef DEFAULT_LINKER + +/* Define if host mkdir takes a single argument. */ +#undef MKDIR_TAKES_ONE_ARG + +/* Define to the name of the distribution. */ +#undef PACKAGE + +/* Define to the version of the distribution. */ +#undef VERSION + +/* Define if using alloca.c. */ +#undef C_ALLOCA + +/* 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 if you have alloca, as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define if you have and it should be used (not on Ultrix). */ +#undef HAVE_ALLOCA_H /* Define if you don't have vprintf but do have _doprnt. */ #undef HAVE_DOPRNT +/* Define if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if you have . */ +#undef HAVE_VFORK_H + /* Define if you have the vprintf function. */ #undef HAVE_VPRINTF +/* Define as __inline if that's what the C compiler calls it. */ +#undef inline + +/* Define to `long' if doesn't define. */ +#undef off_t + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define to `unsigned' if doesn't define. */ +#undef size_t + +/* 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 have the ANSI C header files. */ #undef STDC_HEADERS @@ -93,6 +191,18 @@ /* Define if you can safely include both and . */ #undef TIME_WITH_SYS_TIME +/* Define vfork as fork if vfork does not work. */ +#undef vfork + +/* Define if you have the __argz_count function. */ +#undef HAVE___ARGZ_COUNT + +/* Define if you have the __argz_next function. */ +#undef HAVE___ARGZ_NEXT + +/* Define if you have the __argz_stringify function. */ +#undef HAVE___ARGZ_STRINGIFY + /* Define if you have the atoll function. */ #undef HAVE_ATOLL @@ -111,6 +221,21 @@ /* Define if you have the bzero function. */ #undef HAVE_BZERO +/* Define if you have the dcgettext function. */ +#undef HAVE_DCGETTEXT + +/* Define if you have the fputc_unlocked function. */ +#undef HAVE_FPUTC_UNLOCKED + +/* Define if you have the fputs_unlocked function. */ +#undef HAVE_FPUTS_UNLOCKED + +/* Define if you have the getcwd function. */ +#undef HAVE_GETCWD + +/* Define if you have the getpagesize function. */ +#undef HAVE_GETPAGESIZE + /* Define if you have the getrlimit function. */ #undef HAVE_GETRLIMIT @@ -126,39 +251,78 @@ /* Define if you have the kill function. */ #undef HAVE_KILL +/* Define if you have the munmap function. */ +#undef HAVE_MUNMAP + /* Define if you have the popen function. */ #undef HAVE_POPEN +/* Define if you have the putc_unlocked function. */ +#undef HAVE_PUTC_UNLOCKED + /* Define if you have the putenv function. */ #undef HAVE_PUTENV /* Define if you have the rindex function. */ #undef HAVE_RINDEX +/* Define if you have the setenv function. */ +#undef HAVE_SETENV + +/* Define if you have the setlocale function. */ +#undef HAVE_SETLOCALE + /* Define if you have the setrlimit function. */ #undef HAVE_SETRLIMIT +/* Define if you have the stpcpy function. */ +#undef HAVE_STPCPY + +/* Define if you have the strcasecmp function. */ +#undef HAVE_STRCASECMP + /* Define if you have the strchr function. */ #undef HAVE_STRCHR +/* Define if you have the strdup function. */ +#undef HAVE_STRDUP + /* Define if you have the strerror function. */ #undef HAVE_STRERROR /* Define if you have the strrchr function. */ #undef HAVE_STRRCHR +/* Define if you have the strsignal function. */ +#undef HAVE_STRSIGNAL + /* Define if you have the strtoul function. */ #undef HAVE_STRTOUL /* Define if you have the sysconf function. */ #undef HAVE_SYSCONF +/* Define if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define if you have the header file. */ +#undef HAVE_DIRECT_H + /* Define if you have the header file. */ #undef HAVE_FCNTL_H /* Define if you have the header file. */ #undef HAVE_LIMITS_H +/* Define if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define if you have the header file. */ +#undef HAVE_NL_TYPES_H + /* Define if you have the header file. */ #undef HAVE_STAB_H @@ -183,20 +347,20 @@ /* Define if you have the header file. */ #undef HAVE_SYS_RESOURCE_H +/* Define if you have the header file. */ +#undef HAVE_SYS_STAT_H + /* Define if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define if you have the header file. */ #undef HAVE_SYS_TIMES_H -/* Define if you have the header file. */ -#undef HAVE_SYS_WAIT_H - /* Define if you have the header file. */ #undef HAVE_TIME_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H -/* Define if you have the header file. */ -#undef HAVE_WAIT_H +/* Define if you have the i library (-li). */ +#undef HAVE_LIBI diff --git a/contrib/gcc/config/alpha/alpha-interix.h b/contrib/gcc/config/alpha/alpha-interix.h new file mode 100644 index 0000000..668fe93 --- /dev/null +++ b/contrib/gcc/config/alpha/alpha-interix.h @@ -0,0 +1,252 @@ +/* Definitions of target machine for GNU compiler, for DEC Alpha + running Windows/NT. + Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. + + Donn Terry, Softway Systems, Inc. + From code + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + +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. */ + +/* cpp handles __STDC__ */ +/* The three "Alpha" defines on the first such line are from the CLAXP spec */ +#undef CPP_PREDEFINES +#define CPP_PREDEFINES " \ + -D__INTERIX \ + -D__OPENNT \ + -D__Alpha_AXP -D_M_ALPHA -D_ALPHA_ \ + -D__alpha -D__alpha__\ + -D__stdcall= \ + -D__cdecl= \ + -Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(alpha) -Amachine(alpha)" + +#undef CPP_SUBTARGET_SPEC +#define CPP_SUBTARGET_SPEC "\ +-remap \ +%{posix:-D_POSIX_SOURCE} \ +-idirafter %$INTERIX_ROOT/usr/include" + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (alpha Interix)"); + +/* alpha.h sets this, but it doesn't apply to us */ +#undef OBJECT_FORMAT_ECOFF +#undef OBJECT_FORMAT_COFF + +/* LINK_SPEC */ + +/* MD_STARTFILE_PREFIX */ + +/* ASM_OUTPUT_LOOP_ALIGN; ASM_OUTPUT_ALIGN_CODE */ + +/* Codegen macro overrides for NT internal conventions */ + +/* the below are ecoff specific... we don't need them, so + undef them (they'll get a default later) */ + +#undef PUT_SDB_BLOCK_START +#undef PUT_SDB_BLOCK_END + +/* the following are OSF linker (not gld) specific... we don't want them */ +#undef HAS_INIT_SECTION +#undef LD_INIT_SWITCH +#undef LD_FINI_SWITCH + + +/* The following are needed for C++, but also needed for profiling */ + +/* Support const sections and the ctors and dtors sections for g++. + Note that there appears to be two different ways to support const + sections at the moment. You can either #define the symbol + READONLY_DATA_SECTION (giving it some code which switches to the + readonly data section) or else you can #define the symbols + EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and + SELECT_RTX_SECTION. We do both here just to be on the safe side. */ + +#define USE_CONST_SECTION 1 + +#define CONST_SECTION_ASM_OP ".rdata" + +/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. + + Note that we want to give these sections the SHF_WRITE attribute + because these sections will actually contain data (i.e. tables of + addresses of functions in the current root executable or shared library + file) and, in the case of a shared library, the relocatable addresses + will have to be properly resolved/relocated (and then written into) by + the dynamic linker when it actually attaches the given shared library + to the executing process. (Note that on SVR4, you may wish to use the + `-z text' option to the ELF linker, when building a shared library, as + an additional check that you are doing everything right. But if you do + use the `-z text' option when building a shared library, you will get + errors unless the .ctors and .dtors sections are marked as writable + via the SHF_WRITE attribute.) */ + +#define CTORS_SECTION_ASM_OP ".ctors" +#define DTORS_SECTION_ASM_OP ".dtors" + +/* A default list of other sections which we might be "in" at any given + time. For targets that use additional sections (e.g. .tdesc) you + should override this definition in the target-specific file which + includes this file. */ + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_const, in_ctors, in_dtors + +/* A default list of extra section function definitions. For targets + that use additional sections (e.g. .tdesc) you should override this + definition in the target-specific file which includes this file. */ + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CONST_SECTION_FUNCTION \ + CTORS_SECTION_FUNCTION \ + DTORS_SECTION_FUNCTION + +#undef READONLY_DATA_SECTION +#define READONLY_DATA_SECTION() const_section () + +extern void text_section (); + +#define CONST_SECTION_FUNCTION \ +void \ +const_section () \ +{ \ + if (!USE_CONST_SECTION) \ + text_section(); \ + else if (in_section != in_const) \ + { \ + fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ + in_section = in_const; \ + } \ +} + +#define CTORS_SECTION_FUNCTION \ +void \ +ctors_section () \ +{ \ + if (in_section != in_ctors) \ + { \ + fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ + in_section = in_ctors; \ + } \ +} + +#define DTORS_SECTION_FUNCTION \ +void \ +dtors_section () \ +{ \ + if (in_section != in_dtors) \ + { \ + fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ + in_section = in_dtors; \ + } \ +} + +#define INT_ASM_OP ".long" + +/* A C statement (sans semicolon) to output an element in the table of + global constructors. */ +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* A C statement (sans semicolon) to output an element in the table of + global destructors. */ +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* The linker will take care of this, and having them causes problems with + ld -r (specifically -rU). */ +#define CTOR_LISTS_DEFINED_EXTERNALLY 1 + +#define SET_ASM_OP ".set" +/* Output a definition (implements alias) */ +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ +do \ +{ \ + fprintf ((FILE), "\t"); \ + assemble_name (FILE, LABEL1); \ + fprintf (FILE, "="); \ + assemble_name (FILE, LABEL2); \ + fprintf (FILE, "\n"); \ + } \ +while (0) + +/* We use the defaults, so undef the null definitions */ +#undef PUT_SDB_FUNCTION_START +#undef PUT_SDB_FUNCTION_END +#undef PUT_SDB_EPILOGUE_END + +#define HOST_PTR_PRINTF "%p" +#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) + +/* DWARF2 Unwinding doesn't work with exception handling yet. */ +#undef DWARF2_UNWIND_INFO + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + +/* The definition of this macro implies that there are cases where + a scalar value cannot be returned in registers. + + On NT (according to the spec) anything except strings/array that fits + in 64 bits is returned in the registers (this appears to differ from + the rest of the Alpha family). */ + +#undef RETURN_IN_MEMORY +#define RETURN_IN_MEMORY(TYPE) \ + (TREE_CODE (TYPE) == ARRAY_TYPE || int_size_in_bytes(TYPE) > 8) + +#define ASM_LOAD_ADDR(loc, reg) " lda " #reg "," #loc "\n" + +#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"); \ + fprintf (FILE, "\t.set noat\n"); \ + fprintf (FILE, "\t.globl\t__fltused\n"); \ + ASM_OUTPUT_SOURCE_FILENAME (FILE, main_input_filename); \ +} + +/* The current Interix assembler (consistent with the DEC documentation) + uses a=b NOT .set a,b; .set is for assembler options. */ +#undef ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL +#define ASM_OUTPUT_DEFINE_LABEL_DIFFERENCE_SYMBOL(FILE, SY, HI, LO) \ + do { \ + assemble_name (FILE, SY); \ + fputc ('=', FILE); \ + assemble_name (FILE, HI); \ + fputc ('-', FILE); \ + assemble_name (FILE, LO); \ + } while (0) diff --git a/contrib/gcc/config/alpha/alpha.c b/contrib/gcc/config/alpha/alpha.c index 0b72289..2d62693 100644 --- a/contrib/gcc/config/alpha/alpha.c +++ b/contrib/gcc/config/alpha/alpha.c @@ -1,5 +1,5 @@ /* Subroutines used for code generation on the DEC Alpha. - Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -48,7 +48,7 @@ extern int rtx_equal_function_value_matters; /* Specify which cpu to schedule for. */ enum processor_type alpha_cpu; -static char* const alpha_cpu_name[] = +static const char * const alpha_cpu_name[] = { "ev4", "ev5", "ev6" }; @@ -67,11 +67,11 @@ enum alpha_fp_trap_mode alpha_fptm; /* Strings decoded into the above options. */ -char *alpha_cpu_string; /* -mcpu= */ -char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */ -char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */ -char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */ -char *alpha_mlat_string; /* -mmemory-latency= */ +const char *alpha_cpu_string; /* -mcpu= */ +const char *alpha_tp_string; /* -mtrap-precision=[p|s|i] */ +const char *alpha_fprm_string; /* -mfp-rounding-mode=[n|m|c|d] */ +const char *alpha_fptm_string; /* -mfp-trap-mode=[n|u|su|sui] */ +const char *alpha_mlat_string; /* -mmemory-latency= */ /* Save information from a "cmpxx" operation until the branch or scc is emitted. */ @@ -79,6 +79,10 @@ char *alpha_mlat_string; /* -mmemory-latency= */ rtx alpha_compare_op0, alpha_compare_op1; int alpha_compare_fp_p; +/* Define the information needed to modify the epilogue for EH. */ + +rtx alpha_eh_epilogue_sp_ofs; + /* Non-zero if inside of a function, because the Alpha asm can't handle .files inside of functions. */ @@ -96,6 +100,10 @@ int alpha_memory_latency = 3; static int alpha_function_needs_gp; +/* The alias set for prologue/epilogue register save/restore. */ + +static int alpha_sr_alias_set; + /* Declarations of static functions. */ static void alpha_set_memflags_1 PROTO((rtx, int, int, int)); @@ -126,49 +134,6 @@ static int alpha_does_function_need_gp void override_options () { - alpha_cpu - = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6 - : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4); - - if (alpha_cpu_string) - { - if (! strcmp (alpha_cpu_string, "ev4") - || ! strcmp (alpha_cpu_string, "21064")) - { - alpha_cpu = PROCESSOR_EV4; - target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX); - } - else if (! strcmp (alpha_cpu_string, "ev5") - || ! strcmp (alpha_cpu_string, "21164")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags &= ~ (MASK_BWX | MASK_CIX | MASK_MAX); - } - else if (! strcmp (alpha_cpu_string, "ev56") - || ! strcmp (alpha_cpu_string, "21164a")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags |= MASK_BWX; - target_flags &= ~ (MASK_CIX | MASK_MAX); - } - else if (! strcmp (alpha_cpu_string, "pca56") - || ! strcmp (alpha_cpu_string, "21164PC") - || ! strcmp (alpha_cpu_string, "21164pc")) - { - alpha_cpu = PROCESSOR_EV5; - target_flags |= MASK_BWX | MASK_MAX; - target_flags &= ~ MASK_CIX; - } - else if (! strcmp (alpha_cpu_string, "ev6") - || ! strcmp (alpha_cpu_string, "21264")) - { - alpha_cpu = PROCESSOR_EV6; - target_flags |= MASK_BWX | MASK_CIX | MASK_MAX; - } - else - error ("bad value `%s' for -mcpu switch", alpha_cpu_string); - } - alpha_tp = ALPHA_TP_PROG; alpha_fprm = ALPHA_FPRM_NORM; alpha_fptm = ALPHA_FPTM_N; @@ -226,10 +191,54 @@ override_options () error ("bad value `%s' for -mfp-trap-mode switch", alpha_fptm_string); } - /* Do some sanity checks on the above option. */ + alpha_cpu + = TARGET_CPU_DEFAULT & MASK_CPU_EV6 ? PROCESSOR_EV6 + : (TARGET_CPU_DEFAULT & MASK_CPU_EV5 ? PROCESSOR_EV5 : PROCESSOR_EV4); + + if (alpha_cpu_string) + { + if (! strcmp (alpha_cpu_string, "ev4") + || ! strcmp (alpha_cpu_string, "21064")) + { + alpha_cpu = PROCESSOR_EV4; + target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX); + } + else if (! strcmp (alpha_cpu_string, "ev5") + || ! strcmp (alpha_cpu_string, "21164")) + { + alpha_cpu = PROCESSOR_EV5; + target_flags &= ~ (MASK_BWX | MASK_MAX | MASK_FIX | MASK_CIX); + } + else if (! strcmp (alpha_cpu_string, "ev56") + || ! strcmp (alpha_cpu_string, "21164a")) + { + alpha_cpu = PROCESSOR_EV5; + target_flags |= MASK_BWX; + target_flags &= ~ (MASK_MAX | MASK_FIX | MASK_CIX); + } + else if (! strcmp (alpha_cpu_string, "pca56") + || ! strcmp (alpha_cpu_string, "21164PC") + || ! strcmp (alpha_cpu_string, "21164pc")) + { + alpha_cpu = PROCESSOR_EV5; + target_flags |= MASK_BWX | MASK_MAX; + target_flags &= ~ (MASK_FIX | MASK_CIX); + } + else if (! strcmp (alpha_cpu_string, "ev6") + || ! strcmp (alpha_cpu_string, "21264")) + { + alpha_cpu = PROCESSOR_EV6; + target_flags |= MASK_BWX | MASK_MAX | MASK_FIX; + target_flags &= ~ (MASK_CIX); + } + else + error ("bad value `%s' for -mcpu switch", alpha_cpu_string); + } + + /* Do some sanity checks on the above options. */ if ((alpha_fptm == ALPHA_FPTM_SU || alpha_fptm == ALPHA_FPTM_SUI) - && alpha_tp != ALPHA_TP_INSN) + && alpha_tp != ALPHA_TP_INSN && alpha_cpu != PROCESSOR_EV6) { warning ("fp software completion requires -mtrap-precision=i"); alpha_tp = ALPHA_TP_INSN; @@ -256,11 +265,11 @@ override_options () if (!alpha_mlat_string) alpha_mlat_string = "L1"; - if (isdigit (alpha_mlat_string[0]) + if (ISDIGIT ((unsigned char)alpha_mlat_string[0]) && (lat = strtol (alpha_mlat_string, &end, 10), *end == '\0')) ; else if ((alpha_mlat_string[0] == 'L' || alpha_mlat_string[0] == 'l') - && isdigit (alpha_mlat_string[1]) + && ISDIGIT ((unsigned char)alpha_mlat_string[1]) && alpha_mlat_string[2] == '\0') { static int const cache_latency[][4] = @@ -298,6 +307,9 @@ override_options () /* Default the definition of "small data" to 8 bytes. */ if (!g_switch_set) g_switch_value = 8; + + /* Acquire a unique set number for our register saves and restores. */ + alpha_sr_alias_set = new_alias_set (); } /* Returns 1 if VALUE is a mask that contains full bytes of zero or ones. */ @@ -337,7 +349,6 @@ reg_or_6bit_operand (op, mode) { return ((GET_CODE (op) == CONST_INT && (unsigned HOST_WIDE_INT) INTVAL (op) < 64) - || GET_CODE (op) == CONSTANT_P_RTX || register_operand (op, mode)); } @@ -351,7 +362,6 @@ reg_or_8bit_operand (op, mode) { return ((GET_CODE (op) == CONST_INT && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100) - || GET_CODE (op) == CONSTANT_P_RTX || register_operand (op, mode)); } @@ -363,8 +373,7 @@ cint8_operand (op, mode) enum machine_mode mode ATTRIBUTE_UNUSED; { return ((GET_CODE (op) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100) - || GET_CODE (op) == CONSTANT_P_RTX); + && (unsigned HOST_WIDE_INT) INTVAL (op) < 0x100)); } /* Return 1 if the operand is a valid second operand to an add insn. */ @@ -375,11 +384,9 @@ add_operand (op, mode) enum machine_mode mode; { if (GET_CODE (op) == CONST_INT) + /* Constraints I, J, O and P are covered by K. */ return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'K') - || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L') - || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O')); - else if (GET_CODE (op) == CONSTANT_P_RTX) - return 1; + || CONST_OK_FOR_LETTER_P (INTVAL (op), 'L')); return register_operand (op, mode); } @@ -393,10 +400,8 @@ sext_add_operand (op, mode) enum machine_mode mode; { if (GET_CODE (op) == CONST_INT) - return ((unsigned HOST_WIDE_INT) INTVAL (op) < 255 - || (unsigned HOST_WIDE_INT) (- INTVAL (op)) < 255); - else if (GET_CODE (op) == CONSTANT_P_RTX) - return 1; + return (CONST_OK_FOR_LETTER_P (INTVAL (op), 'I') + || CONST_OK_FOR_LETTER_P (INTVAL (op), 'O')); return register_operand (op, mode); } @@ -427,8 +432,6 @@ and_operand (op, mode) return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100 || zap_mask (INTVAL (op))); - else if (GET_CODE (op) == CONSTANT_P_RTX) - return 1; return register_operand (op, mode); } @@ -443,8 +446,6 @@ or_operand (op, mode) if (GET_CODE (op) == CONST_INT) return ((unsigned HOST_WIDE_INT) INTVAL (op) < 0x100 || (unsigned HOST_WIDE_INT) ~ INTVAL (op) < 0x100); - else if (GET_CODE (op) == CONSTANT_P_RTX) - return 1; return register_operand (op, mode); } @@ -483,9 +484,9 @@ mode_mask_operand (op, mode) return (GET_CODE (op) == CONST_INT && (INTVAL (op) == 0xff || INTVAL (op) == 0xffff - || INTVAL (op) == 0xffffffff + || INTVAL (op) == (HOST_WIDE_INT)0xffffffff #if HOST_BITS_PER_WIDE_INT == 64 - || INTVAL (op) == 0xffffffffffffffff + || INTVAL (op) == -1 #endif )); } @@ -544,7 +545,6 @@ reg_or_cint_operand (op, mode) enum machine_mode mode; { return (GET_CODE (op) == CONST_INT - || GET_CODE (op) == CONSTANT_P_RTX || register_operand (op, mode)); } @@ -562,7 +562,7 @@ some_operand (op, mode) switch (GET_CODE (op)) { case REG: case MEM: case CONST_DOUBLE: case CONST_INT: case LABEL_REF: - case SYMBOL_REF: case CONST: case CONSTANT_P_RTX: + case SYMBOL_REF: case CONST: return 1; case SUBREG: @@ -611,9 +611,11 @@ input_operand (op, mode) return GET_MODE_CLASS (mode) == MODE_FLOAT && op == CONST0_RTX (mode); case CONST_INT: - case CONSTANT_P_RTX: return mode == QImode || mode == HImode || add_operand (op, mode); + case CONSTANT_P_RTX: + return 1; + default: break; } @@ -726,40 +728,49 @@ divmod_operator (op, mode) a constant. It must be a valid address. This means that we can do this as an aligned reference plus some offset. - Take into account what reload will do. - - We could say that out-of-range stack slots are alignable, but that would - complicate get_aligned_mem and it isn't worth the trouble since few - functions have large stack space. */ + Take into account what reload will do. */ int aligned_memory_operand (op, mode) register rtx op; enum machine_mode mode; { - if (GET_CODE (op) == SUBREG) + rtx base; + + if (reload_in_progress) { - if (GET_MODE (op) != mode) - return 0; - op = SUBREG_REG (op); - mode = GET_MODE (op); + rtx tmp = op; + if (GET_CODE (tmp) == SUBREG) + tmp = SUBREG_REG (tmp); + if (GET_CODE (tmp) == REG + && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) + { + op = reg_equiv_memory_loc[REGNO (tmp)]; + if (op == 0) + return 0; + } } - if (reload_in_progress && GET_CODE (op) == REG - && REGNO (op) >= FIRST_PSEUDO_REGISTER) - op = reg_equiv_mem[REGNO (op)]; - - if (GET_CODE (op) != MEM || GET_MODE (op) != mode - || ! memory_address_p (mode, XEXP (op, 0))) + if (GET_CODE (op) != MEM + || GET_MODE (op) != mode) return 0; - op = XEXP (op, 0); - if (GET_CODE (op) == PLUS) - op = XEXP (op, 0); + /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) + sorts of constructs. Dig for the real base register. */ + if (reload_in_progress + && GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 0)) == PLUS) + base = XEXP (XEXP (op, 0), 0); + else + { + if (! memory_address_p (mode, op)) + return 0; + base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); + } - return (GET_CODE (op) == REG - && REGNO_POINTER_ALIGN (REGNO (op)) >= 4); + return (GET_CODE (base) == REG + && REGNO_POINTER_ALIGN (REGNO (base)) >= 4); } /* Similar, but return 1 if OP is a MEM which is not alignable. */ @@ -769,31 +780,42 @@ unaligned_memory_operand (op, mode) register rtx op; enum machine_mode mode; { - if (GET_CODE (op) == SUBREG) + rtx base; + + if (reload_in_progress) { - if (GET_MODE (op) != mode) - return 0; - op = SUBREG_REG (op); - mode = GET_MODE (op); + rtx tmp = op; + if (GET_CODE (tmp) == SUBREG) + tmp = SUBREG_REG (tmp); + if (GET_CODE (tmp) == REG + && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) + { + op = reg_equiv_memory_loc[REGNO (tmp)]; + if (op == 0) + return 0; + } } - if (reload_in_progress && GET_CODE (op) == REG - && REGNO (op) >= FIRST_PSEUDO_REGISTER) - op = reg_equiv_mem[REGNO (op)]; - - if (GET_CODE (op) != MEM || GET_MODE (op) != mode) + if (GET_CODE (op) != MEM + || GET_MODE (op) != mode) return 0; - op = XEXP (op, 0); - if (! memory_address_p (mode, op)) - return 1; - - if (GET_CODE (op) == PLUS) - op = XEXP (op, 0); + /* LEGITIMIZE_RELOAD_ADDRESS creates (plus (plus reg const_hi) const_lo) + sorts of constructs. Dig for the real base register. */ + if (reload_in_progress + && GET_CODE (op) == PLUS + && GET_CODE (XEXP (op, 0)) == PLUS) + base = XEXP (XEXP (op, 0), 0); + else + { + if (! memory_address_p (mode, op)) + return 0; + base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op); + } - return (GET_CODE (op) != REG - || REGNO_POINTER_ALIGN (REGNO (op)) < 4); + return (GET_CODE (base) == REG + && REGNO_POINTER_ALIGN (REGNO (base)) < 4); } /* Return 1 if OP is either a register or an unaligned memory location. */ @@ -822,6 +844,74 @@ any_memory_operand (op, mode) && REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)); } +/* Returns 1 if OP is not an eliminable register. + + This exists to cure a pathological abort in the s8addq (et al) patterns, + + long foo () { long t; bar(); return (long) &t * 26107; } + + which run afoul of a hack in reload to cure a (presumably) similar + problem with lea-type instructions on other targets. But there is + one of us and many of them, so work around the problem by selectively + preventing combine from making the optimization. */ + +int +reg_not_elim_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + rtx inner = op; + if (GET_CODE (op) == SUBREG) + inner = SUBREG_REG (op); + if (inner == frame_pointer_rtx || inner == arg_pointer_rtx) + return 0; + + return register_operand (op, mode); +} + +/* Return 1 is OP is a memory location that is not a reference (using + an AND) to an unaligned location. Take into account what reload + will do. */ + +int +normal_memory_operand (op, mode) + register rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + if (reload_in_progress) + { + rtx tmp = op; + if (GET_CODE (tmp) == SUBREG) + tmp = SUBREG_REG (tmp); + if (GET_CODE (tmp) == REG + && REGNO (tmp) >= FIRST_PSEUDO_REGISTER) + { + op = reg_equiv_memory_loc[REGNO (tmp)]; + + /* This may not have been assigned an equivalent address if it will + be eliminated. In that case, it doesn't matter what we do. */ + if (op == 0) + return 1; + } + } + + return GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) != AND; +} + +/* Accept a register, but not a subreg of any kind. This allows us to + avoid pathological cases in reload wrt data movement common in + int->fp conversion. */ + +int +reg_no_subreg_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + if (GET_CODE (op) == SUBREG) + return 0; + return register_operand (op, mode); +} + /* Return 1 if this function can directly return via $26. */ int @@ -835,7 +925,8 @@ direct_return () /* REF is an alignable memory location. Place an aligned SImode reference into *PALIGNED_MEM and the number of bits to shift into - *PBITNUM. */ + *PBITNUM. SCRATCH is a free register for use in reloading out + of range stack slots. */ void get_aligned_mem (ref, paligned_mem, pbitnum) @@ -845,33 +936,33 @@ get_aligned_mem (ref, paligned_mem, pbitnum) rtx base; HOST_WIDE_INT offset = 0; - if (GET_CODE (ref) == SUBREG) - { - offset = SUBREG_WORD (ref) * UNITS_PER_WORD; - if (BYTES_BIG_ENDIAN) - offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref))) - - MIN (UNITS_PER_WORD, - GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref))))); - ref = SUBREG_REG (ref); - } + if (GET_CODE (ref) != MEM) + abort (); - if (GET_CODE (ref) == REG) - ref = reg_equiv_mem[REGNO (ref)]; + if (reload_in_progress + && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0))) + { + base = find_replacement (&XEXP (ref, 0)); - if (reload_in_progress) - base = find_replacement (&XEXP (ref, 0)); + if (! memory_address_p (GET_MODE (ref), base)) + abort (); + } else - base = XEXP (ref, 0); + { + base = XEXP (ref, 0); + } if (GET_CODE (base) == PLUS) offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); - *paligned_mem = gen_rtx_MEM (SImode, - plus_constant (base, offset & ~3)); - MEM_IN_STRUCT_P (*paligned_mem) = MEM_IN_STRUCT_P (ref); - MEM_VOLATILE_P (*paligned_mem) = MEM_VOLATILE_P (ref); + *paligned_mem = gen_rtx_MEM (SImode, plus_constant (base, offset & ~3)); + MEM_COPY_ATTRIBUTES (*paligned_mem, ref); RTX_UNCHANGING_P (*paligned_mem) = RTX_UNCHANGING_P (ref); + /* Sadly, we cannot use alias sets here because we may overlap other + data in a different alias set. */ + /* MEM_ALIAS_SET (*paligned_mem) = MEM_ALIAS_SET (ref); */ + *pbitnum = GEN_INT ((offset & 3) * 8); } @@ -886,23 +977,21 @@ get_unaligned_address (ref, extra_offset) rtx base; HOST_WIDE_INT offset = 0; - if (GET_CODE (ref) == SUBREG) - { - offset = SUBREG_WORD (ref) * UNITS_PER_WORD; - if (BYTES_BIG_ENDIAN) - offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (ref))) - - MIN (UNITS_PER_WORD, - GET_MODE_SIZE (GET_MODE (SUBREG_REG (ref))))); - ref = SUBREG_REG (ref); - } + if (GET_CODE (ref) != MEM) + abort (); - if (GET_CODE (ref) == REG) - ref = reg_equiv_mem[REGNO (ref)]; + if (reload_in_progress + && ! memory_address_p (GET_MODE (ref), XEXP (ref, 0))) + { + base = find_replacement (&XEXP (ref, 0)); - if (reload_in_progress) - base = find_replacement (&XEXP (ref, 0)); + if (! memory_address_p (GET_MODE (ref), base)) + abort (); + } else - base = XEXP (ref, 0); + { + base = XEXP (ref, 0); + } if (GET_CODE (base) == PLUS) offset += INTVAL (XEXP (base, 1)), base = XEXP (base, 0); @@ -945,6 +1034,12 @@ alpha_set_memflags_1 (x, in_struct_p, volatile_p, unchanging_p) MEM_IN_STRUCT_P (x) = in_struct_p; MEM_VOLATILE_P (x) = volatile_p; RTX_UNCHANGING_P (x) = unchanging_p; + /* Sadly, we cannot use alias sets because the extra aliasing + produced by the AND interferes. Given that two-byte quantities + are the only thing we would be able to differentiate anyway, + there does not seem to be any point in convoluting the early + out of the alias check. */ + /* MEM_ALIAS_SET (x) = alias_set; */ break; default: @@ -963,14 +1058,19 @@ alpha_set_memflags (insn, ref) rtx insn; rtx ref; { - /* Note that it is always safe to get these flags, though they won't - be what we think if REF is not a MEM. */ - int in_struct_p = MEM_IN_STRUCT_P (ref); - int volatile_p = MEM_VOLATILE_P (ref); - int unchanging_p = RTX_UNCHANGING_P (ref); - - if (GET_CODE (ref) != MEM - || (! in_struct_p && ! volatile_p && ! unchanging_p)) + int in_struct_p, volatile_p, unchanging_p; + + if (GET_CODE (ref) != MEM) + return; + + in_struct_p = MEM_IN_STRUCT_P (ref); + volatile_p = MEM_VOLATILE_P (ref); + unchanging_p = RTX_UNCHANGING_P (ref); + + /* This is only called from alpha.md, after having had something + generated from one of the insn patterns. So if everything is + zero, the pattern is already up-to-date. */ + if (! in_struct_p && ! volatile_p && ! unchanging_p) return; alpha_set_memflags_1 (insn, in_struct_p, volatile_p, unchanging_p); @@ -1128,7 +1228,7 @@ alpha_emit_set_const_1 (target, mode, c, n) for (; bits > 0; bits--) if ((temp = (alpha_emit_set_const (subtarget, mode, - (unsigned HOST_WIDE_INT) c >> bits, i))) != 0 + (unsigned HOST_WIDE_INT) (c >> bits), i))) != 0 || ((temp = (alpha_emit_set_const (subtarget, mode, ((unsigned HOST_WIDE_INT) c) >> bits, i))) @@ -1176,70 +1276,66 @@ alpha_emit_set_const_1 (target, mode, c, n) return 0; } -#if HOST_BITS_PER_WIDE_INT == 64 /* 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, c) +alpha_emit_set_long_const (target, c1, c2) rtx target; - HOST_WIDE_INT c; + HOST_WIDE_INT c1, c2; { - /* Use a pseudo if highly optimizing and still generating RTL. */ - rtx subtarget - = (flag_expensive_optimizations && rtx_equal_function_value_matters - ? 0 : target); HOST_WIDE_INT d1, d2, d3, d4; - rtx r1, r2; /* Decompose the entire word */ - d1 = ((c & 0xffff) ^ 0x8000) - 0x8000; - c -= d1; - d2 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000; - c = (c - d2) >> 32; - d3 = ((c & 0xffff) ^ 0x8000) - 0x8000; - c -= d3; - d4 = ((c & 0xffffffff) ^ 0x80000000) - 0x80000000; - - if (c - d4 != 0) - abort(); +#if HOST_BITS_PER_WIDE_INT >= 64 + if (c2 != -(c1 < 0)) + abort (); + d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; + c1 -= d1; + d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; + c1 = (c1 - d2) >> 32; + d3 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; + c1 -= d3; + d4 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; + if (c1 != d4) + abort (); +#else + d1 = ((c1 & 0xffff) ^ 0x8000) - 0x8000; + c1 -= d1; + d2 = ((c1 & 0xffffffff) ^ 0x80000000) - 0x80000000; + if (c1 != d2) + abort (); + c2 += (d2 < 0); + d3 = ((c2 & 0xffff) ^ 0x8000) - 0x8000; + c2 -= d3; + d4 = ((c2 & 0xffffffff) ^ 0x80000000) - 0x80000000; + if (c2 != d4) + abort (); +#endif /* Construct the high word */ - if (d3 == 0) - r1 = copy_to_suggested_reg (GEN_INT (d4), subtarget, DImode); - else if (d4 == 0) - r1 = copy_to_suggested_reg (GEN_INT (d3), subtarget, DImode); + if (d4) + { + emit_move_insn (target, GEN_INT (d4)); + if (d3) + emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d3))); + } else - r1 = expand_binop (DImode, add_optab, GEN_INT (d3), GEN_INT (d4), - subtarget, 0, OPTAB_WIDEN); + emit_move_insn (target, GEN_INT (d3)); /* Shift it into place */ - r2 = expand_binop (DImode, ashl_optab, r1, GEN_INT (32), - subtarget, 0, OPTAB_WIDEN); - - if (subtarget == 0 && d1 == d3 && d2 == d4) - r1 = expand_binop (DImode, add_optab, r1, r2, subtarget, 0, OPTAB_WIDEN); - else - { - r1 = r2; - - /* Add in the low word */ - if (d2 != 0) - r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d2), - subtarget, 0, OPTAB_WIDEN); - if (d1 != 0) - r1 = expand_binop (DImode, add_optab, r1, GEN_INT (d1), - subtarget, 0, OPTAB_WIDEN); - } + emit_move_insn (target, gen_rtx_ASHIFT (DImode, target, GEN_INT (32))); - if (subtarget == 0) - r1 = copy_to_suggested_reg(r1, target, DImode); + /* Add in the low bits. */ + if (d2) + emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d2))); + if (d1) + emit_move_insn (target, gen_rtx_PLUS (DImode, target, GEN_INT (d1))); - return r1; + return target; } -#endif /* HOST_BITS_PER_WIDE_INT == 64 */ /* Generate the comparison for a conditional branch. */ @@ -1416,7 +1512,7 @@ alpha_emit_conditional_move (cmp, mode) abort (); } - /* ??? We mark the the branch mode to be CCmode to prevent the compare + /* ??? We mark the branch mode to be CCmode to prevent the compare and cmov from being combined, since the compare insn follows IEEE rules that the cmov does not. */ if (alpha_compare_fp_p && !flag_fast_math) @@ -1517,6 +1613,8 @@ alpha_expand_unaligned_load (tgt, mem, size, ofs, sign) emit_insn (gen_extqh (exth, memh, addr)); mode = DImode; break; + default: + abort(); } addr = expand_binop (mode, ior_optab, gen_lowpart (mode, extl), @@ -1790,7 +1888,8 @@ alpha_expand_block_move (operands) { rtx bytes_rtx = operands[2]; rtx align_rtx = operands[3]; - HOST_WIDE_INT bytes = INTVAL (bytes_rtx); + HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx); + HOST_WIDE_INT bytes = orig_bytes; HOST_WIDE_INT src_align = INTVAL (align_rtx); HOST_WIDE_INT dst_align = src_align; rtx orig_src = operands[1]; @@ -1863,17 +1962,24 @@ alpha_expand_block_move (operands) enum machine_mode mode; tmp = XEXP (XEXP (orig_src, 0), 0); - mode = mode_for_size (bytes, MODE_INT, 1); + /* Don't use the existing register if we're reading more than + 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 - && GET_MODE_SIZE (GET_MODE (tmp)) <= bytes) + && GET_MODE_SIZE (GET_MODE (tmp)) >= bytes) { - /* Whee! Optimize the load to use the existing register. */ - data_regs[nregs++] = gen_lowpart (mode, tmp); + if (mode == TImode) + { + data_regs[nregs] = gen_lowpart (DImode, tmp); + data_regs[nregs+1] = gen_highpart (DImode, tmp); + nregs += 2; + } + else + data_regs[nregs++] = gen_lowpart (mode, tmp); goto src_done; } - /* ??? We could potentially be copying 3 bytes or whatnot from - a wider reg. Probably not worth worrying about. */ /* No appropriate mode; fall back on memory. */ orig_src = change_address (orig_src, GET_MODE (orig_src), copy_addr_to_reg (XEXP (orig_src, 0))); @@ -1890,9 +1996,9 @@ alpha_expand_block_move (operands) for (i = 0; i < words; ++i) { emit_move_insn (data_regs[nregs+i], - change_address(orig_src, DImode, - plus_constant (XEXP (orig_src, 0), - ofs + i*8))); + change_address (orig_src, DImode, + plus_constant (XEXP (orig_src, 0), + ofs + i*8))); } nregs += words; @@ -1909,9 +2015,9 @@ alpha_expand_block_move (operands) for (i = 0; i < words; ++i) { emit_move_insn (data_regs[nregs+i], - change_address(orig_src, SImode, - plus_constant (XEXP (orig_src, 0), - ofs + i*4))); + change_address (orig_src, SImode, + plus_constant (XEXP (orig_src, 0), + ofs + i*4))); } nregs += words; @@ -1925,7 +2031,8 @@ alpha_expand_block_move (operands) for (i = 0; i < words+1; ++i) data_regs[nregs+i] = gen_reg_rtx(DImode); - alpha_expand_unaligned_load_words(data_regs+nregs, orig_src, words, ofs); + alpha_expand_unaligned_load_words (data_regs + nregs, orig_src, + words, ofs); nregs += words; bytes -= words * 8; @@ -1979,7 +2086,7 @@ alpha_expand_block_move (operands) } src_done: - if (nregs > sizeof(data_regs)/sizeof(*data_regs)) + if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs))) abort(); /* @@ -1993,19 +2100,51 @@ alpha_expand_block_move (operands) enum machine_mode mode; tmp = XEXP (XEXP (orig_dst, 0), 0); - mode = mode_for_size (bytes, MODE_INT, 1); - if (GET_MODE (tmp) == mode && nregs == 1) + mode = mode_for_size (orig_bytes * BITS_PER_UNIT, MODE_INT, 1); + if (GET_MODE (tmp) == mode) { - emit_move_insn (tmp, data_regs[0]); - i = 1; - goto dst_done; + if (nregs == 1) + { + emit_move_insn (tmp, data_regs[0]); + i = 1; + goto dst_done; + } + else if (nregs == 2 && mode == TImode) + { + /* Undo the subregging done above when copying between + two TImode registers. */ + if (GET_CODE (data_regs[0]) == SUBREG + && GET_MODE (SUBREG_REG (data_regs[0])) == TImode) + { + emit_move_insn (tmp, SUBREG_REG (data_regs[0])); + } + else + { + rtx seq; + + start_sequence (); + emit_move_insn (gen_lowpart (DImode, tmp), data_regs[0]); + emit_move_insn (gen_highpart (DImode, tmp), data_regs[1]); + seq = get_insns (); + end_sequence (); + + emit_no_conflict_block (seq, tmp, data_regs[0], + data_regs[1], NULL_RTX); + } + + i = 2; + goto dst_done; + } } /* ??? If nregs > 1, consider reconstructing the word in regs. */ /* ??? Optimize mode < dst_mode with strict_low_part. */ - /* No appropriate mode; fall back on memory. */ + + /* No appropriate mode; fall back on memory. We can speed things + up by recognizing extra alignment information. */ orig_dst = change_address (orig_dst, GET_MODE (orig_dst), copy_addr_to_reg (XEXP (orig_dst, 0))); + dst_align = GET_MODE_SIZE (GET_MODE (tmp)); } /* Write out the data in whatever chunks reading the source allowed. */ @@ -2013,9 +2152,9 @@ alpha_expand_block_move (operands) { while (i < nregs && GET_MODE (data_regs[i]) == DImode) { - emit_move_insn (change_address(orig_dst, DImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), + emit_move_insn (change_address (orig_dst, DImode, + plus_constant (XEXP (orig_dst, 0), + ofs)), data_regs[i]); ofs += 8; i++; @@ -2030,13 +2169,13 @@ alpha_expand_block_move (operands) tmp = expand_binop (DImode, lshr_optab, data_regs[i], GEN_INT (32), NULL_RTX, 1, OPTAB_WIDEN); - emit_move_insn (change_address(orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs)), + emit_move_insn (change_address (orig_dst, SImode, + plus_constant (XEXP (orig_dst, 0), + ofs)), gen_lowpart (SImode, data_regs[i])); - emit_move_insn (change_address(orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs+4)), + emit_move_insn (change_address (orig_dst, SImode, + plus_constant (XEXP (orig_dst, 0), + ofs+4)), gen_lowpart (SImode, tmp)); ofs += 8; i++; @@ -2155,6 +2294,22 @@ alpha_expand_block_clear (operands) align = 2; } } + else if (GET_CODE (tmp) == ADDRESSOF) + { + enum machine_mode mode; + + mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 1); + if (GET_MODE (XEXP (tmp, 0)) == mode) + { + emit_move_insn (XEXP (tmp, 0), const0_rtx); + return 1; + } + + /* No appropriate mode; fall back on memory. */ + orig_dst = change_address (orig_dst, GET_MODE (orig_dst), + copy_addr_to_reg (tmp)); + align = GET_MODE_SIZE (GET_MODE (XEXP (tmp, 0))); + } /* Handle a block of contiguous words first. */ @@ -2179,9 +2334,9 @@ alpha_expand_block_clear (operands) for (i = 0; i < words; ++i) { - emit_move_insn (change_address(orig_dst, SImode, - plus_constant (XEXP (orig_dst, 0), - ofs + i*4)), + emit_move_insn (change_address (orig_dst, SImode, + plus_constant (XEXP (orig_dst, 0), + ofs + i*4)), const0_rtx); } @@ -2431,6 +2586,7 @@ void alpha_init_expanders () { alpha_return_addr_rtx = NULL_RTX; + alpha_eh_epilogue_sp_ofs = NULL_RTX; /* Arrange to save and restore machine status around nested functions. */ save_machine_status = alpha_save_machine_status; @@ -2454,7 +2610,7 @@ alpha_return_addr (count, frame) /* No rtx yet. Invent one, and initialize it from $26 in the prologue. */ alpha_return_addr_rtx = gen_reg_rtx (Pmode); - init = gen_rtx_SET (Pmode, alpha_return_addr_rtx, + init = gen_rtx_SET (VOIDmode, alpha_return_addr_rtx, gen_rtx_REG (Pmode, REG_RA)); /* Emit the insn to the prologue with the other argument copies. */ @@ -2478,9 +2634,9 @@ alpha_ra_ever_killed () return regs_ever_live[REG_RA]; push_topmost_sequence (); - top = get_insns(); + top = get_insns (); pop_topmost_sequence (); - + return reg_set_between_p (gen_rtx_REG (Pmode, REG_RA), top, NULL_RTX); } @@ -2729,7 +2885,7 @@ print_operand (file, x, code) && CONST_DOUBLE_LOW (x) == -1) fprintf (file, "q"); #else - else if (GET_CODE (x) == CONST_INT && INTVAL (x) == 0xffffffffffffffff) + else if (GET_CODE (x) == CONST_INT && INTVAL (x) == -1) fprintf (file, "q"); else if (GET_CODE (x) == CONST_DOUBLE && CONST_DOUBLE_HIGH (x) == 0 @@ -2826,6 +2982,37 @@ print_operand (file, x, code) output_operand_lossage ("invalid %%xn code"); } } + +void +print_operand_address (file, addr) + FILE *file; + rtx addr; +{ + int basereg = 31; + HOST_WIDE_INT offset = 0; + + if (GET_CODE (addr) == AND) + addr = XEXP (addr, 0); + + if (GET_CODE (addr) == PLUS + && GET_CODE (XEXP (addr, 1)) == CONST_INT) + { + offset = INTVAL (XEXP (addr, 1)); + addr = XEXP (addr, 0); + } + if (GET_CODE (addr) == REG) + basereg = REGNO (addr); + else if (GET_CODE (addr) == SUBREG + && GET_CODE (SUBREG_REG (addr)) == REG) + basereg = REGNO (SUBREG_REG (addr)) + SUBREG_WORD (addr); + else if (GET_CODE (addr) == CONST_INT) + offset = INTVAL (addr); + else + abort (); + + fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset); + fprintf (file, "($%d)", basereg); +} /* Emit RTL insns to initialize the variable parts of a trampoline at TRAMP. FNADDR is an RTX for the address of the function's pure @@ -2846,10 +3033,14 @@ alpha_initialize_trampoline (tramp, fnaddr, cxt, fnofs, cxtofs, jmpofs) int fnofs, cxtofs, jmpofs; { rtx temp, temp1, addr; - /* ??? Something is wrong with VMS codegen in that we get aborts when - using ptr_mode. Hack around it for now. */ + /* VMS really uses DImode pointers in memory at this point. */ enum machine_mode mode = TARGET_OPEN_VMS ? Pmode : ptr_mode; +#ifdef POINTERS_EXTEND_UNSIGNED + fnaddr = convert_memory_address (mode, fnaddr); + cxt = convert_memory_address (mode, cxt); +#endif + /* Store function address and CXT. */ addr = memory_address (mode, plus_constant (tramp, fnofs)); emit_move_insn (gen_rtx (MEM, mode, addr), fnaddr); @@ -2953,7 +3144,7 @@ alpha_builtin_saveregs (arglist) dest = change_address (block, ptr_mode, XEXP (block, 0)); emit_move_insn (dest, addr); - if (flag_check_memory_usage) + if (current_function_check_memory_usage) emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, dest, ptr_mode, GEN_INT (GET_MODE_SIZE (ptr_mode)), @@ -2967,7 +3158,7 @@ alpha_builtin_saveregs (arglist) POINTER_SIZE/BITS_PER_UNIT)); emit_move_insn (dest, argsize); - if (flag_check_memory_usage) + if (current_function_check_memory_usage) emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, dest, ptr_mode, GEN_INT (GET_MODE_SIZE @@ -3190,13 +3381,39 @@ alpha_does_function_need_gp () void alpha_write_verstamp (file) - FILE *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 () +{ + rtx seq = gen_sequence (); + end_sequence (); + + if (GET_CODE (seq) == SEQUENCE) + { + int i = XVECLEN (seq, 0); + while (--i >= 0) + RTX_FRAME_RELATED_P (XVECEXP (seq, 0, i)) = 1; + return emit_insn (seq); + } + else + { + seq = emit_insn (seq); + RTX_FRAME_RELATED_P (seq) = 1; + return seq; + } +} + +#define FRP(exp) (start_sequence (), exp, set_frame_related_p ()) + /* Write function prologue. */ /* On vms we have two kinds of functions: @@ -3226,7 +3443,7 @@ alpha_expand_prologue () HOST_WIDE_INT frame_size; /* Offset from base reg to register save area. */ HOST_WIDE_INT reg_offset; - rtx sa_reg; + rtx sa_reg, mem; int i; sa_size = alpha_sa_size (); @@ -3276,8 +3493,8 @@ alpha_expand_prologue () if (frame_size != 0) { - emit_move_insn (stack_pointer_rtx, - plus_constant (stack_pointer_rtx, -frame_size)); + FRP (emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (-frame_size)))); } } else @@ -3292,9 +3509,10 @@ alpha_expand_prologue () HOST_WIDE_INT leftover = frame_size + 4096 - blocks * 8192; rtx ptr = gen_rtx_REG (DImode, 22); rtx count = gen_rtx_REG (DImode, 23); + rtx seq; emit_move_insn (count, GEN_INT (blocks)); - emit_move_insn (ptr, plus_constant (stack_pointer_rtx, 4096)); + emit_insn (gen_adddi3 (ptr, stack_pointer_rtx, GEN_INT (4096))); /* Because of the difficulty in emitting a new basic block this late in the compilation, generate the loop as a single insn. */ @@ -3307,7 +3525,42 @@ alpha_expand_prologue () emit_move_insn (last, const0_rtx); } - emit_move_insn (stack_pointer_rtx, plus_constant (ptr, -leftover)); + if (TARGET_WINDOWS_NT) + { + /* For NT stack unwind (done by 'reverse execution'), it's + not OK to take the result of a loop, even though the value + is already in ptr, so we reload it via a single operation + 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. */ + + 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))); + seq = emit_insn (gen_subdi3 (stack_pointer_rtx, stack_pointer_rtx, + ptr)); + } + else + { + seq = emit_insn (gen_adddi3 (stack_pointer_rtx, ptr, + GEN_INT (-leftover))); + } + + /* This alternative is special, because the DWARF code cannot + possibly intuit through the loop above. So we invent this + note it looks at instead. */ + RTX_FRAME_RELATED_P (seq) = 1; + REG_NOTES (seq) + = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, + gen_rtx_SET (VOIDmode, stack_pointer_rtx, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (-frame_size))), + REG_NOTES (seq)); } /* Cope with very large offsets to the register save area. */ @@ -3323,21 +3576,23 @@ alpha_expand_prologue () bias = reg_offset, reg_offset = 0; sa_reg = gen_rtx_REG (DImode, 24); - emit_move_insn (sa_reg, plus_constant (stack_pointer_rtx, bias)); + FRP (emit_insn (gen_adddi3 (sa_reg, stack_pointer_rtx, GEN_INT (bias)))); } /* Save regs in stack order. Beginning with VMS PV. */ if (TARGET_OPEN_VMS && vms_is_stack_procedure) { - emit_move_insn (gen_rtx_MEM (DImode, stack_pointer_rtx), - gen_rtx_REG (DImode, REG_PV)); + mem = gen_rtx_MEM (DImode, stack_pointer_rtx); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_PV))); } /* Save register RA next. */ if (imask & (1L << REG_RA)) { - emit_move_insn (gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DImode, REG_RA)); + mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (mem, gen_rtx_REG (DImode, REG_RA))); imask &= ~(1L << REG_RA); reg_offset += 8; } @@ -3346,18 +3601,18 @@ alpha_expand_prologue () for (i = 0; i < 32; i++) if (imask & (1L << i)) { - emit_move_insn (gen_rtx_MEM (DImode, - plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DImode, i)); + mem = gen_rtx_MEM (DImode, plus_constant (sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (mem, gen_rtx_REG (DImode, i))); reg_offset += 8; } for (i = 0; i < 32; i++) if (fmask & (1L << i)) { - emit_move_insn (gen_rtx_MEM (DFmode, - plus_constant (sa_reg, reg_offset)), - gen_rtx_REG (DFmode, i+32)); + mem = gen_rtx_MEM (DFmode, plus_constant (sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (mem, gen_rtx_REG (DFmode, i+32))); reg_offset += 8; } @@ -3366,25 +3621,25 @@ alpha_expand_prologue () if (!vms_is_stack_procedure) { /* Register frame procedures fave the fp. */ - emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), - hard_frame_pointer_rtx); + FRP (emit_move_insn (gen_rtx_REG (DImode, vms_save_fp_regno), + hard_frame_pointer_rtx)); } if (vms_base_regno != REG_PV) - emit_move_insn (gen_rtx_REG (DImode, vms_base_regno), - gen_rtx_REG (DImode, REG_PV)); + FRP (emit_move_insn (gen_rtx_REG (DImode, vms_base_regno), + gen_rtx_REG (DImode, REG_PV))); if (vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) { - emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); + FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); } /* If we have to allocate space for outgoing args, do it now. */ if (current_function_outgoing_args_size != 0) { - emit_move_insn (stack_pointer_rtx, - plus_constant (hard_frame_pointer_rtx, - - ALPHA_ROUND (current_function_outgoing_args_size))); + FRP (emit_move_insn (stack_pointer_rtx, + plus_constant (hard_frame_pointer_rtx, + - ALPHA_ROUND (current_function_outgoing_args_size)))); } } else @@ -3393,13 +3648,13 @@ alpha_expand_prologue () if (frame_pointer_needed) { if (TARGET_CAN_FAULT_IN_PROLOGUE) - emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); + FRP (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx)); else { /* This must always be the last instruction in the prologue, thus we emit a special move + clobber. */ - emit_insn (gen_init_fp (hard_frame_pointer_rtx, - stack_pointer_rtx, sa_reg)); + FRP (emit_insn (gen_init_fp (hard_frame_pointer_rtx, + stack_pointer_rtx, sa_reg))); } } } @@ -3616,6 +3871,12 @@ output_end_prologue (file) /* Write function epilogue. */ +/* ??? At some point we will want to support full unwind, and so will + need to mark the epilogue as well. At the moment, we just confuse + dwarf2out. */ +#undef FRP +#define FRP(exp) exp + void alpha_expand_epilogue () { @@ -3630,7 +3891,7 @@ alpha_expand_epilogue () HOST_WIDE_INT reg_offset; int fp_is_frame_pointer, fp_offset; rtx sa_reg, sa_reg_exp = NULL; - rtx sp_adj1, sp_adj2; + rtx sp_adj1, sp_adj2, mem; int i; sa_size = alpha_sa_size (); @@ -3664,7 +3925,7 @@ alpha_expand_epilogue () && vms_unwind_regno == HARD_FRAME_POINTER_REGNUM) || (!TARGET_OPEN_VMS && frame_pointer_needed)) { - emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx); + FRP (emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx)); } /* Cope with very large offsets to the register save area. */ @@ -3682,13 +3943,17 @@ alpha_expand_epilogue () sa_reg = gen_rtx_REG (DImode, 22); sa_reg_exp = plus_constant (stack_pointer_rtx, bias); - emit_move_insn (sa_reg, sa_reg_exp); + FRP (emit_move_insn (sa_reg, sa_reg_exp)); } /* Restore registers in order, excepting a true frame pointer. */ - emit_move_insn (gen_rtx_REG (DImode, REG_RA), - gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset))); + if (! alpha_eh_epilogue_sp_ofs) + { + mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (gen_rtx_REG (DImode, REG_RA), mem)); + } reg_offset += 8; imask &= ~(1L << REG_RA); @@ -3699,10 +3964,9 @@ alpha_expand_epilogue () fp_offset = reg_offset; else { - emit_move_insn (gen_rtx_REG (DImode, i), - gen_rtx_MEM (DImode, - plus_constant(sa_reg, - reg_offset))); + mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (gen_rtx_REG (DImode, i), mem)); } reg_offset += 8; } @@ -3710,54 +3974,57 @@ alpha_expand_epilogue () for (i = 0; i < 32; ++i) if (fmask & (1L << i)) { - emit_move_insn (gen_rtx_REG (DFmode, i+32), - gen_rtx_MEM (DFmode, - plus_constant(sa_reg, reg_offset))); + mem = gen_rtx_MEM (DFmode, plus_constant(sa_reg, reg_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (gen_rtx_REG (DFmode, i+32), mem)); reg_offset += 8; } } - if (frame_size) + if (frame_size || alpha_eh_epilogue_sp_ofs) { + sp_adj1 = stack_pointer_rtx; + + if (alpha_eh_epilogue_sp_ofs) + { + sp_adj1 = gen_rtx_REG (DImode, 23); + emit_move_insn (sp_adj1, + gen_rtx_PLUS (Pmode, stack_pointer_rtx, + alpha_eh_epilogue_sp_ofs)); + } + /* If the stack size is large, begin computation into a temporary register so as not to interfere with a potential fp restore, which must be consecutive with an SP restore. */ if (frame_size < 32768) - { - sp_adj1 = stack_pointer_rtx; - sp_adj2 = GEN_INT (frame_size); - } + sp_adj2 = GEN_INT (frame_size); else if (frame_size < 0x40007fffL) { int low = ((frame_size & 0xffff) ^ 0x8000) - 0x8000; - sp_adj2 = plus_constant (stack_pointer_rtx, frame_size - low); + sp_adj2 = plus_constant (sp_adj1, frame_size - low); if (sa_reg_exp && rtx_equal_p (sa_reg_exp, sp_adj2)) sp_adj1 = sa_reg; else { sp_adj1 = gen_rtx_REG (DImode, 23); - emit_move_insn (sp_adj1, sp_adj2); + FRP (emit_move_insn (sp_adj1, sp_adj2)); } sp_adj2 = GEN_INT (low); } else { - sp_adj2 = gen_rtx_REG (DImode, 23); - sp_adj1 = alpha_emit_set_const (sp_adj2, DImode, frame_size, 3); - if (!sp_adj1) + rtx tmp = gen_rtx_REG (DImode, 23); + FRP (sp_adj2 = alpha_emit_set_const (tmp, DImode, frame_size, 3)); + if (!sp_adj2) { /* We can't drop new things to memory this late, afaik, so build it up by pieces. */ -#if HOST_BITS_PER_WIDE_INT == 64 - sp_adj1 = alpha_emit_set_long_const (sp_adj2, frame_size); - if (!sp_adj1) + FRP (sp_adj2 = alpha_emit_set_long_const (tmp, frame_size, + -(frame_size < 0))); + if (!sp_adj2) abort (); -#else - abort (); -#endif } - sp_adj2 = stack_pointer_rtx; } /* From now on, things must be in order. So emit blockages. */ @@ -3766,29 +4033,29 @@ alpha_expand_epilogue () if (fp_is_frame_pointer) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_MEM (DImode, - plus_constant(sa_reg, fp_offset))); + mem = gen_rtx_MEM (DImode, plus_constant(sa_reg, fp_offset)); + MEM_ALIAS_SET (mem) = alpha_sr_alias_set; + FRP (emit_move_insn (hard_frame_pointer_rtx, mem)); } else if (TARGET_OPEN_VMS) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno)); + FRP (emit_move_insn (hard_frame_pointer_rtx, + gen_rtx_REG (DImode, vms_save_fp_regno))); } /* Restore the stack pointer. */ emit_insn (gen_blockage ()); - emit_move_insn (stack_pointer_rtx, - gen_rtx_PLUS (DImode, sp_adj1, sp_adj2)); + FRP (emit_move_insn (stack_pointer_rtx, + gen_rtx_PLUS (DImode, sp_adj1, sp_adj2))); } else { if (TARGET_OPEN_VMS && !vms_is_stack_procedure) { emit_insn (gen_blockage ()); - emit_move_insn (hard_frame_pointer_rtx, - gen_rtx_REG (DImode, vms_save_fp_regno)); + FRP (emit_move_insn (hard_frame_pointer_rtx, + gen_rtx_REG (DImode, vms_save_fp_regno))); } } @@ -3817,10 +4084,10 @@ alpha_end_function (file, fnname, decl) Don't do this for global functions in object files destined for a shared library because the function may be overridden by the application - or other libraries. - ??? Is this just ELF? */ + or other libraries. Similarly, don't do this for weak functions. */ - if (!flag_pic || !TREE_PUBLIC (current_function_decl)) + if (!DECL_WEAK (current_function_decl) + && (!flag_pic || !TREE_PUBLIC (current_function_decl))) SYMBOL_REF_FLAG (XEXP (DECL_RTL (current_function_decl), 0)) = 1; } @@ -3843,7 +4110,7 @@ static int num_source_filenames = 0; /* Name of the file containing the current function. */ -static char *current_function_file = ""; +static const char *current_function_file = ""; /* Offsets to alpha virtual arg/local debugging pointers. */ @@ -4095,10 +4362,7 @@ alpha_handle_trap_shadows (insns) { struct shadow_summary shadow; int trap_pending, exception_nesting; - rtx i; - - if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions) - return; + rtx i, n; trap_pending = 0; exception_nesting = 0; @@ -4201,7 +4465,9 @@ alpha_handle_trap_shadows (insns) else { close_shadow: - emit_insn_before (gen_trapb (), i); + n = emit_insn_before (gen_trapb (), i); + PUT_MODE (n, TImode); + PUT_MODE (i, TImode); trap_pending = 0; shadow.used.i = 0; shadow.used.fp = 0; @@ -4223,14 +4489,572 @@ alpha_handle_trap_shadows (insns) } } } + +#ifdef HAIFA +/* Alpha can only issue instruction groups simultaneously if they are + suitibly aligned. This is very processor-specific. */ + +enum alphaev4_pipe { + EV4_STOP = 0, + EV4_IB0 = 1, + EV4_IB1 = 2, + EV4_IBX = 4 +}; + +enum alphaev5_pipe { + EV5_STOP = 0, + EV5_NONE = 1, + EV5_E01 = 2, + EV5_E0 = 4, + EV5_E1 = 8, + EV5_FAM = 16, + EV5_FA = 32, + EV5_FM = 64 +}; + +static enum alphaev4_pipe alphaev4_insn_pipe PROTO((rtx)); +static enum alphaev5_pipe alphaev5_insn_pipe PROTO((rtx)); +static rtx alphaev4_next_group PROTO((rtx, int*, int*)); +static rtx alphaev5_next_group PROTO((rtx, int*, int*)); +static rtx alphaev4_next_nop PROTO((int*)); +static rtx alphaev5_next_nop PROTO((int*)); + +static void alpha_align_insns + PROTO((rtx, int, rtx (*)(rtx, int*, int*), rtx (*)(int*), int)); + +static enum alphaev4_pipe +alphaev4_insn_pipe (insn) + rtx insn; +{ + if (recog_memoized (insn) < 0) + return EV4_STOP; + if (get_attr_length (insn) != 4) + return EV4_STOP; + + switch (get_attr_type (insn)) + { + case TYPE_ILD: + case TYPE_FLD: + return EV4_IBX; + + case TYPE_LDSYM: + case TYPE_IADD: + case TYPE_ILOG: + case TYPE_ICMOV: + case TYPE_ICMP: + case TYPE_IST: + case TYPE_FST: + case TYPE_SHIFT: + case TYPE_IMUL: + case TYPE_FBR: + return EV4_IB0; + + case TYPE_MISC: + case TYPE_IBR: + case TYPE_JSR: + case TYPE_FCPYS: + case TYPE_FCMOV: + case TYPE_FADD: + case TYPE_FDIV: + case TYPE_FMUL: + return EV4_IB1; + + default: + abort(); + } +} + +static enum alphaev5_pipe +alphaev5_insn_pipe (insn) + rtx insn; +{ + if (recog_memoized (insn) < 0) + return EV5_STOP; + if (get_attr_length (insn) != 4) + return EV5_STOP; + + switch (get_attr_type (insn)) + { + case TYPE_ILD: + case TYPE_FLD: + case TYPE_LDSYM: + case TYPE_IADD: + case TYPE_ILOG: + case TYPE_ICMOV: + case TYPE_ICMP: + return EV5_E01; + + case TYPE_IST: + case TYPE_FST: + case TYPE_SHIFT: + case TYPE_IMUL: + case TYPE_MISC: + case TYPE_MVI: + return EV5_E0; + + case TYPE_IBR: + case TYPE_JSR: + return EV5_E1; + + case TYPE_FCPYS: + return EV5_FAM; + + case TYPE_FBR: + case TYPE_FCMOV: + case TYPE_FADD: + case TYPE_FDIV: + return EV5_FA; + + case TYPE_FMUL: + return EV5_FM; + + default: + abort(); + } +} + +/* IN_USE is a mask of the slots currently filled within the insn group. + The mask bits come from alphaev4_pipe above. If EV4_IBX is set, then + the insn in EV4_IB0 can be swapped by the hardware into EV4_IB1. + + 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; +{ + int len, in_use; + + len = in_use = 0; + + if (GET_RTX_CLASS (GET_CODE (insn)) != 'i' + || GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == USE) + goto next_and_done; + + while (1) + { + enum alphaev4_pipe pipe; + + pipe = alphaev4_insn_pipe (insn); + switch (pipe) + { + case EV4_STOP: + /* Force complex instructions to start new groups. */ + if (in_use) + goto done; + + /* If this is a completely unrecognized insn, its an asm. + We don't know how long it is, so record length as -1 to + signal a needed realignment. */ + if (recog_memoized (insn) < 0) + len = -1; + else + len = get_attr_length (insn); + goto next_and_done; + + case EV4_IBX: + if (in_use & EV4_IB0) + { + if (in_use & EV4_IB1) + goto done; + in_use |= EV4_IB1; + } + else + in_use |= EV4_IB0 | EV4_IBX; + break; + + case EV4_IB0: + if (in_use & EV4_IB0) + { + if (!(in_use & EV4_IBX) || (in_use & EV4_IB1)) + goto done; + in_use |= EV4_IB1; + } + in_use |= EV4_IB0; + break; + + case EV4_IB1: + if (in_use & EV4_IB1) + goto done; + in_use |= EV4_IB1; + break; + + default: + abort(); + } + len += 4; + + /* Haifa doesn't do well scheduling branches. */ + if (GET_CODE (insn) == JUMP_INSN) + goto next_and_done; + + next: + insn = next_nonnote_insn (insn); + + if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i') + goto done; + + /* Let Haifa tell us where it thinks insn group boundaries are. */ + if (GET_MODE (insn) == TImode) + goto done; + + if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) + goto next; + } + + next_and_done: + insn = next_nonnote_insn (insn); + + done: + *plen = len; + *pin_use = in_use; + return insn; +} + +/* IN_USE is a mask of the slots currently filled within the insn group. + The mask bits come from alphaev5_pipe above. If EV5_E01 is set, then + the insn in EV5_E0 can be swapped by the hardware into EV5_E1. + + 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; +{ + int len, in_use; + + len = in_use = 0; + + if (GET_RTX_CLASS (GET_CODE (insn)) != 'i' + || GET_CODE (PATTERN (insn)) == CLOBBER + || GET_CODE (PATTERN (insn)) == USE) + goto next_and_done; + + while (1) + { + enum alphaev5_pipe pipe; + + pipe = alphaev5_insn_pipe (insn); + switch (pipe) + { + case EV5_STOP: + /* Force complex instructions to start new groups. */ + if (in_use) + goto done; + + /* If this is a completely unrecognized insn, its an asm. + We don't know how long it is, so record length as -1 to + signal a needed realignment. */ + if (recog_memoized (insn) < 0) + len = -1; + else + len = get_attr_length (insn); + goto next_and_done; + + /* ??? Most of the places below, we would like to abort, as + it would indicate an error either in Haifa, or in the + scheduling description. Unfortunately, Haifa never + schedules the last instruction of the BB, so we don't + have an accurate TI bit to go off. */ + case EV5_E01: + if (in_use & EV5_E0) + { + if (in_use & EV5_E1) + goto done; + in_use |= EV5_E1; + } + else + in_use |= EV5_E0 | EV5_E01; + break; + + case EV5_E0: + if (in_use & EV5_E0) + { + if (!(in_use & EV5_E01) || (in_use & EV5_E1)) + goto done; + in_use |= EV5_E1; + } + in_use |= EV5_E0; + break; + + case EV5_E1: + if (in_use & EV5_E1) + goto done; + in_use |= EV5_E1; + break; + + case EV5_FAM: + if (in_use & EV5_FA) + { + if (in_use & EV5_FM) + goto done; + in_use |= EV5_FM; + } + else + in_use |= EV5_FA | EV5_FAM; + break; + + case EV5_FA: + if (in_use & EV5_FA) + goto done; + in_use |= EV5_FA; + break; + + case EV5_FM: + if (in_use & EV5_FM) + goto done; + in_use |= EV5_FM; + break; + + case EV5_NONE: + break; + + default: + abort(); + } + len += 4; + + /* Haifa doesn't do well scheduling branches. */ + /* ??? If this is predicted not-taken, slotting continues, except + that no more IBR, FBR, or JSR insns may be slotted. */ + if (GET_CODE (insn) == JUMP_INSN) + goto next_and_done; + + next: + insn = next_nonnote_insn (insn); + + if (!insn || GET_RTX_CLASS (GET_CODE (insn)) != 'i') + goto done; + + /* Let Haifa tell us where it thinks insn group boundaries are. */ + if (GET_MODE (insn) == TImode) + goto done; + + if (GET_CODE (insn) == CLOBBER || GET_CODE (insn) == USE) + goto next; + } + + next_and_done: + insn = next_nonnote_insn (insn); + + done: + *plen = len; + *pin_use = in_use; + return insn; +} + +static rtx +alphaev4_next_nop (pin_use) + int *pin_use; +{ + int in_use = *pin_use; + rtx nop; + + if (!(in_use & EV4_IB0)) + { + in_use |= EV4_IB0; + nop = gen_nop (); + } + else if ((in_use & (EV4_IBX|EV4_IB1)) == EV4_IBX) + { + in_use |= EV4_IB1; + nop = gen_nop (); + } + else if (TARGET_FP && !(in_use & EV4_IB1)) + { + in_use |= EV4_IB1; + nop = gen_fnop (); + } + else + nop = gen_unop (); + + *pin_use = in_use; + return nop; +} + +static rtx +alphaev5_next_nop (pin_use) + int *pin_use; +{ + int in_use = *pin_use; + rtx nop; + if (!(in_use & EV5_E1)) + { + in_use |= EV5_E1; + nop = gen_nop (); + } + else if (TARGET_FP && !(in_use & EV5_FA)) + { + in_use |= EV5_FA; + nop = gen_fnop (); + } + else if (TARGET_FP && !(in_use & EV5_FM)) + { + in_use |= EV5_FM; + nop = gen_fnop (); + } + else + nop = gen_unop (); + + *pin_use = in_use; + return nop; +} + +/* The instruction group alignment main loop. */ + +static void +alpha_align_insns (insns, max_align, next_group, next_nop, gp_in_use) + rtx insns; + int max_align; + rtx (*next_group) PROTO((rtx, int*, int*)); + rtx (*next_nop) PROTO((int*)); + int gp_in_use; +{ + /* ALIGN is the known alignment for the insn group. */ + int align; + /* OFS is the offset of the current insn in the insn group. */ + int ofs; + int prev_in_use, in_use, len; + rtx i, next; + + /* Let shorten branches care for assigning alignments to code labels. */ + shorten_branches (insns); + + align = (FUNCTION_BOUNDARY/BITS_PER_UNIT < max_align + ? FUNCTION_BOUNDARY/BITS_PER_UNIT : max_align); + + /* Account for the initial GP load, which happens before the scheduled + prologue we emitted as RTL. */ + ofs = prev_in_use = 0; + if (alpha_does_function_need_gp()) + { + ofs = 8 & (align - 1); + prev_in_use = gp_in_use; + } + + i = insns; + if (GET_CODE (i) == NOTE) + i = next_nonnote_insn (i); + + while (i) + { + next = (*next_group)(i, &in_use, &len); + + /* When we see a label, resync alignment etc. */ + if (GET_CODE (i) == CODE_LABEL) + { + int new_align = 1 << label_to_alignment (i); + if (new_align >= align) + { + align = new_align < max_align ? new_align : max_align; + ofs = 0; + } + else if (ofs & (new_align-1)) + ofs = (ofs | (new_align-1)) + 1; + if (len != 0) + abort(); + } + + /* Handle complex instructions special. */ + else if (in_use == 0) + { + /* Asms will have length < 0. This is a signal that we have + lost alignment knowledge. Assume, however, that the asm + will not mis-align instructions. */ + if (len < 0) + { + ofs = 0; + align = 4; + len = 0; + } + } + + /* If the known alignment is smaller than the recognized insn group, + realign the output. */ + else if (align < len) + { + int new_log_align = len > 8 ? 4 : 3; + rtx where; + + where = prev_nonnote_insn (i); + if (!where || GET_CODE (where) != CODE_LABEL) + where = i; + + emit_insn_before (gen_realign (GEN_INT (new_log_align)), where); + align = 1 << new_log_align; + ofs = 0; + } + + /* If the group won't fit in the same INT16 as the previous, + we need to add padding to keep the group together. Rather + than simply leaving the insn filling to the assembler, we + can make use of the knowledge of what sorts of instructions + were issued in the previous group to make sure that all of + the added nops are really free. */ + else if (ofs + len > align) + { + int nop_count = (align - ofs) / 4; + rtx where; + + /* Insert nops before labels and branches to truely merge the + execution of the nops with the previous instruction group. */ + where = prev_nonnote_insn (i); + if (where) + { + if (GET_CODE (where) == CODE_LABEL) + { + rtx where2 = prev_nonnote_insn (where); + if (where2 && GET_CODE (where2) == JUMP_INSN) + where = where2; + } + else if (GET_CODE (where) != JUMP_INSN) + where = i; + } + else + where = i; + + do + emit_insn_before ((*next_nop)(&prev_in_use), where); + while (--nop_count); + ofs = 0; + } + + ofs = (ofs + len) & (align - 1); + prev_in_use = in_use; + i = next; + } +} +#endif /* HAIFA */ + /* Machine dependant reorg pass. */ void alpha_reorg (insns) rtx insns; { - alpha_handle_trap_shadows (insns); + if (alpha_tp != ALPHA_TP_PROG || flag_exceptions) + alpha_handle_trap_shadows (insns); + +#ifdef HAIFA + /* Due to the number of extra trapb insns, don't bother fixing up + alignment when trap precision is instruction. Moreover, we can + only do our job when sched2 is run and Haifa is our scheduler. */ + if (optimize && !optimize_size + && alpha_tp != ALPHA_TP_INSN + && flag_schedule_insns_after_reload) + { + if (alpha_cpu == PROCESSOR_EV4) + alpha_align_insns (insns, 8, alphaev4_next_group, + alphaev4_next_nop, EV4_IB0); + else if (alpha_cpu == PROCESSOR_EV5) + alpha_align_insns (insns, 16, alphaev5_next_group, + alphaev5_next_nop, EV5_E01 | EV5_E0); + } +#endif } diff --git a/contrib/gcc/config/alpha/alpha.h b/contrib/gcc/config/alpha/alpha.h index 43b0dee..e9c3f6d 100644 --- a/contrib/gcc/config/alpha/alpha.h +++ b/contrib/gcc/config/alpha/alpha.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for DEC Alpha. - Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) This file is part of GNU CC. @@ -95,73 +95,76 @@ extern enum alpha_fp_trap_mode alpha_fptm; /* This means that floating-point support exists in the target implementation of the Alpha architecture. This is usually the default. */ - -#define MASK_FP 1 +#define MASK_FP (1 << 0) #define TARGET_FP (target_flags & MASK_FP) /* This means that floating-point registers are allowed to be used. Note that Alpha implementations without FP operations are required to provide the FP registers. */ -#define MASK_FPREGS 2 +#define MASK_FPREGS (1 << 1) #define TARGET_FPREGS (target_flags & MASK_FPREGS) /* This means that gas is used to process the assembler file. */ -#define MASK_GAS 4 +#define MASK_GAS (1 << 2) #define TARGET_GAS (target_flags & MASK_GAS) /* This means that we should mark procedures as IEEE conformant. */ -#define MASK_IEEE_CONFORMANT 8 +#define MASK_IEEE_CONFORMANT (1 << 3) #define TARGET_IEEE_CONFORMANT (target_flags & MASK_IEEE_CONFORMANT) /* This means we should be IEEE-compliant except for inexact. */ -#define MASK_IEEE 16 +#define MASK_IEEE (1 << 4) #define TARGET_IEEE (target_flags & MASK_IEEE) /* This means we should be fully IEEE-compliant. */ -#define MASK_IEEE_WITH_INEXACT 32 +#define MASK_IEEE_WITH_INEXACT (1 << 5) #define TARGET_IEEE_WITH_INEXACT (target_flags & MASK_IEEE_WITH_INEXACT) /* This means we must construct all constants rather than emitting them as literal data. */ -#define MASK_BUILD_CONSTANTS 128 +#define MASK_BUILD_CONSTANTS (1 << 6) #define TARGET_BUILD_CONSTANTS (target_flags & MASK_BUILD_CONSTANTS) /* This means we handle floating points in VAX F- (float) or G- (double) Format. */ -#define MASK_FLOAT_VAX 512 +#define MASK_FLOAT_VAX (1 << 7) #define TARGET_FLOAT_VAX (target_flags & MASK_FLOAT_VAX) /* This means that the processor has byte and half word loads and stores (the BWX extension). */ -#define MASK_BWX 1024 +#define MASK_BWX (1 << 8) #define TARGET_BWX (target_flags & MASK_BWX) -/* This means that the processor has the CIX extension. */ -#define MASK_CIX 2048 -#define TARGET_CIX (target_flags & MASK_CIX) - /* This means that the processor has the MAX extension. */ -#define MASK_MAX 4096 +#define MASK_MAX (1 << 9) #define TARGET_MAX (target_flags & MASK_MAX) +/* This means that the processor has the FIX extension. */ +#define MASK_FIX (1 << 10) +#define TARGET_FIX (target_flags & MASK_FIX) + +/* This means that the processor has the CIX extension. */ +#define MASK_CIX (1 << 11) +#define TARGET_CIX (target_flags & MASK_CIX) + /* This means that the processor is an EV5, EV56, or PCA56. This is defined only in TARGET_CPU_DEFAULT. */ -#define MASK_CPU_EV5 8192 +#define MASK_CPU_EV5 (1 << 28) /* Likewise for EV6. */ -#define MASK_CPU_EV6 16384 +#define MASK_CPU_EV6 (1 << 29) /* This means we support the .arch directive in the assembler. Only defined in TARGET_CPU_DEFAULT. */ -#define MASK_SUPPORT_ARCH 32768 +#define MASK_SUPPORT_ARCH (1 << 30) #define TARGET_SUPPORT_ARCH (target_flags & MASK_SUPPORT_ARCH) /* These are for target os support and cannot be changed at runtime. */ @@ -185,26 +188,32 @@ extern enum alpha_fp_trap_mode alpha_fptm; where VALUE is the bits to set or minus the bits to clear. An empty string NAME is used to identify the default VALUE. */ -#define TARGET_SWITCHES \ - { {"no-soft-float", MASK_FP}, \ - {"soft-float", - MASK_FP}, \ - {"fp-regs", MASK_FPREGS}, \ - {"no-fp-regs", - (MASK_FP|MASK_FPREGS)}, \ - {"alpha-as", -MASK_GAS}, \ - {"gas", MASK_GAS}, \ - {"ieee-conformant", MASK_IEEE_CONFORMANT}, \ - {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT}, \ - {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT}, \ - {"build-constants", MASK_BUILD_CONSTANTS}, \ - {"float-vax", MASK_FLOAT_VAX}, \ - {"float-ieee", -MASK_FLOAT_VAX}, \ - {"bwx", MASK_BWX}, \ - {"no-bwx", -MASK_BWX}, \ - {"cix", MASK_CIX}, \ - {"no-cix", -MASK_CIX}, \ - {"max", MASK_MAX}, \ - {"no-max", -MASK_MAX}, \ - {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT} } +#define TARGET_SWITCHES \ + { {"no-soft-float", MASK_FP, "Use hardware fp"}, \ + {"soft-float", - MASK_FP, "Do not use hardware fp"}, \ + {"fp-regs", MASK_FPREGS, "Use fp registers"}, \ + {"no-fp-regs", - (MASK_FP|MASK_FPREGS), "Do not use fp registers"}, \ + {"alpha-as", -MASK_GAS, "Do not assume GAS"}, \ + {"gas", MASK_GAS, "Assume GAS"}, \ + {"ieee-conformant", MASK_IEEE_CONFORMANT, \ + "Request IEEE-conformant math library routines (OSF/1)"}, \ + {"ieee", MASK_IEEE|MASK_IEEE_CONFORMANT, \ + "Emit IEEE-conformant code, without inexact exceptions"}, \ + {"ieee-with-inexact", MASK_IEEE_WITH_INEXACT|MASK_IEEE_CONFORMANT, \ + "Emit IEEE-conformant code, with inexact exceptions"}, \ + {"build-constants", MASK_BUILD_CONSTANTS, \ + "Do not emit complex integer constants to read-only memory"}, \ + {"float-vax", MASK_FLOAT_VAX, "Use VAX fp"}, \ + {"float-ieee", -MASK_FLOAT_VAX, "Do not use VAX fp"}, \ + {"bwx", MASK_BWX, "Emit code for the byte/word ISA extension"}, \ + {"no-bwx", -MASK_BWX, ""}, \ + {"max", MASK_MAX, "Emit code for the motion video ISA extension"}, \ + {"no-max", -MASK_MAX, ""}, \ + {"fix", MASK_FIX, "Emit code for the fp move and sqrt ISA extension"}, \ + {"no-fix", -MASK_FIX, ""}, \ + {"cix", MASK_CIX, "Emit code for the counting ISA extension"}, \ + {"no-cix", -MASK_CIX, ""}, \ + {"", TARGET_DEFAULT | TARGET_CPU_DEFAULT, ""} } #define TARGET_DEFAULT MASK_FP|MASK_FPREGS @@ -229,19 +238,24 @@ extern enum alpha_fp_trap_mode alpha_fptm; extern char *m88k_short_data; #define TARGET_OPTIONS { { "short-data-", &m88k_short_data } } */ -extern char *alpha_cpu_string; /* For -mcpu= */ -extern char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */ -extern char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */ -extern char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */ -extern char *alpha_mlat_string; /* For -mmemory-latency= */ - -#define TARGET_OPTIONS \ -{ \ - {"cpu=", &alpha_cpu_string}, \ - {"fp-rounding-mode=", &alpha_fprm_string}, \ - {"fp-trap-mode=", &alpha_fptm_string}, \ - {"trap-precision=", &alpha_tp_string}, \ - {"memory-latency=", &alpha_mlat_string}, \ +extern const char *alpha_cpu_string; /* For -mcpu= */ +extern const char *alpha_fprm_string; /* For -mfp-rounding-mode=[n|m|c|d] */ +extern const char *alpha_fptm_string; /* For -mfp-trap-mode=[n|u|su|sui] */ +extern const char *alpha_tp_string; /* For -mtrap-precision=[p|f|i] */ +extern const char *alpha_mlat_string; /* For -mmemory-latency= */ + +#define TARGET_OPTIONS \ +{ \ + {"cpu=", &alpha_cpu_string, \ + "Generate code for a given CPU"}, \ + {"fp-rounding-mode=", &alpha_fprm_string, \ + "Control the generated fp rounding mode"}, \ + {"fp-trap-mode=", &alpha_fptm_string, \ + "Control the IEEE trap mode"}, \ + {"trap-precision=", &alpha_tp_string, \ + "Control the precision given to fp exceptions"}, \ + {"memory-latency=", &alpha_mlat_string, \ + "Tune expected memory latency"}, \ } /* Attempt to describe CPU characteristics to the preprocessor. */ @@ -249,6 +263,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */ /* Corresponding to amask... */ #define CPP_AM_BWX_SPEC "-D__alpha_bwx__ -Acpu(bwx)" #define CPP_AM_MAX_SPEC "-D__alpha_max__ -Acpu(max)" +#define CPP_AM_FIX_SPEC "-D__alpha_fix__ -Acpu(fix)" #define CPP_AM_CIX_SPEC "-D__alpha_cix__ -Acpu(cix)" /* Corresponding to implver... */ @@ -261,7 +276,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */ #define CPP_CPU_EV5_SPEC "%(cpp_im_ev5)" #define CPP_CPU_EV56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx)" #define CPP_CPU_PCA56_SPEC "%(cpp_im_ev5) %(cpp_am_bwx) %(cpp_am_max)" -#define CPP_CPU_EV6_SPEC "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_cix)" +#define CPP_CPU_EV6_SPEC "%(cpp_im_ev6) %(cpp_am_bwx) %(cpp_am_max) %(cpp_am_fix)" #ifndef CPP_CPU_DEFAULT_SPEC # if TARGET_CPU_DEFAULT & MASK_CPU_EV6 @@ -311,6 +326,7 @@ extern char *alpha_mlat_string; /* For -mmemory-latency= */ #define EXTRA_SPECS \ { "cpp_am_bwx", CPP_AM_BWX_SPEC }, \ { "cpp_am_max", CPP_AM_MAX_SPEC }, \ + { "cpp_am_fix", CPP_AM_FIX_SPEC }, \ { "cpp_am_cix", CPP_AM_CIX_SPEC }, \ { "cpp_im_ev4", CPP_IM_EV4_SPEC }, \ { "cpp_im_ev5", CPP_IM_EV5_SPEC }, \ @@ -483,7 +499,7 @@ extern void override_options (); Alpha we'll get better performance by aligning on an octaword boundary. */ -#define ALIGN_LABEL_AFTER_BARRIER(FILE) \ +#define LABEL_ALIGN_AFTER_BARRIER(FILE) \ (optimize > 0 && write_symbols != SDB_DEBUG ? 4 : 0) /* No data type wants to be aligned rounder than this. */ @@ -613,17 +629,20 @@ extern void override_options (); registers can hold 32-bit and 64-bit integers as well, but not 16-bit or 8-bit values. */ -#define HARD_REGNO_MODE_OK(REGNO, MODE) \ - ((REGNO) < 32 || ((MODE) != QImode && (MODE) != HImode)) +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO) >= 32 && (REGNO) <= 62 \ + ? GET_MODE_UNIT_SIZE (MODE) == 8 || GET_MODE_UNIT_SIZE (MODE) == 4 \ + : 1) + +/* A C expression that is nonzero if a value of mode + MODE1 is accessible in mode MODE2 without copying. -/* Value is 1 if it is a good idea to tie two pseudo registers - when one has mode MODE1 and one has mode MODE2. - If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2, - for any hard reg, then this must be 0 for correct output. */ + This asymmetric test is true when MODE1 could be put + in an FP register but MODE2 could not. */ #define MODES_TIEABLE_P(MODE1, MODE2) \ - ((MODE1) == QImode || (MODE1) == HImode \ - ? (MODE2) == QImode || (MODE2) == HImode \ + (HARD_REGNO_MODE_OK (32, (MODE1)) \ + ? HARD_REGNO_MODE_OK (32, (MODE2)) \ : 1) /* Specify the registers used for certain standard purposes. @@ -771,11 +790,12 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, 'S' is a 6-bit constant (valid for a shift insn). */ #define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' ? GET_CODE (OP) == MEM && GET_CODE (XEXP (OP, 0)) != AND \ + ((C) == 'Q' ? normal_memory_operand (OP, VOIDmode) \ : (C) == 'R' ? current_file_function_operand (OP, Pmode) \ : (C) == 'S' ? (GET_CODE (OP) == CONST_INT \ && (unsigned HOST_WIDE_INT) INTVAL (OP) < 64) \ : 0) +extern int normal_memory_operand (); /* Given an rtx X being reloaded into a reg required to be in class CLASS, return the class of reg to actually use. @@ -807,7 +827,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, && (((CLASS) == FLOAT_REGS \ && ((MODE) == SImode || (MODE) == HImode || (MODE) == QImode)) \ || (((MODE) == QImode || (MODE) == HImode) \ - && ! TARGET_BWX && unaligned_memory_operand (IN, MODE)))) \ + && ! TARGET_BWX && ! aligned_memory_operand (IN, MODE)))) \ ? GENERAL_REGS \ : ((CLASS) == FLOAT_REGS && GET_CODE (IN) == MEM \ && GET_CODE (XEXP (IN, 0)) == AND) ? GENERAL_REGS \ @@ -835,10 +855,10 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, : NO_REGS) /* If we are copying between general and FP registers, we need a memory - location unless the CIX extension is available. */ + location unless the FIX extension is available. */ #define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ - (! TARGET_CIX && (CLASS1) != (CLASS2)) + (! TARGET_FIX && (CLASS1) != (CLASS2)) /* Specify the mode to be used for memory when a secondary memory location is needed. If MODE is floating-point, use it. Otherwise, @@ -871,7 +891,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, #define REGISTER_MOVE_COST(CLASS1, CLASS2) \ (((CLASS1) == FLOAT_REGS) == ((CLASS2) == FLOAT_REGS) \ ? 2 \ - : TARGET_CIX ? 3 : 4+2*alpha_memory_latency) + : TARGET_FIX ? 3 : 4+2*alpha_memory_latency) /* A C expressions returning the cost of moving data of MODE from a register to or from memory. @@ -989,26 +1009,25 @@ 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) \ + 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 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)) +#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. @@ -1182,6 +1201,10 @@ extern struct rtx_def *alpha_builtin_saveregs (); extern struct rtx_def *alpha_compare_op0, *alpha_compare_op1; extern int alpha_compare_fp_p; +/* Define the information needed to modify the epilogue for EH. */ + +extern struct rtx_def *alpha_eh_epilogue_sp_ofs; + /* 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. */ extern void alpha_need_linkage (); @@ -1293,6 +1316,7 @@ do { \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 16, 24, 8) +extern void alpha_initialize_trampoline (); /* A C expression whose value is RTL representing the value of the return address for the frame COUNT steps up from the current frame. @@ -1302,6 +1326,9 @@ do { \ #define RETURN_ADDR_RTX alpha_return_addr extern struct rtx_def *alpha_return_addr (); +/* Before the prologue, RA lives in $26. */ +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, 26) + /* Initialize data used by insn expanders. This is called from insn_emit, once for every function before code is generated. */ @@ -1310,11 +1337,11 @@ extern void alpha_init_expanders (); /* Addressing modes, and classification of registers for them. */ -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ +/* #define HAVE_POST_INCREMENT 0 */ +/* #define HAVE_POST_DECREMENT 0 */ -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ +/* #define HAVE_PRE_DECREMENT 0 */ +/* #define HAVE_PRE_INCREMENT 0 */ /* Macros to check register numbers against specific register classes. */ @@ -1365,18 +1392,32 @@ extern void alpha_init_expanders (); /* Nonzero if X is a hard reg that can be used as an index or if it is a pseudo reg. */ #define REG_OK_FOR_INDEX_P(X) 0 + /* Nonzero if X is a hard reg that can be used as a base reg or if it is a pseudo reg. */ #define REG_OK_FOR_BASE_P(X) \ (REGNO (X) < 32 || REGNO (X) == 63 || REGNO (X) >= FIRST_PSEUDO_REGISTER) +/* ??? Nonzero if X is the frame pointer, or some virtual register + that may eliminate to the frame pointer. These will be allowed to + have offsets greater than 32K. This is done because register + elimination offsets will change the hi/lo split, and if we split + before reload, we will require additional instructions. */ +#define REG_OK_FP_BASE_P(X) \ + (REGNO (X) == 31 || REGNO (X) == 63 \ + || (REGNO (X) >= FIRST_PSEUDO_REGISTER \ + && REGNO (X) < LAST_VIRTUAL_REGISTER)) + #else /* Nonzero if X is a hard reg that can be used as an index. */ #define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) + /* Nonzero if X is a hard reg that can be used as a base reg. */ #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) +#define REG_OK_FP_BASE_P(X) 0 + #endif /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression @@ -1391,16 +1432,34 @@ extern void alpha_init_expanders (); First define the basic valid address. */ -#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \ -{ if (REG_P (X) && REG_OK_FOR_BASE_P (X)) \ - goto ADDR; \ - if (CONSTANT_ADDRESS_P (X)) \ - goto ADDR; \ - if (GET_CODE (X) == PLUS \ - && REG_P (XEXP (X, 0)) \ - && REG_OK_FOR_BASE_P (XEXP (X, 0)) \ - && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ - goto ADDR; \ +#define GO_IF_LEGITIMATE_SIMPLE_ADDRESS(MODE, X, ADDR) \ +{ \ + rtx tmp = (X); \ + if (GET_CODE (tmp) == SUBREG \ + && (GET_MODE_SIZE (GET_MODE (tmp)) \ + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \ + tmp = SUBREG_REG (tmp); \ + if (REG_P (tmp) && REG_OK_FOR_BASE_P (tmp)) \ + goto ADDR; \ + if (CONSTANT_ADDRESS_P (X)) \ + goto ADDR; \ + if (GET_CODE (X) == PLUS) \ + { \ + tmp = XEXP (X, 0); \ + if (GET_CODE (tmp) == SUBREG \ + && (GET_MODE_SIZE (GET_MODE (tmp)) \ + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (tmp))))) \ + tmp = SUBREG_REG (tmp); \ + if (REG_P (tmp)) \ + { \ + if (REG_OK_FP_BASE_P (tmp) \ + && GET_CODE (XEXP (X, 1)) == CONST_INT) \ + goto ADDR; \ + if (REG_OK_FOR_BASE_P (tmp) \ + && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ + goto ADDR; \ + } \ + } \ } /* Now accept the simple address, or, for DImode only, an AND of a simple @@ -1596,9 +1655,11 @@ do { \ #define MOVE_MAX 8 -/* Controls how many units are moved by expr.c before resorting to movstr. - Without byte/word accesses, we want no more than one; with, several single - byte accesses are better. */ +/* If a memory-to-memory move would take MOVE_RATIO or more simple + move-instruction pairs, we will do a movstr or libcall instead. + + Without byte/word accesses, we want no more than four instructions; + with, several single byte accesses are better. */ #define MOVE_RATIO (TARGET_BWX ? 7 : 2) @@ -1693,6 +1754,12 @@ do { \ /* The EV4 is dual issue; EV5/EV6 are quad issue. */ #define ISSUE_RATE (alpha_cpu == PROCESSOR_EV4 ? 2 : 4) +/* Describe the fact that MULTI instructions are multiple instructions + and so to assume they don't pair with anything. */ +#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \ + if (recog_memoized (INSN) < 0 || get_attr_type (INSN) == TYPE_MULTI) \ + (CAN_ISSUE_MORE) = 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, @@ -1970,7 +2037,7 @@ literal_section () \ This is suitable for output with `assemble_name'. */ #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \ - sprintf (LABEL, "*$%s%d", PREFIX, NUM) + sprintf ((LABEL), "*$%s%ld", (PREFIX), (long)(NUM)) /* Check a floating-point value for validity for a particular machine mode. */ @@ -2078,6 +2145,11 @@ literal_section () \ } \ while (0) +/* To get unaligned data, we have to turn off auto alignment. */ +#define UNALIGNED_SHORT_ASM_OP ".align 0\n\t.word" +#define UNALIGNED_INT_ASM_OP ".align 0\n\t.long" +#define UNALIGNED_DOUBLE_INT_ASM_OP ".align 0\n\t.quad" + /* This is how to output an insn to push a register on the stack. It need not be very fast code. */ @@ -2237,41 +2309,22 @@ do { \ /* Print a memory address as an operand to reference that memory location. */ -#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ -{ rtx addr = (ADDR); \ - int basereg = 31; \ - HOST_WIDE_INT offset = 0; \ - \ - if (GET_CODE (addr) == AND) \ - addr = XEXP (addr, 0); \ - \ - if (GET_CODE (addr) == REG) \ - basereg = REGNO (addr); \ - else if (GET_CODE (addr) == CONST_INT) \ - offset = INTVAL (addr); \ - else if (GET_CODE (addr) == PLUS \ - && GET_CODE (XEXP (addr, 0)) == REG \ - && GET_CODE (XEXP (addr, 1)) == CONST_INT) \ - basereg = REGNO (XEXP (addr, 0)), offset = INTVAL (XEXP (addr, 1)); \ - else \ - abort (); \ - \ - fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, offset); \ - fprintf (FILE, "($%d)", basereg); \ -} +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ + print_operand_address((FILE), (ADDR)) + /* Define the codes that are matched by predicates in alpha.c. */ #define PREDICATE_CODES \ {"reg_or_0_operand", {SUBREG, REG, CONST_INT}}, \ - {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"cint8_operand", {CONST_INT, CONSTANT_P_RTX}}, \ - {"reg_or_cint_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"sext_add_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ + {"reg_or_6bit_operand", {SUBREG, REG, CONST_INT}}, \ + {"reg_or_8bit_operand", {SUBREG, REG, CONST_INT}}, \ + {"cint8_operand", {CONST_INT}}, \ + {"reg_or_cint_operand", {SUBREG, REG, CONST_INT}}, \ + {"add_operand", {SUBREG, REG, CONST_INT}}, \ + {"sext_add_operand", {SUBREG, REG, CONST_INT}}, \ {"const48_operand", {CONST_INT}}, \ - {"and_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ - {"or_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ + {"and_operand", {SUBREG, REG, CONST_INT}}, \ + {"or_operand", {SUBREG, REG, CONST_INT}}, \ {"mode_mask_operand", {CONST_INT}}, \ {"mul8_operand", {CONST_INT}}, \ {"mode_width_operand", {CONST_INT}}, \ @@ -2284,14 +2337,16 @@ do { \ {"current_file_function_operand", {SYMBOL_REF}}, \ {"call_operand", {REG, SYMBOL_REF}}, \ {"input_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ - SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \ + SYMBOL_REF, CONST, LABEL_REF}}, \ {"some_operand", {SUBREG, REG, MEM, CONST_INT, CONST_DOUBLE, \ - SYMBOL_REF, CONST, LABEL_REF, CONSTANT_P_RTX}}, \ + SYMBOL_REF, CONST, LABEL_REF}}, \ {"aligned_memory_operand", {MEM}}, \ {"unaligned_memory_operand", {MEM}}, \ {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \ {"any_memory_operand", {MEM}}, \ - {"hard_fp_register_operand", {SUBREG, REG}}, + {"hard_fp_register_operand", {SUBREG, REG}}, \ + {"reg_not_elim_operand", {SUBREG, REG}}, \ + {"reg_no_subreg_operand", {REG}}, /* Tell collect that the object format is ECOFF. */ #define OBJECT_FORMAT_COFF @@ -2462,6 +2517,7 @@ extern int current_file_function_operand (); extern int alpha_sa_size (); extern int alpha_adjust_cost (); extern void print_operand (); +extern void print_operand_address (); extern int reg_or_0_operand (); extern int reg_or_8bit_operand (); extern int mul8_operand (); @@ -2482,6 +2538,7 @@ extern int divmod_operator (); extern int call_operand (); extern int reg_or_cint_operand (); extern int hard_fp_register_operand (); +extern int reg_not_elim_operand (); extern void alpha_set_memflags (); extern int aligned_memory_operand (); extern void get_aligned_mem (); diff --git a/contrib/gcc/config/alpha/alpha.md b/contrib/gcc/config/alpha/alpha.md index 87ebf95..6d075e9 100644 --- a/contrib/gcc/config/alpha/alpha.md +++ b/contrib/gcc/config/alpha/alpha.md @@ -1,5 +1,5 @@ ;; Machine description for DEC Alpha for GNU C compiler -;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. ;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) ;; This file is part of GNU CC. @@ -29,6 +29,7 @@ ;; 3 mskxh ;; 4 cvtlq ;; 5 cvtql +;; 6 nt_lda ;; ;; UNSPEC_VOLATILE: ;; @@ -38,6 +39,8 @@ ;; 3 builtin_longjmp ;; 4 trapb ;; 5 prologue_stack_probe_loop +;; 6 realign +;; 7 exception_receiver ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in alpha.h. @@ -51,9 +54,13 @@ ;; separately. (define_attr "type" - "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof" + "ild,fld,ldsym,ist,fst,ibr,fbr,jsr,iadd,ilog,shift,icmov,fcmov,icmp,imul,fadd,fmul,fcpys,fdiv,fsqrt,misc,mvi,ftoi,itof,multi" (const_string "iadd")) +;; Describe a user's asm statement. +(define_asm_attributes + [(set_attr "type" "multi")]) + ;; Define the operand size an insn operates on. Used primarily by mul ;; and div operations that have size dependant timings. @@ -149,13 +156,18 @@ ; Memory takes at least 2 clocks. Return one from here and fix up with ; user-defined latencies in adjust_cost. -; ??? How to: "An instruction of class LD cannot be issued in the _second_ -; cycle after an instruction of class ST is issued." (define_function_unit "ev5_ebox" 2 0 (and (eq_attr "cpu" "ev5") (eq_attr "type" "ild,fld,ldsym")) 1 1) +; Loads can dual issue with one another, but loads and stores do not mix. +(define_function_unit "ev5_e0" 1 0 + (and (eq_attr "cpu" "ev5") + (eq_attr "type" "ild,fld,ldsym")) + 1 1 + [(eq_attr "type" "ist,fst")]) + ; Stores, shifts, multiplies can only issue to E0 (define_function_unit "ev5_e0" 1 0 (and (eq_attr "cpu" "ev5") @@ -420,12 +432,23 @@ (match_operand:SI 2 "add_operand" "")))] "" " -{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]), - gen_rtx_PLUS (DImode, - gen_lowpart (DImode, operands[1]), - gen_lowpart (DImode, operands[2])))); - DONE; -} ") +{ + if (optimize) + { + rtx op1 = gen_lowpart (DImode, operands[1]); + rtx op2 = gen_lowpart (DImode, operands[2]); + + if (! cse_not_expected) + { + rtx tmp = gen_reg_rtx (DImode); + emit_insn (gen_adddi3 (tmp, op1, op2)); + emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); + } + else + emit_insn (gen_adddi3 (gen_lowpart (DImode, operands[0]), op1, op2)); + DONE; + } +}") (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") @@ -470,7 +493,7 @@ (sign_extend:DI (plus:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "const_int_operand" "")))) - (clobber (match_operand:SI 3 "register_operand" ""))] + (clobber (match_operand:SI 3 "reg_not_elim_operand" ""))] "! sext_add_operand (operands[2], SImode) && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) % 4 == 0" [(set (match_dup 3) (match_dup 4)) @@ -512,20 +535,57 @@ (plus:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ,rJ,rJ,rJ") (match_operand:DI 2 "add_operand" "rI,O,K,L")))] "" - "@ - addq %r1,%2,%0 - subq %r1,%n2,%0 - lda %0,%2(%r1) - ldah %0,%h2(%r1)") + "* +{ + const char * const pattern[4] = { + \"addq %r1,%2,%0\", + \"subq %r1,%n2,%0\", + \"lda %0,%2(%r1)\", + \"ldah %0,%h2(%r1)\" + }; + + /* The NT stack unwind code can't handle a subq to adjust the stack + (that's a bug, but not one we can do anything about). As of NT4.0 SP3, + the exception handling code will loop if a subq is used and an + exception occurs. + + The 19980616 change to emit prologues as RTL also confused some + versions of GDB, which also interprets prologues. This has been + fixed as of GDB 4.18, but it does not harm to unconditionally + use lda here. */ + + int which = which_alternative; + + if (operands[0] == stack_pointer_rtx + && GET_CODE (operands[2]) == CONST_INT + && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')) + which = 2; + + return pattern[which]; +}") + +;; ??? Allow large constants when basing off the frame pointer or some +;; virtual register that may eliminate to the frame pointer. This is +;; done because register elimination offsets will change the hi/lo split, +;; and if we split before reload, we will require additional instructions. + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (plus:DI (match_operand:DI 1 "reg_no_subreg_operand" "r") + (match_operand:DI 2 "const_int_operand" "n")))] + "REG_OK_FP_BASE_P (operands[1])" + "#") -;; Don't do this if we are adjusting SP since we don't want to do -;; it in two steps. +;; Don't do this if we are adjusting SP since we don't want to do it +;; in two steps. Don't split FP sources for the reason listed above. (define_split [(set (match_operand:DI 0 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "const_int_operand" "")))] "! add_operand (operands[2], DImode) - && REGNO (operands[0]) != STACK_POINTER_REGNUM" + && operands[0] != stack_pointer_rtx + && operands[1] != frame_pointer_rtx + && operands[1] != arg_pointer_rtx" [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 3))) (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 4)))] " @@ -540,24 +600,24 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r") - (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") + (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") (match_operand:SI 2 "const48_operand" "I,I")) (match_operand:SI 3 "sext_add_operand" "rI,O")))] "" "@ - s%2addl %r1,%3,%0 - s%2subl %r1,%n3,%0") + s%2addl %1,%3,%0 + s%2subl %1,%n3,%0") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,r") (sign_extend:DI - (plus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") + (plus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r,r") (match_operand:SI 2 "const48_operand" "I,I")) (match_operand:SI 3 "sext_add_operand" "rI,O"))))] "" "@ - s%2addl %r1,%3,%0 - s%2subl %r1,%n3,%0") + s%2addl %1,%3,%0 + s%2subl %1,%n3,%0") (define_split [(set (match_operand:DI 0 "register_operand" "") @@ -567,7 +627,7 @@ (match_operand 3 "" "")]) (match_operand:SI 4 "const48_operand" "")) (match_operand:SI 5 "add_operand" "")))) - (clobber (match_operand:DI 6 "register_operand" ""))] + (clobber (match_operand:DI 6 "reg_not_elim_operand" ""))] "" [(set (match_dup 6) (match_dup 7)) (set (match_dup 0) @@ -582,12 +642,12 @@ (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r,r") - (plus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,rJ") + (plus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r,r") (match_operand:DI 2 "const48_operand" "I,I")) - (match_operand:DI 3 "reg_or_8bit_operand" "rI,O")))] + (match_operand:DI 3 "sext_add_operand" "rI,O")))] "" "@ - s%2addq %r1,%3,%0 + s%2addq %1,%3,%0 s%2subq %1,%n3,%0") ;; These variants of the above insns can occur if the third operand @@ -656,9 +716,7 @@ [(set (match_dup 5) (plus:SI (mult:SI (match_dup 1) (match_dup 2)) (match_dup 3))) (set (match_dup 0) (sign_extend:DI (plus:SI (match_dup 5) (match_dup 4))))] - " -{ operands[5] = gen_lowpart (SImode, operands[0]); -}") + "operands[5] = gen_lowpart (SImode, operands[0]);") (define_insn "" [(set (match_operand:DI 0 "some_operand" "=&r") @@ -706,11 +764,22 @@ (match_operand:SI 2 "reg_or_8bit_operand" "")))] "" " -{ emit_insn (gen_rtx_SET (VOIDmode, gen_lowpart (DImode, operands[0]), - gen_rtx_MINUS (DImode, - gen_lowpart (DImode, operands[1]), - gen_lowpart (DImode, operands[2])))); - DONE; +{ + if (optimize) + { + rtx op1 = gen_lowpart (DImode, operands[1]); + rtx op2 = gen_lowpart (DImode, operands[2]); + + if (! cse_not_expected) + { + rtx tmp = gen_reg_rtx (DImode); + emit_insn (gen_subdi3 (tmp, op1, op2)); + emit_move_insn (gen_lowpart (DImode, operands[0]), tmp); + } + else + emit_insn (gen_subdi3 (gen_lowpart (DImode, operands[0]), op1, op2)); + DONE; + } } ") (define_insn "" @@ -736,64 +805,67 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "reg_or_8bit_operand" "rI")))] "" - "s%2subl %r1,%3,%0") + "s%2subl %1,%3,%0") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI - (minus:SI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (minus:SI (mult:SI (match_operand:SI 1 "reg_not_elim_operand" "r") (match_operand:SI 2 "const48_operand" "I")) (match_operand:SI 3 "reg_or_8bit_operand" "rI"))))] "" - "s%2subl %r1,%3,%0") + "s%2subl %1,%3,%0") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (minus:DI (mult:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") + (minus:DI (mult:DI (match_operand:DI 1 "reg_not_elim_operand" "r") (match_operand:DI 2 "const48_operand" "I")) (match_operand:DI 3 "reg_or_8bit_operand" "rI")))] "" - "s%2subq %r1,%3,%0") + "s%2subq %1,%3,%0") (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=r") (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") - (match_operand:SI 2 "reg_or_0_operand" "rJ")))] + (match_operand:SI 2 "reg_or_8bit_operand" "rI")))] "" - "mull %r1,%r2,%0" + "mull %r1,%2,%0" [(set_attr "type" "imul") (set_attr "opsize" "si")]) (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") - (match_operand:SI 2 "reg_or_0_operand" "rJ"))))] + (sign_extend:DI + (mult:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") + (match_operand:SI 2 "reg_or_8bit_operand" "rI"))))] "" - "mull %r1,%r2,%0" + "mull %r1,%2,%0" [(set_attr "type" "imul") (set_attr "opsize" "si")]) (define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (match_operand:DI 1 "reg_or_0_operand" "%rJ") - (match_operand:DI 2 "reg_or_0_operand" "rJ")))] + (match_operand:DI 2 "reg_or_8bit_operand" "rI")))] "" - "mulq %r1,%r2,%0" + "mulq %r1,%2,%0" [(set_attr "type" "imul")]) (define_insn "umuldi3_highpart" [(set (match_operand:DI 0 "register_operand" "=r") (truncate:DI (lshiftrt:TI - (mult:TI (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) - (zero_extend:TI (match_operand:DI 2 "register_operand" "r"))) + (mult:TI (zero_extend:TI + (match_operand:DI 1 "reg_or_0_operand" "%rJ")) + (zero_extend:TI + (match_operand:DI 2 "reg_or_8bit_operand" "rI"))) (const_int 64))))] "" - "umulh %1,%2,%0" + "umulh %r1,%2,%0" [(set_attr "type" "imul") (set_attr "opsize" "udi")]) @@ -816,6 +888,7 @@ ;; do the right thing if the inputs are not properly sign-extended. ;; But Linux, for instance, does not have this problem. Is it worth ;; the complication here to eliminate the sign extension? +;; Interix/NT has the same sign-extension problem. (define_expand "divsi3" [(set (reg:DI 24) @@ -1146,7 +1219,15 @@ "eqv %r1,%2,%0" [(set_attr "type" "ilog")]) -;; Handle the FFS insn if we support CIX. +;; Handle the FFS insn iff we support CIX. +;; +;; These didn't make it into EV6 pass 2 as planned. Instead they +;; cropped cttz/ctlz/ctpop from the old CIX and renamed it FIX for +;; "Square Root and Floating Point Convert Extension". +;; +;; I'm assured that these insns will make it into EV67 (first pass +;; due Summer 1999), presumably with a new AMASK bit, and presumably +;; will still be named CIX. (define_expand "ffsdi2" [(set (match_dup 2) @@ -1168,7 +1249,7 @@ (unspec [(match_operand:DI 1 "register_operand" "r")] 1))] "TARGET_CIX" "cttz %1,%0" - ; ev6 calls all mvi and cttz/ctlz/popc class imisc, so just + ; EV6 calls all mvi and cttz/ctlz/popc class imisc, so just ; reuse the existing type name. [(set_attr "type" "mvi")]) @@ -1495,6 +1576,29 @@ "ext%M2l %r1,%3,%0" [(set_attr "type" "shift")]) +;; Combine has some strange notion of preserving existing undefined behaviour +;; in shifts larger than a word size. So capture these patterns that it +;; should have turned into zero_extracts. + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (and (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") + (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (const_int 3))) + (match_operand:DI 3 "mode_mask_operand" "n")))] + "" + "ext%U3l %1,%2,%0" + [(set_attr "type" "shift")]) + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=r") + (lshiftrt:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") + (ashift:DI (match_operand:DI 2 "reg_or_8bit_operand" "rI") + (const_int 3))))] + "" + "extql %1,%2,%0" + [(set_attr "type" "shift")]) + (define_insn "extqh" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI @@ -1639,22 +1743,22 @@ "HOST_BITS_PER_WIDE_INT == 64 && GET_CODE (operands[3]) == CONST_INT && (((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) - == INTVAL (operands[3])) + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) || ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) - == INTVAL (operands[3])) + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) || ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) - == INTVAL (operands[3])))" + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])))" "* { #if HOST_BITS_PER_WIDE_INT == 64 if ((unsigned HOST_WIDE_INT) 0xff << INTVAL (operands[2]) - == INTVAL (operands[3])) + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) return \"insbl %1,%s2,%0\"; if ((unsigned HOST_WIDE_INT) 0xffff << INTVAL (operands[2]) - == INTVAL (operands[3])) + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) return \"inswl %1,%s2,%0\"; if ((unsigned HOST_WIDE_INT) 0xffffffff << INTVAL (operands[2]) - == INTVAL (operands[3])) + == (unsigned HOST_WIDE_INT) INTVAL (operands[3])) return \"insll %1,%s2,%0\"; #endif abort(); @@ -1794,60 +1898,62 @@ ;; instruction. To allow combine et al to do useful things, we keep the ;; operation as a unit until after reload, at which point we split the ;; instructions. +;; +;; Note that we (attempt to) only consider this optimization when the +;; ultimate destination is memory. If we will be doing further integer +;; 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_fp0_operand" "fG")] 5))] + "TARGET_FP" + "cvtql%` %R1,%0" + [(set_attr "type" "fadd") + (set_attr "trap" "yes")]) (define_split - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" ""))) - (clobber (match_scratch:DI 2 ""))] + [(set (match_operand:SI 0 "memory_operand" "") + (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0)) + (clobber (match_scratch:DI 2 "")) + (clobber (match_scratch:SI 3 ""))] "TARGET_FP && reload_completed" [(set (match_dup 2) (fix:DI (match_dup 1))) - (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))] + (set (match_dup 3) (unspec:SI [(match_dup 2)] 5)) + (set (match_dup 0) (match_dup 3))] "") -;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here. (define_split - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "")))] + [(set (match_operand:SI 0 "memory_operand" "") + (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "")) 0)) + (clobber (match_scratch:DI 2 ""))] "TARGET_FP && reload_completed" [(set (match_dup 2) (fix:DI (match_dup 1))) - (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))] - "operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));") + (set (match_dup 3) (unspec:SI [(match_dup 2)] 5)) + (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]));") (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=f") - (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))] - "TARGET_FP" - "cvtql%` %R1,%0" - [(set_attr "type" "fadd") - (set_attr "trap" "yes")]) - -(define_insn "fix_truncdfsi2_tp" - [(set (match_operand:SI 0 "register_operand" "=&f") - (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG"))) - (clobber (match_scratch:DI 2 "=&f"))] + [(set (match_operand:SI 0 "memory_operand" "=m") + (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0)) + (clobber (match_scratch:DI 2 "=&f")) + (clobber (match_scratch:SI 3 "=&f"))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "#" [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] + [(set (match_operand:SI 0 "memory_operand" "=m") + (subreg:SI (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")) 0)) + (clobber (match_scratch:DI 2 "=f"))] "TARGET_FP && alpha_tp != ALPHA_TP_INSN" "#" [(set_attr "type" "fadd") (set_attr "trap" "yes")]) -(define_expand "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP" - "{ if (alpha_tp == ALPHA_TP_INSN) - { emit_insn(gen_fix_truncdfsi2_tp(operands[0], operands[1])); DONE; } - }") - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&f") + [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "cvt%-q%(c %R1,%0" @@ -1855,7 +1961,7 @@ (set_attr "trap" "yes")]) (define_insn "fix_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") + [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] "TARGET_FP" "cvt%-q%(c %R1,%0" @@ -1865,55 +1971,52 @@ ;; Likewise between SFmode and SImode. (define_split - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "")))) - (clobber (match_scratch:DI 2 ""))] + [(set (match_operand:SI 0 "memory_operand" "") + (subreg:SI (fix:DI (float_extend:DF + (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0)) + (clobber (match_scratch:DI 2 "")) + (clobber (match_scratch:SI 3 ""))] "TARGET_FP && reload_completed" [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1)))) - (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))] + (set (match_dup 3) (unspec:SI [(match_dup 2)] 5)) + (set (match_dup 0) (match_dup 3))] "") -;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here. (define_split - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" ""))))] + [(set (match_operand:SI 0 "memory_operand" "") + (subreg:SI (fix:DI (float_extend:DF + (match_operand:SF 1 "reg_or_fp0_operand" ""))) 0)) + (clobber (match_scratch:DI 2 ""))] "TARGET_FP && reload_completed" [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1)))) - (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))] - "operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));") - -(define_insn "fix_truncsfsi2_tp" - [(set (match_operand:SI 0 "register_operand" "=&f") - (fix:SI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG")))) - (clobber (match_scratch:DI 2 "=&f"))] + (set (match_dup 3) (unspec:SI [(match_dup 2)] 5)) + (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]));") + +(define_insn "" + [(set (match_operand:SI 0 "memory_operand" "=m") + (subreg:SI (fix:DI (float_extend:DF + (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0)) + (clobber (match_scratch:DI 2 "=&f")) + (clobber (match_scratch:SI 3 "=&f"))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "#" [(set_attr "type" "fadd") (set_attr "trap" "yes")]) (define_insn "" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] + [(set (match_operand:SI 0 "memory_operand" "=m") + (subreg:SI (fix:DI (float_extend:DF + (match_operand:SF 1 "reg_or_fp0_operand" "fG"))) 0)) + (clobber (match_scratch:DI 2 "=f"))] "TARGET_FP && alpha_tp != ALPHA_TP_INSN" "#" [(set_attr "type" "fadd") (set_attr "trap" "yes")]) -(define_expand "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "=f") - (fix:SI (float_extend:DF - (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] - "TARGET_FP" - "{ if (alpha_tp == ALPHA_TP_INSN) - { emit_insn(gen_fix_truncsfsi2_tp(operands[0], operands[1])); DONE; } - }") - (define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&f") + [(set (match_operand:DI 0 "reg_no_subreg_operand" "=&f") (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" @@ -1922,7 +2025,7 @@ (set_attr "trap" "yes")]) (define_insn "fix_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "=f") + [(set (match_operand:DI 0 "reg_no_subreg_operand" "=f") (fix:DI (float_extend:DF (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))] "TARGET_FP" @@ -1932,7 +2035,7 @@ (define_insn "" [(set (match_operand:SF 0 "register_operand" "=&f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] + (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "cvtq%,%+%& %1,%0" [(set_attr "type" "fadd") @@ -1940,7 +2043,7 @@ (define_insn "floatdisf2" [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "register_operand" "f")))] + (float:SF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP" "cvtq%,%+%& %1,%0" [(set_attr "type" "fadd") @@ -1948,7 +2051,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] + (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP && alpha_tp == ALPHA_TP_INSN" "cvtq%-%+%& %1,%0" [(set_attr "type" "fadd") @@ -1956,7 +2059,7 @@ (define_insn "floatdidf2" [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "f")))] + (float:DF (match_operand:DI 1 "reg_no_subreg_operand" "f")))] "TARGET_FP" "cvtq%-%+%& %1,%0" [(set_attr "type" "fadd") @@ -1990,7 +2093,7 @@ (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,m,f")))] "TARGET_FP && alpha_tp != ALPHA_TP_INSN" "@ - cpys %1,%1,%0 + fmov %1,%0 ld%, %0,%1 st%- %1,%0" [(set_attr "type" "fcpys,fld,fst") @@ -2205,7 +2308,7 @@ (define_insn "" [(set (match_operand:SF 0 "register_operand" "=&f") (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP && TARGET_CIX && alpha_tp == ALPHA_TP_INSN" + "TARGET_FP && TARGET_FIX && alpha_tp == ALPHA_TP_INSN" "sqrt%,%)%& %R1,%0" [(set_attr "type" "fsqrt") (set_attr "opsize" "si") @@ -2214,7 +2317,7 @@ (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") (sqrt:SF (match_operand:SF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP && TARGET_CIX" + "TARGET_FP && TARGET_FIX" "sqrt%,%)%& %R1,%0" [(set_attr "type" "fsqrt") (set_attr "opsize" "si") @@ -2223,7 +2326,7 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=&f") (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP && TARGET_CIX && alpha_tp == ALPHA_TP_INSN" + "TARGET_FP && TARGET_FIX && alpha_tp == ALPHA_TP_INSN" "sqrt%-%)%& %R1,%0" [(set_attr "type" "fsqrt") (set_attr "trap" "yes")]) @@ -2231,7 +2334,7 @@ (define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=f") (sqrt:DF (match_operand:DF 1 "reg_or_fp0_operand" "fG")))] - "TARGET_FP && TARGET_CIX" + "TARGET_FP && TARGET_FIX" "sqrt%-%)%& %1,%0" [(set_attr "type" "fsqrt") (set_attr "trap" "yes")]) @@ -2262,7 +2365,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") - (if_then_else:DI + (if_then_else:SI (match_operator 2 "signed_comparison_operator" [(match_operand:DI 3 "reg_or_0_operand" "rJ,rJ,J,J") (match_operand:DI 4 "reg_or_0_operand" "J,J,rJ,rJ")]) @@ -2322,69 +2425,6 @@ cmovlbc %r2,%3,%0" [(set_attr "type" "icmov")]) -;; This form is added since combine thinks that an IF_THEN_ELSE with both -;; arms constant is a single insn, so it won't try to form it if combine -;; knows they are really two insns. This occurs in divides by powers -;; of two. - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=r") - (if_then_else:DI - (match_operator 2 "signed_comparison_operator" - [(match_operand:DI 3 "reg_or_0_operand" "rJ") - (const_int 0)]) - (plus:DI (match_dup 0) - (match_operand:DI 1 "reg_or_8bit_operand" "rI")) - (match_dup 0))) - (clobber (match_scratch:DI 4 "=&r"))] - "" - "addq %0,%1,%4\;cmov%C2 %r3,%4,%0" - [(set_attr "type" "icmov") - (set_attr "length" "8")]) - -(define_split - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator 2 "signed_comparison_operator" - [(match_operand:DI 3 "reg_or_0_operand" "") - (const_int 0)]) - (plus:DI (match_dup 0) - (match_operand:DI 1 "reg_or_8bit_operand" "")) - (match_dup 0))) - (clobber (match_operand:DI 4 "register_operand" ""))] - "" - [(set (match_dup 4) (plus:DI (match_dup 0) (match_dup 1))) - (set (match_dup 0) (if_then_else:DI (match_op_dup 2 - [(match_dup 3) - (const_int 0)]) - (match_dup 4) (match_dup 0)))] - "") - -(define_split - [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (if_then_else:DI - (match_operator 1 "comparison_operator" - [(zero_extract:DI (match_operand:DI 2 "register_operand" "") - (const_int 1) - (match_operand:DI 3 "const_int_operand" "")) - (const_int 0)]) - (match_operand:DI 4 "reg_or_8bit_operand" "") - (match_operand:DI 5 "reg_or_8bit_operand" ""))) - (clobber (match_operand:DI 6 "register_operand" ""))])] - "INTVAL (operands[3]) != 0" - [(set (match_dup 6) - (lshiftrt:DI (match_dup 2) (match_dup 3))) - (set (match_dup 0) - (if_then_else:DI (match_op_dup 1 - [(zero_extract:DI (match_dup 6) - (const_int 1) - (const_int 0)) - (const_int 0)]) - (match_dup 4) - (match_dup 5)))] - "") - ;; For ABS, we have two choices, depending on whether the input and output ;; registers are the same or not. (define_expand "absdi2" @@ -2460,7 +2500,7 @@ (define_insn "sminqi3" [(set (match_operand:QI 0 "register_operand" "=r") - (smin:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ") + (smin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "minsb8 %r1,%2,%0" @@ -2468,7 +2508,7 @@ (define_insn "uminqi3" [(set (match_operand:QI 0 "register_operand" "=r") - (umin:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ") + (umin:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "minub8 %r1,%2,%0" @@ -2476,7 +2516,7 @@ (define_insn "smaxqi3" [(set (match_operand:QI 0 "register_operand" "=r") - (smax:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ") + (smax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "maxsb8 %r1,%2,%0" @@ -2484,7 +2524,7 @@ (define_insn "umaxqi3" [(set (match_operand:QI 0 "register_operand" "=r") - (umax:SI (match_operand:QI 1 "reg_or_0_operand" "%rJ") + (umax:QI (match_operand:QI 1 "reg_or_0_operand" "%rJ") (match_operand:QI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "maxub8 %r1,%2,%0" @@ -2492,7 +2532,7 @@ (define_insn "sminhi3" [(set (match_operand:HI 0 "register_operand" "=r") - (smin:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ") + (smin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "minsw4 %r1,%2,%0" @@ -2500,7 +2540,7 @@ (define_insn "uminhi3" [(set (match_operand:HI 0 "register_operand" "=r") - (umin:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ") + (umin:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "minuw4 %r1,%2,%0" @@ -2508,7 +2548,7 @@ (define_insn "smaxhi3" [(set (match_operand:HI 0 "register_operand" "=r") - (smax:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ") + (smax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "maxsw4 %r1,%2,%0" @@ -2516,7 +2556,7 @@ (define_insn "umaxhi3" [(set (match_operand:HI 0 "register_operand" "=r") - (umax:SI (match_operand:HI 1 "reg_or_0_operand" "%rJ") + (umax:HI (match_operand:HI 1 "reg_or_0_operand" "%rJ") (match_operand:HI 2 "reg_or_8bit_operand" "rI")))] "TARGET_MAX" "maxuw4 %r1,%2,%0" @@ -3197,7 +3237,7 @@ (define_expand "movsicc" [(set (match_operand:SI 0 "register_operand" "") - (if_then_else:DI (match_operand 1 "comparison_operator" "") + (if_then_else:SI (match_operand 1 "comparison_operator" "") (match_operand:SI 2 "reg_or_8bit_operand" "") (match_operand:SI 3 "reg_or_8bit_operand" "")))] "" @@ -3610,7 +3650,7 @@ abort (); operands[1] = XEXP (operands[1], 0); - if (GET_CODE (operands[0]) != SYMBOL_REF && GET_CODE (operands[0]) != REG) + if (GET_CODE (operands[1]) != SYMBOL_REF && GET_CODE (operands[1]) != REG) operands[1] = force_reg (DImode, operands[1]); }") @@ -3675,7 +3715,7 @@ bsr $26,$%0..ng jsr $26,%0\;ldgp $29,0($26)" [(set_attr "type" "jsr") - (set_attr "length" "12,*,12")]) + (set_attr "length" "12,*,16")]) (define_insn "" [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i")) @@ -3698,7 +3738,7 @@ (clobber (reg:DI 27))] "TARGET_OPEN_VMS" "@ - bis %2,%2,$27\;jsr $26,0\;ldq $27,0($29) + mov %2,$27\;jsr $26,0\;ldq $27,0($29) ldq $27,%2\;jsr $26,%0\;ldq $27,0($29)" [(set_attr "type" "jsr") (set_attr "length" "12,16")]) @@ -3715,7 +3755,7 @@ bsr $26,$%1..ng jsr $26,%1\;ldgp $29,0($26)" [(set_attr "type" "jsr") - (set_attr "length" "12,*,12")]) + (set_attr "length" "12,*,16")]) (define_insn "" [(set (match_operand 0 "register_operand" "=rf,rf,rf") @@ -3740,7 +3780,7 @@ (clobber (reg:DI 27))] "TARGET_OPEN_VMS" "@ - bis %3,%3,$27\;jsr $26,0\;ldq $27,0($29) + mov %3,$27\;jsr $26,0\;ldq $27,0($29) ldq $27,%3\;jsr $26,%1\;ldq $27,0($29)" [(set_attr "type" "jsr") (set_attr "length" "12,16")]) @@ -3811,12 +3851,6 @@ "jmp $31,(%0),0" [(set_attr "type" "ibr")]) -(define_insn "nop" - [(const_int 0)] - "" - "nop" - [(set_attr "type" "ilog")]) - (define_expand "tablejump" [(use (match_operand:SI 0 "register_operand" "")) (use (match_operand:SI 1 "" ""))] @@ -3987,72 +4021,68 @@ ;; they are simpler. (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") - (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] - "! TARGET_CIX + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m") + (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r"))] + "! TARGET_FIX && (register_operand (operands[0], SFmode) || reg_or_fp0_operand (operands[1], SFmode))" "@ - bis %r1,%r1,%0 - ldl %0,%1 - stl %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%, %0,%1 - st%, %R1,%0" - [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")]) + mov %r1,%0 + ldl %0,%1 + st%, %R1,%0 + stl %r1,%0" + [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r") - (match_operand:SF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))] - "TARGET_CIX + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r") + (match_operand:SF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))] + "TARGET_FIX && (register_operand (operands[0], SFmode) || reg_or_fp0_operand (operands[1], SFmode))" "@ - bis %r1,%r1,%0 - ldl %0,%1 - stl %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%, %0,%1 + mov %r1,%0 + ldl %0,%1 st%, %R1,%0 + stl %r1,%0 itofs %1,%0 ftois %1,%0" - [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")]) + [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m") - (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG"))] - "! TARGET_CIX + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m") + (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r"))] + "! TARGET_FIX && (register_operand (operands[0], DFmode) || reg_or_fp0_operand (operands[1], DFmode))" "@ - bis %r1,%r1,%0 - ldq %0,%1 - stq %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%- %0,%1 - st%- %R1,%0" - [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst")]) + mov %r1,%0 + ldq %0,%1 + st%- %R1,%0 + stq %r1,%0" + [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist")]) (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m,f,f,f,m,f,*r") - (match_operand:DF 1 "input_operand" "rG,m,rG,f,G,m,fG,r,*f"))] - "TARGET_CIX + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,r,m,m,f,*r") + (match_operand:DF 1 "input_operand" "fG,m,rG,m,fG,r,r,*f"))] + "TARGET_FIX && (register_operand (operands[0], DFmode) || reg_or_fp0_operand (operands[1], DFmode))" "@ - bis %r1,%r1,%0 - ldq %0,%1 - stq %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%- %0,%1 + mov %r1,%0 + ldq %0,%1 st%- %R1,%0 + stq %r1,%0 itoft %1,%0 ftoit %1,%0" - [(set_attr "type" "ilog,ild,ist,fcpys,fcpys,fld,fst,itof,ftoi")]) + [(set_attr "type" "fcpys,fld,ilog,ild,fst,ist,itof,ftoi")]) (define_expand "movsf" [(set (match_operand:SF 0 "nonimmediate_operand" "") @@ -4077,131 +4107,110 @@ }") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m") - (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG"))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_CIX + [(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_WINDOWS_NT && ! TARGET_OPEN_VMS && ! TARGET_FIX && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%1 ldah %0,%h1 ldl %0,%1 stl %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%, %0,%1 st%, %R1,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst")]) + [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst")]) (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,m,f,f,f,m,r,*f") - (match_operand:SI 1 "input_operand" "r,J,I,K,L,m,rJ,f,J,m,fG,f,*r"))] - "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_CIX + [(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_WINDOWS_NT && ! TARGET_OPEN_VMS && TARGET_FIX && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%1 ldah %0,%h1 ldl %0,%1 stl %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%, %0,%1 st%, %R1,%0 ftois %1,%0 itofs %1,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")]) + [(set_attr "type" "ilog,iadd,iadd,ild,ist,fcpys,fld,fst,ftoi,itof")]) (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,r,r,r,r,m,f,f,f,m") - (match_operand:SI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,m,fG"))] + [(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_WINDOWS_NT || TARGET_OPEN_VMS) && (register_operand (operands[0], SImode) || reg_or_0_operand (operands[1], SImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %1,%0 lda %0,%1 ldah %0,%h1 lda %0,%1 ldl %0,%1 stl %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ld%, %0,%1 st%, %R1,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")]) + [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")]) (define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,f,f") - (match_operand:HI 1 "input_operand" "r,J,I,n,f,J"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,f") + (match_operand:HI 1 "input_operand" "rJ,n,fJ"))] "! TARGET_BWX && (register_operand (operands[0], HImode) || register_operand (operands[1], HImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%L1 - cpys %1,%1,%0 - cpys $f31,$f31,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")]) + fmov %R1,%0" + [(set_attr "type" "ilog,iadd,fcpys")]) (define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f") - (match_operand:HI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,f") + (match_operand:HI 1 "input_operand" "rJ,n,m,rJ,fJ"))] "TARGET_BWX && (register_operand (operands[0], HImode) || reg_or_0_operand (operands[1], HImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%L1 ldwu %0,%1 stw %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")]) + fmov %R1,%0" + [(set_attr "type" "ilog,iadd,ild,ist,fcpys")]) (define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,f,f") - (match_operand:QI 1 "input_operand" "r,J,I,n,f,J"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,f") + (match_operand:QI 1 "input_operand" "rJ,n,fJ"))] "! TARGET_BWX && (register_operand (operands[0], QImode) || register_operand (operands[1], QImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%L1 - cpys %1,%1,%0 - cpys $f31,$f31,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,fcpys,fcpys")]) + fmov %R1,%0" + [(set_attr "type" "ilog,iadd,fcpys")]) (define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,r,r,m,f,f") - (match_operand:QI 1 "input_operand" "r,J,I,n,m,rJ,f,J"))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m,f") + (match_operand:QI 1 "input_operand" "rJ,n,m,rJ,fJ"))] "TARGET_BWX && (register_operand (operands[0], QImode) || reg_or_0_operand (operands[1], QImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%L1 ldbu %0,%1 stb %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,ild,ist,fcpys,fcpys")]) + fmov %R1,%0" + [(set_attr "type" "ilog,iadd,ild,ist,fcpys")]) ;; We do two major things here: handle mem->mem and construct long ;; constants. @@ -4247,48 +4256,42 @@ }") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q") - (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG"))] - "! TARGET_CIX + [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q") + (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f"))] + "! TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%1 ldah %0,%h1 lda %0,%1 ldq%A1 %0,%1 stq%A0 %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ldt %0,%1 stt %R1,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst")]) + [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst")]) (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,r,r,m,f,f,f,Q,r,*f") - (match_operand:DI 1 "input_operand" "r,J,I,K,L,s,m,rJ,f,J,Q,fG,f,*r"))] - "TARGET_CIX + [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,r,m,f,f,Q,r,*f") + (match_operand:DI 1 "input_operand" "rJ,K,L,s,m,rJ,fJ,Q,f,f,*r"))] + "TARGET_FIX && (register_operand (operands[0], DImode) || reg_or_0_operand (operands[1], DImode))" "@ - bis %1,%1,%0 - bis $31,$31,%0 - bis $31,%1,%0 + mov %r1,%0 lda %0,%1 ldah %0,%h1 lda %0,%1 ldq%A1 %0,%1 stq%A0 %r1,%0 - cpys %1,%1,%0 - cpys $f31,$f31,%0 + fmov %R1,%0 ldt %0,%1 stt %R1,%0 ftoit %1,%0 itoft %1,%0" - [(set_attr "type" "ilog,ilog,ilog,iadd,iadd,ldsym,ild,ist,fcpys,fcpys,fld,fst,ftoi,itof")]) + [(set_attr "type" "ilog,iadd,iadd,ldsym,ild,ist,fcpys,fld,fst,ftoi,itof")]) ;; We do three major things here: handle mem->mem, put 64-bit constants in ;; memory, and construct long 32-bit constants. @@ -4320,24 +4323,31 @@ { if (TARGET_BUILD_CONSTANTS) { -#if HOST_BITS_PER_WIDE_INT == 64 - HOST_WIDE_INT i; + HOST_WIDE_INT i0, i1; if (GET_CODE (operands[1]) == CONST_INT) - i = INTVAL (operands[1]); + { + i0 = INTVAL (operands[1]); + i1 = -(i0 < 0); + } else if (GET_CODE (operands[1]) == CONST_DOUBLE) - i = CONST_DOUBLE_LOW (operands[1]); + { +#if HOST_BITS_PER_WIDE_INT >= 64 + i0 = CONST_DOUBLE_LOW (operands[1]); + i1 = -(i0 < 0); +#else + i0 = CONST_DOUBLE_LOW (operands[1]); + i1 = CONST_DOUBLE_HIGH (operands[1]); +#endif + } else abort(); - tem = alpha_emit_set_long_const (operands[0], i); + tem = alpha_emit_set_long_const (operands[0], i0, i1); if (rtx_equal_p (tem, operands[0])) DONE; else operands[1] = tem; -#else - abort(); -#endif } else { @@ -4553,15 +4563,22 @@ { if (aligned_memory_operand (operands[1], QImode)) { - rtx aligned_mem, bitnum; - rtx scratch = (reload_in_progress - ? gen_rtx_REG (SImode, REGNO (operands[0])) - : gen_reg_rtx (SImode)); + if (reload_in_progress) + { + emit_insn (gen_reload_inqi_help + (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[0])))); + } + else + { + rtx aligned_mem, bitnum; + rtx scratch = gen_reg_rtx (SImode); - get_aligned_mem (operands[1], &aligned_mem, &bitnum); + get_aligned_mem (operands[1], &aligned_mem, &bitnum); - emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, - scratch)); + emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, + scratch)); + } } else { @@ -4610,7 +4627,7 @@ rtx temp3 = gen_reg_rtx (DImode); rtx seq = gen_unaligned_storeqi (get_unaligned_address (operands[0], 0), - operands[1], temp1, temp2, temp3); + operands[1], temp1, temp2, temp3); alpha_set_memflags (seq, operands[0]); emit_insn (seq); @@ -4664,15 +4681,22 @@ { if (aligned_memory_operand (operands[1], HImode)) { - rtx aligned_mem, bitnum; - rtx scratch = (reload_in_progress - ? gen_rtx_REG (SImode, REGNO (operands[0])) - : gen_reg_rtx (SImode)); + if (reload_in_progress) + { + emit_insn (gen_reload_inhi_help + (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[0])))); + } + else + { + rtx aligned_mem, bitnum; + rtx scratch = gen_reg_rtx (SImode); - get_aligned_mem (operands[1], &aligned_mem, &bitnum); + get_aligned_mem (operands[1], &aligned_mem, &bitnum); - emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, - scratch)); + emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, + scratch)); + } } else { @@ -4738,48 +4762,76 @@ (define_expand "reload_inqi" [(parallel [(match_operand:QI 0 "register_operand" "=r") - (match_operand:QI 1 "unaligned_memory_operand" "m") + (match_operand:QI 1 "any_memory_operand" "m") (match_operand:TI 2 "register_operand" "=&r")])] "! TARGET_BWX" " { - rtx addr = get_unaligned_address (operands[1], 0); + rtx scratch, seq; - /* 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. */ - rtx scratch = gen_rtx_REG (DImode, - REGNO (operands[0]) == REGNO (operands[2]) - ? REGNO (operands[2]) + 1 : REGNO (operands[2])); + if (GET_CODE (operands[1]) != MEM) + abort (); - rtx seq = gen_unaligned_loadqi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); + if (aligned_memory_operand (operands[1], QImode)) + { + seq = gen_reload_inqi_help (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[2]))); + } + else + { + rtx addr; + + /* 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 (REGNO (operands[0]) == REGNO (operands[2])) + scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); + else + scratch = gen_rtx_REG (DImode, REGNO (operands[2])); - alpha_set_memflags (seq, operands[1]); + addr = get_unaligned_address (operands[1], 0); + seq = gen_unaligned_loadqi (operands[0], addr, scratch, + gen_rtx_REG (DImode, REGNO (operands[0]))); + alpha_set_memflags (seq, operands[1]); + } emit_insn (seq); DONE; }") (define_expand "reload_inhi" [(parallel [(match_operand:HI 0 "register_operand" "=r") - (match_operand:HI 1 "unaligned_memory_operand" "m") + (match_operand:HI 1 "any_memory_operand" "m") (match_operand:TI 2 "register_operand" "=&r")])] "! TARGET_BWX" " { - rtx addr = get_unaligned_address (operands[1], 0); + rtx scratch, seq; - /* 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. */ - rtx scratch = gen_rtx_REG (DImode, - REGNO (operands[0]) == REGNO (operands[2]) - ? REGNO (operands[2]) + 1 : REGNO (operands[2])); + if (GET_CODE (operands[1]) != MEM) + abort (); - rtx seq = gen_unaligned_loadhi (operands[0], addr, scratch, - gen_rtx_REG (DImode, REGNO (operands[0]))); + if (aligned_memory_operand (operands[1], HImode)) + { + seq = gen_reload_inhi_help (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[2]))); + } + else + { + rtx addr; + + /* 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 (REGNO (operands[0]) == REGNO (operands[2])) + scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1); + else + scratch = gen_rtx_REG (DImode, REGNO (operands[2])); - alpha_set_memflags (seq, operands[1]); + addr = get_unaligned_address (operands[1], 0); + seq = gen_unaligned_loadhi (operands[0], addr, scratch, + gen_rtx_REG (DImode, REGNO (operands[0]))); + alpha_set_memflags (seq, operands[1]); + } emit_insn (seq); DONE; }") @@ -4791,16 +4843,15 @@ "! TARGET_BWX" " { + if (GET_CODE (operands[0]) != MEM) + abort (); + if (aligned_memory_operand (operands[0], QImode)) { - rtx aligned_mem, bitnum; - - get_aligned_mem (operands[0], &aligned_mem, &bitnum); - - emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, - REGNO (operands[2]) + 1))); + emit_insn (gen_reload_outqi_help + (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[2])), + gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); } else { @@ -4818,7 +4869,6 @@ alpha_set_memflags (seq, operands[0]); emit_insn (seq); } - DONE; }") @@ -4829,16 +4879,15 @@ "! TARGET_BWX" " { + if (GET_CODE (operands[0]) != MEM) + abort (); + if (aligned_memory_operand (operands[0], HImode)) { - rtx aligned_mem, bitnum; - - get_aligned_mem (operands[0], &aligned_mem, &bitnum); - - emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, - gen_rtx_REG (SImode, REGNO (operands[2])), - gen_rtx_REG (SImode, - REGNO (operands[2]) + 1))); + emit_insn (gen_reload_outhi_help + (operands[0], operands[1], + gen_rtx_REG (SImode, REGNO (operands[2])), + gen_rtx_REG (SImode, REGNO (operands[2]) + 1))); } else { @@ -4856,7 +4905,102 @@ alpha_set_memflags (seq, operands[0]); emit_insn (seq); } + DONE; +}") + +;; Helpers for the above. The way reload is structured, we can't +;; 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" + [(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" "r") + (match_operand:QI 1 "memory_operand" "m")) + (clobber (match_operand:SI 2 "register_operand" "r"))] + "! TARGET_BWX && reload_completed" + [(const_int 0)] + " +{ + rtx aligned_mem, bitnum; + get_aligned_mem (operands[1], &aligned_mem, &bitnum); + emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum, + operands[2])); + DONE; +}") + +(define_split + [(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_completed" + [(const_int 0)] + " +{ + rtx aligned_mem, bitnum; + get_aligned_mem (operands[1], &aligned_mem, &bitnum); + emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum, + operands[2])); + DONE; +}") + +(define_split + [(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_completed" + [(const_int 0)] + " +{ + rtx aligned_mem, bitnum; + get_aligned_mem (operands[0], &aligned_mem, &bitnum); + emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, + operands[2], operands[3])); + DONE; +}") + +(define_split + [(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_completed" + [(const_int 0)] + " +{ + rtx aligned_mem, bitnum; + get_aligned_mem (operands[0], &aligned_mem, &bitnum); + emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum, + operands[2], operands[3])); DONE; }") @@ -5080,29 +5224,14 @@ "" "* { - static int label_no; - int count_regno = REGNO (operands[0]); - int ptr_regno = REGNO (operands[1]); - char label[64]; - - /* Ho hum, output the hard way to get the label at the beginning of - the line. Wish there were a magic char you could get - asm_output_printf to do that. Then we could use %= as well and - get rid of the label_no bits here too. */ - - ASM_GENERATE_INTERNAL_LABEL (label, \"LSC\", label_no); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"LSC\", label_no++); - - fprintf (asm_out_file, \"\\tstq $31,-8192($%d)\\n\", ptr_regno); - fprintf (asm_out_file, \"\\tsubq $%d,1,$%d\\n\", count_regno, count_regno); - fprintf (asm_out_file, \"\\tlda $%d,-8192($%d)\\n\", ptr_regno, ptr_regno); - fprintf (asm_out_file, \"\\tbne $%d,\", count_regno); - assemble_name (asm_out_file, label); - putc ('\\n', asm_out_file); - - return \"\"; + operands[2] = gen_label_rtx (); + ASM_OUTPUT_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\"; }" - [(set_attr "length" "16")]) + [(set_attr "length" "16") + (set_attr "type" "multi")]) (define_expand "prologue" [(clobber (const_int 0))] @@ -5114,13 +5243,39 @@ (match_operand:DI 1 "register_operand" "r")) (clobber (mem:BLK (match_operand:DI 2 "register_operand" "r")))] "" - "bis %1,%1,%0") + "mov %1,%0") (define_expand "epilogue" [(clobber (const_int 0))] "" "alpha_expand_epilogue (); DONE;") +(define_expand "eh_epilogue" + [(use (match_operand:DI 0 "register_operand" "r")) + (use (match_operand:DI 1 "register_operand" "r")) + (use (match_operand:DI 2 "register_operand" "r"))] + "! TARGET_OPEN_VMS" + " +{ + alpha_eh_epilogue_sp_ofs = operands[1]; + if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 26) + { + rtx ra = gen_rtx_REG (Pmode, 26); + emit_move_insn (ra, operands[2]); + operands[2] = ra; + } +}") + +;; 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")] 6))] + "" + "lda %0,%1(%0)") + (define_expand "builtin_longjmp" [(unspec_volatile [(match_operand 0 "register_operand" "r")] 3)] "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" @@ -5143,19 +5298,29 @@ where to look for it when we get back to setjmp's function for restoring the gp. */ emit_indirect_jump (pv); + DONE; }") (define_insn "builtin_setjmp_receiver" - [(unspec_volatile [(match_operand 0 "" "")] 2)] + [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)] "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT && TARGET_AS_CAN_SUBTRACT_LABELS" "\\n$LSJ%=:\;ldgp $29,$LSJ%=-%l0($27)" - [(set_attr "length" "8")]) + [(set_attr "length" "8") + (set_attr "type" "multi")]) (define_insn "" - [(unspec_volatile [(match_operand 0 "" "")] 2)] + [(unspec_volatile [(label_ref (match_operand 0 "" ""))] 2)] "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" - "br $27,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($27)" - [(set_attr "length" "12")]) + "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)" + [(set_attr "length" "12") + (set_attr "type" "multi")]) + +(define_insn "exception_receiver" + [(unspec_volatile [(const_int 0)] 7)] + "! TARGET_OPEN_VMS && ! TARGET_WINDOWS_NT" + "br $29,$LSJ%=\\n$LSJ%=:\;ldgp $29,0($29)" + [(set_attr "length" "12") + (set_attr "type" "multi")]) (define_expand "nonlocal_goto_receiver" [(unspec_volatile [(const_int 0)] 1) @@ -5187,7 +5352,8 @@ (clobber (reg:DI 0))] "TARGET_OPEN_VMS" "lda $0,OTS$HOME_ARGS\;ldq $0,8($0)\;jsr $0,OTS$HOME_ARGS" - [(set_attr "length" "16")]) + [(set_attr "length" "16") + (set_attr "type" "multi")]) ;; Close the trap shadow of preceeding instructions. This is generated ;; by alpha_reorg. @@ -5197,6 +5363,31 @@ "" "trapb" [(set_attr "type" "misc")]) + +;; No-op instructions used by machine-dependant reorg to preserve +;; alignment for instruction issue. + +(define_insn "nop" + [(const_int 0)] + "" + "nop" + [(set_attr "type" "ilog")]) + +(define_insn "fnop" + [(const_int 1)] + "TARGET_FP" + "fnop" + [(set_attr "type" "fcpys")]) + +(define_insn "unop" + [(const_int 2)] + "" + "unop") + +(define_insn "realign" + [(unspec_volatile [(match_operand 0 "immediate_operand" "i")] 6)] + "" + ".align %0 #realign") ;; Peepholes go at the end. @@ -5220,5 +5411,5 @@ ; (match_operand:SI 1 "hard_fp_register_operand" "f")) ; (set (match_operand:DI 2 "register_operand" "=r") ; (sign_extend:DI (match_dup 0)))] -; "TARGET_CIX && dead_or_set_p (insn, operands[0])" +; "TARGET_FIX && dead_or_set_p (insn, operands[0])" ; "ftois %1,%2") diff --git a/contrib/gcc/config/alpha/alpha32.h b/contrib/gcc/config/alpha/alpha32.h new file mode 100644 index 0000000..3cbcfe1 --- /dev/null +++ b/contrib/gcc/config/alpha/alpha32.h @@ -0,0 +1,104 @@ +/* Definitions of target machine for GNU compiler, for DEC Alpha + running Windows/NT. + Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc. + + Derived from code + Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) + + Donn Terry, Softway Systems, Inc. + + This file contains the code-generation stuff common to the 32-bit + versions of the DEC/Compaq Alpha architecture. It is shared by + Interix and NT/Win32 ports. It should not contain compile-time + or run-time dependent environment values (such as compiler options + or anything containing a file or pathname.) + +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. */ + +#undef TARGET_WINDOWS_NT +#define TARGET_WINDOWS_NT 1 + +/* WinNT (and thus Interix) use unsigned int */ +#define SIZE_TYPE "unsigned int" + +/* Pointer is 32 bits but the hardware has 64-bit addresses, sign extended. */ +#undef POINTER_SIZE +#define POINTER_SIZE 32 +#define POINTERS_EXTEND_UNSIGNED 0 + +/* We don't change Pmode to the "obvious" SI mode... the above appears + to affect the in-memory size; we want the registers to stay DImode + to match the md file */ + +/* "long" is 32 bits. */ +#undef LONG_TYPE_SIZE +#define LONG_TYPE_SIZE 32 + + +/* Output assembler code for a block containing the constant parts + of a trampoline, leaving space for the variable parts. + + The trampoline should set the static chain pointer to value placed + into the trampoline and should branch to the specified routine. */ + +#undef TRAMPOLINE_TEMPLATE +#define TRAMPOLINE_TEMPLATE(FILE) \ +{ \ + fprintf (FILE, "\tbr $27,$LTRAMPP\n"); \ + fprintf (FILE, "$LTRAMPP:\n\tldl $1,12($27)\n"); \ + fprintf (FILE, "\tldl $27,16($27)\n"); \ + fprintf (FILE, "\tjmp $31,($27),0\n"); \ + fprintf (FILE, "\t.long 0,0\n"); \ +} + +/* Length in units of the trampoline for entering a nested function. */ + +#undef TRAMPOLINE_SIZE +#define TRAMPOLINE_SIZE 24 + +/* 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. */ + +#undef INITIALIZE_TRAMPOLINE +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ + alpha_initialize_trampoline (TRAMP, FNADDR, CXT, 20, 16, 12) + +/* Output code to add DELTA to the first argument, and then jump to FUNCTION. + Used for C++ multiple inheritance. */ + +#undef ASM_OUTPUT_MI_THUNK +#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \ +do { \ + char *op, *fn_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0); \ + int reg; \ + \ + /* Mark end of prologue. */ \ + output_end_prologue (FILE); \ + \ + /* Rely on the assembler to macro expand a large delta. */ \ + reg = aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) ? 17 : 16; \ + fprintf (FILE, "\tlda $%d,%ld($%d)\n", reg, (long)(DELTA), reg); \ + \ + op = "jsr"; \ + if (current_file_function_operand (XEXP (DECL_RTL (FUNCTION), 0))) \ + op = "br"; \ + fprintf (FILE, "\t%s $31,", op); \ + assemble_name (FILE, fn_name); \ + fputc ('\n', FILE); \ +} while (0) diff --git a/contrib/gcc/config/alpha/crtbegin.asm b/contrib/gcc/config/alpha/crtbegin.asm index c28440d..f954f1a 100644 --- a/contrib/gcc/config/alpha/crtbegin.asm +++ b/contrib/gcc/config/alpha/crtbegin.asm @@ -50,6 +50,8 @@ __CTOR_LIST__: __DTOR_LIST__: .quad -1 +.section .eh_frame,"aw" +__EH_FRAME_BEGIN__: # # Fragment of the ELF _fini routine that invokes our dtor cleanup. @@ -67,18 +69,33 @@ __DTOR_LIST__: 1: ldgp $29,0($29) jsr $26,__do_global_dtors_aux + # Ideally this call would go in crtend.o, except that we can't + # get hold of __EH_FRAME_BEGIN__ there. + + jsr $26,__do_frame_takedown + # Must match the alignment we got from crti.o else we get # zero-filled holes in our _fini function and then SIGILL. .align 3 # + # Fragment of the ELF _init routine that sets up the frame info. + # + +.section .init,"ax" + br $29,1f +1: ldgp $29,0($29) + jsr $26,__do_frame_setup + .align 3 + + # # Invoke our destructors in order. # .data # Support recursive calls to exit. -9: .quad __DTOR_LIST__ +$ptr: .quad __DTOR_LIST__ .text @@ -86,15 +103,14 @@ __DTOR_LIST__: .ent __do_global_dtors_aux __do_global_dtors_aux: - ldgp $29,0($27) lda $30,-16($30) .frame $30,16,$26,0 stq $9,8($30) stq $26,0($30) .mask 0x4000200,-16 - .prologue 1 + .prologue 0 - lda $9,9b + lda $9,$ptr br 1f 0: stq $1,0($9) jsr $26,($27) @@ -109,3 +125,68 @@ __do_global_dtors_aux: ret .end __do_global_dtors_aux + + # + # Install our frame info. + # + + # ??? How can we rationally keep this size correct? + +.section .bss + .type $object,@object + .align 3 +$object: + .zero 48 + .size $object, 48 + +.text + + .align 3 + .ent __do_frame_setup + +__do_frame_setup: + ldgp $29,0($27) + lda $30,-16($30) + .frame $30,16,$26,0 + stq $26,0($30) + .mask 0x4000000,-16 + .prologue 1 + + lda $1,__register_frame_info + beq $1,0f + lda $16,__EH_FRAME_BEGIN__ + lda $17,$object + jsr $26,__register_frame_info + ldq $26,0($30) +0: lda $30,16($30) + ret + + .end __do_frame_setup + + # + # Remove our frame info. + # + + .align 3 + .ent __do_frame_takedown + +__do_frame_takedown: + ldgp $29,0($27) + lda $30,-16($30) + .frame $30,16,$26,0 + stq $26,0($30) + .mask 0x4000000,-16 + .prologue 1 + + lda $1,__deregister_frame_info + beq $1,0f + lda $16,__EH_FRAME_BEGIN__ + jsr $26,__deregister_frame_info + ldq $26,0($30) +0: lda $30,16($30) + ret + + .end __do_frame_takedown + +.weak __register_frame_info +.weak __deregister_frame_info diff --git a/contrib/gcc/config/alpha/crtend.asm b/contrib/gcc/config/alpha/crtend.asm index 36f11b9..4a0cc5e 100644 --- a/contrib/gcc/config/alpha/crtend.asm +++ b/contrib/gcc/config/alpha/crtend.asm @@ -50,6 +50,9 @@ __CTOR_END__: __DTOR_END__: .quad 0 +.section .eh_frame,"aw" +__FRAME_END__: + .quad 0 # # Fragment of the ELF _init routine that invokes our ctor startup diff --git a/contrib/gcc/config/alpha/elf.h b/contrib/gcc/config/alpha/elf.h index 4f4703c..6cea3da 100644 --- a/contrib/gcc/config/alpha/elf.h +++ b/contrib/gcc/config/alpha/elf.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for DEC Alpha w/ELF. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by Richard Henderson (rth@tamu.edu). This file is part of GNU CC. @@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */ #define OBJECT_FORMAT_ELF #define DBX_DEBUGGING_INFO +#define DWARF2_DEBUGGING_INFO #undef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG @@ -34,7 +35,7 @@ Boston, MA 02111-1307, USA. */ #define CC1_SPEC "%{G*}" #undef ASM_SPEC -#define ASM_SPEC "%{G*} %{relax:-relax}" +#define ASM_SPEC "%{G*} %{relax:-relax} %{gdwarf*:-no-mdebug}" #undef LINK_SPEC #define LINK_SPEC "-m elf64alpha %{G*} %{relax:-relax} \ @@ -49,18 +50,21 @@ Boston, MA 02111-1307, USA. */ /* Output at beginning of assembler file. */ #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ -{ \ - alpha_write_verstamp (FILE); \ - output_file_directive (FILE, main_input_filename); \ +do { \ + if (write_symbols != DWARF2_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_BWX | TARGET_MAX | TARGET_CIX) \ + fprintf (FILE, "\t.set noreorder\n"); \ + if (TARGET_BWX | TARGET_MAX | TARGET_FIX | TARGET_CIX) \ { \ fprintf (FILE, "\t.arch %s\n", \ (alpha_cpu == PROCESSOR_EV6 ? "ev6" \ : TARGET_MAX ? "pca56" : "ev56")); \ } \ -} +} while (0) extern void output_file_directive (); @@ -79,8 +83,9 @@ extern void output_file_directive (); #else #define ASM_FILE_END(FILE) \ do { \ - fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ - IDENT_ASM_OP, version_string); \ + if (!flag_no_ident) \ + fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ + IDENT_ASM_OP, version_string); \ } while (0) #endif @@ -434,20 +439,23 @@ void FN () \ size_directive_output was set by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ -#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ -do { \ - char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ - if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ - && ! AT_END && TOP_LEVEL \ - && DECL_INITIAL (DECL) == error_mark_node \ - && !size_directive_output) \ - { \ - size_directive_output = 1; \ - fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ - assemble_name (FILE, name); \ - fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ - } \ - } while (0) +#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ +do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + size_directive_output = 1; \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + putc (',', FILE); \ + fprintf (FILE, HOST_WIDE_INT_PRINT_DEC, \ + int_size_in_bytes (TREE_TYPE (DECL))); \ + putc ('\n', FILE); \ + } \ +} while (0) /* A table of bytes codes used by the ASM_OUTPUT_ASCII and ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table @@ -518,3 +526,9 @@ do { \ /* We support #pragma. */ #define HANDLE_SYSV_PRAGMA + +/* Undo the auto-alignment stuff from alpha.h. ELF has unaligned data + pseudos natively. */ +#undef UNALIGNED_SHORT_ASM_OP +#undef UNALIGNED_INT_ASM_OP +#undef UNALIGNED_DOUBLE_INT_ASM_OP diff --git a/contrib/gcc/config/alpha/lib1funcs.asm b/contrib/gcc/config/alpha/lib1funcs.asm new file mode 100644 index 0000000..e63180a --- /dev/null +++ b/contrib/gcc/config/alpha/lib1funcs.asm @@ -0,0 +1,325 @@ +/* DEC Alpha division and remainder support. + Copyright (C) 1994, 1999 Free Software Foundation, Inc. + +This file is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free 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, 675 Mass Ave, Cambridge, MA 02139, 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. */ + +/* This had to be written in assembler because the division functions + use a non-standard calling convention. + + This file provides an implementation of __divqu, __divq, __divlu, + __divl, __remqu, __remq, __remlu and __reml. CPP macros control + the exact operation. + + Operation performed: $27 := $24 o $25, clobber $28, return address to + caller in $23, where o one of the operations. + + The following macros need to be defined: + + SIZE, the number of bits, 32 or 64. + + TYPE, either UNSIGNED or SIGNED + + OPERATION, either DIVISION or REMAINDER + + SPECIAL_CALLING_CONVENTION, 0 or 1. It is useful for debugging to + define this to 0. That removes the `__' prefix to make the function + name not collide with the existing libc.a names, and uses the + standard Alpha procedure calling convention. +*/ + +#ifndef SPECIAL_CALLING_CONVENTION +#define SPECIAL_CALLING_CONVENTION 1 +#endif + +#ifdef L_divl +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __divl +#else +#define FUNCTION_NAME divl +#endif +#define SIZE 32 +#define TYPE SIGNED +#define OPERATION DIVISION +#endif + +#ifdef L_divlu +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __divlu +#else +#define FUNCTION_NAME divlu +#endif +#define SIZE 32 +#define TYPE UNSIGNED +#define OPERATION DIVISION +#endif + +#ifdef L_divq +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __divq +#else +#define FUNCTION_NAME divq +#endif +#define SIZE 64 +#define TYPE SIGNED +#define OPERATION DIVISION +#endif + +#ifdef L_divqu +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __divqu +#else +#define FUNCTION_NAME divqu +#endif +#define SIZE 64 +#define TYPE UNSIGNED +#define OPERATION DIVISION +#endif + +#ifdef L_reml +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __reml +#else +#define FUNCTION_NAME reml +#endif +#define SIZE 32 +#define TYPE SIGNED +#define OPERATION REMAINDER +#endif + +#ifdef L_remlu +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __remlu +#else +#define FUNCTION_NAME remlu +#endif +#define SIZE 32 +#define TYPE UNSIGNED +#define OPERATION REMAINDER +#endif + +#ifdef L_remq +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __remq +#else +#define FUNCTION_NAME remq +#endif +#define SIZE 64 +#define TYPE SIGNED +#define OPERATION REMAINDER +#endif + +#ifdef L_remqu +#if SPECIAL_CALLING_CONVENTION +#define FUNCTION_NAME __remqu +#else +#define FUNCTION_NAME remqu +#endif +#define SIZE 64 +#define TYPE UNSIGNED +#define OPERATION REMAINDER +#endif + +#define tmp0 $3 +#define tmp1 $28 +#define cnt $1 +#define result_sign $2 + +#if SPECIAL_CALLING_CONVENTION +#define N $24 +#define D $25 +#define Q RETREG +#define RETREG $27 +#else +#define N $16 +#define D $17 +#define Q RETREG +#define RETREG $0 +#endif + +/* Misc symbols to make alpha assembler easier to read. */ +#define zero $31 +#define sp $30 + +/* Symbols to make interface nicer. */ +#define UNSIGNED 0 +#define SIGNED 1 +#define DIVISION 0 +#define REMAINDER 1 + + .set noreorder + .set noat +.text + .align 3 + .globl FUNCTION_NAME + .ent FUNCTION_NAME +FUNCTION_NAME: + + .frame $30,0,$26,0 + .prologue 0 + +/* Under the special calling convention, we have to preserve all register + values but $23 and $28. */ +#if SPECIAL_CALLING_CONVENTION + lda sp,-64(sp) +#if OPERATION == DIVISION + stq N,0(sp) +#endif + stq D,8(sp) + stq cnt,16(sp) + stq result_sign,24(sp) + stq tmp0,32(sp) +#endif + +/* If we are computing the remainder, move N to the register that is used + for the return value, and redefine what register is used for N. */ +#if OPERATION == REMAINDER + bis N,N,RETREG +#undef N +#define N RETREG +#endif + +/* Perform conversion from 32 bit types to 64 bit types. */ +#if SIZE == 32 +#if TYPE == SIGNED + /* If there are problems with the signed case, add these instructions. + The caller should already have done this. + addl N,0,N # sign extend N + addl D,0,D # sign extend D + */ +#else /* UNSIGNED */ + zap N,0xf0,N # zero extend N (caller required to sign extend) + zap D,0xf0,D # zero extend D +#endif +#endif + +/* Check for divide by zero. */ + bne D,$34 + lda $16,-2(zero) + call_pal 0xaa +$34: + +#if TYPE == SIGNED +#if OPERATION == DIVISION + xor N,D,result_sign +#else + bis N,N,result_sign +#endif +/* Get the absolute values of N and D. */ + subq zero,N,tmp0 + cmovlt N,tmp0,N + subq zero,D,tmp0 + cmovlt D,tmp0,D +#endif + +/* Compute CNT = ceil(log2(N)) - ceil(log2(D)). This is the number of + divide iterations we will have to perform. Should you wish to optimize + this, check a few bits at a time, preferably using zap/zapnot. Be + careful though, this code runs fast fro the most common cases, when the + quotient is small. */ + bge N,$35 + bis zero,1,cnt + blt D,$40 + .align 3 +$39: addq D,D,D + addl cnt,1,cnt + bge D,$39 + br zero,$40 +$35: cmpult N,D,tmp0 + bis zero,zero,cnt + bne tmp0,$42 + .align 3 +$44: addq D,D,D + cmpult N,D,tmp0 + addl cnt,1,cnt + beq tmp0,$44 +$42: srl D,1,D +$40: + subl cnt,1,cnt + + +/* Actual divide. Could be optimized with unrolling. */ +#if OPERATION == DIVISION + bis zero,zero,Q +#endif + blt cnt,$46 + .align 3 +$49: cmpule D,N,tmp1 + subq N,D,tmp0 + srl D,1,D + subl cnt,1,cnt + cmovne tmp1,tmp0,N +#if OPERATION == DIVISION + addq Q,Q,Q + bis Q,tmp1,Q +#endif + bge cnt,$49 +$46: + + +/* The result is now in RETREG. NOTE! It was written to RETREG using + either N or Q as a synonym! */ + + +/* Change the sign of the result as needed. */ +#if TYPE == SIGNED + subq zero,RETREG,tmp0 + cmovlt result_sign,tmp0,RETREG +#endif + + +/* Restore clobbered registers. */ +#if SPECIAL_CALLING_CONVENTION +#if OPERATION == DIVISION + ldq N,0(sp) +#endif + ldq D,8(sp) + ldq cnt,16(sp) + ldq result_sign,24(sp) + ldq tmp0,32(sp) + + lda sp,64(sp) +#endif + + +/* Sign extend an *unsigned* 32 bit result, as required by the Alpha + 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. */ + addl RETREG,0,RETREG +#endif + + +#if SPECIAL_CALLING_CONVENTION + ret zero,($23),1 +#else + ret zero,($26),1 +#endif + .end FUNCTION_NAME diff --git a/contrib/gcc/config/alpha/linux-ecoff.h b/contrib/gcc/config/alpha/linux-ecoff.h index a6cd5b2..824d028 100644 --- a/contrib/gcc/config/alpha/linux-ecoff.h +++ b/contrib/gcc/config/alpha/linux-ecoff.h @@ -17,13 +17,14 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ECOFF)"); -#undef SUB_CPP_PREDEFINES -#define SUB_CPP_PREDEFINES "-D__ECOFF__" +#undef CPP_SUBTARGET_SPEC +#define CPP_SUBTARGET_SPEC "-D__ECOFF__" #undef LINK_SPEC #define LINK_SPEC "-G 8 %{O*:-O3} %{!O*:-O1}" diff --git a/contrib/gcc/config/alpha/linux-elf.h b/contrib/gcc/config/alpha/linux-elf.h index 90009f1..fc07127 100644 --- a/contrib/gcc/config/alpha/linux-elf.h +++ b/contrib/gcc/config/alpha/linux-elf.h @@ -17,7 +17,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (Alpha GNU/Linux for ELF)"); diff --git a/contrib/gcc/config/alpha/linux.h b/contrib/gcc/config/alpha/linux.h index 3791c89..b8eb9e9 100644 --- a/contrib/gcc/config/alpha/linux.h +++ b/contrib/gcc/config/alpha/linux.h @@ -17,14 +17,16 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #undef TARGET_DEFAULT #define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS) #undef CPP_PREDEFINES #define CPP_PREDEFINES \ -"-Dlinux -Dunix -Asystem(linux) -D_LONGLONG -D__alpha__ " SUB_CPP_PREDEFINES +"-Dlinux -Dunix -Asystem(linux) -D_LONGLONG -D__alpha__ " \ +SUB_CPP_PREDEFINES #undef LIB_SPEC #define LIB_SPEC "%{pg:-lgmon} %{pg:-lc_p} %{!pg:-lc}" diff --git a/contrib/gcc/config/alpha/netbsd-elf.h b/contrib/gcc/config/alpha/netbsd-elf.h index 17d7bb0..6e4f4da 100644 --- a/contrib/gcc/config/alpha/netbsd-elf.h +++ b/contrib/gcc/config/alpha/netbsd-elf.h @@ -16,7 +16,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (Alpha NetBSD/ELF)"); diff --git a/contrib/gcc/config/alpha/netbsd.h b/contrib/gcc/config/alpha/netbsd.h index 054e9e0..5189064 100644 --- a/contrib/gcc/config/alpha/netbsd.h +++ b/contrib/gcc/config/alpha/netbsd.h @@ -16,7 +16,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #undef TARGET_DEFAULT #define TARGET_DEFAULT (MASK_FP | MASK_FPREGS | MASK_GAS) diff --git a/contrib/gcc/config/alpha/osf.h b/contrib/gcc/config/alpha/osf.h index 956961f..5054444 100644 --- a/contrib/gcc/config/alpha/osf.h +++ b/contrib/gcc/config/alpha/osf.h @@ -30,9 +30,19 @@ Boston, MA 02111-1307, USA. */ -Dunix -D__osf__ -D_LONGLONG -DSYSTYPE_BSD \ -D_SYSTYPE_BSD -Asystem(unix) -Asystem(xpg4)" +/* Accept DEC C flags for multithreaded programs. We use _PTHREAD_USE_D4 + instead of PTHREAD_USE_D4 since both have the same effect and the former + doesn't invade the users' namespace. */ + +#undef CPP_SUBTARGET_SPEC +#define CPP_SUBTARGET_SPEC \ +"%{pthread|threads:-D_REENTRANT} %{threads:-D_PTHREAD_USE_D4}" + /* Under OSF4, -p and -pg require -lprof1, and -lprof1 requires -lpdf. */ -#define LIB_SPEC "%{p:-lprof1 -lpdf} %{pg:-lprof1 -lpdf} %{a:-lprof2} -lc" +#define LIB_SPEC \ +"%{p|pg:-lprof1%{pthread|threads:_r} -lpdf} %{a:-lprof2} \ + %{threads: -lpthreads} %{pthread|threads: -lpthread -lmach -lexc} -lc" /* Pass "-G 8" to ld because Alpha's CC does. Pass -O3 if we are optimizing, -O1 if we are not. Pass -shared, -non_shared or diff --git a/contrib/gcc/config/alpha/t-ieee b/contrib/gcc/config/alpha/t-ieee new file mode 100644 index 0000000..a1f93db --- /dev/null +++ b/contrib/gcc/config/alpha/t-ieee @@ -0,0 +1,6 @@ +# All alphas get an IEEE complaint set of libraries. +MULTILIB_OPTIONS = mieee +MULTILIB_DIRNAMES = ieee + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib diff --git a/contrib/gcc/config/alpha/t-interix b/contrib/gcc/config/alpha/t-interix new file mode 100644 index 0000000..d6d80e9 --- /dev/null +++ b/contrib/gcc/config/alpha/t-interix @@ -0,0 +1,16 @@ +# t-interix + +# System headers will track gcc's needs. +# Even LANG_EXTRA_HEADERS may be temporary. +USER_H=$(LANG_EXTRA_HEADERS) + +# We don't want this one either. +INSTALL_ASSERT_H= + + + +CROSS_LIBGCC1 = libgcc1-asm.a +LIBGCC1 = libgcc1-asm.a + +LIB1ASMSRC = alpha/lib1funcs.asm +LIB1ASMFUNCS = _divqu _divq _divlu _divl _remqu _remq _remlu _reml diff --git a/contrib/gcc/config/alpha/vms.h b/contrib/gcc/config/alpha/vms.h index 44cf5bf..44388b2 100644 --- a/contrib/gcc/config/alpha/vms.h +++ b/contrib/gcc/config/alpha/vms.h @@ -439,10 +439,6 @@ extern int vms_valid_decl_attribute_p (); #define ASM_OUTPUT_ALIGN(FILE,LOG) \ fprintf (FILE, "\t.align %d\n", LOG); -#define UNALIGNED_SHORT_ASM_OP ".word" -#define UNALIGNED_INT_ASM_OP ".long" -#define UNALIGNED_DOUBLE_INT_ASM_OP ".quad" - #define ASM_OUTPUT_SECTION(FILE,SECTION) \ (strcmp (SECTION, ".text") == 0) \ ? text_section () \ diff --git a/contrib/gcc/config/alpha/vxworks.h b/contrib/gcc/config/alpha/vxworks.h index 6dee4b3..7ef1fee 100644 --- a/contrib/gcc/config/alpha/vxworks.h +++ b/contrib/gcc/config/alpha/vxworks.h @@ -36,11 +36,11 @@ Boston, MA 02111-1307, USA. */ #undef LIB_SPEC #define LIB_SPEC "" -/* VxWorks uses object files, not loadable images. make linker just - combine objects. */ +/* VxWorks uses object files, not loadable images. Make linker just combine + objects. Also show using 32 bit mode and set start of text to 0. */ #undef LINK_SPEC -#define LINK_SPEC "-r" +#define LINK_SPEC "-r -taso -T 0" /* VxWorks provides the functionality of crt0.o and friends itself. */ diff --git a/contrib/gcc/config/alpha/xm-alpha-interix.h b/contrib/gcc/config/alpha/xm-alpha-interix.h new file mode 100644 index 0000000..02c53b8 --- /dev/null +++ b/contrib/gcc/config/alpha/xm-alpha-interix.h @@ -0,0 +1,45 @@ +/* Configuration for GNU compiler + for an DEC/Compaq Alpha + Copyright (C) 1999 Free Software Foundation, Inc. + Donn Terry, Softway Systems, Inc. + derived from code by Douglas B. Rupp (drupp@cs.washington.edu) + +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. */ + +#include + +#undef HOST_BITS_PER_LONG +#define HOST_BITS_PER_LONG 32 + +#define HOST_BITS_PER_WIDE_INT 64 +#ifdef __GNUC__ +# define HOST_WIDE_INT long long +#else +# define HOST_WIDE_INT __int64 +#endif + + +#define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG +#ifdef __GNUC__ +# define HOST_WIDEST_INT long long +#else +# define HOST_WIDEST_INT __int64 +#endif +#define HOST_WIDEST_INT_PRINT_DEC "%lld" +#define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu" +#define HOST_WIDEST_INT_PRINT_HEX "0x%llx" diff --git a/contrib/gcc/config/alpha/xm-alpha.h b/contrib/gcc/config/alpha/xm-alpha.h index 7665127..c04844f 100644 --- a/contrib/gcc/config/alpha/xm-alpha.h +++ b/contrib/gcc/config/alpha/xm-alpha.h @@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA. */ #if defined(__GNUC__) && !defined(USE_C_ALLOCA) #define alloca __builtin_alloca #else -#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS) +#if !defined(_WIN32) && !defined(USE_C_ALLOCA) && !defined(OPEN_VMS) && !defined(__INTERIX) #include #else extern void *alloca (); diff --git a/contrib/gcc/config/dbxcoff.h b/contrib/gcc/config/dbxcoff.h index 9497a70..1d5b448 100644 --- a/contrib/gcc/config/dbxcoff.h +++ b/contrib/gcc/config/dbxcoff.h @@ -49,8 +49,8 @@ Boston, MA 02111-1307, USA. */ #undef DBX_OUTPUT_MAIN_SOURCE_FILE_END #define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \ - fprintf (FILE, \ - "\t.text\n\t.stabs \"\",%d,0,0,Letext\nLetext:\n", N_SO) + asm_fprintf (FILE, \ + "\t.text\n\t.stabs \"\",%d,0,0,%LLetext\n%LLetext:\n", N_SO) /* Like block addresses, stabs line numbers are relative to the current function. */ diff --git a/contrib/gcc/config/dbxelf.h b/contrib/gcc/config/dbxelf.h new file mode 100644 index 0000000..3971bc1 --- /dev/null +++ b/contrib/gcc/config/dbxelf.h @@ -0,0 +1,109 @@ +/* Definitions needed when using stabs embedded in ELF sections. + Copyright (C) 1999 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. */ + +/* This file may be included by any ELF target which wishes to + support -gstabs generating stabs in sections, as produced by gas + and understood by gdb. */ + +#ifndef __DBX_ELF_H +#define __DBX_ELF_H + +/* Output DBX (stabs) debugging information if doing -gstabs. */ + +#undef DBX_DEBUGGING_INFO +#define DBX_DEBUGGING_INFO + +/* Make LBRAC and RBRAC addresses relative to the start of the + function. The native Solaris stabs debugging format works this + way, gdb expects it, and it reduces the number of relocation + entries... */ + +#undef DBX_BLOCKS_FUNCTION_RELATIVE +#define DBX_BLOCKS_FUNCTION_RELATIVE 1 + +/* ... but, to make this work, functions must appear prior to line info. */ + +#undef DBX_FUNCTION_FIRST +#define DBX_FUNCTION_FIRST + +/* When generating stabs debugging, use N_BINCL entries. */ + +#undef DBX_USE_BINCL +#define DBX_USE_BINCL + +/* There is no limit to the length of stabs strings. */ + +#ifndef DBX_CONTIN_LENGTH +#define DBX_CONTIN_LENGTH 0 +#endif + +/* When using stabs, gcc2_compiled must be a stabs entry, not an + ordinary symbol, or gdb won't see it. Furthermore, since gdb reads + the input piecemeal, starting with each N_SO, it's a lot easier if + the gcc2 flag symbol is *after* the N_SO rather than before it. So + we emit an N_OPT stab there. */ + +#define ASM_IDENTIFY_GCC(FILE) \ +do \ + { \ + if (write_symbols != DBX_DEBUG) \ + fputs ("gcc2_compiled.:\n", FILE); \ + } \ +while (0) + +#define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) \ +do \ + { \ + if (write_symbols == DBX_DEBUG) \ + fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \ + } \ +while (0) + +/* Like block addresses, stabs line numbers are relative to the + current function. */ + +#undef ASM_OUTPUT_SOURCE_LINE +#define ASM_OUTPUT_SOURCE_LINE(FILE, LINE) \ +do \ + { \ + static int sym_lineno = 1; \ + char temp[256]; \ + ASM_GENERATE_INTERNAL_LABEL (temp, "LM", sym_lineno); \ + fprintf (FILE, ".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; \ + } \ +while (0) + +/* Generate a blank trailing N_SO to mark the end of the .o file, since + we can't depend upon the linker to mark .o file boundaries with + embedded stabs. */ + +#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END +#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \ + asm_fprintf (FILE, \ + "\t.text\n\t.stabs \"\",%d,0,0,%LLetext\n%LLetext:\n", N_SO) + +#endif /* __DBX_ELF_H */ diff --git a/contrib/gcc/config/elfos.h b/contrib/gcc/config/elfos.h new file mode 100644 index 0000000..6c10731 --- /dev/null +++ b/contrib/gcc/config/elfos.h @@ -0,0 +1,704 @@ +/* elfos.h -- operating system specific defines to be used when + targeting GCC for some generic ELF system + Copyright (C) 1991, 1994, 1995, 1999 Free Software Foundation, Inc. + Based on svr4.h contributed by Ron Guilmette (rfg@netcom.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. */ + +/* For the sake of libgcc2.c, indicate target supports atexit. */ +#define HAVE_ATEXIT + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC "crtend.o%s" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared: \ + %{!symbolic: \ + %{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}\ + crtbegin.o%s" + +/* 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 string is patterned after the ones produced by native svr4 + C compilers. */ + +#define IDENT_ASM_OP ".ident" + +#define ASM_FILE_END(FILE) \ +do { \ + if (!flag_no_ident) \ + fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ + IDENT_ASM_OP, version_string); \ + } while (0) + +/* Output #ident as a .ident. */ + +#define ASM_OUTPUT_IDENT(FILE, NAME) \ + fprintf (FILE, "\t%s\t\"%s\"\n", IDENT_ASM_OP, NAME); + +/* Use periods rather than dollar signs in special g++ assembler names. */ + +#define NO_DOLLAR_IN_LABEL + +/* Writing `int' for a bitfield forces int alignment for the structure. */ + +#define PCC_BITFIELD_TYPE_MATTERS 1 + +/* Implicit library calls should use memcpy, not bcopy, etc. */ + +#define TARGET_MEM_FUNCTIONS + +/* Handle #pragma weak and #pragma pack. */ + +#define HANDLE_SYSV_PRAGMA + +/* System V Release 4 uses DWARF debugging info. */ + +#define DWARF_DEBUGGING_INFO + +/* All ELF targets can support DWARF-2. */ + +#define DWARF2_DEBUGGING_INFO + +/* Also allow them to support STABS debugging. */ + +#include "dbxelf.h" + +/* The GNU tools operate better with stabs. Since we don't have + any native tools to be compatible with, default to stabs. */ + +#ifndef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG +#endif + +#undef ASM_BYTE_OP +#define ASM_BYTE_OP ".byte" + +#undef SET_ASM_OP +#define SET_ASM_OP ".set" + +/* 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) + +/* This is how to allocate empty space in some section. The .zero + pseudo-op is used for this on most svr4 assemblers. */ + +#define SKIP_ASM_OP ".zero" + +#undef ASM_OUTPUT_SKIP +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t%s\t%u\n", SKIP_ASM_OP, (SIZE)) + +/* This is how to output a reference to a user-level label named NAME. + `assemble_name' uses this. + + For System V Release 4 the convention is *not* to prepend a leading + underscore onto user-level symbol names. */ + +#undef ASM_OUTPUT_LABELREF +#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME) + +/* 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%d:\n", PREFIX, NUM); \ +} while (0) + +/* 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. + This is suitable for output with `assemble_name'. + + 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_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(LABEL, PREFIX, NUM) \ +do { \ + sprintf (LABEL, "*.%s%d", PREFIX, NUM); \ +} while (0) + +/* Output the label which precedes a jumptable. Note that for all svr4 + systems where we actually generate jumptables (which is to say every + svr4 target except i386, where we use casesi instead) we put the jump- + tables into the .rodata section and since other stuff could have been + put into the .rodata section prior to any given jumptable, we have to + make sure that the location counter for the .rodata section gets pro- + perly re-aligned prior to the actual beginning of the jump table. */ + +#define ALIGN_ASM_OP ".align" + +#ifndef ASM_OUTPUT_BEFORE_CASE_LABEL +#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \ + ASM_OUTPUT_ALIGN ((FILE), 2); +#endif + +#undef ASM_OUTPUT_CASE_LABEL +#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); \ + } while (0) + +/* The standard SVR4 assembler seems to require that certain builtin + library routines (e.g. .udiv) be explicitly declared as .globl + in each assembly file where they are referenced. */ + +#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \ + ASM_GLOBALIZE_LABEL (FILE, XSTR (FUN, 0)) + +/* This says how to output assembler code to declare an + uninitialized external linkage data object. Under SVR4, + the linker seems to want the alignment of data objects + to depend on their types. We do exactly that here. */ + +#define COMMON_ASM_OP ".comm" + +#undef ASM_OUTPUT_ALIGNED_COMMON +#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGN) \ +do { \ + fprintf ((FILE), "\t%s\t", COMMON_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), ",%u,%u\n", (SIZE), (ALIGN) / BITS_PER_UNIT); \ +} while (0) + +/* This says how to output assembler code to declare an + uninitialized internal linkage data object. Under SVR4, + the linker seems to want the alignment of data objects + to depend on their types. We do exactly that here. */ + +#define LOCAL_ASM_OP ".local" + +#undef ASM_OUTPUT_ALIGNED_LOCAL +#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \ +do { \ + fprintf ((FILE), "\t%s\t", LOCAL_ASM_OP); \ + assemble_name ((FILE), (NAME)); \ + fprintf ((FILE), "\n"); \ + ASM_OUTPUT_ALIGNED_COMMON (FILE, NAME, SIZE, ALIGN); \ +} while (0) + +/* This is the pseudo-op used to generate a 32-bit word of data with a + specific value in some section. This is the same for all known svr4 + assemblers. */ + +#define INT_ASM_OP ".long" + +/* This is the pseudo-op used to generate a contiguous sequence of byte + values from a double-quoted string WITHOUT HAVING A TERMINATING NUL + AUTOMATICALLY APPENDED. This is the same for most svr4 assemblers. */ + +#undef ASCII_DATA_ASM_OP +#define ASCII_DATA_ASM_OP ".ascii" + +/* Support const sections and the ctors and dtors sections for g++. + Note that there appears to be two different ways to support const + sections at the moment. You can either #define the symbol + READONLY_DATA_SECTION (giving it some code which switches to the + readonly data section) or else you can #define the symbols + EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and + SELECT_RTX_SECTION. We do both here just to be on the safe side. */ + +#define USE_CONST_SECTION 1 + +#define CONST_SECTION_ASM_OP ".section\t.rodata" + +/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. + + Note that we want to give these sections the SHF_WRITE attribute + because these sections will actually contain data (i.e. tables of + addresses of functions in the current root executable or shared library + file) and, in the case of a shared library, the relocatable addresses + will have to be properly resolved/relocated (and then written into) by + the dynamic linker when it actually attaches the given shared library + to the executing process. (Note that on SVR4, you may wish to use the + `-z text' option to the ELF linker, when building a shared library, as + an additional check that you are doing everything right. But if you do + use the `-z text' option when building a shared library, you will get + errors unless the .ctors and .dtors sections are marked as writable + via the SHF_WRITE attribute.) */ + +#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" +#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"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 + crtstuff.c and other files know this by defining the following symbols. + The definitions say how to change sections to the .init and .fini + sections. This is the same for all known svr4 assemblers. */ + +#define INIT_SECTION_ASM_OP ".section\t.init" +#define FINI_SECTION_ASM_OP ".section\t.fini" + +/* A default list of other sections which we might be "in" at any given + time. For targets that use additional sections (e.g. .tdesc) you + should override this definition in the target-specific file which + includes this file. */ + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_const, in_ctors, in_dtors + +/* A default list of extra section function definitions. For targets + that use additional sections (e.g. .tdesc) you should override this + definition in the target-specific file which includes this file. */ + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CONST_SECTION_FUNCTION \ + CTORS_SECTION_FUNCTION \ + DTORS_SECTION_FUNCTION + +#define READONLY_DATA_SECTION() const_section () + +extern void text_section (); + +#define CONST_SECTION_FUNCTION \ +void \ +const_section () \ +{ \ + if (!USE_CONST_SECTION) \ + text_section(); \ + else if (in_section != in_const) \ + { \ + fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ + in_section = in_const; \ + } \ +} + +#define CTORS_SECTION_FUNCTION \ +void \ +ctors_section () \ +{ \ + if (in_section != in_ctors) \ + { \ + fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ + in_section = in_ctors; \ + } \ +} + +#define DTORS_SECTION_FUNCTION \ +void \ +dtors_section () \ +{ \ + if (in_section != in_dtors) \ + { \ + fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ + in_section = in_dtors; \ + } \ +} + +/* Switch into a generic section. + This is currently only used to support section attributes. */ + +#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ +do { \ + static struct section_info \ + { \ + struct section_info *next; \ + char *name; \ + enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \ + } *sections; \ + struct section_info *s; \ + char *mode; \ + enum sect_enum type; \ + \ + for (s = sections; s; s = s->next) \ + if (!strcmp (NAME, s->name)) \ + break; \ + \ + if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \ + type = SECT_EXEC, mode = "ax"; \ + else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \ + type = SECT_RO, mode = "a"; \ + else \ + type = SECT_RW, mode = "aw"; \ + \ + if (s == 0) \ + { \ + s = (struct section_info *) xmalloc (sizeof (struct section_info)); \ + s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \ + strcpy (s->name, NAME); \ + s->type = type; \ + s->next = sections; \ + sections = s; \ + fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, mode); \ + } \ + else \ + { \ + if (DECL && s->type != type) \ + error_with_decl (DECL, "%s causes a section type conflict"); \ + \ + fprintf (FILE, ".section\t%s\n", NAME); \ + } \ +} while (0) + +#define MAKE_DECL_ONE_ONLY(DECL) (DECL_WEAK (DECL) = 1) +#define UNIQUE_SECTION_P(DECL) (DECL_ONE_ONLY (DECL)) +#define UNIQUE_SECTION(DECL,RELOC) \ +do { \ + int len; \ + char *name, *string, *prefix; \ + \ + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ + \ + if (! DECL_ONE_ONLY (DECL)) \ + { \ + if (TREE_CODE (DECL) == FUNCTION_DECL) \ + prefix = ".text."; \ + else if (DECL_READONLY_SECTION (DECL, RELOC)) \ + prefix = ".rodata."; \ + else \ + prefix = ".data."; \ + } \ + else if (TREE_CODE (DECL) == FUNCTION_DECL) \ + prefix = ".gnu.linkonce.t."; \ + else if (DECL_READONLY_SECTION (DECL, RELOC)) \ + prefix = ".gnu.linkonce.r."; \ + else \ + prefix = ".gnu.linkonce.d."; \ + \ + len = strlen (name) + strlen (prefix); \ + string = alloca (len + 1); \ + sprintf (string, "%s%s", prefix, name); \ + \ + DECL_SECTION_NAME (DECL) = build_string (len, string); \ +} while (0) +/* A C statement (sans semicolon) to output an element in the table of + global constructors. */ +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* A C statement (sans semicolon) to output an element in the table of + global destructors. */ +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* A C statement or statements to switch to the appropriate + section for output of DECL. DECL is either a `VAR_DECL' node + or a constant of some sort. RELOC indicates whether forming + the initial value of DECL requires link-time relocations. */ + +#define SELECT_SECTION(DECL,RELOC) \ +{ \ + if (TREE_CODE (DECL) == STRING_CST) \ + { \ + if (! flag_writable_strings) \ + const_section (); \ + else \ + data_section (); \ + } \ + else if (TREE_CODE (DECL) == VAR_DECL) \ + { \ + if ((flag_pic && RELOC) \ + || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ + || !DECL_INITIAL (DECL) \ + || (DECL_INITIAL (DECL) != error_mark_node \ + && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ + data_section (); \ + else \ + const_section (); \ + } \ + else \ + const_section (); \ +} + +/* A C statement or statements to switch to the appropriate + section for output of RTX in mode MODE. RTX is some kind + of constant in RTL. The argument MODE is redundant except + in the case of a `const_int' rtx. Currently, these always + go into the const section. */ + +#undef SELECT_RTX_SECTION +#define SELECT_RTX_SECTION(MODE,RTX) const_section() + +/* Define the strings used for the special svr4 .type and .size directives. + These strings generally do not vary from one system running svr4 to + another, but if a given system (e.g. m88k running svr) needs to use + different pseudo-op names for these, they may be overridden in the + file which includes this one. */ + +#define TYPE_ASM_OP ".type" +#define SIZE_ASM_OP ".size" + +/* This is how we tell the assembler that a symbol is weak. */ + +#define ASM_WEAKEN_LABEL(FILE,NAME) \ + do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ + fputc ('\n', FILE); } while (0) + +/* The following macro defines the format used to output the second + operand of the .type assembler directive. Different svr4 assemblers + expect various different forms for this operand. The one given here + is just a default. You may need to override it in your machine- + specific tm.h file (depending upon the particulars of your assembler). */ + +#define TYPE_OPERAND_FMT "@%s" + +/* Write the extra assembler code needed to declare a function's result. + Most svr4 assemblers don't require any special declaration of the + result value, but there are exceptions. */ + +#ifndef ASM_DECLARE_RESULT +#define ASM_DECLARE_RESULT(FILE, RESULT) +#endif + +/* These macros generate the special .type and .size directives which + are used to set the corresponding fields of the linker symbol table + entries in an ELF object file under SVR4. These macros also output + the starting labels for the relevant functions/objects. */ + +/* Write the extra assembler code needed to declare a function properly. + Some svr4 assemblers need to also have something extra said about the + function's return value. We allow for that here. */ + +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + do { \ + fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (FILE, NAME); \ + putc (',', FILE); \ + fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ + putc ('\n', FILE); \ + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ + ASM_OUTPUT_LABEL(FILE, NAME); \ + } while (0) + +/* Write the extra assembler code needed to declare an object properly. */ + +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + do { \ + fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (FILE, NAME); \ + putc (',', FILE); \ + fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ + putc ('\n', FILE); \ + size_directive_output = 0; \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ + { \ + size_directive_output = 1; \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + ASM_OUTPUT_LABEL(FILE, NAME); \ + } while (0) + +/* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + +#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ +do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + size_directive_output = 1; \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) + +/* This is how to declare the size of a function. */ + +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ + do { \ + if (!flag_inhibit_size_directive) \ + { \ + char label[256]; \ + static int labelno; \ + labelno++; \ + ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ + ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, (FNAME)); \ + fprintf (FILE, ","); \ + assemble_name (FILE, label); \ + fprintf (FILE, "-"); \ + assemble_name (FILE, (FNAME)); \ + putc ('\n', FILE); \ + } \ + } while (0) + +/* A table of bytes codes used by the ASM_OUTPUT_ASCII and + ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table + corresponds to a particular byte value [0..255]. For any + given byte value, if the value in the corresponding table + position is zero, the given character can be output directly. + If the table value is 1, the byte must be output as a \ooo + octal escape. If the tables value is anything else, then the + byte value should be output as a \ followed by the value + in the table. Note that we can use standard UN*X escape + sequences for many control characters, but we don't use + \a to represent BEL because some svr4 assemblers (e.g. on + the i386) don't know about that. Also, we don't use \v + since some versions of gas, such as 2.2 did not accept it. */ + +#define ESCAPES \ +"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\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\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\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" + +/* Some svr4 assemblers have a limit on the number of characters which + can appear in the operand of a .string directive. If your assembler + has such a limitation, you should define STRING_LIMIT to reflect that + limit. Note that at least some svr4 assemblers have a limit on the + actual number of bytes in the double-quoted string, and that they + count each character in an escape sequence as one byte. Thus, an + escape sequence like \377 would count as four bytes. + + If your target assembler doesn't support the .string directive, you + should define this to zero. +*/ + +#define STRING_LIMIT ((unsigned) 256) + +#define STRING_ASM_OP ".string" + +/* The routine used to output NUL terminated strings. We use a special + version of this for most svr4 targets because doing so makes the + 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). */ + +#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \ + do \ + { \ + register unsigned char *_limited_str = (unsigned char *) (STR); \ + register unsigned ch; \ + fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \ + for (; ch = *_limited_str; _limited_str++) \ + { \ + register int escape; \ + switch (escape = ESCAPES[ch]) \ + { \ + case 0: \ + putc (ch, (FILE)); \ + break; \ + case 1: \ + fprintf ((FILE), "\\%03o", ch); \ + break; \ + default: \ + putc ('\\', (FILE)); \ + putc (escape, (FILE)); \ + break; \ + } \ + } \ + fprintf ((FILE), "\"\n"); \ + } \ + while (0) + +/* The routine used to output sequences of byte values. We use a special + version of this for most svr4 targets because doing so makes the + generated assembly code more compact (and thus faster to assemble) + as well as more readable. Note that if we find subparts of the + character sequence which end with NUL (and which are shorter than + STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ + +#undef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ + do \ + { \ + register unsigned char *_ascii_bytes = (unsigned char *) (STR); \ + register unsigned char *limit = _ascii_bytes + (LENGTH); \ + register unsigned bytes_in_chunk = 0; \ + for (; _ascii_bytes < limit; _ascii_bytes++) \ + { \ + register 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) <= STRING_LIMIT) \ + { \ + if (bytes_in_chunk > 0) \ + { \ + fprintf ((FILE), "\"\n"); \ + bytes_in_chunk = 0; \ + } \ + ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \ + _ascii_bytes = p; \ + } \ + else \ + { \ + register int escape; \ + register unsigned ch; \ + if (bytes_in_chunk == 0) \ + fprintf ((FILE), "\t%s\t\"", ASCII_DATA_ASM_OP); \ + switch (escape = ESCAPES[ch = *_ascii_bytes]) \ + { \ + case 0: \ + putc (ch, (FILE)); \ + bytes_in_chunk++; \ + break; \ + case 1: \ + fprintf ((FILE), "\\%03o", ch); \ + bytes_in_chunk += 4; \ + break; \ + default: \ + putc ('\\', (FILE)); \ + putc (escape, (FILE)); \ + bytes_in_chunk += 2; \ + break; \ + } \ + } \ + } \ + if (bytes_in_chunk > 0) \ + fprintf ((FILE), "\"\n"); \ + } \ + while (0) + +/* All SVR4 targets use the ELF object file format. */ +#define OBJECT_FORMAT_ELF diff --git a/contrib/gcc/config/float-sh.h b/contrib/gcc/config/float-sh.h index 9a94298..4466924 100644 --- a/contrib/gcc/config/float-sh.h +++ b/contrib/gcc/config/float-sh.h @@ -37,7 +37,7 @@ #undef FLT_MAX_10_EXP #define FLT_MAX_10_EXP 38 -#ifdef __SH3E__ +#if defined (__SH3E__) || defined (__SH4_SINGLE_ONLY__) /* Number of base-FLT_RADIX digits in the significand of a double */ #undef DBL_MANT_DIG diff --git a/contrib/gcc/config/fp-bit.c b/contrib/gcc/config/fp-bit.c index f4a1e2a..6b8bd70 100644 --- a/contrib/gcc/config/fp-bit.c +++ b/contrib/gcc/config/fp-bit.c @@ -156,8 +156,8 @@ __floatsixf (){ abort(); } #else /* !EXTENDED_FLOAT_STUBS, rest of file */ -typedef SFtype __attribute__ ((mode (SF))); -typedef DFtype __attribute__ ((mode (DF))); +typedef float SFtype __attribute__ ((mode (SF))); +typedef float DFtype __attribute__ ((mode (DF))); typedef int HItype __attribute__ ((mode (HI))); typedef int SItype __attribute__ ((mode (SI))); @@ -460,7 +460,6 @@ pack_d ( fp_number_type * src) else if (fraction == 0) { exp = 0; - sign = 0; } else { @@ -735,7 +734,7 @@ _fpadd_parts (fp_number_type * a, { tfraction = a_fraction - b_fraction; } - if (tfraction > 0) + if (tfraction >= 0) { tmp->sign = 0; tmp->normal_exp = a_normal_exp; @@ -1000,8 +999,7 @@ multiply (FLO_type arg_a, FLO_type arg_b) #if defined(L_div_sf) || defined(L_div_df) static INLINE fp_number_type * _fpdiv_parts (fp_number_type * a, - fp_number_type * b, - fp_number_type * tmp) + fp_number_type * b) { fractype bit; fractype numerator; @@ -1093,13 +1091,12 @@ divide (FLO_type arg_a, FLO_type arg_b) { fp_number_type a; fp_number_type b; - fp_number_type tmp; fp_number_type *res; unpack_d ((FLO_union_type *) & arg_a, &a); unpack_d ((FLO_union_type *) & arg_b, &b); - res = _fpdiv_parts (&a, &b, &tmp); + res = _fpdiv_parts (&a, &b); return pack_d (res); } @@ -1332,7 +1329,7 @@ si_to_float (SItype arg_a) { /* Special case for minint, since there is no +ve integer representation for it */ - if (arg_a == 0x80000000) + if (arg_a == (SItype) 0x80000000) { return -2147483648.0; } diff --git a/contrib/gcc/config/i386/aix386ng.h b/contrib/gcc/config/i386/aix386ng.h index a177b69..9a8dae6 100644 --- a/contrib/gcc/config/i386/aix386ng.h +++ b/contrib/gcc/config/i386/aix386ng.h @@ -1,5 +1,5 @@ /* Definitions for IBM PS2 running AIX/386. - Copyright (C) 1988, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 1996, 1998 Free Software Foundation, Inc. Contributed by Minh Tran-Le . This file is part of GNU CC. @@ -58,9 +58,7 @@ Boston, MA 02111-1307, USA. */ #undef ASM_FILE_START #define ASM_FILE_START(FILE) \ - do { fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, dump_base_name); \ - fprintf (FILE, "\n"); \ + do { output_file_directive (FILE, main_input_filename); \ if (optimize) \ ASM_FILE_START_1 (FILE); \ else \ diff --git a/contrib/gcc/config/i386/bsd.h b/contrib/gcc/config/i386/bsd.h index d50be36..34db79a 100644 --- a/contrib/gcc/config/i386/bsd.h +++ b/contrib/gcc/config/i386/bsd.h @@ -49,9 +49,7 @@ Boston, MA 02111-1307, USA. */ ??? I am skeptical of this -- RMS. */ #define ASM_FILE_START(FILE) \ - do { fprintf (FILE, "\t.file\t"); \ - output_quoted_string (FILE, dump_base_name); \ - fprintf (FILE, "\n"); \ + do { output_file_directive (FILE, main_input_filename); \ } while (0) /* This was suggested, but it shouldn't be right for DBX output. -- RMS diff --git a/contrib/gcc/config/i386/crtdll.h b/contrib/gcc/config/i386/crtdll.h index f7eaf2b..3202af8 100644 --- a/contrib/gcc/config/i386/crtdll.h +++ b/contrib/gcc/config/i386/crtdll.h @@ -3,7 +3,7 @@ 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. This variant uses CRTDLL.DLL insted of MSVCRTDLL.DLL. - Copyright (C) 1998 Free Software Foundation, Inc. + Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \ - -D__MINGW32__ -DWINNT -D_X86_=1 -D__STDC__=1\ + -D__MINGW32__=0.2 -DWINNT -D_X86_=1 -D__STDC__=1\ -D__stdcall=__attribute__((__stdcall__)) \ -D_stdcall=__attribute__((__stdcall__)) \ -D__cdecl=__attribute__((__cdecl__)) \ @@ -38,5 +38,3 @@ Boston, MA 02111-1307, USA. */ #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{mdll:dllcrt1%O%s} %{!mdll:crt1%O%s}" -#undef MATH_LIBRARY -#define MATH_LIBRARY "-lcrtdll" diff --git a/contrib/gcc/config/i386/cygwin.asm b/contrib/gcc/config/i386/cygwin.asm new file mode 100644 index 0000000..4ac4c91 --- /dev/null +++ b/contrib/gcc/config/i386/cygwin.asm @@ -0,0 +1,32 @@ +/* stuff needed for libgcc1 on win32. */ + +#ifdef L_chkstk + + .global ___chkstk + .global __alloca +___chkstk: +__alloca: + pushl %ecx /* save temp */ + movl %esp,%ecx /* get sp */ + addl $0x8,%ecx /* and point to return addr */ + +probe: cmpl $0x1000,%eax /* > 4k ?*/ + jb done + + subl $0x1000,%ecx /* yes, move pointer down 4k*/ + orl $0x0,(%ecx) /* probe there */ + subl $0x1000,%eax /* decrement count */ + jmp probe /* and do it again */ + +done: subl %eax,%ecx + orl $0x0,(%ecx) /* less that 4k, just peek here */ + + movl %esp,%eax + movl %ecx,%esp /* decrement stack */ + + 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 new file mode 100644 index 0000000..dbea466 --- /dev/null +++ b/contrib/gcc/config/i386/cygwin.h @@ -0,0 +1,525 @@ +/* Operating system specific defines to be used when targeting GCC for + hosting on Windows NT 3.x, using a Unix style C library and tools, + 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) 1995, 1996, 1997, 1998, 1999 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 YES_UNDERSCORES + +#define DBX_DEBUGGING_INFO +#define SDB_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + +#include "i386/gas.h" +#include "dbxcoff.h" + +/* Augment TARGET_SWITCHES with the cygwin/no-cygwin options. */ +#define MASK_WIN32 0x40000000 /* Use -lming32 interface */ +#define MASK_CYGWIN 0x20000000 /* Use -lcygwin interface */ +#define MASK_WINDOWS 0x10000000 /* Use windows interface */ +#define MASK_DLL 0x08000000 /* Use dll interface */ +#define MASK_NOP_FUN_DLLIMPORT 0x20000 /* Ignore dllimport for functions */ + +#define TARGET_WIN32 (target_flags & MASK_WIN32) +#define TARGET_CYGWIN (target_flags & MASK_CYGWIN) +#define TARGET_WINDOWS (target_flags & MASK_WINDOWS) +#define TARGET_DLL (target_flags & MASK_DLL) +#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT) + +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ +{ "cygwin", MASK_CYGWIN, "Use the Cygwin interface" }, \ +{ "no-cygwin", MASK_WIN32, "Use the Mingw32 interface" }, \ +{ "windows", MASK_WINDOWS, "Create GUI application" }, \ +{ "console", -MASK_WINDOWS, "Create console application" }, \ +{ "dll", MASK_DLL, "Generate code for a DLL" }, \ +{ "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, "Ignore dllimport for functions" }, \ +{ "no-nop-fun-dllimport", -MASK_NOP_FUN_DLLIMPORT, "" }, + + +/* 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. */ + +#ifdef CPP_PREDEFINES +#undef CPP_PREDEFINES +#endif + +#define CPP_PREDEFINES "-Di386 -D_WIN32 \ + -DWINNT -D_X86_=1 -D__STDC__=1\ + -D__stdcall=__attribute__((__stdcall__)) \ + -D__cdecl=__attribute__((__cdecl__)) \ + -D__declspec(x)=__attribute__((x)) \ + -Asystem(winnt) -Acpu(i386) -Amachine(i386)" + +/* 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. */ + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{mdll: %{mno-cygwin:dllcrt1%O%s}} \ + %{!mdll: %{!mno-cygwin:crt0%O%s} \ + %{mno-cygwin:crt1%O%s} %{pg:gcrt0%O%s}}" + +#undef CPP_SPEC +#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} \ + %{!mno-cygwin:-D__CYGWIN32__ -D__CYGWIN__} \ + %{mno-cygwin:-iwithprefixbefore \ + ../../../../%(mingw_include_path)/include/mingw32 -D__MINGW32__=0.2}" + +/* 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 } + +/* 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 + 'libcygwin.a'. For Windows applications, include more libraries, but + always include kernel32. We'd like to specific subsystem windows to + ld, but that doesn't work just yet. */ + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-lgmon} \ + %{!mno-cygwin:-lcygwin} \ + %{mno-cygwin:-lmingw32 -lmoldname -lcrtdll} \ + %{mwindows:-lgdi32 -lcomdlg32} \ + -luser32 -lkernel32 -ladvapi32 -lshell32" + +#define LINK_SPEC "%{mwindows:--subsystem windows} \ + %{mconsole:--subsystem console} \ + %{mdll:--dll -e _DllMainCRTStartup@12}" + + +#define SIZE_TYPE "unsigned int" +#define PTRDIFF_TYPE "int" +#define WCHAR_UNSIGNED 1 +#define WCHAR_TYPE_SIZE 16 +#define WCHAR_TYPE "short unsigned int" + +#define HAVE_ATEXIT 1 + + +/* Enable parsing of #pragma pack(push,) and #pragma pack(pop). */ +#define HANDLE_PRAGMA_PACK_PUSH_POP 1 + +/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS + is a valid machine specific attribute for DECL. + The attributes in ATTRIBUTES have previously been assigned to DECL. */ +extern int i386_pe_valid_decl_attribute_p (); + +#undef VALID_MACHINE_DECL_ATTRIBUTE +#define VALID_MACHINE_DECL_ATTRIBUTE(DECL, ATTRIBUTES, IDENTIFIER, ARGS) \ + i386_pe_valid_decl_attribute_p (DECL, ATTRIBUTES, IDENTIFIER, ARGS) + +/* A C expression whose value is nonzero if IDENTIFIER with arguments ARGS + is a valid machine specific attribute for TYPE. + The attributes in ATTRIBUTES have previously been assigned to TYPE. */ + +#undef VALID_MACHINE_TYPE_ATTRIBUTE +#define VALID_MACHINE_TYPE_ATTRIBUTE(TYPE, ATTRIBUTES, IDENTIFIER, ARGS) \ + i386_pe_valid_type_attribute_p (TYPE, ATTRIBUTES, IDENTIFIER, ARGS) +extern int i386_pe_valid_type_attribute_p (); + +extern union tree_node *i386_pe_merge_decl_attributes (); +#define MERGE_MACHINE_DECL_ATTRIBUTES(OLD, NEW) \ + i386_pe_merge_decl_attributes ((OLD), (NEW)) + +/* Used to implement dllexport overriding dllimport semantics. It's also used + to handle vtables - the first pass won't do anything because + DECL_CONTEXT (DECL) will be 0 so i386_pe_dll{ex,im}port_p will return 0. + It's also used to handle dllimport override semantics. */ +#if 0 +#define REDO_SECTION_INFO_P(DECL) \ + ((DECL_MACHINE_ATTRIBUTES (DECL) != NULL_TREE) \ + || (TREE_CODE (DECL) == VAR_DECL && DECL_VIRTUAL_P (DECL))) +#else +#define REDO_SECTION_INFO_P(DECL) 1 +#endif + + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_ctor, in_dtor, in_drectve + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CTOR_SECTION_FUNCTION \ + DTOR_SECTION_FUNCTION \ + DRECTVE_SECTION_FUNCTION \ + SWITCH_TO_SECTION_FUNCTION + +#define CTOR_SECTION_FUNCTION \ +void \ +ctor_section () \ +{ \ + if (in_section != in_ctor) \ + { \ + fprintf (asm_out_file, "\t.section .ctor\n"); \ + in_section = in_ctor; \ + } \ +} + +#define DTOR_SECTION_FUNCTION \ +void \ +dtor_section () \ +{ \ + if (in_section != in_dtor) \ + { \ + fprintf (asm_out_file, "\t.section .dtor\n"); \ + in_section = in_dtor; \ + } \ +} + +#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; \ + } \ +} + +/* 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 (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_ctor: ctor_section (); break; \ + case in_dtor: dtor_section (); break; \ + case in_drectve: drectve_section (); break; \ + default: abort (); break; \ + } \ +} + +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* 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. */ + +extern void i386_pe_encode_section_info (); + +#ifdef ENCODE_SECTION_INFO +#undef ENCODE_SECTION_INFO +#endif +#define ENCODE_SECTION_INFO(DECL) i386_pe_encode_section_info (DECL) + +/* Utility used only in this file. */ +#define I386_PE_STRIP_ENCODING(SYM_NAME) \ + ((SYM_NAME) + ((SYM_NAME)[0] == '@' ? 3 : 0)) + +/* This macro gets just the user-specified name + out of the string in a SYMBOL_REF. Discard + trailing @[NUM] encoded by ENCODE_SECTION_INFO. */ +#undef STRIP_NAME_ENCODING +#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ +do { \ + char *_p; \ + char *_name = I386_PE_STRIP_ENCODING (SYMBOL_NAME); \ + for (_p = _name; *_p && *_p != '@'; ++_p) \ + ; \ + if (*_p == '@') \ + { \ + int _len = _p - _name; \ + (VAR) = (char *) alloca (_len + 1); \ + strncpy ((VAR), _name, _len); \ + (VAR)[_len] = '\0'; \ + } \ + else \ + (VAR) = _name; \ +} while (0) + + +/* 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_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); \ + 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); \ + 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, + and returns float values in the 387 and needs stack probes */ +#undef TARGET_DEFAULT + +#define TARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE) + +/* 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 + +#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL) +extern void i386_pe_unique_section (); +#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC) + +#define SUPPORTS_ONE_ONLY 1 + +/* A C statement to output something to the assembler file to switch to section + NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or + NULL_TREE. Some target formats do not support arbitrary sections. Do not + define this macro in such cases. */ +#undef ASM_OUTPUT_SECTION_NAME +#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \ +do { \ + static struct section_info \ + { \ + struct section_info *next; \ + char *name; \ + enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \ + } *sections; \ + struct section_info *s; \ + char *mode; \ + enum sect_enum type; \ + \ + for (s = sections; s; s = s->next) \ + if (!strcmp (NAME, s->name)) \ + break; \ + \ + if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \ + type = SECT_EXEC, mode = "x"; \ + else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \ + type = SECT_RO, mode = ""; \ + else \ + type = SECT_RW, mode = "w"; \ + \ + if (s == 0) \ + { \ + s = (struct section_info *) xmalloc (sizeof (struct section_info)); \ + s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \ + strcpy (s->name, NAME); \ + s->type = type; \ + s->next = sections; \ + sections = s; \ + fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \ + /* Functions may have been compiled at various levels of \ + optimization so we can't use `same_size' here. Instead, \ + have the linker pick one. */ \ + if ((DECL) && DECL_ONE_ONLY (DECL)) \ + fprintf (STREAM, "\t.linkonce %s\n", \ + TREE_CODE (DECL) == FUNCTION_DECL \ + ? "discard" : "same_size"); \ + } \ + else \ + { \ + fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \ + } \ +} while (0) + +/* 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); \ + 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) + +/* Output function declarations at the end of the file. */ +#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. */ +#define DWARF2_UNWIND_INFO 0 + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + +#define SUBTARGET_PROLOGUE \ + if (profile_flag \ + && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),\ + "main") == 0) \ + { \ + rtx xops[1]; \ + xops[0] = gen_rtx_MEM (FUNCTION_MODE, \ + gen_rtx (SYMBOL_REF, Pmode, "_monstartup")); \ + if (do_rtl) \ + emit_call_insn (gen_rtx (CALL, VOIDmode, xops[0], const0_rtx)); \ + else \ + output_asm_insn (AS1 (call,%P1), xops); \ + } + +/* External function declarations. */ + +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +#ifdef BUFSIZ /* stdio.h has been included, ok to use FILE * */ +#define STDIO_PROTO(ARGS) PROTO(ARGS) +#else +#define STDIO_PROTO(ARGS) () +#endif + +extern void i386_pe_record_external_function PROTO((char *)); +extern void i386_pe_declare_function_type STDIO_PROTO((FILE *, char *, int)); +extern void i386_pe_record_exported_symbol PROTO((char *)); +extern void i386_pe_asm_file_end STDIO_PROTO((FILE *)); + +/* 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 + +/* A bitfield declared as `int' forces `int' alignment for the struct. */ +#undef PCC_BITFIELDS_TYPE_MATTERS +#define PCC_BITFIELDS_TYPE_MATTERS 0 + +/* Enable alias attribute support. */ +#ifndef SET_ASM_OP +#define SET_ASM_OP "\t.set" +#endif + diff --git a/contrib/gcc/config/i386/dgux.c b/contrib/gcc/config/i386/dgux.c index ff36135..638d1e0 100644 --- a/contrib/gcc/config/i386/dgux.c +++ b/contrib/gcc/config/i386/dgux.c @@ -16,7 +16,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ #include #include "i386/i386.c" @@ -29,6 +30,7 @@ struct option char *string; int *variable; int on_value; + char *description; }; static int diff --git a/contrib/gcc/config/i386/dgux.h b/contrib/gcc/config/i386/dgux.h index dae050f..9e41d65 100644 --- a/contrib/gcc/config/i386/dgux.h +++ b/contrib/gcc/config/i386/dgux.h @@ -16,7 +16,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* for now, we are just like the sysv4 version with a few hacks @@ -25,7 +26,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "i386/sysv4.h" #ifndef VERSION_INFO2 -#define VERSION_INFO2 "$Revision: 1.3 $" +#define VERSION_INFO2 "$Revision: 1.6 $" #endif #ifndef VERSION_STRING @@ -46,7 +47,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #define MASK_NOLEGEND 0x20000000 /* Discard legend information */ #define MASK_EXTERNAL_LEGEND 0x10000000 /* Make external legends */ #define MASK_IDENTIFY_REVISION 0x08000000 /* Emit 'ident' to .s */ -#define MASK_WARN_PASS_STRUCT 0x04000000 /* Emit 'ident' to .s */ +#define MASK_WARN_PASS_STRUCT 0x04000000 /* Warn when structures are passed */ #define TARGET_STANDARD (target_flags & MASK_STANDARD) #define TARGET_NOLEGEND (target_flags & MASK_NOLEGEND) @@ -56,12 +57,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ - { "standard", MASK_STANDARD }, \ - { "legend", -MASK_NOLEGEND }, \ - { "no-legend", MASK_NOLEGEND }, \ - { "external-legend", MASK_EXTERNAL_LEGEND }, \ - { "identify-revision", MASK_IDENTIFY_REVISION }, \ - { "warn-passed-structs", MASK_WARN_PASS_STRUCT }, + { "standard", MASK_STANDARD, "Retain standard MXDB information" }, \ + { "legend", -MASK_NOLEGEND, "Retain legend information" }, \ + { "no-legend", MASK_NOLEGEND, "" }, \ + { "external-legend", MASK_EXTERNAL_LEGEND, "Generate external legend information" }, \ + { "identify-revision", MASK_IDENTIFY_REVISION, "Emit identifying info in .s file" }, \ + { "warn-passed-structs", MASK_WARN_PASS_STRUCT, "Warn when a function arg is a structure" }, #undef DWARF_DEBUGGING_INFO #define DWARF_DEBUGGING_INFO @@ -123,7 +124,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ do { \ extern int flag_signed_bitfields; \ flag_signed_bitfields = 0; \ - abort_helper (); \ optimization_options (LEVEL,SIZE); \ } while (0) @@ -219,23 +219,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif /* CROSS_COMPILE */ -#if !defined (no_abort) || defined (CRT_BEGIN) || defined (CRT_END) -#undef abort - -char insn; int insn_; char * file_; int line_; -#define abort() \ - (insn_ = (int) insn, \ - file_ = __FILE__, \ - line_ = __LINE__, \ - fancy_abort ()) -#define abort_helper() \ - do { \ - extern void abort_aux (); \ - atexit (abort_aux); \ - } while (0) -#define _abort_aux -#endif /* no abort */ - /* The maximum alignment which the object file format can support. page alignment would seem to be enough */ #undef MAX_OFILE_ALIGNMENT diff --git a/contrib/gcc/config/i386/djgpp-rtems.h b/contrib/gcc/config/i386/djgpp-rtems.h new file mode 100644 index 0000000..b355cc5 --- /dev/null +++ b/contrib/gcc/config/i386/djgpp-rtems.h @@ -0,0 +1,41 @@ +/* Configuration for an i386 running RTEMS on top of MS-DOS with + DJGPP v2.x. + + Copyright (C) 1996,1999 Free Software Foundation, Inc. + Contributed by Joel Sherrill (joel@OARcorp.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. */ + +#include "i386/djgpp.h" + +/* Specify predefined symbols in preprocessor. */ + +#ifdef CPP_PREDEFINES +#undef CPP_PREDEFINES +#endif +#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DDJGPP=2 -DMSDOS \ + -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386) \ + -Asystem(rtems)" + +/* Generate calls to memcpy, memcmp and memset. */ +#ifndef TARGET_MEM_FUNCTIONS +#define TARGET_MEM_FUNCTIONS +#endif + +/* end of i386/djgpp-rtems.h */ + diff --git a/contrib/gcc/config/i386/djgpp.h b/contrib/gcc/config/i386/djgpp.h new file mode 100644 index 0000000..5727b0a --- /dev/null +++ b/contrib/gcc/config/i386/djgpp.h @@ -0,0 +1,161 @@ +/* Configuration for an i386 running MS-DOS with DJGPP. + Copyright (C) 1997, 1998, 1999 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. */ + + +#include "dbxcoff.h" + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + +#define HANDLE_SYSV_PRAGMA + +/* Enable parsing of #pragma pack(push,) and #pragma pack(pop). */ +#define HANDLE_PRAGMA_PACK_PUSH_POP 1 + +#define YES_UNDERSCORES + +#include "i386/gas.h" + +/* Enable alias attribute support. */ +#ifndef SET_ASM_OP +#define SET_ASM_OP "\t.set" +#endif + +/* Search for as.exe and ld.exe in DJGPP's binary directory. */ +#define MD_EXEC_PREFIX "$DJDIR/bin/" + +/* Correctly handle absolute filename detection in cp/xref.c */ +#define FILE_NAME_ABSOLUTE_P(NAME) \ + (((NAME)[0] == '/') || ((NAME)[0] == '\\') || \ + (((NAME)[0] >= 'A') && ((NAME)[0] <= 'z') && ((NAME)[1] == ':'))) + +#ifdef CPP_PREDEFINES +#undef CPP_PREDEFINES +#endif +#define CPP_PREDEFINES "-Dunix -Di386 -DGO32 -DDJGPP=2 -DMSDOS \ + -Asystem(unix) -Asystem(msdos) -Acpu(i386) -Amachine(i386)" + +/* We need to override link_command_spec in gcc.c so support -Tdjgpp.djl. + This cannot be done in LINK_SPECS as that LINK_SPECS is processed + before library search directories are known by the linker. + This avoids problems when specs file is not available. An alternate way, + suggested by Robert Hoehne, is to use SUBTARGET_EXTRA_SPECS instead. +*/ + +#undef LINK_COMMAND_SPEC +#define LINK_COMMAND_SPEC \ +"%{!fsyntax-only: \ +%{!c:%{!M:%{!MM:%{!E:%{!S:%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \ +\t%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\ +\t%{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ +\t%{static:} %{L*} %D %o\ +\t%{!nostdlib:%{!nodefaultlibs:%G %L %G}}\ +\t%{!A:%{!nostdlib:%{!nostartfiles:%E}}}\ +\t-Tdjgpp.djl %{T*}}}}}}}\n\ +%{!c:%{!M:%{!MM:%{!E:%{!S:stubify %{v} %{o*:%*} %{!o*:a.out} }}}}}" + +/* Always just link in 'libc.a'. */ +#undef LIB_SPEC +#define LIB_SPEC "-lc" + +/* Pick the right startup code depending on the -pg flag. */ +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:crt0.o%s}" + +/* Make sure that gcc will not look for .h files in /usr/local/include + unless user explicitly requests it. */ +#undef LOCAL_INCLUDE_DIR + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_ctor, in_dtor + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CTOR_SECTION_FUNCTION \ + DTOR_SECTION_FUNCTION + +#define CTOR_SECTION_FUNCTION \ +void \ +ctor_section () \ +{ \ + if (in_section != in_ctor) \ + { \ + fprintf (asm_out_file, "\t.section .ctor\n"); \ + in_section = in_ctor; \ + } \ +} + +#define DTOR_SECTION_FUNCTION \ +void \ +dtor_section () \ +{ \ + if (in_section != in_dtor) \ + { \ + fprintf (asm_out_file, "\t.section .dtor\n"); \ + in_section = in_dtor; \ + } \ +} + +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* Allow (eg) __attribute__((section "locked")) to work */ +#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC)\ + do { \ + fprintf (FILE, "\t.section %s\n", NAME); \ + } while (0) + +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } 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); \ + } while (0) + +/* 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.p2align %d\n", LOG) + +/* djgpp has atexit (). */ +#undef HAVE_ATEXIT +#define HAVE_ATEXIT + +/* djgpp automatically calls its own version of __main, so don't define one + in libgcc, nor call one in main(). */ +#define HAS_INIT_SECTION diff --git a/contrib/gcc/config/i386/freebsd-elf.h b/contrib/gcc/config/i386/freebsd-elf.h index 0a556fe..e97d4ca 100644 --- a/contrib/gcc/config/i386/freebsd-elf.h +++ b/contrib/gcc/config/i386/freebsd-elf.h @@ -3,6 +3,7 @@ Contributed by Eric Youngdale. Modified for stabs-in-ELF by H.J. Lu. Adapted from GNU/Linux version by John Polstra. + Continued development by David O'Brien This file is part of GNU CC. @@ -34,6 +35,23 @@ Boston, MA 02111-1307, USA. */ libraries compiled with the native cc, so undef it. */ #undef NO_DOLLAR_IN_LABEL +/* Use more efficient ``thunks'' to implement C++ vtables. */ +#undef DEFAULT_VTABLE_THUNKS +#define DEFAULT_VTABLE_THUNKS 1 + +/* Override the default comment-starter of "/". */ +#undef ASM_COMMENT_START +#define ASM_COMMENT_START "#" + +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +#undef SET_ASM_OP +#define SET_ASM_OP ".set" + /* This is how to output an element of a case-vector that is relative. This is only used for PIC code. See comments by the `casesi' insn in i386.md for an explanation of the expression this outputs. */ @@ -45,6 +63,10 @@ Boston, MA 02111-1307, USA. */ necessary when compiling PIC code. */ #define JUMP_TABLES_IN_TEXT_SECTION (flag_pic) +/* Use stabs instead of DWARF debug format. */ +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + /* Copy this from the svr4 specifications... */ /* Define the register numbers to be used in Dwarf debugging information. The SVR4 reference port C compiler uses the following register numbers @@ -113,23 +135,15 @@ Boston, MA 02111-1307, USA. */ : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+3 \ : (-1)) -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ +/* Tell final.c that we don't need a label passed to mcount. */ #undef FUNCTION_PROFILER #define FUNCTION_PROFILER(FILE, LABELNO) \ { \ if (flag_pic) \ - { \ - fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ - LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ - } \ + fprintf (FILE, "\tcall *.mcount@GOT(%%ebx)\n"); \ else \ - { \ - fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ - fprintf (FILE, "\tcall mcount\n"); \ - } \ + fprintf (FILE, "\tcall .mcount\n"); \ } #undef SIZE_TYPE @@ -140,6 +154,9 @@ Boston, MA 02111-1307, USA. */ #undef WCHAR_TYPE #define WCHAR_TYPE "int" + +#undef WCHAR_UNSIGNED +#define WCHAR_UNSIGNED 0 #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD @@ -150,21 +167,53 @@ Boston, MA 02111-1307, USA. */ #undef CPP_SPEC #define CPP_SPEC "%(cpp_cpu) %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} %{posix:-D_POSIX_SOURCE}" -#undef LIB_SPEC -#if 1 -/* We no longer link with libc_p.a or libg.a by default. If you - * want to profile or debug the C library, please add - * -lc_p or -ggdb to LDFLAGS at the link time, respectively. - */ -#define LIB_SPEC \ - "%{!shared: %{mieee-fp:-lieee} %{p:-lgmon} %{pg:-lgmon} \ - %{!ggdb:-lc} %{ggdb:-lg}}" -#else -#define LIB_SPEC \ +/* This defines which switch letters take arguments. On FreeBSD, most of + the normal cases (defined in gcc.c) apply, and we also have -h* and + -z* options (for the linker) (comming from svr4). + We also have -R (alias --rpath), no -z, --soname (-h), --assert etc. */ + +#undef SWITCH_TAKES_ARG +#define SWITCH_TAKES_ARG(CHAR) \ + (DEFAULT_SWITCH_TAKES_ARG (CHAR) \ + || (CHAR) == 'h' \ + || (CHAR) == 'z' \ + || (CHAR) == 'R') + +/* Provide a STARTFILE_SPEC appropriate for FreeBSD. Here we add + the magical crtbegin.o file (see crtstuff.c) which provides part + of the support for getting C++ file-scope static object constructed + before entering `main'. */ + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ "%{!shared: \ - %{mieee-fp:-lieee} %{p:-lgmon -lc_p} %{pg:-lgmon -lc_p} \ - %{!p:%{!pg:%{!g*:-lc} %{g*:-lg}}}}" -#endif + %{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}" + +/* Provide a ENDFILE_SPEC appropriate for FreeBSD. Here we tack on + the magical crtend.o file (see crtstuff.c) which provides part of + the support for getting C++ file-scope static object constructed + before entering `main', followed by a normal "finalizer" file, + `crtn.o'. */ + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC \ + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" + +/* Provide a LIB_SPEC appropriate for FreeBSD. Just select the appropriate + libc, depending on whether we're doing profiling or need threads support. + (simular to the default, except no -lg, and no -p. */ + +#undef LIB_SPEC +#define LIB_SPEC "%{!shared: \ + %{!pg:%{!pthread:%{!kthread:-lc} \ + %{kthread:-lpthread -lc}} \ + %{pthread:-lc_r}} \ + %{pg:%{!pthread:%{!kthread:-lc_p} \ + %{kthread:-lpthread_p -lc_p}} \ + %{pthread:-lc_r_p}}}" /* Provide a LINK_SPEC appropriate for FreeBSD. Here we provide support for the special GCC options -static and -shared, which allow us to @@ -181,15 +230,17 @@ Boston, MA 02111-1307, USA. */ done. */ #undef LINK_SPEC -#define LINK_SPEC "-m elf_i386 %{shared:-shared} \ - %{!shared: \ - %{!ibcs: \ +#define LINK_SPEC "-m elf_i386 \ + %{Wl,*:%*} \ + %{v:-V} \ + %{assert*} %{R*} %{rpath*} %{defsym*} \ + %{shared:-Bshareable %{h*} %{soname*}} \ + %{!shared: \ %{!static: \ - %{rdynamic:-export-dynamic} \ + %{rdynamic:-export-dynamic} \ %{!dynamic-linker:-dynamic-linker /usr/libexec/ld-elf.so.1}} \ - %{static:-static}}}" - -/* Get perform_* macros to build libgcc.a. */ + %{static:-Bstatic}} \ + %{symbolic:-Bsymbolic}" /* A C statement to output to the stdio stream FILE an assembler command to advance the location counter to a multiple of 1< -#undef CPP_PREDEFINES -#define CPP_PREDEFINES "-Di386 -Acpu(i386) -Amachine(i386) \ --Dunix -Asystem(unix) -DMACH -Asystem(mach) -D__GNU__ -Asystem(gnu)" +/* Get machine-independent configuration parameters for the GNU system. */ +#include #undef TARGET_VERSION #define TARGET_VERSION fprintf (stderr, " (i386 GNU)"); +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-D__ELF__ -D__i386__ -DMACH -Asystem(mach) \ + -Dunix -Asystem(unix) -Asystem(posix) -D__GNU__ -Asystem(gnu)" + +#undef CPP_SPEC +#define CPP_SPEC "%(cpp_cpu) \ + %{fPIC:-D__PIC__ -D__pic__} %{fpic:-D__PIC__ -D__pic__} \ + %{posix:-D_POSIX_SOURCE} %{bsd:-D_BSD_SOURCE}" + +#undef CC1_SPEC +#define CC1_SPEC "%(cc1_cpu)" + #undef LINK_SPEC #define LINK_SPEC "-m elf_i386 %{shared:-shared} \ %{!shared: \ @@ -18,6 +29,10 @@ %{!dynamic-linker:-dynamic-linker /lib/ld.so}} \ %{static:-static}}" - -/* Get machine-independent configuration parameters for the GNU system. */ -#include +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{!shared: \ + %{!static: \ + %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \ + %{static:crt0.o%s}} \ + crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" diff --git a/contrib/gcc/config/i386/i386-coff.h b/contrib/gcc/config/i386/i386-coff.h index 915e307..2e00b7a 100644 --- a/contrib/gcc/config/i386/i386-coff.h +++ b/contrib/gcc/config/i386/i386-coff.h @@ -22,14 +22,20 @@ Boston, MA 02111-1307, USA. */ #include "i386/gas.h" +#include "dbxcoff.h" /* Specify predefined symbols in preprocessor. */ #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Di386" +/* We want to be able to get DBX debugging information via -gstabs. */ + #undef DBX_DEBUGGING_INFO -#define SDB_DEBUGGING_INFO +#define DBX_DEBUGGING_INFO + +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG /* Support the ctors and dtors sections for g++. */ diff --git a/contrib/gcc/config/i386/i386-interix.h b/contrib/gcc/config/i386/i386-interix.h new file mode 100644 index 0000000..8e9f443 --- /dev/null +++ b/contrib/gcc/config/i386/i386-interix.h @@ -0,0 +1,575 @@ +/* Target definitions for GNU compiler for Intel 80386 running Interix + Parts Copyright (C) 1991, 1999 Free Software Foundation, Inc. + + Parts: + by Douglas B. Rupp (drupp@cs.washington.edu). + by Ron Guilmette (rfg@netcom.com). + by Donn Terry (donn@softway.com). + by Mumit Khan (khan@xraylith.wisc.edu). + +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 YES_UNDERSCORES + +/* YES_UNDERSCORES must preceed gas.h */ +#include +/* The rest must follow. */ + +#define DBX_DEBUGGING_INFO +#define SDB_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + +#define HANDLE_SYSV_PRAGMA +#undef HANDLE_PRAGMA_WEAK /* until the link format can handle it */ + +/* 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 compatability */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE | \ + MASK_ALIGN_DOUBLE) + +#undef TARGET_CPU_DEFAULT +#define TARGET_CPU_DEFAULT 2 /* 486 */ + +#define WCHAR_UNSIGNED 1 +#define WCHAR_TYPE_SIZE 16 +#define WCHAR_TYPE "short unsigned int" + +/* WinNT (and thus Interix) use unsigned int */ +#define SIZE_TYPE "unsigned int" + +#define ASM_LOAD_ADDR(loc, reg) " leal " #loc "," #reg "\n" + +/* For the sake of libgcc2.c, indicate target supports atexit. */ +#define HAVE_ATEXIT + +/* cpp handles __STDC__ */ +#undef CPP_PREDEFINES +#define CPP_PREDEFINES " \ + -D__INTERIX \ + -D__OPENNT \ + -D_M_IX86=300 -D_X86_=1 \ + -D__stdcall=__attribute__((__stdcall__)) \ + -D__cdecl=__attribute__((__cdecl__)) \ + -Asystem(unix) -Asystem(interix) -Asystem(interix) -Acpu(i386) -Amachine(i386)" + +#undef CPP_SPEC +/* Write out the correct language type definition for the header files. + Unless we have assembler language, write out the symbols for C. + cpp_cpu is an Intel specific variant. See i386.h + mieee is an Alpha specific variant. Cross polination a bad idea. + */ +#define CPP_SPEC "\ +%{!.S: -D__LANGUAGE_C__ -D__LANGUAGE_C %{!ansi:-DLANGUAGE_C}} \ +%{.S: -D__LANGUAGE_ASSEMBLY__ -D__LANGUAGE_ASSEMBLY %{!ansi:-DLANGUAGE_ASSEMBLY}} \ +%{.cc: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \ +%{.cxx: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \ +%{.C: -D__LANGUAGE_C_PLUS_PLUS__ -D__LANGUAGE_C_PLUS_PLUS -D__cplusplus} \ +%{.m: -D__LANGUAGE_OBJECTIVE_C__ -D__LANGUAGE_OBJECTIVE_C} \ +-remap \ +%(cpp_cpu) \ +%{posix:-D_POSIX_SOURCE} \ +-idirafter %$INTERIX_ROOT/usr/include" + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (i386 Interix)"); + +/* 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) + +/* A table of bytes codes used by the ASM_OUTPUT_ASCII and + ASM_OUTPUT_LIMITED_STRING macros. Each byte in the table + corresponds to a particular byte value [0..255]. For any + given byte value, if the value in the corresponding table + position is zero, the given character can be output directly. + If the table value is 1, the byte must be output as a \ooo + octal escape. If the tables value is anything else, then the + byte value should be output as a \ followed by the value + in the table. Note that we can use standard UN*X escape + sequences for many control characters, but we don't use + \a to represent BEL because some svr4 assemblers (e.g. on + the i386) don't know about that. Also, we don't use \v + since some versions of gas, such as 2.2 did not accept it. */ + +#define ESCAPES \ +"\1\1\1\1\1\1\1\1btn\1fr\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\ +\0\0\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\\\0\0\0\ +\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\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\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\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" + +/* Some svr4 assemblers have a limit on the number of characters which + can appear in the operand of a .string directive. If your assembler + has such a limitation, you should define STRING_LIMIT to reflect that + limit. Note that at least some svr4 assemblers have a limit on the + actual number of bytes in the double-quoted string, and that they + count each character in an escape sequence as one byte. Thus, an + escape sequence like \377 would count as four bytes. + + If your target assembler doesn't support the .string directive, you + should define this to zero. +*/ + +#define STRING_LIMIT ((unsigned) 256) + +#define STRING_ASM_OP ".string" + +/* The routine used to output NUL terminated strings. We use a special + version of this for most svr4 targets because doing so makes the + 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). */ + +#define ASM_OUTPUT_LIMITED_STRING(FILE, STR) \ + do \ + { \ + register unsigned char *_limited_str = (unsigned char *) (STR); \ + register unsigned ch; \ + fprintf ((FILE), "\t%s\t\"", STRING_ASM_OP); \ + for (; (ch = *_limited_str); _limited_str++) \ + { \ + register int escape = ESCAPES[ch]; \ + switch (escape) \ + { \ + case 0: \ + putc (ch, (FILE)); \ + break; \ + case 1: \ + fprintf ((FILE), "\\%03o", ch); \ + break; \ + default: \ + putc ('\\', (FILE)); \ + putc (escape, (FILE)); \ + break; \ + } \ + } \ + fprintf ((FILE), "\"\n"); \ + } \ + while (0) + +/* The routine used to output sequences of byte values. We use a special + version of this for most svr4 targets because doing so makes the + generated assembly code more compact (and thus faster to assemble) + as well as more readable. Note that if we find subparts of the + character sequence which end with NUL (and which are shorter than + STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING. */ + +#undef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(FILE, STR, LENGTH) \ + do \ + { \ + register unsigned char *_ascii_bytes = (unsigned char *) (STR); \ + register unsigned char *limit = _ascii_bytes + (LENGTH); \ + register unsigned bytes_in_chunk = 0; \ + for (; _ascii_bytes < limit; _ascii_bytes++) \ + { \ + register unsigned char *p; \ + if (bytes_in_chunk >= 64) \ + { \ + fputc ('\n', (FILE)); \ + bytes_in_chunk = 0; \ + } \ + for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \ + continue; \ + if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \ + { \ + if (bytes_in_chunk > 0) \ + { \ + fputc ('\n', (FILE)); \ + bytes_in_chunk = 0; \ + } \ + ASM_OUTPUT_LIMITED_STRING ((FILE), _ascii_bytes); \ + _ascii_bytes = p; \ + } \ + else \ + { \ + if (bytes_in_chunk == 0) \ + fprintf ((FILE), "\t.byte\t"); \ + else \ + fputc (',', (FILE)); \ + fprintf ((FILE), "0x%02x", *_ascii_bytes); \ + bytes_in_chunk += 5; \ + } \ + } \ + if (bytes_in_chunk > 0) \ + fprintf ((FILE), "\n"); \ + } \ + while (0) + +/* This is how to output an element of a case-vector that is relative. + This is only used for PIC code. See comments by the `casesi' insn in + i386.md for an explanation of the expression this outputs. + PE format differs on what PC-relative offsets look like (see + coff_i386_rtype_to_howto), and we need to compensate (by one word) here. */ + +#undef ASM_OUTPUT_ADDR_DIFF_ELT +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ + fprintf (FILE, "\t.long __GLOBAL_OFFSET_TABLE_+[.-%s%d+4]\n", LPREFIX, VALUE) + +/* Indicate that jump tables go in the text section. This is + necessary when compiling PIC code. */ + +#define JUMP_TABLES_IN_TEXT_SECTION 1 + +/* Emit code to check the stack when allocating more that 4000 + bytes in one go. */ + +#define CHECK_STACK_LIMIT 0x1000 + +/* the following are OSF linker (not gld) specific... we don't want them */ +#undef HAS_INIT_SECTION +#undef LD_INIT_SWITCH +#undef LD_FINI_SWITCH + + +/* The following are needed for C++, but also needed for profiling */ + +/* Support const sections and the ctors and dtors sections for g++. + Note that there appears to be two different ways to support const + sections at the moment. You can either #define the symbol + READONLY_DATA_SECTION (giving it some code which switches to the + readonly data section) or else you can #define the symbols + EXTRA_SECTIONS, EXTRA_SECTION_FUNCTIONS, SELECT_SECTION, and + SELECT_RTX_SECTION. We do both here just to be on the safe side. */ + +#define USE_CONST_SECTION 1 + +#define CONST_SECTION_ASM_OP ".section\t.rdata,\"r\"" + +/* Define the pseudo-ops used to switch to the .ctors and .dtors sections. + + Note that we want to give these sections the SHF_WRITE attribute + because these sections will actually contain data (i.e. tables of + addresses of functions in the current root executable or shared library + file) and, in the case of a shared library, the relocatable addresses + will have to be properly resolved/relocated (and then written into) by + the dynamic linker when it actually attaches the given shared library + to the executing process. (Note that on SVR4, you may wish to use the + `-z text' option to the ELF linker, when building a shared library, as + an additional check that you are doing everything right. But if you do + use the `-z text' option when building a shared library, you will get + errors unless the .ctors and .dtors sections are marked as writable + via the SHF_WRITE attribute.) */ + +#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"x\"" +#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"x\"" + +/* A default list of other sections which we might be "in" at any given + time. For targets that use additional sections (e.g. .tdesc) you + should override this definition in the target-specific file which + includes this file. */ + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_const, in_ctors, in_dtors + +/* A default list of extra section function definitions. For targets + that use additional sections (e.g. .tdesc) you should override this + definition in the target-specific file which includes this file. */ + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CONST_SECTION_FUNCTION \ + CTORS_SECTION_FUNCTION \ + DTORS_SECTION_FUNCTION + +#undef READONLY_DATA_SECTION +#define READONLY_DATA_SECTION() const_section () + +extern void text_section (); + +#define CONST_SECTION_FUNCTION \ +void \ +const_section () \ +{ \ + if (!USE_CONST_SECTION) \ + text_section(); \ + else if (in_section != in_const) \ + { \ + fprintf (asm_out_file, "%s\n", CONST_SECTION_ASM_OP); \ + in_section = in_const; \ + } \ +} + +#define CTORS_SECTION_FUNCTION \ +void \ +ctors_section () \ +{ \ + if (in_section != in_ctors) \ + { \ + fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \ + in_section = in_ctors; \ + } \ +} + +#define DTORS_SECTION_FUNCTION \ +void \ +dtors_section () \ +{ \ + if (in_section != in_dtors) \ + { \ + fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \ + in_section = in_dtors; \ + } \ +} + +#if 0 +/* Currently gas chokes on this; that's not too hard to fix, but there's + not a lot of impeteus to do it, either. If it is done, gas will have + to handle long section name escapes (which are defined in the COFF/PE + document as /nnn where nnn is a string table index). The benefit: + section attributes and -ffunction-sections, neither of which seem to + be critical. */ +/* gas may have been fixed? bfd was. */ + +/* Switch into a generic section. + This is currently only used to support section attributes. + + We make the section read-only and executable for a function decl, + read-only for a const data decl, and writable for a non-const data decl. */ +#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME) \ + fprintf (FILE, ".section\t%s,\"%s\",@progbits\n", NAME, \ + (DECL) && TREE_CODE (DECL) == FUNCTION_DECL ? "ax" : \ + (DECL) && TREE_READONLY (DECL) ? "a" : "aw") +#endif + +#define INT_ASM_OP ".long" + +/* The MS compilers take alignment as a number of bytes, so we do as well */ +#undef ASM_OUTPUT_ALIGN +#define ASM_OUTPUT_ALIGN(FILE,LOG) \ + if ((LOG)!=0) fprintf ((FILE), "\t.balign %d\n", 1<<(LOG)) + +/* A C statement (sans semicolon) to output an element in the table of + global constructors. */ +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* A C statement (sans semicolon) to output an element in the table of + global destructors. */ +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtors_section (); \ + fprintf (FILE, "\t%s\t ", INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* The linker will take care of this, and having them causes problems with + ld -r (specifically -rU). */ +#define CTOR_LISTS_DEFINED_EXTERNALLY 1 + +#define SET_ASM_OP ".set" +/* Output a definition (implements alias) */ +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ +do \ +{ \ + fprintf ((FILE), "\t%s\t", SET_ASM_OP); \ + assemble_name (FILE, LABEL1); \ + fprintf (FILE, ","); \ + assemble_name (FILE, LABEL2); \ + fprintf (FILE, "\n"); \ + } \ +while (0) + +#define HOST_PTR_PRINTF "%p" +#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 + problem, so.... */ + +/* Forward references to tags are allowed. */ +#define SDB_ALLOW_FORWARD_REFERENCES + +/* Unknown tags are also allowed. */ +#define SDB_ALLOW_UNKNOWN_REFERENCES + +/* The integer half of this list needs to be constant. However, there's + a lot of disagreement about what the floating point adjustments should + be. We pick one that works with gdb. (The underlying problem is + what to do about the segment registers. Since we have access to them + from /proc, we'll allow them to be accessed in gdb, even tho the + gcc compiler can't generate them. (There's some evidence that + MSVC does, but possibly only for certain special "canned" sequences.) */ + +#undef DBX_REGISTER_NUMBER +#define DBX_REGISTER_NUMBER(n) \ +((n) == 0 ? 0 \ + : (n) == 1 ? 2 \ + : (n) == 2 ? 1 \ + : (n) == 3 ? 3 \ + : (n) == 4 ? 6 \ + : (n) == 5 ? 7 \ + : (n) == 6 ? 5 \ + : (n) == 7 ? 4 \ + : ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) ? (n)+8 \ + : (-1)) + +/* 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). + + Apply stddef, handle (as yet unimplemented) pic. + + stddef renaming does NOT apply to Alpha. */ + +char *gen_stdcall_suffix (); + +#undef ENCODE_SECTION_INFO +#define ENCODE_SECTION_INFO(DECL) \ +do \ + { \ + if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + 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)); \ + } \ +while (0) + +/* This macro gets just the user-specified name + out of the string in a SYMBOL_REF. Discard + trailing @[NUM] encoded by ENCODE_SECTION_INFO. */ +#undef STRIP_NAME_ENCODING +#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ +do { \ + char *_p; \ + char *_name = SYMBOL_NAME; \ + for (_p = _name; *_p && *_p != '@'; ++_p) \ + ; \ + if (*_p == '@') \ + { \ + int _len = _p - _name; \ + (VAR) = (char *) alloca (_len + 1); \ + strncpy ((VAR), _name, _len); \ + (VAR)[_len] = '\0'; \ + } \ + else \ + (VAR) = _name; \ +} while (0) + +#if 0 +/* Turn this back on when the linker is updated to handle grouped + .data$ sections correctly. See corresponding note in i386/interix.c. + MK. */ + +/* 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 + +#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL) +extern void i386_pe_unique_section (); +#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC) + +#define SUPPORTS_ONE_ONLY 1 + +/* A C statement to output something to the assembler file to switch to section + NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or + NULL_TREE. Some target formats do not support arbitrary sections. Do not + define this macro in such cases. */ +#undef ASM_OUTPUT_SECTION_NAME +#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \ +do { \ + static struct section_info \ + { \ + struct section_info *next; \ + char *name; \ + enum sect_enum {SECT_RW, SECT_RO, SECT_EXEC} type; \ + } *sections; \ + struct section_info *s; \ + char *mode; \ + enum sect_enum type; \ + \ + for (s = sections; s; s = s->next) \ + if (!strcmp (NAME, s->name)) \ + break; \ + \ + if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \ + type = SECT_EXEC, mode = "x"; \ + else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \ + type = SECT_RO, mode = "r"; \ + else \ + type = SECT_RW, mode = "w"; \ + \ + if (s == 0) \ + { \ + s = (struct section_info *) xmalloc (sizeof (struct section_info)); \ + s->name = xmalloc ((strlen (NAME) + 1) * sizeof (*NAME)); \ + strcpy (s->name, NAME); \ + s->type = type; \ + s->next = sections; \ + sections = s; \ + fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \ + /* Functions may have been compiled at various levels of \ + optimization so we can't use `same_size' here. Instead, \ + have the linker pick one. */ \ + if ((DECL) && DECL_ONE_ONLY (DECL)) \ + fprintf (STREAM, "\t.linkonce %s\n", \ + TREE_CODE (DECL) == FUNCTION_DECL \ + ? "discard" : "same_size"); \ + } \ + else \ + { \ + fprintf (STREAM, ".section\t%s,\"%s\"\n", NAME, mode); \ + } \ +} while (0) + +#endif /* 0 */ + +/* DWARF2 Unwinding doesn't work with exception handling yet. */ +#define DWARF2_UNWIND_INFO 0 + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + diff --git a/contrib/gcc/config/i386/i386.c b/contrib/gcc/config/i386/i386.c index b2512a0..3efedb6 100644 --- a/contrib/gcc/config/i386/i386.c +++ b/contrib/gcc/config/i386/i386.c @@ -100,8 +100,42 @@ struct processor_costs pentiumpro_cost = { 17 /* cost of a divide/mod */ }; +/* We use decoding time together with execution time. + To get correct vale add 1 for short decodable, 2 for long decodable + and 4 for vector decodable instruction to execution time and divide + by two (because CPU is able to do two insns at a time). */ + +struct processor_costs k6_cost = { + 1, /* cost of an add instruction */ + 1, /* cost of a lea instruction */ + 1, /* variable shift costs */ + 1, /* constant shift costs */ + 3, /* cost of starting a multiply */ + 0, /* cost of multiply per each bit set */ + 20 /* cost of a divide/mod */ +}; + struct processor_costs *ix86_cost = &pentium_cost; +/* Processor feature/optimization bitmasks. */ +#define m_386 (1< j && (int) ix86_arch >= (int) PROCESSOR_PENTIUMPRO) + if (i > j && (int) ix86_arch >= (int) PROCESSOR_K6) error ("-mcpu=%s does not support -march=%s", ix86_cpu_string, ix86_arch_string); @@ -311,6 +352,11 @@ override_options () def_align = (TARGET_486) ? 4 : 2; /* Validate -malign-loops= value, or provide default. */ +#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN + i386_align_loops = 4; +#else + i386_align_loops = 2; +#endif if (i386_align_loops_string) { i386_align_loops = atoi (i386_align_loops_string); @@ -318,14 +364,13 @@ override_options () fatal ("-malign-loops=%d is not between 0 and %d", i386_align_loops, MAX_CODE_ALIGN); } - else + + /* Validate -malign-jumps= value, or provide default. */ #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - i386_align_loops = 4; + i386_align_jumps = 4; #else - i386_align_loops = 2; + i386_align_jumps = def_align; #endif - - /* Validate -malign-jumps= value, or provide default. */ if (i386_align_jumps_string) { i386_align_jumps = atoi (i386_align_jumps_string); @@ -333,14 +378,9 @@ override_options () fatal ("-malign-jumps=%d is not between 0 and %d", i386_align_jumps, MAX_CODE_ALIGN); } - else -#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN - i386_align_jumps = 4; -#else - i386_align_jumps = def_align; -#endif /* Validate -malign-functions= value, or provide default. */ + i386_align_funcs = def_align; if (i386_align_funcs_string) { i386_align_funcs = atoi (i386_align_funcs_string); @@ -348,19 +388,26 @@ override_options () fatal ("-malign-functions=%d is not between 0 and %d", i386_align_funcs, MAX_CODE_ALIGN); } - else - i386_align_funcs = def_align; + + /* Validate -mpreferred_stack_boundary= value, or provide default. + The default of 128 bits is for Pentium III's SSE __m128. */ + i386_preferred_stack_boundary = 128; + if (i386_preferred_stack_boundary_string) + { + i = atoi (i386_preferred_stack_boundary_string); + if (i < 2 || i > 31) + fatal ("-mpreferred_stack_boundary=%d is not between 2 and 31", i); + i386_preferred_stack_boundary = (1 << i) * BITS_PER_UNIT; + } /* Validate -mbranch-cost= value, or provide default. */ + i386_branch_cost = 1; if (i386_branch_cost_string) { i386_branch_cost = atoi (i386_branch_cost_string); if (i386_branch_cost < 0 || i386_branch_cost > 5) - fatal ("-mbranch-cost=%d is not between 0 and 5", - i386_branch_cost); + fatal ("-mbranch-cost=%d is not between 0 and 5", i386_branch_cost); } - else - i386_branch_cost = 1; /* Keep nonleaf frame pointers. */ if (TARGET_OMIT_LEAF_FRAME_POINTER) @@ -592,9 +639,19 @@ i386_valid_type_attribute_p (type, attributes, identifier, args) int i386_comp_type_attributes (type1, type2) - tree type1 ATTRIBUTE_UNUSED; - tree type2 ATTRIBUTE_UNUSED; + tree type1; + tree type2; { + /* Check for mismatch of non-default calling convention. */ + char *rtdstr = TARGET_RTD ? "cdecl" : "stdcall"; + + if (TREE_CODE (type1) != FUNCTION_TYPE) + return 1; + + /* Check for mismatched return types (cdecl vs stdcall). */ + if (!lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type1)) + != !lookup_attribute (rtdstr, TYPE_ATTRIBUTES (type2))) + return 0; return 1; } @@ -814,150 +871,6 @@ function_arg_partial_nregs (cum, mode, type, named) return 0; } -/* Output an insn whose source is a 386 integer register. SRC is the - rtx for the register, and TEMPLATE is the op-code template. SRC may - be either SImode or DImode. - - The template will be output with operands[0] as SRC, and operands[1] - as a pointer to the top of the 386 stack. So a call from floatsidf2 - would look like this: - - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - - where %z0 corresponds to the caller's operands[1], and is used to - emit the proper size suffix. - - ??? Extend this to handle HImode - a 387 can load and store HImode - values directly. */ - -void -output_op_from_reg (src, template) - rtx src; - char *template; -{ - rtx xops[4]; - int size = GET_MODE_SIZE (GET_MODE (src)); - - xops[0] = src; - xops[1] = AT_SP (Pmode); - xops[2] = GEN_INT (size); - xops[3] = stack_pointer_rtx; - - if (size > UNITS_PER_WORD) - { - rtx high; - - if (size > 2 * UNITS_PER_WORD) - { - high = gen_rtx_REG (SImode, REGNO (src) + 2); - output_asm_insn (AS1 (push%L0,%0), &high); - } - - high = gen_rtx_REG (SImode, REGNO (src) + 1); - output_asm_insn (AS1 (push%L0,%0), &high); - } - - output_asm_insn (AS1 (push%L0,%0), &src); - output_asm_insn (template, xops); - output_asm_insn (AS2 (add%L3,%2,%3), xops); -} - -/* Output an insn to pop an value from the 387 top-of-stack to 386 - register DEST. The 387 register stack is popped if DIES is true. If - the mode of DEST is an integer mode, a `fist' integer store is done, - otherwise a `fst' float store is done. */ - -void -output_to_reg (dest, dies, scratch_mem) - rtx dest; - int dies; - rtx scratch_mem; -{ - rtx xops[4]; - int size = GET_MODE_SIZE (GET_MODE (dest)); - - if (! scratch_mem) - xops[0] = AT_SP (Pmode); - else - xops[0] = scratch_mem; - - xops[1] = stack_pointer_rtx; - xops[2] = GEN_INT (size); - xops[3] = dest; - - if (! scratch_mem) - output_asm_insn (AS2 (sub%L1,%2,%1), xops); - - if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_INT) - { - if (dies) - output_asm_insn (AS1 (fistp%z3,%y0), xops); - else if (GET_MODE (xops[3]) == DImode && ! dies) - { - /* There is no DImode version of this without a stack pop, so - we must emulate it. It doesn't matter much what the second - instruction is, because the value being pushed on the FP stack - is not used except for the following stack popping store. - This case can only happen without optimization, so it doesn't - matter that it is inefficient. */ - output_asm_insn (AS1 (fistp%z3,%0), xops); - output_asm_insn (AS1 (fild%z3,%0), xops); - } - else - output_asm_insn (AS1 (fist%z3,%y0), xops); - } - - else if (GET_MODE_CLASS (GET_MODE (dest)) == MODE_FLOAT) - { - if (dies) - output_asm_insn (AS1 (fstp%z3,%y0), xops); - else - { - if (GET_MODE (dest) == XFmode) - { - output_asm_insn (AS1 (fstp%z3,%y0), xops); - output_asm_insn (AS1 (fld%z3,%y0), xops); - } - else - output_asm_insn (AS1 (fst%z3,%y0), xops); - } - } - - else - abort (); - - if (! scratch_mem) - output_asm_insn (AS1 (pop%L0,%0), &dest); - else - output_asm_insn (AS2 (mov%L0,%0,%3), xops); - - - if (size > UNITS_PER_WORD) - { - dest = gen_rtx_REG (SImode, REGNO (dest) + 1); - if (! scratch_mem) - output_asm_insn (AS1 (pop%L0,%0), &dest); - else - { - xops[0] = adj_offsettable_operand (xops[0], 4); - xops[3] = dest; - output_asm_insn (AS2 (mov%L0,%0,%3), xops); - } - - if (size > 2 * UNITS_PER_WORD) - { - dest = gen_rtx_REG (SImode, REGNO (dest) + 1); - if (! scratch_mem) - output_asm_insn (AS1 (pop%L0,%0), &dest); - else - { - xops[0] = adj_offsettable_operand (xops[0], 4); - output_asm_insn (AS2 (mov%L0,%0,%3), xops); - } - } - } -} - char * singlemove_string (operands) rtx *operands; @@ -983,32 +896,6 @@ singlemove_string (operands) } } -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. */ - -static rtx -find_addr_reg (addr) - rtx addr; -{ - while (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - abort (); - } - - if (GET_CODE (addr) == REG) - return addr; - abort (); -} - /* Output an insn to add the constant N to the register X. */ static void @@ -1046,7 +933,6 @@ output_move_double (operands) rtx latehalf[2]; rtx middlehalf[2]; rtx xops[2]; - rtx addreg0 = 0, addreg1 = 0; int dest_overlapped_low = 0; int size = GET_MODE_SIZE (GET_MODE (operands[0])); @@ -1083,11 +969,14 @@ output_move_double (operands) else optype1 = RNDOP; - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ + /* Check for the cases that are not supposed to happen + either due to the operand constraints or the fact + that all memory operands on the x86 are offsettable. + Abort if we get one, because generating code for these + cases is painful. */ - if (optype0 == RNDOP || optype1 == RNDOP) + if (optype0 == RNDOP || optype1 == RNDOP + || optype0 == MEMOP || optype1 == MEMOP) abort (); /* If one operand is decrementing and one is incrementing @@ -1122,15 +1011,6 @@ output_move_double (operands) optype1 = OFFSOP; } - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the second word. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (operands[0], 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (operands[1], 0)); - /* Ok, we can do one word at a time. Normally we do the low-numbered word first, but if either operand is autodecrementing then we @@ -1227,8 +1107,7 @@ output_move_double (operands) emit the move late-half first. Otherwise, compute the MEM address into the upper part of N and use that as a pointer to the memory operand. */ - if (optype0 == REGOP - && (optype1 == OFFSOP || optype1 == MEMOP)) + if (optype0 == REGOP && optype1 == OFFSOP) { if (reg_mentioned_p (operands[0], XEXP (operands[1], 0)) && reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) @@ -1260,10 +1139,6 @@ output_move_double (operands) || reg_mentioned_p (latehalf[0], XEXP (operands[1], 0))) goto compadr; - /* JRV says this can't happen: */ - if (addreg0 || addreg1) - abort (); - /* Only the middle reg conflicts; simply put it last. */ output_asm_insn (singlemove_string (operands), operands); output_asm_insn (singlemove_string (latehalf), latehalf); @@ -1298,29 +1173,11 @@ output_move_double (operands) || REGNO (operands[0]) == REGNO (latehalf[1]))) || dest_overlapped_low) { - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - asm_add (size-4, addreg0); - if (addreg1) - asm_add (size-4, addreg1); - - /* Do that word. */ + /* Do the high-numbered word. */ output_asm_insn (singlemove_string (latehalf), latehalf); - /* Undo the adds we just did. */ - if (addreg0) - asm_add (-4, addreg0); - if (addreg1) - asm_add (-4, addreg1); - if (size == 12) - { - output_asm_insn (singlemove_string (middlehalf), middlehalf); - if (addreg0) - asm_add (-4, addreg0); - if (addreg1) - asm_add (-4, addreg1); - } + output_asm_insn (singlemove_string (middlehalf), middlehalf); /* Do low-numbered word. */ return singlemove_string (operands); @@ -1332,30 +1189,11 @@ output_move_double (operands) /* Do the middle one of the three words for long double */ if (size == 12) - { - if (addreg0) - asm_add (4, addreg0); - if (addreg1) - asm_add (4, addreg1); + output_asm_insn (singlemove_string (middlehalf), middlehalf); - output_asm_insn (singlemove_string (middlehalf), middlehalf); - } - - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - asm_add (4, addreg0); - if (addreg1) - asm_add (4, addreg1); - - /* Do that word. */ + /* Do the high-numbered word. */ output_asm_insn (singlemove_string (latehalf), latehalf); - /* Undo the adds we just did. */ - if (addreg0) - asm_add (4-size, addreg0); - if (addreg1) - asm_add (4-size, addreg1); - return ""; } @@ -1440,125 +1278,6 @@ output_move_pushmem (operands, insn, length, tmp_start, n_operands) return ""; } -/* Output the appropriate code to move data between two memory locations */ - -char * -output_move_memory (operands, insn, length, tmp_start, n_operands) - rtx operands[]; - rtx insn; - int length; - int tmp_start; - int n_operands; -{ - struct - { - char *load; - char *store; - rtx xops[3]; - } tmp_info[MAX_TMPS]; - - rtx dest = operands[0]; - rtx src = operands[1]; - rtx qi_tmp = NULL_RTX; - int max_tmps = 0; - int offset = 0; - int i, num_tmps; - rtx xops[3]; - - if (GET_CODE (dest) == MEM - && GET_CODE (XEXP (dest, 0)) == PRE_INC - && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx) - return output_move_pushmem (operands, insn, length, tmp_start, n_operands); - - if (! offsettable_memref_p (src)) - fatal_insn ("Source is not offsettable", insn); - - if (! offsettable_memref_p (dest)) - fatal_insn ("Destination is not offsettable", insn); - - /* Figure out which temporary registers we have available */ - for (i = tmp_start; i < n_operands; i++) - { - if (GET_CODE (operands[i]) == REG) - { - if ((length & 1) != 0 && qi_tmp == 0 && QI_REG_P (operands[i])) - qi_tmp = operands[i]; - - if (reg_overlap_mentioned_p (operands[i], dest)) - fatal_insn ("Temporary register overlaps the destination", insn); - - if (reg_overlap_mentioned_p (operands[i], src)) - fatal_insn ("Temporary register overlaps the source", insn); - - tmp_info[max_tmps++].xops[2] = operands[i]; - if (max_tmps == MAX_TMPS) - break; - } - } - - if (max_tmps == 0) - fatal_insn ("No scratch registers were found to do memory->memory moves", - insn); - - if ((length & 1) != 0) - { - if (qi_tmp == 0) - fatal_insn ("No byte register found when moving odd # of bytes.", - insn); - } - - while (length > 1) - { - for (num_tmps = 0; num_tmps < max_tmps; num_tmps++) - { - if (length >= 4) - { - tmp_info[num_tmps].load = AS2(mov%L0,%1,%2); - tmp_info[num_tmps].store = AS2(mov%L0,%2,%0); - tmp_info[num_tmps].xops[0] - = adj_offsettable_operand (dest, offset); - tmp_info[num_tmps].xops[1] - = adj_offsettable_operand (src, offset); - - offset += 4; - length -= 4; - } - - else if (length >= 2) - { - tmp_info[num_tmps].load = AS2(mov%W0,%1,%2); - tmp_info[num_tmps].store = AS2(mov%W0,%2,%0); - tmp_info[num_tmps].xops[0] - = adj_offsettable_operand (dest, offset); - tmp_info[num_tmps].xops[1] - = adj_offsettable_operand (src, offset); - - offset += 2; - length -= 2; - } - else - break; - } - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].load, tmp_info[i].xops); - - for (i = 0; i < num_tmps; i++) - output_asm_insn (tmp_info[i].store, tmp_info[i].xops); - } - - if (length == 1) - { - xops[0] = adj_offsettable_operand (dest, offset); - xops[1] = adj_offsettable_operand (src, offset); - xops[2] = qi_tmp; - output_asm_insn (AS2(mov%B0,%1,%2), xops); - output_asm_insn (AS2(mov%B0,%2,%0), xops); - } - - return ""; -} - int standard_80387_constant_p (x) rtx x; @@ -1586,6 +1305,7 @@ standard_80387_constant_p (x) /* Note that on the 80387, other constants, such as pi, are much slower to load as standard constants than to load from doubles in memory! */ + /* ??? Not true on K6: all constants are equal cost. */ #endif return 0; @@ -1646,6 +1366,17 @@ symbolic_operand (op, mode) } } +/* Return nonzero if OP is a constant shift count small enough to + encode into an lea instruction. */ + +int +small_shift_operand (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + return (GET_CODE (op) == CONST_INT && INTVAL (op) > 0 && INTVAL (op) < 4); +} + /* Test for a valid operand for a call instruction. Don't allow the arg pointer register or virtual regs since they may change into reg + const, which the patterns @@ -1994,14 +1725,19 @@ load_pic_register (do_rtl) { emit_insn (gen_prologue_get_pc (xops[0], xops[1])); emit_insn (gen_prologue_set_got (xops[0], - gen_rtx (SYMBOL_REF, Pmode, - "$_GLOBAL_OFFSET_TABLE_"), +#ifdef YES_UNDERSCORES + gen_rtx_SYMBOL_REF (Pmode, + "$__GLOBAL_OFFSET_TABLE_"), +#else + gen_rtx_SYMBOL_REF (Pmode, + "$_GLOBAL_OFFSET_TABLE_"), +#endif xops[1])); } else { output_asm_insn (AS1 (call,%X1), xops); - output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_,%0", xops); + output_asm_insn ("addl $%__GLOBAL_OFFSET_TABLE_,%0", xops); pic_label_rtx = 0; } } @@ -2024,7 +1760,7 @@ load_pic_register (do_rtl) ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (xops[1])); output_asm_insn (AS1 (pop%L0,%0), xops); - output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops); + output_asm_insn ("addl $%__GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops); } } @@ -2036,6 +1772,67 @@ load_pic_register (do_rtl) emit_insn (gen_blockage ()); } +/* Compute the size of local storage taking into consideration the + desired stack alignment which is to be maintained. Also determine + the number of registers saved below the local storage. */ + +HOST_WIDE_INT +ix86_compute_frame_size (size, nregs_on_stack) + HOST_WIDE_INT size; + int *nregs_on_stack; +{ + int limit; + int nregs; + int regno; + int padding; + int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table + || current_function_uses_const_pool); + HOST_WIDE_INT total_size; + + limit = frame_pointer_needed + ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM; + + nregs = 0; + + for (regno = limit - 1; regno >= 0; regno--) + if ((regs_ever_live[regno] && ! call_used_regs[regno]) + || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) + nregs++; + + padding = 0; + total_size = size + (nregs * UNITS_PER_WORD); + +#ifdef PREFERRED_STACK_BOUNDARY + { + int offset; + int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + + offset = 4; + if (frame_pointer_needed) + offset += UNITS_PER_WORD; + + total_size += offset; + + padding = ((total_size + preferred_alignment - 1) + & -preferred_alignment) - total_size; + + if (padding < (((offset + preferred_alignment - 1) + & -preferred_alignment) - offset)) + padding += preferred_alignment; + + /* Don't bother aligning the stack of a leaf function + which doesn't allocate any stack slots. */ + if (size == 0 && current_function_is_leaf) + padding = 0; + } +#endif + + if (nregs_on_stack) + *nregs_on_stack = nregs; + + return size + padding; +} + static void ix86_prologue (do_rtl) int do_rtl; @@ -2045,7 +1842,7 @@ ix86_prologue (do_rtl) rtx xops[4]; int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table || current_function_uses_const_pool); - long tsize = get_frame_size (); + HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *)0); rtx insn; int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset; @@ -2180,6 +1977,10 @@ ix86_prologue (do_rtl) } } +#ifdef SUBTARGET_PROLOGUE + SUBTARGET_PROLOGUE; +#endif + if (pic_reg_used) load_pic_register (do_rtl); @@ -2254,32 +2055,18 @@ ix86_epilogue (do_rtl) int do_rtl; { register int regno; - register int nregs, limit; - int offset; + register int limit; + int nregs; rtx xops[3]; int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table || current_function_uses_const_pool); - long tsize = get_frame_size (); - - /* Compute the number of registers to pop */ - - limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM); - - nregs = 0; - - for (regno = limit - 1; regno >= 0; regno--) - if ((regs_ever_live[regno] && ! call_used_regs[regno]) - || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used)) - nregs++; + int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging; + HOST_WIDE_INT offset; + HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs); - /* sp is often unreliable so we must go off the frame pointer. + /* sp is often unreliable so we may have to go off the frame pointer. */ - In reality, we may not care if sp is unreliable, because we can restore - the register relative to the frame pointer. In theory, since each move - is the same speed as a pop, and we don't need the leal, this is faster. - For now restore multiple registers the old way. */ - - offset = - tsize - (nregs * UNITS_PER_WORD); + offset = -(tsize + nregs * UNITS_PER_WORD); xops[2] = stack_pointer_rtx; @@ -2294,9 +2081,17 @@ ix86_epilogue (do_rtl) if (flag_pic || profile_flag || profile_block_flag) emit_insn (gen_blockage ()); - if (nregs > 1 || ! frame_pointer_needed) + /* If we're only restoring one register and sp is not valid then + using a move instruction to restore the register since it's + less work than reloading sp and popping the register. Otherwise, + restore sp (if necessary) and pop the registers. */ + + limit = frame_pointer_needed + ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM; + + if (nregs > 1 || sp_valid) { - if (frame_pointer_needed) + if ( !sp_valid ) { xops[0] = adj_offsettable_operand (AT_BP (QImode), offset); if (do_rtl) @@ -2504,6 +2299,37 @@ do { \ } while (0) int +legitimate_pic_address_disp_p (disp) + register rtx disp; +{ + if (GET_CODE (disp) != CONST) + return 0; + disp = XEXP (disp, 0); + + if (GET_CODE (disp) == PLUS) + { + if (GET_CODE (XEXP (disp, 1)) != CONST_INT) + return 0; + disp = XEXP (disp, 0); + } + + if (GET_CODE (disp) != UNSPEC + || XVECLEN (disp, 0) != 1) + return 0; + + /* Must be @GOT or @GOTOFF. */ + if (XINT (disp, 1) != 6 + && XINT (disp, 1) != 7) + return 0; + + if (GET_CODE (XVECEXP (disp, 0, 0)) != SYMBOL_REF + && GET_CODE (XVECEXP (disp, 0, 0)) != LABEL_REF) + return 0; + + return 1; +} + +int legitimate_address_p (mode, addr, strict) enum machine_mode mode; register rtx addr; @@ -2524,7 +2350,7 @@ legitimate_address_p (mode, addr, strict) } if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG) - base = addr; + base = addr; else if (GET_CODE (addr) == PLUS) { @@ -2614,6 +2440,12 @@ legitimate_address_p (mode, addr, strict) return FALSE; } + if (GET_MODE (base) != Pmode) + { + ADDR_INVALID ("Base is not in Pmode.\n", base); + return FALSE; + } + if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base)) || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base))) { @@ -2635,6 +2467,12 @@ legitimate_address_p (mode, addr, strict) return FALSE; } + if (GET_MODE (indx) != Pmode) + { + ADDR_INVALID ("Index is not in Pmode.\n", indx); + return FALSE; + } + if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (indx)) || (! strict && ! REG_OK_FOR_INDEX_NONSTRICT_P (indx))) { @@ -2664,20 +2502,10 @@ legitimate_address_p (mode, addr, strict) } } - /* Validate displacement - Constant pool addresses must be handled special. They are - considered legitimate addresses, but only if not used with regs. - When printed, the output routines know to print the reference with the - PIC reg, even though the PIC reg doesn't appear in the RTL. */ + /* Validate displacement. */ if (disp) { - if (GET_CODE (disp) == SYMBOL_REF - && CONSTANT_POOL_ADDRESS_P (disp) - && base == 0 - && indx == 0) - ; - - else if (!CONSTANT_ADDRESS_P (disp)) + if (!CONSTANT_ADDRESS_P (disp)) { ADDR_INVALID ("Displacement is not valid.\n", disp); return FALSE; @@ -2689,20 +2517,32 @@ legitimate_address_p (mode, addr, strict) return FALSE; } - else if (flag_pic && SYMBOLIC_CONST (disp) - && base != pic_offset_table_rtx - && (indx != pic_offset_table_rtx || scale != NULL_RTX)) + if (flag_pic && SYMBOLIC_CONST (disp)) { - ADDR_INVALID ("Displacement is an invalid pic reference.\n", disp); - return FALSE; + if (! legitimate_pic_address_disp_p (disp)) + { + ADDR_INVALID ("Displacement is an invalid PIC construct.\n", + disp); + return FALSE; + } + + if (base != pic_offset_table_rtx + && (indx != pic_offset_table_rtx || scale != NULL_RTX)) + { + ADDR_INVALID ("PIC displacement against invalid base.\n", disp); + return FALSE; + } } - else if (HALF_PIC_P () && HALF_PIC_ADDRESS_P (disp) - && (base != NULL_RTX || indx != NULL_RTX)) + else if (HALF_PIC_P ()) { - ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", - disp); - return FALSE; + if (! HALF_PIC_ADDRESS_P (disp) + || (base != NULL_RTX || indx != NULL_RTX)) + { + ADDR_INVALID ("Displacement is an invalid half-pic reference.\n", + disp); + return FALSE; + } } } @@ -2716,29 +2556,20 @@ legitimate_address_p (mode, addr, strict) /* Return a legitimate reference for ORIG (an address) using the register REG. If REG is 0, a new pseudo is generated. - There are three types of references that must be handled: + There are two types of references that must be handled: 1. Global data references must load the address from the GOT, via the PIC reg. An insn is emitted to do this load, and the reg is returned. - 2. Static data references must compute the address as an offset - from the GOT, whose base is in the PIC reg. An insn is emitted to - compute the address into a reg, and the reg is returned. Static - data objects have SYMBOL_REF_FLAG set to differentiate them from - global data objects. - - 3. Constant pool addresses must be handled special. They are - considered legitimate addresses, but only if not used with regs. - When printed, the output routines know to print the reference with the - PIC reg, even though the PIC reg doesn't appear in the RTL. + 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 + differentiate them from global data objects. The returned + address is the PIC reg + an unspec constant. GO_IF_LEGITIMATE_ADDRESS rejects symbolic references unless the PIC - reg also appears in the address (except for constant pool references, - noted above). - - "switch" statements also require special handling when generating - PIC code. See comments by the `casesi' insn in i386.md for details. */ + reg also appears in the address. */ rtx legitimize_pic_address (orig, reg) @@ -2747,60 +2578,99 @@ legitimize_pic_address (orig, reg) { rtx addr = orig; rtx new = orig; + rtx base; - if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF) + if (GET_CODE (addr) == LABEL_REF + || (GET_CODE (addr) == SYMBOL_REF + && (CONSTANT_POOL_ADDRESS_P (addr) + || SYMBOL_REF_FLAG (addr)))) { - if (GET_CODE (addr) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (addr)) - reg = new = orig; - else - { - if (reg == 0) - reg = gen_reg_rtx (Pmode); + /* This symbol may be referenced via a displacement from the PIC + base address (@GOTOFF). */ - if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FLAG (addr)) - || GET_CODE (addr) == LABEL_REF) - new = gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig); - else - new = gen_rtx_MEM (Pmode, - gen_rtx (PLUS, Pmode, pic_offset_table_rtx, orig)); + current_function_uses_pic_offset_table = 1; + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 7); + new = gen_rtx_CONST (VOIDmode, new); + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); + if (reg != 0) + { emit_move_insn (reg, new); + new = reg; } - current_function_uses_pic_offset_table = 1; - return reg; } - - else if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS) + else if (GET_CODE (addr) == SYMBOL_REF) { - rtx base; + /* This symbol must be referenced via a load from the + Global Offset Table (@GOT). */ + + current_function_uses_pic_offset_table = 1; + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, addr), 6); + new = gen_rtx_CONST (VOIDmode, new); + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); + new = gen_rtx_MEM (Pmode, new); + RTX_UNCHANGING_P (new) = 1; + if (reg == 0) + reg = gen_reg_rtx (Pmode); + emit_move_insn (reg, new); + new = reg; + } + else + { if (GET_CODE (addr) == CONST) { addr = XEXP (addr, 0); - if (GET_CODE (addr) != PLUS) - abort (); + if (GET_CODE (addr) == UNSPEC) + { + /* Check that the unspec is one of the ones we generate? */ + } + else if (GET_CODE (addr) != PLUS) + abort(); } + if (GET_CODE (addr) == PLUS) + { + rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1); + + /* Check first to see if this is a constant offset from a @GOTOFF + symbol reference. */ + if ((GET_CODE (op0) == LABEL_REF + || (GET_CODE (op0) == SYMBOL_REF + && (CONSTANT_POOL_ADDRESS_P (op0) + || SYMBOL_REF_FLAG (op0)))) + && GET_CODE (op1) == CONST_INT) + { + current_function_uses_pic_offset_table = 1; + new = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, op0), 7); + new = gen_rtx_PLUS (VOIDmode, new, op1); + new = gen_rtx_CONST (VOIDmode, new); + new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new); - if (XEXP (addr, 0) == pic_offset_table_rtx) - return orig; - - if (reg == 0) - reg = gen_reg_rtx (Pmode); - - base = legitimize_pic_address (XEXP (addr, 0), reg); - addr = legitimize_pic_address (XEXP (addr, 1), - base == reg ? NULL_RTX : reg); - - if (GET_CODE (addr) == CONST_INT) - return plus_constant (base, INTVAL (addr)); + if (reg != 0) + { + emit_move_insn (reg, new); + new = reg; + } + } + else + { + base = legitimize_pic_address (XEXP (addr, 0), reg); + new = legitimize_pic_address (XEXP (addr, 1), + base == reg ? NULL_RTX : reg); - if (GET_CODE (addr) == PLUS && CONSTANT_P (XEXP (addr, 1))) - { - base = gen_rtx (PLUS, Pmode, base, XEXP (addr, 0)); - addr = XEXP (addr, 1); + if (GET_CODE (new) == CONST_INT) + new = plus_constant (base, INTVAL (new)); + else + { + if (GET_CODE (new) == PLUS && CONSTANT_P (XEXP (new, 1))) + { + base = gen_rtx_PLUS (Pmode, base, XEXP (new, 0)); + new = XEXP (new, 1); + } + new = gen_rtx_PLUS (Pmode, base, new); + } + } } - - return gen_rtx (PLUS, Pmode, base, addr); } return new; } @@ -2815,7 +2685,7 @@ emit_pic_move (operands, mode) rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])) - operands[1] = force_reg (SImode, operands[1]); + operands[1] = force_reg (Pmode, operands[1]); else operands[1] = legitimize_pic_address (operands[1], temp); } @@ -2866,8 +2736,8 @@ legitimize_address (x, oldx, mode) && (log = (unsigned)exact_log2 (INTVAL (XEXP (x, 1)))) < 4) { changed = 1; - x = gen_rtx (MULT, Pmode, force_reg (Pmode, XEXP (x, 0)), - GEN_INT (1 << log)); + x = gen_rtx_MULT (Pmode, force_reg (Pmode, XEXP (x, 0)), + GEN_INT (1 << log)); } if (GET_CODE (x) == PLUS) @@ -3028,31 +2898,14 @@ output_pic_addr_const (file, x, code) break; case SYMBOL_REF: - case LABEL_REF: - if (GET_CODE (x) == SYMBOL_REF) - assemble_name (file, XSTR (x, 0)); - else - { - ASM_GENERATE_INTERNAL_LABEL (buf, "L", - CODE_LABEL_NUMBER (XEXP (x, 0))); - assemble_name (asm_out_file, buf); - } - - if (code == 'X') - ; /* No suffix, dammit. */ - else if (GET_CODE (x) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (x)) - fprintf (file, "@GOTOFF(%%ebx)"); - else if (code == 'P') - fprintf (file, "@PLT"); - else if (GET_CODE (x) == LABEL_REF) - fprintf (file, "@GOTOFF"); - else if (! SYMBOL_REF_FLAG (x)) - fprintf (file, "@GOT"); - else - fprintf (file, "@GOTOFF"); - + assemble_name (file, XSTR (x, 0)); + if (code == 'P' && ! SYMBOL_REF_FLAG (x)) + fputs ("@PLT", file); break; + case LABEL_REF: + x = XEXP (x, 0); + /* FALLTHRU */ case CODE_LABEL: ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x)); assemble_name (asm_out_file, buf); @@ -3090,17 +2943,17 @@ output_pic_addr_const (file, x, code) if (GET_CODE (XEXP (x, 0)) == CONST_INT) { output_pic_addr_const (file, XEXP (x, 0), code); - if (INTVAL (XEXP (x, 1)) >= 0) - fprintf (file, "+"); + fprintf (file, "+"); output_pic_addr_const (file, XEXP (x, 1), code); } - else + else if (GET_CODE (XEXP (x, 1)) == CONST_INT) { output_pic_addr_const (file, XEXP (x, 1), code); - if (INTVAL (XEXP (x, 0)) >= 0) - fprintf (file, "+"); + fprintf (file, "+"); output_pic_addr_const (file, XEXP (x, 0), code); } + else + abort (); break; case MINUS: @@ -3109,11 +2962,141 @@ output_pic_addr_const (file, x, code) output_pic_addr_const (file, XEXP (x, 1), code); break; + case UNSPEC: + if (XVECLEN (x, 0) != 1) + abort (); + output_pic_addr_const (file, XVECEXP (x, 0, 0), code); + switch (XINT (x, 1)) + { + case 6: + fputs ("@GOT", file); + break; + case 7: + fputs ("@GOTOFF", file); + break; + case 8: + fputs ("@PLT", file); + break; + default: + output_operand_lossage ("invalid UNSPEC as operand"); + break; + } + break; + default: output_operand_lossage ("invalid expression as operand"); } } +static void +put_jump_code (code, reverse, file) + enum rtx_code code; + int reverse; + FILE *file; +{ + int flags = cc_prev_status.flags; + int ieee = (TARGET_IEEE_FP && (flags & CC_IN_80387) + && !(cc_prev_status.flags & CC_FCOMI)); + const char *suffix; + + if (flags & CC_Z_IN_NOT_C) + switch (code) + { + case EQ: + fputs (reverse ? "c" : "nc", file); + return; + + case NE: + fputs (reverse ? "nc" : "c", file); + return; + + default: + abort (); + } + if (ieee) + { + switch (code) + { + case LE: + suffix = reverse ? "ae" : "b"; + break; + case GT: + case LT: + case GE: + suffix = reverse ? "ne" : "e"; + break; + case EQ: + suffix = reverse ? "ne" : "e"; + break; + case NE: + suffix = reverse ? "e" : "ne"; + break; + default: + abort (); + } + fputs (suffix, file); + return; + } + if (flags & CC_TEST_AX) + abort(); + if ((flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + abort (); + if (reverse) + code = reverse_condition (code); + switch (code) + { + case EQ: + suffix = "e"; + break; + + case NE: + suffix = "ne"; + break; + + case GT: + suffix = flags & CC_IN_80387 ? "a" : "g"; + break; + + case GTU: + suffix = "a"; + break; + + case LT: + if (flags & CC_NO_OVERFLOW) + suffix = "s"; + else + suffix = flags & CC_IN_80387 ? "b" : "l"; + break; + + case LTU: + suffix = "b"; + break; + + case GE: + if (flags & CC_NO_OVERFLOW) + suffix = "ns"; + else + suffix = flags & CC_IN_80387 ? "ae" : "ge"; + break; + + case GEU: + suffix = "ae"; + break; + + case LE: + suffix = flags & CC_IN_80387 ? "be" : "le"; + break; + + case LEU: + suffix = "be"; + break; + + default: + abort (); + } + fputs (suffix, file); +} + /* Append the correct conditional move suffix which corresponds to CODE. */ static void @@ -3230,12 +3213,13 @@ put_condition_code (code, reverse_cc, mode, file) C -- print opcode suffix for set/cmov insn. c -- like C, but print reversed condition F -- print opcode suffix for fcmov insn. - f -- like C, but print reversed condition + f -- like F, but print reversed condition + D -- print the opcode suffix for a jump + d -- like D, but print reversed condition R -- print the prefix for register names. z -- print the opcode suffix for the size of the current operand. * -- print a star (in certain assembler syntax) w -- print the operand as if it's a "word" (HImode) even if it isn't. - c -- don't print special prefixes before constant operands. J -- print the appropriate jump operand. s -- print a shift double count, followed by the assemblers argument delimiter. @@ -3245,7 +3229,8 @@ put_condition_code (code, reverse_cc, mode, file) k -- likewise, print the SImode name of the register. h -- print the QImode name for a "high" register, either ah, bh, ch or dh. y -- print "st(0)" instead of "st" as a register. - P -- print as a PIC constant */ + P -- print as a PIC constant + _ -- output "_" if YES_UNDERSCORES */ void print_operand (file, x, code) @@ -3262,6 +3247,12 @@ print_operand (file, x, code) putc ('*', file); return; + case '_': +#ifdef YES_UNDERSCORES + putc ('_', file); +#endif + return; + case 'L': PUT_OP_SIZE (code, 'l', file); return; @@ -3296,12 +3287,10 @@ print_operand (file, x, code) /* this is the size of op from size of operand */ switch (GET_MODE_SIZE (GET_MODE (x))) { - case 1: - PUT_OP_SIZE ('B', 'b', file); - return; - case 2: - PUT_OP_SIZE ('W', 'w', file); +#ifdef HAVE_GAS_FILDS_FISTS + PUT_OP_SIZE ('W', 's', file); +#endif return; case 4: @@ -3331,6 +3320,9 @@ print_operand (file, x, code) PUT_OP_SIZE ('Q', 'l', file); return; + + default: + abort (); } case 'b': @@ -3373,6 +3365,14 @@ print_operand (file, x, code) return; + case 'D': + put_jump_code (GET_CODE (x), 0, file); + return; + + case 'd': + put_jump_code (GET_CODE (x), 1, file); + return; + /* This is used by the conditional move instructions. */ case 'C': put_condition_code (GET_CODE (x), 0, MODE_INT, file); @@ -3481,6 +3481,11 @@ print_operand_address (file, addr) switch (GET_CODE (addr)) { case REG: + /* ESI addressing makes instruction vector decoded on the K6. We can + avoid this by ESI+0 addressing. */ + if (REGNO_REG_CLASS (REGNO (addr)) == SIREG + && ix86_cpu == PROCESSOR_K6 && !optimize_size) + output_addr_const (file, const0_rtx); ADDR_BEG (file); fprintf (file, "%se", RP); fputs (hi_reg_name[REGNO (addr)], file); @@ -3596,8 +3601,16 @@ print_operand_address (file, addr) ireg = XEXP (addr, 0); } - output_addr_const (file, const0_rtx); - PRINT_B_I_S (NULL_RTX, ireg, scale, file); + /* (reg,reg,) is shorter than (,reg,2). */ + if (scale == 2) + { + PRINT_B_I_S (ireg, ireg, 1, file); + } + else + { + output_addr_const (file, const0_rtx); + PRINT_B_I_S (NULL_RTX, ireg, scale, file); + } } break; @@ -3646,8 +3659,7 @@ notice_update_cc (exp) if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM || GET_RTX_CLASS (GET_CODE (SET_SRC (exp))) == '<' - || (GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE - && GET_MODE_CLASS (GET_MODE (SET_DEST (exp))) == MODE_INT))) + || GET_CODE (SET_SRC (exp)) == IF_THEN_ELSE)) { if (cc_status.value1 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1)) @@ -3749,7 +3761,7 @@ notice_update_cc (exp) if (stack_regs_mentioned_p (SET_SRC (XVECEXP (exp, 0, 0)))) { cc_status.flags |= CC_IN_80387; - if (0 && TARGET_CMOVE && stack_regs_mentioned_p + if (TARGET_CMOVE && stack_regs_mentioned_p (XEXP (SET_SRC (XVECEXP (exp, 0, 0)), 1))) cc_status.flags |= CC_FCOMI; } @@ -3781,7 +3793,12 @@ split_di (operands, num, lo_half, hi_half) while (num--) { rtx op = operands[num]; - if (GET_CODE (op) == REG) + if (! reload_completed) + { + lo_half[num] = gen_lowpart (SImode, op); + hi_half[num] = gen_highpart (SImode, op); + } + else if (GET_CODE (op) == REG) { lo_half[num] = gen_rtx_REG (SImode, REGNO (op)); hi_half[num] = gen_rtx_REG (SImode, REGNO (op) + 1); @@ -3879,35 +3896,19 @@ output_387_binary_op (insn, operands) switch (GET_CODE (operands[3])) { case PLUS: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fiadd"; - else - base_op = "fadd"; + base_op = "fadd"; break; case MINUS: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fisub"; - else - base_op = "fsub"; + base_op = "fsub"; break; case MULT: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fimul"; - else - base_op = "fmul"; + base_op = "fmul"; break; case DIV: - if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT - || GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT) - base_op = "fidiv"; - else - base_op = "fdiv"; + base_op = "fdiv"; break; default: @@ -3930,17 +3931,8 @@ output_387_binary_op (insn, operands) if (GET_CODE (operands[2]) == MEM) return strcat (buf, AS1 (%z2,%2)); - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1))); - return ""; - } - - else if (NON_STACK_REG_P (operands[2])) - { - output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1))); - return ""; - } + if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2])) + abort (); if (find_regno_note (insn, REG_DEAD, REGNO (operands[2]))) { @@ -3963,18 +3955,6 @@ output_387_binary_op (insn, operands) if (GET_CODE (operands[2]) == MEM) return strcat (buf, AS1 (%z2,%2)); - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], strcat (buf, AS1 (r%z0,%1))); - return ""; - } - - else if (NON_STACK_REG_P (operands[2])) - { - output_op_from_reg (operands[2], strcat (buf, AS1 (%z0,%1))); - return ""; - } - if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2])) abort (); @@ -4012,10 +3992,10 @@ output_387_binary_op (insn, operands) } /* Output code for INSN to convert a float to a signed int. OPERANDS - are the insn operands. The output may be SFmode or DFmode and the - input operand may be SImode or DImode. As a special case, make sure - that the 387 stack top dies if the output mode is DImode, because the - hardware requires this. */ + are the insn operands. The input may be SFmode, DFmode, or XFmode + and the output operand may be SImode or DImode. As a special case, + make sure that the 387 stack top dies if the output mode is DImode, + because the hardware requires this. */ char * output_fix_trunc (insn, operands) @@ -4028,40 +4008,98 @@ output_fix_trunc (insn, operands) if (! STACK_TOP_P (operands[1])) abort (); - xops[0] = GEN_INT (12); - xops[1] = operands[4]; + if (GET_MODE (operands[0]) == DImode && ! stack_top_dies) + abort (); + + xops[0] = GEN_INT (0x0c00); + xops[1] = operands[5]; output_asm_insn (AS1 (fnstc%W2,%2), operands); - output_asm_insn (AS2 (mov%L2,%2,%4), operands); - output_asm_insn (AS2 (mov%B1,%0,%h1), xops); - output_asm_insn (AS2 (mov%L4,%4,%3), operands); + output_asm_insn (AS2 (mov%W5,%2,%w5), operands); + output_asm_insn (AS2 (or%W1,%0,%w1), xops); + output_asm_insn (AS2 (mov%W3,%w5,%3), operands); output_asm_insn (AS1 (fldc%W3,%3), operands); + xops[0] = NON_STACK_REG_P (operands[0]) ? operands[4] : operands[0]; + + if (stack_top_dies) + output_asm_insn (AS1 (fistp%z0,%y0), xops); + else + output_asm_insn (AS1 (fist%z0,%y0), xops); + if (NON_STACK_REG_P (operands[0])) - output_to_reg (operands[0], stack_top_dies, operands[3]); + { + if (GET_MODE (operands[0]) == SImode) + output_asm_insn (AS2 (mov%L0,%4,%0), operands); + else + { + xops[0] = operands[0]; + xops[1] = operands[4]; + output_asm_insn (output_move_double (xops), xops); + } + } - else if (GET_CODE (operands[0]) == MEM) + return AS1 (fldc%W2,%2); +} + +/* Output code for INSN to extend a float. OPERANDS are the insn + operands. The output may be DFmode or XFmode and the input operand + may be SFmode or DFmode. Operands 2 and 3 are scratch memory and + are only necessary if operands 0 or 1 are non-stack registers. */ + +void +output_float_extend (insn, operands) + rtx insn; + rtx *operands; +{ + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[2]; + + if (! STACK_TOP_P (operands[0]) && ! STACK_TOP_P (operands[1])) + abort (); + + if (STACK_TOP_P (operands[0]) && STACK_TOP_P (operands[1]) && stack_top_dies) + return; + + if (STACK_TOP_P (operands[0]) ) { - if (stack_top_dies) - output_asm_insn (AS1 (fistp%z0,%0), operands); - else if (GET_MODE (operands[0]) == DImode && ! stack_top_dies) + if (NON_STACK_REG_P (operands[1])) { - /* There is no DImode version of this without a stack pop, so - we must emulate it. It doesn't matter much what the second - instruction is, because the value being pushed on the FP stack - is not used except for the following stack popping store. - This case can only happen without optimization, so it doesn't - matter that it is inefficient. */ - output_asm_insn (AS1 (fistp%z0,%0), operands); - output_asm_insn (AS1 (fild%z0,%0), operands); + if (GET_MODE (operands[1]) == SFmode) + output_asm_insn (AS2 (mov%L0,%1,%2), operands); + else + { + xops[0] = operands[2]; + xops[1] = operands[1]; + output_asm_insn (output_move_double (xops), xops); + } } - else - output_asm_insn (AS1 (fist%z0,%0), operands); + + xops[0] = NON_STACK_REG_P (operands[1]) ? operands[2] : operands[1]; + + output_asm_insn (AS1 (fld%z0,%y0), xops); } else - abort (); + { + xops[0] = NON_STACK_REG_P (operands[0]) ? operands[3] : operands[0]; - return AS1 (fldc%W2,%2); + if (stack_top_dies + || (GET_CODE (xops[0]) == MEM && GET_MODE (xops[0]) == XFmode)) + { + output_asm_insn (AS1 (fstp%z0,%y0), xops); + if (! stack_top_dies) + output_asm_insn (AS1 (fld%z0,%y0), xops); + } + else + output_asm_insn (AS1 (fst%z0,%y0), xops); + + if (NON_STACK_REG_P (operands[0])) + { + xops[0] = operands[0]; + xops[1] = operands[3]; + output_asm_insn (output_move_double (xops), xops); + } + } } /* Output code for INSN to compare OPERANDS. The two operands might @@ -4078,8 +4116,11 @@ output_float_compare (insn, operands) rtx body = XVECEXP (PATTERN (insn), 0, 0); int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode; rtx tmp; + int cc0_set = 1; + int i; - if (0 && TARGET_CMOVE && STACK_REG_P (operands[1])) + if (TARGET_CMOVE && STACK_REG_P (operands[1]) + && STACK_REG_P (operands[0])) { cc_status.flags |= CC_FCOMI; cc_prev_status.flags &= ~CC_TEST_AX; @@ -4101,7 +4142,7 @@ output_float_compare (insn, operands) if (STACK_REG_P (operands[1]) && stack_top_dies && find_regno_note (insn, REG_DEAD, REGNO (operands[1])) - && REGNO (operands[1]) != FIRST_STACK_REG) + && REGNO (operands[1]) == FIRST_STACK_REG + 1) { /* If both the top of the 387 stack dies, and the other operand is also a stack register that dies, then this must be a @@ -4113,7 +4154,8 @@ output_float_compare (insn, operands) { output_asm_insn (AS2 (fucomip,%y1,%0), operands); output_asm_insn (AS1 (fstp, %y0), operands); - return ""; + if (!TARGET_IEEE_FP) + cc0_set = 0; } else output_asm_insn ("fucompp", operands); @@ -4124,7 +4166,8 @@ output_float_compare (insn, operands) { output_asm_insn (AS2 (fcomip, %y1,%0), operands); output_asm_insn (AS1 (fstp, %y0), operands); - return ""; + if (!TARGET_IEEE_FP) + cc0_set = 0; } else output_asm_insn ("fcompp", operands); @@ -4134,35 +4177,55 @@ output_float_compare (insn, operands) { static char buf[100]; - /* Decide if this is the integer or float compare opcode, or the - unordered float compare. */ + /* Decide if this is a float compare or an unordered float compare. */ if (unordered_compare) strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fucomi" : "fucom"); - else if (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_FLOAT) - strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom"); else - strcpy (buf, "ficom"); + strcpy (buf, (cc_status.flags & CC_FCOMI) ? "fcomi" : "fcom"); /* Modify the opcode if the 387 stack is to be popped. */ if (stack_top_dies) strcat (buf, "p"); - if (NON_STACK_REG_P (operands[1])) - output_op_from_reg (operands[1], strcat (buf, AS1 (%z0,%1))); - else if (cc_status.flags & CC_FCOMI) + if (cc_status.flags & CC_FCOMI) { output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands); - return ""; + if (!TARGET_IEEE_FP) + cc0_set = 0; } else output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands); } /* Now retrieve the condition code. */ + if (cc0_set) + { + char *r = output_fp_cc0_set (insn); + if (r[0]) output_asm_insn (r, operands); + } + + + /* We emit fstp instruction after integer comparsions to improve + scheduling. */ + for (i = 0; i < 2 ; i++) + { + if (STACK_REG_P (operands[i]) + && find_regno_note (insn, REG_DEAD, REGNO (operands[i])) + && REGNO (operands[i]) != FIRST_STACK_REG + && (!stack_top_dies || REGNO (operands[i]) != FIRST_STACK_REG + 1)) + { + rtx xexp[2]; + xexp[0] = gen_rtx_REG (DFmode, + REGNO (operands[i]) - (stack_top_dies != 0)); + output_asm_insn (AS1 (fstp, %y0), xexp); + } + } + + return ""; + - return output_fp_cc0_set (insn); } /* Output opcodes to transfer the results of FP compare or test INSN @@ -4178,17 +4241,19 @@ output_fp_cc0_set (insn) rtx next; enum rtx_code code; - xops[0] = gen_rtx_REG (HImode, 0); - output_asm_insn (AS1 (fnsts%W0,%0), xops); + if (!(cc_status.flags & CC_FCOMI)) + { + xops[0] = gen_rtx_REG (HImode, 0); + output_asm_insn (AS1 (fnsts%W0,%0), xops); + } if (! TARGET_IEEE_FP) { if (!(cc_status.flags & CC_REVERSED)) { next = next_cc0_user (insn); - - if (GET_CODE (next) == JUMP_INSN - && GET_CODE (PATTERN (next)) == SET + + if (GET_CODE (PATTERN (next)) == SET && SET_DEST (PATTERN (next)) == pc_rtx && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE) code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)); @@ -4213,8 +4278,7 @@ output_fp_cc0_set (insn) if (next == NULL_RTX) abort (); - if (GET_CODE (next) == JUMP_INSN - && GET_CODE (PATTERN (next)) == SET + if (GET_CODE (PATTERN (next)) == SET && SET_DEST (PATTERN (next)) == pc_rtx && GET_CODE (SET_SRC (PATTERN (next))) == IF_THEN_ELSE) code = GET_CODE (XEXP (SET_SRC (PATTERN (next)), 0)); @@ -4237,61 +4301,103 @@ output_fp_cc0_set (insn) else abort (); - xops[0] = gen_rtx_REG (QImode, 0); + if (cc_status.flags & CC_FCOMI) + { + /* It is very tricky. We have to do it right. */ + + xops [0] = gen_rtx_REG (QImode, 0); - switch (code) + switch (code) + { + case GT: + case GE: + break; + + case LT: + output_asm_insn (AS1 (setb,%b0), xops); + output_asm_insn (AS1 (setp,%h0), xops); + output_asm_insn (AS2 (cmp%B0,%b0,%h0), xops); + break; + + case LE: + output_asm_insn (AS1 (setbe,%b0), xops); + output_asm_insn (AS1 (setnp,%h0), xops); + output_asm_insn (AS2 (xor%B0,%b0,%h0), xops); + break; + + case EQ: + case NE: + output_asm_insn (AS1 (setne,%b0), xops); + output_asm_insn (AS1 (setp,%h0), xops); + output_asm_insn (AS2 (or%B0,%b0,%h0), xops); + break; + + case GTU: + case LTU: + case GEU: + case LEU: + default: + abort (); + } + } + else { - case GT: - xops[1] = GEN_INT (0x45); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - /* je label */ - break; + xops[0] = gen_rtx_REG (QImode, 0); - case LT: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x01); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* je label */ - break; + switch (code) + { + case GT: + xops[1] = GEN_INT (0x45); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + /* je label */ + break; - case GE: - xops[1] = GEN_INT (0x05); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - /* je label */ - break; + case LT: + xops[1] = GEN_INT (0x45); + xops[2] = GEN_INT (0x01); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); + /* je label */ + break; - case LE: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS1 (dec%B0,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* jb label */ - break; + case GE: + xops[1] = GEN_INT (0x05); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + /* je label */ + break; - case EQ: - xops[1] = GEN_INT (0x45); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); - /* je label */ - break; + case LE: + xops[1] = GEN_INT (0x45); + xops[2] = GEN_INT (0x40); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + output_asm_insn (AS1 (dec%B0,%h0), xops); + output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); + /* jb label */ + break; - case NE: - xops[1] = GEN_INT (0x44); - xops[2] = GEN_INT (0x40); - output_asm_insn (AS2 (and%B0,%1,%h0), xops); - output_asm_insn (AS2 (xor%B0,%2,%h0), xops); - /* jne label */ - break; + case EQ: + xops[1] = GEN_INT (0x45); + xops[2] = GEN_INT (0x40); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + output_asm_insn (AS2 (cmp%B0,%2,%h0), xops); + /* je label */ + break; - case GTU: - case LTU: - case GEU: - case LEU: - default: - abort (); + case NE: + xops[1] = GEN_INT (0x44); + xops[2] = GEN_INT (0x40); + output_asm_insn (AS2 (and%B0,%1,%h0), xops); + output_asm_insn (AS2 (xor%B0,%2,%h0), xops); + /* jne label */ + break; + + case GTU: + case LTU: + case GEU: + case LEU: + default: + abort (); + } } return ""; @@ -4927,16 +5033,36 @@ int agi_dependent (insn, dep_insn) rtx insn, dep_insn; { + int push = 0, push_dep = 0; if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET - && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG) - return reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn); + && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG + && reg_mentioned_in_mem (SET_DEST (PATTERN (dep_insn)), insn)) + return 1; + + if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET + && GET_CODE (SET_DEST (PATTERN (insn))) == MEM + && push_operand (SET_DEST (PATTERN (insn)), + GET_MODE (SET_DEST (PATTERN (insn))))) + push = 1; if (GET_CODE (dep_insn) == INSN && GET_CODE (PATTERN (dep_insn)) == SET && GET_CODE (SET_DEST (PATTERN (dep_insn))) == MEM && push_operand (SET_DEST (PATTERN (dep_insn)), GET_MODE (SET_DEST (PATTERN (dep_insn))))) - return reg_mentioned_in_mem (stack_pointer_rtx, insn); + push_dep = 1; + + /* CPUs contain special hardware to allow two pushes. */ + if (push && push_dep) + return 0; + + /* Push operation implicitly change stack pointer causing AGI stalls. */ + if (push_dep && reg_mentioned_in_mem (stack_pointer_rtx, insn)) + return 1; + + /* Push also implicitly read stack pointer. */ + if (push && modified_in_p (stack_pointer_rtx, dep_insn)) + return 1; return 0; } @@ -5196,6 +5322,13 @@ output_fp_conditional_move (which_alternative, operands) int which_alternative; rtx operands[]; { + enum rtx_code code = GET_CODE (operands[1]); + + /* This should never happen. */ + if (!(cc_prev_status.flags & CC_IN_80387) + && (code == GT || code == LE || code == GE || code == LT)) + abort (); + switch (which_alternative) { case 0: @@ -5220,9 +5353,7 @@ output_int_conditional_move (which_alternative, operands) int which_alternative; rtx operands[]; { - int code = GET_CODE (operands[1]); - enum machine_mode mode; - rtx xops[4]; + enum rtx_code code = GET_CODE (operands[1]); /* This is very tricky. We have to do it right. For a code segement like: @@ -5242,29 +5373,16 @@ output_int_conditional_move (which_alternative, operands) && (cc_prev_status.flags & CC_NO_OVERFLOW)) return NULL_PTR; - mode = GET_MODE (operands [0]); - if (mode == DImode) - { - xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1); - xops [1] = operands [1]; - xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1); - xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1); - } - switch (which_alternative) { case 0: /* r <- cond ? arg : r */ output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - if (mode == DImode) - output_asm_insn (AS2 (cmov%C1,%2,%0), xops); break; case 1: /* r <- cond ? r : arg */ output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - if (mode == DImode) - output_asm_insn (AS2 (cmov%c1,%3,%0), xops); break; default: @@ -5273,3 +5391,346 @@ output_int_conditional_move (which_alternative, operands) return ""; } + +int +x86_adjust_cost (insn, link, dep_insn, cost) + rtx insn, link, dep_insn; + int cost; +{ + rtx next_inst; + + if (GET_CODE (dep_insn) == CALL_INSN || GET_CODE (insn) == JUMP_INSN) + return 0; + + if (GET_CODE (dep_insn) == INSN + && GET_CODE (PATTERN (dep_insn)) == SET + && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG + && GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SET + && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)), + SET_SRC (PATTERN (insn)))) + return 0; /* ??? */ + + + switch (ix86_cpu) + { + case PROCESSOR_PENTIUM: + if (cost != 0 && is_fp_insn (insn) && is_fp_insn (dep_insn) + && !is_fp_dest (dep_insn)) + return 0; + + if (agi_dependent (insn, dep_insn)) + return cost ? cost + 1 : 2; + + if (GET_CODE (insn) == INSN + && GET_CODE (PATTERN (insn)) == SET + && SET_DEST (PATTERN (insn)) == cc0_rtx + && (next_inst = next_nonnote_insn (insn)) + && GET_CODE (next_inst) == JUMP_INSN) + /* compare probably paired with jump */ + return 0; + + /* Stores stalls one cycle longer than other insns. */ + if (is_fp_insn (insn) && cost && is_fp_store (dep_insn)) + cost++; + break; + case PROCESSOR_K6: + default: + if (!is_fp_dest (dep_insn)) + { + if(!agi_dependent (insn, dep_insn)) + return 0; + if (TARGET_486) + return 2; + } + else + if (is_fp_store (insn) && is_fp_insn (dep_insn) + && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn)) + && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))) + && (GET_CODE (NEXT_INSN (insn)) == INSN) + && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN) + && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE) + && (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) + == NOTE_INSN_LOOP_END)) + return 3; + break; + } + + return cost; +} + +/* Output assembly code for a left shift. + + Always use "sal" when shifting a memory operand or for a non constant + shift count. + + When optimizing for size, we know that src == dest, and we should always + use "sal". If src != dest, then copy src to dest and use "sal". + + Pentium and PPro (speed): + + When src == dest, use "add" for a shift counts of one, else use + "sal". If we modeled Pentium AGI stalls and U/V pipelining better we + would want to generate lea for some shifts on the Pentium. + + When src != dest, use "lea" for small shift counts. Otherwise, + copy src to dest and use the normal shifting code. Exception for + TARGET_DOUBLE_WITH_ADD. */ + +char * +output_ashl (insn, operands) + rtx insn, *operands; +{ + /* Handle case where srcreg != dstreg. */ + if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) + { + if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1) + switch (GET_MODE (operands[0])) + { + case SImode: + output_asm_insn (AS2 (mov%L0,%1,%0), operands); + return AS2 (add%L0,%1,%0); + case HImode: + output_asm_insn (AS2 (mov%L0,%k1,%k0), operands); + if (i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS2 (add%L0,%k1,%k0); + } + return AS2 (add%W0,%k1,%k0); + case QImode: + output_asm_insn (AS2 (mov%B0,%1,%0), operands); + return AS2 (add%B0,%1,%0); + default: + abort (); + } + else + { + CC_STATUS_INIT; + + /* This should be extremely rare (impossible?). We can not encode a + shift of the stack pointer using an lea instruction. So copy the + stack pointer into the destination register and use an lea. */ + if (operands[1] == stack_pointer_rtx) + { + output_asm_insn (AS2 (mov%L0,%k1,%k0), operands); + operands[1] = operands[0]; + } + + /* For shifts up to and including 3 bits, use lea. */ + operands[1] = gen_rtx_MULT (SImode, + gen_rtx_REG (SImode, REGNO (operands[1])), + GEN_INT (1 << INTVAL (operands[2]))); + return AS2 (lea%L0,%a1,%k0); + } + } + + /* Source and destination match. */ + + /* Handle variable shift. */ + if (REG_P (operands[2])) + switch (GET_MODE (operands[0])) + { + case SImode: + return AS2 (sal%L0,%b2,%0); + case HImode: + if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS2 (sal%L0,%b2,%k0); + } + else + return AS2 (sal%W0,%b2,%0); + case QImode: + return AS2 (sal%B0,%b2,%0); + default: + abort (); + } + + /* Always perform shift by 1 using an add instruction. */ + if (REG_P (operands[0]) && operands[2] == const1_rtx) + switch (GET_MODE (operands[0])) + { + case SImode: + return AS2 (add%L0,%0,%0); + case HImode: + if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS2 (add%L0,%k0,%k0); + } + else + return AS2 (add%W0,%0,%0); + case QImode: + return AS2 (add%B0,%0,%0); + default: + abort (); + } + +#if 0 + /* ??? Currently disabled. Because our model of Pentium is far from being + exact, this change will need some benchmarking. */ + /* Shift reg by 2 or 3 use an lea instruction for Pentium if this is + insn is expected to issue into the V pipe (the insn's mode will be + TImode for a U pipe, and !TImode for a V pipe instruction). */ + if (! optimize_size + && REG_P (operands[0]) + && GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) <= 3 + && (int)ix86_cpu == (int)PROCESSOR_PENTIUM + && GET_MODE (insn) != TImode) + { + CC_STATUS_INIT; + operands[1] = gen_rtx_MULT (SImode, gen_rtx_REG (SImode, REGNO (operands[1])), + GEN_INT (1 << INTVAL (operands[2]))); + return AS2 (lea%L0,%a1,%0); + } +#endif + + /* Otherwise use a shift instruction. */ + switch (GET_MODE (operands[0])) + { + case SImode: + return AS2 (sal%L0,%2,%0); + case HImode: + if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS2 (sal%L0,%2,%k0); + } + else + return AS2 (sal%W0,%2,%0); + case QImode: + return AS2 (sal%B0,%2,%0); + default: + abort (); + } +} + +/* Given the memory address ADDR, calculate the length of the address or + the length of just the displacement (controlled by DISP_LENGTH). + + The length returned does not include the one-byte modrm, opcode, + or prefix. */ + +int +memory_address_info (addr, disp_length) + rtx addr; + int disp_length; +{ + rtx base, index, disp, scale; + rtx op0, op1; + int len; + + if (GET_CODE (addr) == PRE_DEC + || GET_CODE (addr) == POST_INC) + return 0; + + /* Register Indirect. */ + if (register_operand (addr, Pmode)) + { + /* Special cases: ebp and esp need the two-byte modrm form. + + We change [ESI] to [ESI+0] on the K6 when not optimizing + for size. */ + if (addr == stack_pointer_rtx + || addr == arg_pointer_rtx + || addr == frame_pointer_rtx + || (REGNO_REG_CLASS (REGNO (addr)) == SIREG + && ix86_cpu == PROCESSOR_K6 && !optimize_size)) + return 1; + else + return 0; + } + + /* Direct Addressing. */ + if (CONSTANT_P (addr)) + return 4; + + index = base = disp = scale = NULL_RTX; + op0 = XEXP (addr, 0); + op1 = XEXP (addr, 1); + + if (GET_CODE (addr) == PLUS) + { + if (register_operand (op0, Pmode)) + { + if (register_operand (op1, Pmode)) + index = op0, base = op1; + else + base = op0, disp = op1; + } + else if (GET_CODE (op0) == MULT) + { + index = XEXP (op0, 0); + scale = XEXP (op0, 1); + if (register_operand (op1, Pmode)) + base = op1; + else + disp = op1; + } + else if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 0)) == MULT) + { + index = XEXP (XEXP (op0, 0), 0); + scale = XEXP (XEXP (op0, 0), 1); + base = XEXP (op0, 1); + disp = op1; + } + else if (GET_CODE (op0) == PLUS) + { + index = XEXP (op0, 0); + base = XEXP (op0, 1); + disp = op1; + } + else + abort (); + } + else if (GET_CODE (addr) == MULT + /* We're called for lea too, which implements ashift on occasion. */ + || GET_CODE (addr) == ASHIFT) + { + index = XEXP (addr, 0); + scale = XEXP (addr, 1); + } + else + abort (); + + /* Allow arg pointer and stack pointer as index if there is not scaling */ + if (base && index && !scale + && (index == stack_pointer_rtx + || index == arg_pointer_rtx + || index == frame_pointer_rtx)) + { + rtx tmp = base; + base = index; + index = tmp; + } + + /* Special case: ebp cannot be encoded as a base without a displacement. */ + if (base == frame_pointer_rtx && !disp) + disp = const0_rtx; + + /* Scaling can not be encoded without base or displacement. + Except for scale == 1 where we can encode reg + reg instead of reg * 2. */ + if (!base && index + && (!scale || GET_CODE (scale) != CONST_INT || (INTVAL (scale) != 1))) + disp = const0_rtx; + + /* Find the length of the displacement constant. */ + len = 0; + if (disp) + { + if (GET_CODE (disp) == CONST_INT + && CONST_OK_FOR_LETTER_P (INTVAL (disp), 'K')) + len = 1; + else + len = 4; + } + + /* An index requires the two-byte modrm form. Not important + if we are computing just length of the displacement. */ + if (index && ! disp_length) + len += 1; + + return len; +} diff --git a/contrib/gcc/config/i386/i386.h b/contrib/gcc/config/i386/i386.h index b8fef11..5e27fd8 100644 --- a/contrib/gcc/config/i386/i386.h +++ b/contrib/gcc/config/i386/i386.h @@ -155,62 +155,67 @@ extern int target_flags; #define TARGET_486 (ix86_cpu == PROCESSOR_I486) #define TARGET_PENTIUM (ix86_cpu == PROCESSOR_PENTIUM) #define TARGET_PENTIUMPRO (ix86_cpu == PROCESSOR_PENTIUMPRO) -#define TARGET_USE_LEAVE (ix86_cpu == PROCESSOR_I386) -#define TARGET_PUSH_MEMORY (ix86_cpu == PROCESSOR_I386) -#define TARGET_ZERO_EXTEND_WITH_AND (ix86_cpu != PROCESSOR_I386 \ - && ix86_cpu != PROCESSOR_PENTIUMPRO) -#define TARGET_DOUBLE_WITH_ADD (ix86_cpu != PROCESSOR_I386) -#define TARGET_USE_BIT_TEST (ix86_cpu == PROCESSOR_I386) -#define TARGET_UNROLL_STRLEN (ix86_cpu != PROCESSOR_I386) -#define TARGET_USE_Q_REG (ix86_cpu == PROCESSOR_PENTIUM \ - || ix86_cpu == PROCESSOR_PENTIUMPRO) -#define TARGET_USE_ANY_REG (ix86_cpu == PROCESSOR_I486) -#define TARGET_CMOVE (ix86_arch == PROCESSOR_PENTIUMPRO) -#define TARGET_DEEP_BRANCH_PREDICTION (ix86_cpu == PROCESSOR_PENTIUMPRO) +#define TARGET_K6 (ix86_cpu == PROCESSOR_K6) + +#define CPUMASK (1 << ix86_cpu) +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_unroll_strlen, x86_use_q_reg, x86_use_any_reg; +extern const int x86_double_with_add; + +#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_Q_REG (x86_use_q_reg & CPUMASK) +#define TARGET_USE_ANY_REG (x86_use_any_reg & CPUMASK) +#define TARGET_CMOVE (x86_cmove & (1 << ix86_arch)) +#define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK) +#define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK) + #define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE) #define TARGET_SWITCHES \ -{ { "80387", MASK_80387 }, \ - { "no-80387", -MASK_80387 }, \ - { "hard-float", MASK_80387 }, \ - { "soft-float", -MASK_80387 }, \ - { "no-soft-float", MASK_80387 }, \ - { "386", 0 }, \ - { "no-386", 0 }, \ - { "486", 0 }, \ - { "no-486", 0 }, \ - { "pentium", 0 }, \ - { "pentiumpro", 0 }, \ - { "rtd", MASK_RTD }, \ - { "no-rtd", -MASK_RTD }, \ - { "align-double", MASK_ALIGN_DOUBLE }, \ - { "no-align-double", -MASK_ALIGN_DOUBLE }, \ - { "svr3-shlib", MASK_SVR3_SHLIB }, \ - { "no-svr3-shlib", -MASK_SVR3_SHLIB }, \ - { "ieee-fp", MASK_IEEE_FP }, \ - { "no-ieee-fp", -MASK_IEEE_FP }, \ - { "fp-ret-in-387", MASK_FLOAT_RETURNS }, \ - { "no-fp-ret-in-387", -MASK_FLOAT_RETURNS }, \ - { "no-fancy-math-387", MASK_NO_FANCY_MATH_387 }, \ - { "fancy-math-387", -MASK_NO_FANCY_MATH_387 }, \ - { "omit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER }, \ - { "no-omit-leaf-frame-pointer",-MASK_OMIT_LEAF_FRAME_POINTER }, \ - { "no-wide-multiply", MASK_NO_WIDE_MULTIPLY }, \ - { "wide-multiply", -MASK_NO_WIDE_MULTIPLY }, \ - { "schedule-prologue", MASK_SCHEDULE_PROLOGUE }, \ - { "no-schedule-prologue", -MASK_SCHEDULE_PROLOGUE }, \ - { "debug-addr", MASK_DEBUG_ADDR }, \ - { "no-debug-addr", -MASK_DEBUG_ADDR }, \ - { "move", -MASK_NO_MOVE }, \ - { "no-move", MASK_NO_MOVE }, \ - { "debug-arg", MASK_DEBUG_ARG }, \ - { "no-debug-arg", -MASK_DEBUG_ARG }, \ - { "stack-arg-probe", MASK_STACK_PROBE }, \ - { "no-stack-arg-probe", -MASK_STACK_PROBE }, \ - { "windows", 0 }, \ - { "dll", 0 }, \ +{ { "80387", MASK_80387, "Use hardware fp" }, \ + { "no-80387", -MASK_80387, "Do not use hardware fp" },\ + { "hard-float", MASK_80387, "Use hardware fp" }, \ + { "soft-float", -MASK_80387, "Do not use hardware fp" },\ + { "no-soft-float", MASK_80387, "Use hardware fp" }, \ + { "386", 0, "Same as -mcpu=i386" }, \ + { "486", 0, "Same as -mcpu=i486" }, \ + { "pentium", 0, "Same as -mcpu=pentium" }, \ + { "pentiumpro", 0, "Same as -mcpu=pentiumpro" }, \ + { "rtd", MASK_RTD, "Alternate calling convention" },\ + { "no-rtd", -MASK_RTD, "Use normal calling convention" },\ + { "align-double", MASK_ALIGN_DOUBLE, "Align some doubles on dword boundary" },\ + { "no-align-double", -MASK_ALIGN_DOUBLE, "Align doubles on word boundary" }, \ + { "svr3-shlib", MASK_SVR3_SHLIB, "Uninitialized locals in .bss" }, \ + { "no-svr3-shlib", -MASK_SVR3_SHLIB, "Uninitialized locals in .data" }, \ + { "ieee-fp", MASK_IEEE_FP, "Use IEEE math for fp comparisons" }, \ + { "no-ieee-fp", -MASK_IEEE_FP, "Do not use IEEE math for fp comparisons" }, \ + { "fp-ret-in-387", MASK_FLOAT_RETURNS, "Return values of functions in FPU registers" }, \ + { "no-fp-ret-in-387", -MASK_FLOAT_RETURNS , "Do not return values of functions in FPU registers"}, \ + { "no-fancy-math-387", MASK_NO_FANCY_MATH_387, "Do not generate sin, cos, sqrt for 387" }, \ + { "fancy-math-387", -MASK_NO_FANCY_MATH_387, "Generate sin, cos, sqrt for FPU"}, \ + { "omit-leaf-frame-pointer", MASK_OMIT_LEAF_FRAME_POINTER, "Omit the frame pointer in leaf functions" }, \ + { "no-omit-leaf-frame-pointer",-MASK_OMIT_LEAF_FRAME_POINTER, "" }, \ + { "no-wide-multiply", MASK_NO_WIDE_MULTIPLY, "multiplies of 32 bits constrained to 32 bits" }, \ + { "wide-multiply", -MASK_NO_WIDE_MULTIPLY, "multiplies of 32 bits are 64 bits" }, \ + { "schedule-prologue", MASK_SCHEDULE_PROLOGUE, "Schedule function prologues" }, \ + { "no-schedule-prologue", -MASK_SCHEDULE_PROLOGUE, "" }, \ + { "debug-addr", MASK_DEBUG_ADDR, 0 /* intentionally undoc */ }, \ + { "no-debug-addr", -MASK_DEBUG_ADDR, 0 /* intentionally undoc */ }, \ + { "move", -MASK_NO_MOVE, "Generate mem-mem moves" }, \ + { "no-move", MASK_NO_MOVE, "Don't generate mem-mem moves" }, \ + { "debug-arg", MASK_DEBUG_ARG, 0 /* intentionally undoc */ }, \ + { "no-debug-arg", -MASK_DEBUG_ARG, 0 /* intentionally undoc */ }, \ + { "stack-arg-probe", MASK_STACK_PROBE, "Enable stack probing" }, \ + { "no-stack-arg-probe", -MASK_STACK_PROBE, "" }, \ + { "windows", 0, 0 /* intentionally undoc */ }, \ + { "dll", 0, 0 /* intentionally undoc */ }, \ SUBTARGET_SWITCHES \ - { "", MASK_SCHEDULE_PROLOGUE | TARGET_DEFAULT}} + { "", MASK_SCHEDULE_PROLOGUE | TARGET_DEFAULT, 0 }} /* Which processor to schedule for. The cpu attribute defines a list that mirrors this list, so changes to i386.md must be made at the same time. */ @@ -219,7 +224,8 @@ enum processor_type {PROCESSOR_I386, /* 80386 */ PROCESSOR_I486, /* 80486DX, 80486SX, 80486DX[24] */ PROCESSOR_PENTIUM, - PROCESSOR_PENTIUMPRO}; + PROCESSOR_PENTIUMPRO, + PROCESSOR_K6}; #define PROCESSOR_I386_STRING "i386" #define PROCESSOR_I486_STRING "i486" @@ -227,28 +233,20 @@ enum processor_type #define PROCESSOR_PENTIUM_STRING "pentium" #define PROCESSOR_I686_STRING "i686" #define PROCESSOR_PENTIUMPRO_STRING "pentiumpro" +#define PROCESSOR_K6_STRING "k6" extern enum processor_type ix86_cpu; extern int ix86_arch; /* Define the default processor. This is overridden by other tm.h files. */ -#define PROCESSOR_DEFAULT \ - ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_I486) \ - ? PROCESSOR_I486 \ - : ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUM) \ - ? PROCESSOR_PENTIUM \ - : ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUMPRO) \ - ? PROCESSOR_PENTIUMPRO \ - : PROCESSOR_I386 +#define PROCESSOR_DEFAULT (enum processor_type) TARGET_CPU_DEFAULT #define PROCESSOR_DEFAULT_STRING \ - ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_I486) \ - ? PROCESSOR_I486_STRING \ - : ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUM) \ - ? PROCESSOR_PENTIUM_STRING \ - : ((enum processor_type) TARGET_CPU_DEFAULT == PROCESSOR_PENTIUMPRO) \ - ? PROCESSOR_PENTIUMPRO_STRING \ - : PROCESSOR_I386_STRING + (PROCESSOR_DEFAULT == PROCESSOR_I486 ? PROCESSOR_I486_STRING \ + : PROCESSOR_DEFAULT == PROCESSOR_PENTIUM ? PROCESSOR_PENTIUM_STRING \ + : PROCESSOR_DEFAULT == PROCESSOR_PENTIUMPRO ? PROCESSOR_PENTIUMPRO_STRING \ + : PROCESSOR_DEFAULT == PROCESSOR_K6 ? PROCESSOR_K6_STRING \ + : PROCESSOR_I386_STRING) /* This macro is similar to `TARGET_SWITCHES' but defines names of command options that have values. Its definition is an @@ -260,14 +258,15 @@ extern int ix86_arch; 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}, \ - { "arch=", &ix86_arch_string}, \ - { "reg-alloc=", &i386_reg_alloc_order }, \ - { "regparm=", &i386_regparm_string }, \ - { "align-loops=", &i386_align_loops_string }, \ - { "align-jumps=", &i386_align_jumps_string }, \ - { "align-functions=", &i386_align_funcs_string }, \ - { "branch-cost=", &i386_branch_cost_string }, \ +{ { "cpu=", &ix86_cpu_string, "Schedule code for given CPU"}, \ + { "arch=", &ix86_arch_string, "Generate code for given CPU"}, \ + { "reg-alloc=", &i386_reg_alloc_order, "Control allocation order of integer registers" }, \ + { "regparm=", &i386_regparm_string, "Number of registers used to pass integer arguments" }, \ + { "align-loops=", &i386_align_loops_string, "Loop code aligned to this power of 2" }, \ + { "align-jumps=", &i386_align_jumps_string, "Jump targets are aligned to this power of 2" }, \ + { "align-functions=", &i386_align_funcs_string, "Function starts are aligned to this power of 2" }, \ + { "preferred-stack-boundary=", &i386_preferred_stack_boundary_string, "Attempt to keep stack aligned to this power of 2" }, \ + { "branch-cost=", &i386_branch_cost_string, "Branches are this expensive (1-5, arbitrary units)" }, \ SUBTARGET_OPTIONS \ } @@ -295,44 +294,45 @@ extern int ix86_arch; #define CC1_CPU_SPEC "\ %{!mcpu*: \ %{m386:-mcpu=i386 -march=i386} \ -%{mno-486:-mcpu=i386 -march=i386} \ %{m486:-mcpu=i486 -march=i486} \ -%{mno-386:-mcpu=i486 -march=i486} \ -%{mno-pentium:-mcpu=i486 -march=i486} \ %{mpentium:-mcpu=pentium} \ -%{mno-pentiumpro:-mcpu=pentium} \ %{mpentiumpro:-mcpu=pentiumpro}}" #endif #define CPP_486_SPEC "%{!ansi:-Di486} -D__i486 -D__i486__" #define CPP_586_SPEC "%{!ansi:-Di586 -Dpentium} \ -D__i586 -D__i586__ -D__pentium -D__pentium__" +#define CPP_K6_SPEC "%{!ansi:-Di586 -Dk6} \ + -D__i586 -D__i586__ -D__k6 -D__k6__" #define CPP_686_SPEC "%{!ansi:-Di686 -Dpentiumpro} \ -D__i686 -D__i686__ -D__pentiumpro -D__pentiumpro__" #ifndef CPP_CPU_DEFAULT_SPEC #if TARGET_CPU_DEFAULT == 1 #define CPP_CPU_DEFAULT_SPEC "%(cpp_486)" -#else +#endif #if TARGET_CPU_DEFAULT == 2 #define CPP_CPU_DEFAULT_SPEC "%(cpp_586)" -#else +#endif #if TARGET_CPU_DEFAULT == 3 #define CPP_CPU_DEFAULT_SPEC "%(cpp_686)" -#else -#define CPP_CPU_DEFAULT_SPEC "" #endif +#if TARGET_CPU_DEFAULT == 4 +#define CPP_CPU_DEFAULT_SPEC "%(cpp_k6)" #endif +#ifndef CPP_CPU_DEFAULT_SPEC +#define CPP_CPU_DEFAULT_SPEC "" #endif #endif /* CPP_CPU_DEFAULT_SPEC */ #ifndef CPP_CPU_SPEC #define CPP_CPU_SPEC "\ --Asystem(unix) -Acpu(i386) -Amachine(i386) \ +-Acpu(i386) -Amachine(i386) \ %{!ansi:-Di386} -D__i386 -D__i386__ \ %{mcpu=i486:%(cpp_486)} %{m486:%(cpp_486)} \ %{mpentium:%(cpp_586)} %{mcpu=pentium:%(cpp_586)} \ %{mpentiumpro:%(cpp_686)} %{mcpu=pentiumpro:%(cpp_686)} \ +%{mcpu=k6:%(cpp_k6)} \ %{!mcpu*:%{!m486:%{!mpentium*:%(cpp_cpu_default)}}}" #endif @@ -357,6 +357,7 @@ extern int ix86_arch; #define EXTRA_SPECS \ { "cpp_486", CPP_486_SPEC}, \ { "cpp_586", CPP_586_SPEC}, \ + { "cpp_k6", CPP_K6_SPEC}, \ { "cpp_686", CPP_686_SPEC}, \ { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \ { "cpp_cpu", CPP_CPU_SPEC }, \ @@ -407,9 +408,13 @@ extern int ix86_arch; /* Allocation boundary (in *bits*) for storing arguments in argument list. */ #define PARM_BOUNDARY 32 -/* Boundary (in *bits*) on which stack pointer should be aligned. */ +/* Boundary (in *bits*) on which the stack pointer must be aligned. */ #define STACK_BOUNDARY 32 +/* Boundary (in *bits*) on which the stack pointer preferrs to be + aligned; the compiler cannot rely on having this alignment. */ +#define PREFERRED_STACK_BOUNDARY i386_preferred_stack_boundary + /* Allocation boundary (in *bits*) for the code of a function. For i486, we get better performance by aligning to a cache line (i.e. 16 byte) boundary. */ @@ -502,6 +507,46 @@ extern int ix86_arch; : (ALIGN)) \ : (ALIGN)) +/* If defined, a C expression to compute the alignment for a local + 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. + + One use of this macro is to increase alignment of medium-size + data to make it all fit in fewer cache lines. */ + +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == ARRAY_TYPE \ + ? ((TYPE_MODE (TREE_TYPE (TYPE)) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TREE_TYPE (TYPE)) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : TREE_CODE (TYPE) == COMPLEX_TYPE \ + ? ((TYPE_MODE (TYPE) == DCmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TYPE) == XCmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : ((TREE_CODE (TYPE) == RECORD_TYPE \ + || TREE_CODE (TYPE) == UNION_TYPE \ + || TREE_CODE (TYPE) == QUAL_UNION_TYPE) \ + && TYPE_FIELDS (TYPE)) \ + ? ((DECL_MODE (TYPE_FIELDS (TYPE)) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (DECL_MODE (TYPE_FIELDS (TYPE)) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : TREE_CODE (TYPE) == REAL_TYPE \ + ? ((TYPE_MODE (TYPE) == DFmode && (ALIGN) < 64) \ + ? 64 \ + : (TYPE_MODE (TYPE) == XFmode && (ALIGN) < 128) \ + ? 128 \ + : (ALIGN)) \ + : (ALIGN)) + /* Set this non-zero if move instructions will actually fail to work when given unaligned data. */ #define STRICT_ALIGNMENT 0 @@ -664,8 +709,8 @@ extern int ix86_arch; #define MODES_TIEABLE_P(MODE1, MODE2) \ ((MODE1) == (MODE2) \ - || ((MODE1) == SImode && (MODE2) == HImode \ - || (MODE1) == HImode && (MODE2) == SImode)) + || ((MODE1) == SImode && (MODE2) == HImode) \ + || ((MODE1) == HImode && (MODE2) == SImode)) /* Specify the registers used for certain standard purposes. The values of these macros are register numbers. */ @@ -834,11 +879,6 @@ enum reg_class #define STACK_TOP_P(xop) (REG_P (xop) && REGNO (xop) == FIRST_STACK_REG) -/* Try to maintain the accuracy of the death notes for regs satisfying the - following. Important for stack like regs, to know when to pop. */ - -/* #define PRESERVE_DEATH_INFO_REGNO_P(x) FP_REGNO_P(x) */ - /* 1 if register REGNO can magically overlap other regs. Note that nonzero values work only in very special circumstances. */ @@ -896,19 +936,10 @@ enum reg_class /* Similar, but for floating constants, and defining letters G and H. Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if TARGET_387 isn't set, because the stack register converter may need to - load 0.0 into the function value register. - - We disallow these constants when -fomit-frame-pointer and compiling - PIC code since reload might need to force the constant to memory. - Forcing the constant to memory changes the elimination offsets after - the point where they must stay constant. - - However, we must allow them after reload as completed as reg-stack.c - will create insns which use these constants. */ + load 0.0 into the function value register. */ #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ - (((reload_completed || !flag_pic || !flag_omit_frame_pointer) && (C) == 'G') \ - ? standard_80387_constant_p (VALUE) : 0) + ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0) /* Place additional restrictions on the register class to use when it is necessary to be able to hold a value of mode MODE in a reload @@ -931,8 +962,11 @@ enum reg_class Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and movdf to do mem-to-mem moves through integer regs. */ -#define PREFERRED_RELOAD_CLASS(X,CLASS) \ - (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode ? NO_REGS \ +#define PREFERRED_RELOAD_CLASS(X,CLASS) \ + (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode \ + ? (standard_80387_constant_p (X) \ + ? reg_class_subset_p (CLASS, FLOAT_REGS) ? CLASS : FLOAT_REGS \ + : NO_REGS) \ : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \ : ((CLASS) == ALL_REGS \ && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS \ @@ -1532,25 +1566,16 @@ do { \ /* Output assembler code for a block containing the constant parts of a trampoline, leaving space for the variable parts. */ -/* On the 386, the trampoline contains three instructions: +/* On the 386, the trampoline contains two instructions: mov #STATIC,ecx - mov #FUNCTION,eax - jmp @eax */ -#define TRAMPOLINE_TEMPLATE(FILE) \ -{ \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb9)); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb8)); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_SHORT (FILE, const0_rtx); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xff)); \ - ASM_OUTPUT_CHAR (FILE, GEN_INT (0xe0)); \ -} + jmp FUNCTION + The trampoline is generated entirely at runtime. The operand of JMP + is the address of FUNCTION relative to the instruction following the + JMP (which is 5 bytes long). */ /* Length in units of the trampoline for entering a nested function. */ -#define TRAMPOLINE_SIZE 12 +#define TRAMPOLINE_SIZE 10 /* Emit RTL insns to initialize the variable parts of a trampoline. FNADDR is an RTX for the address of the function's pure code. @@ -1558,8 +1583,14 @@ do { \ #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \ { \ + /* Compute offset from the end of the jmp to the target function. */ \ + rtx disp = expand_binop (SImode, sub_optab, FNADDR, \ + plus_constant (TRAMP, 10), \ + NULL_RTX, 1, OPTAB_DIRECT); \ + emit_move_insn (gen_rtx_MEM (QImode, TRAMP), GEN_INT (0xb9)); \ emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 1)), CXT); \ - emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), FNADDR); \ + emit_move_insn (gen_rtx_MEM (QImode, plus_constant (TRAMP, 5)), GEN_INT (0xe9));\ + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (TRAMP, 6)), disp); \ } /* Definitions for register eliminations. @@ -1601,30 +1632,33 @@ do { \ (OFFSET) = 8; /* Skip saved PC and previous frame pointer */ \ else \ { \ - int regno; \ - int offset = 0; \ + int nregs; \ + int offset; \ + int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; \ + HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), \ + &nregs); \ \ - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ - if ((regs_ever_live[regno] && ! call_used_regs[regno]) \ - || ((current_function_uses_pic_offset_table \ - || current_function_uses_const_pool) \ - && flag_pic && regno == PIC_OFFSET_TABLE_REGNUM)) \ - offset += 4; \ + (OFFSET) = (tsize + nregs * UNITS_PER_WORD); \ \ - (OFFSET) = offset + get_frame_size (); \ + offset = 4; \ + if (frame_pointer_needed) \ + offset += UNITS_PER_WORD; \ \ - if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ - (OFFSET) += 4; /* Skip saved PC */ \ + if ((FROM) == ARG_POINTER_REGNUM) \ + (OFFSET) += offset; \ + else \ + (OFFSET) -= ((offset + preferred_alignment - 1) \ + & -preferred_alignment) - offset; \ } \ } /* Addressing modes, and classification of registers for them. */ -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ +/* #define HAVE_POST_INCREMENT 0 */ +/* #define HAVE_POST_DECREMENT 0 */ -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ +/* #define HAVE_PRE_DECREMENT 0 */ +/* #define HAVE_PRE_INCREMENT 0 */ /* Macros to check register numbers against specific register classes. */ @@ -1703,15 +1737,15 @@ do { \ #define MAX_REGS_PER_ADDRESS 2 -#define CONSTANT_ADDRESS_P(X) \ - (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ - || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ - || GET_CODE (X) == HIGH) +#define CONSTANT_ADDRESS_P(X) \ + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST) /* Nonzero if the constant value X is a legitimate general operand. It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ -#define LEGITIMATE_CONSTANT_P(X) 1 +#define LEGITIMATE_CONSTANT_P(X) \ + (GET_CODE (X) == CONST_DOUBLE ? standard_80387_constant_p (X) : 1) #ifdef REG_OK_STRICT #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ @@ -1764,8 +1798,7 @@ do { \ that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ #define LEGITIMATE_PIC_OPERAND_P(X) \ - (! SYMBOLIC_CONST (X) \ - || (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))) + (! SYMBOLIC_CONST (X) || legitimate_pic_address_disp_p (X)) #define SYMBOLIC_CONST(X) \ (GET_CODE (X) == SYMBOL_REF \ @@ -1893,10 +1926,10 @@ while (0) in one reasonably fast instruction. */ #define MOVE_MAX 4 -/* The number of scalar move insns which should be generated instead - of a string move insn or a library call. Increasing the value - will always make code faster, but eventually incurs high cost in - increased code size. +/* If a memory-to-memory move would take MOVE_RATIO or more simple + move-instruction pairs, we will do a movstr or libcall instead. + 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. @@ -2243,70 +2276,7 @@ while (0) the same cost as a data-dependence. */ #define ADJUST_COST(insn,link,dep_insn,cost) \ - { \ - rtx next_inst; \ - if (GET_CODE (dep_insn) == CALL_INSN) \ - (cost) = 0; \ - \ - else if (GET_CODE (dep_insn) == INSN \ - && GET_CODE (PATTERN (dep_insn)) == SET \ - && GET_CODE (SET_DEST (PATTERN (dep_insn))) == REG \ - && GET_CODE (insn) == INSN \ - && GET_CODE (PATTERN (insn)) == SET \ - && !reg_overlap_mentioned_p (SET_DEST (PATTERN (dep_insn)), \ - SET_SRC (PATTERN (insn)))) \ - { \ - (cost) = 0; \ - } \ - \ - else if (GET_CODE (insn) == JUMP_INSN) \ - { \ - (cost) = 0; \ - } \ - \ - if (TARGET_PENTIUM) \ - { \ - if (cost !=0 && is_fp_insn (insn) && is_fp_insn (dep_insn) \ - && !is_fp_dest (dep_insn)) \ - { \ - (cost) = 0; \ - } \ - \ - if (agi_dependent (insn, dep_insn)) \ - { \ - (cost) = 3; \ - } \ - else if (GET_CODE (insn) == INSN \ - && GET_CODE (PATTERN (insn)) == SET \ - && SET_DEST (PATTERN (insn)) == cc0_rtx \ - && (next_inst = next_nonnote_insn (insn)) \ - && GET_CODE (next_inst) == JUMP_INSN) \ - { /* compare probably paired with jump */ \ - (cost) = 0; \ - } \ - } \ - else \ - if (!is_fp_dest (dep_insn)) \ - { \ - if(!agi_dependent (insn, dep_insn)) \ - (cost) = 0; \ - else if (TARGET_486) \ - (cost) = 2; \ - } \ - else \ - if (is_fp_store (insn) && is_fp_insn (dep_insn) \ - && NEXT_INSN (insn) && NEXT_INSN (NEXT_INSN (insn)) \ - && NEXT_INSN (NEXT_INSN (NEXT_INSN (insn))) \ - && (GET_CODE (NEXT_INSN (insn)) == INSN) \ - && (GET_CODE (NEXT_INSN (NEXT_INSN (insn))) == JUMP_INSN) \ - && (GET_CODE (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) == NOTE) \ - && (NOTE_LINE_NUMBER (NEXT_INSN (NEXT_INSN (NEXT_INSN (insn)))) \ - == NOTE_INSN_LOOP_END)) \ - { \ - (cost) = 3; \ - } \ - } - + (cost) = x86_adjust_cost(insn, link, dep_insn, cost) #define ADJUST_BLOCKAGE(last_insn,insn,blockage) \ { \ @@ -2323,6 +2293,8 @@ while (0) } \ } +#define ISSUE_RATE ((int)ix86_cpu > (int)PROCESSOR_I486 ? 2 : 1) + /* Add any extra modes needed to represent the condition code. @@ -2606,7 +2578,7 @@ do { long l; \ F,f -- likewise, but for floating-point. */ #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. @@ -2741,11 +2713,8 @@ extern void function_arg_advance (); extern struct rtx_def *function_arg (); extern int function_arg_partial_nregs (); extern char *output_strlen_unroll (); -extern void output_op_from_reg (); -extern void output_to_reg (); extern char *singlemove_string (); extern char *output_move_double (); -extern char *output_move_memory (); extern char *output_move_pushmem (); extern int standard_80387_constant_p (); extern char *output_move_const_single (); @@ -2773,6 +2742,7 @@ extern int shift_op (); extern int VOIDmode_compare_op (); extern char *output_387_binary_op (); extern char *output_fix_trunc (); +extern void output_float_extend (); extern char *output_float_compare (); extern char *output_fp_cc0_set (); extern void save_386_machine_status (); @@ -2793,6 +2763,9 @@ extern int reg_mentioned_in_mem (); extern char *output_int_conditional_move (); extern char *output_fp_conditional_move (); extern int ix86_can_use_return_insn_p (); +extern int small_shift_operand (); +extern char *output_ashl (); +extern int memory_address_info (); #ifdef NOTYET extern struct rtx_def *copy_all_rtx (); @@ -2807,11 +2780,13 @@ extern char *i386_regparm_string; /* # registers to use to pass args */ extern char *i386_align_loops_string; /* power of two alignment for loops */ extern char *i386_align_jumps_string; /* power of two alignment for non-loop jumps */ extern char *i386_align_funcs_string; /* power of two alignment for functions */ +extern char *i386_preferred_stack_boundary_string;/* power of two alignment for stack boundary */ extern char *i386_branch_cost_string; /* values 1-5: see jump.c */ extern int i386_regparm; /* i386_regparm_string as a number */ extern int i386_align_loops; /* power of two alignment for loops */ extern int i386_align_jumps; /* power of two alignment for non-loop jumps */ extern int i386_align_funcs; /* power of two alignment for functions */ +extern int i386_preferred_stack_boundary; /* preferred stack boundary alignment in bits */ extern int i386_branch_cost; /* values 1-5: see jump.c */ extern char *hi_reg_name[]; /* names for 16 bit regs */ extern char *qi_reg_name[]; /* names for 8 bit regs (low) */ diff --git a/contrib/gcc/config/i386/i386.md b/contrib/gcc/config/i386/i386.md index f85992f..fb3e1b2 100644 --- a/contrib/gcc/config/i386/i386.md +++ b/contrib/gcc/config/i386/i386.md @@ -64,13 +64,50 @@ ;; prevent insns referencing it being scheduled across the initial ;; decrement of the stack pointer. ;; 5 This is a `bsf' operation. +;; 6 This is the @GOT offset of a PIC address. +;; 7 This is the @GOTOFF offset of a PIC address. +;; 8 This is a reference to a symbol's @PLT address. ;; This shadows the processor_type enumeration, so changes must be made ;; to i386.h at the same time. -(define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul" +(define_attr "type" + "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul" (const_string "integer")) +(define_attr "memory" "none,load,store" + (cond [(eq_attr "type" "idiv,lea") + (const_string "none") + + (eq_attr "type" "fld") + (const_string "load") + + (eq_attr "type" "test") + (if_then_else (match_operand 0 "memory_operand" "") + (const_string "load") + (const_string "none")) + + (eq_attr "type" "compare,fcompare") + (if_then_else (ior (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "")) + (const_string "load") + (const_string "none")) + + (and (eq_attr "type" "integer,memory,fpop") + (match_operand 0 "memory_operand" "")) + (const_string "store") + + (and (eq_attr "type" "integer,memory,fpop") + (match_operand 1 "memory_operand" "")) + (const_string "load") + + (and (eq_attr "type" "binary,imul,fpmul,fpdiv") + (ior (match_operand 1 "memory_operand" "") + (match_operand 2 "memory_operand" ""))) + (const_string "load")] + + (const_string "none"))) + ;; Functional units ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY @@ -89,11 +126,11 @@ ;; Floating point (define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486")) + (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486")) 5 5) (define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro")) + (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 3 0) (define_function_unit "fp" 1 0 @@ -117,12 +154,69 @@ 10 10) (define_function_unit "fp" 1 0 - (eq_attr "type" "fld") + (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6")) 1 0) -(define_function_unit "integer" 1 0 - (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386")) - 2 0) +;; K6 FPU is not pipelined. +(define_function_unit "fp" 1 0 + (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6")) + 2 2) + +;; i386 and i486 have one integer unit, which need not be modeled + +(define_function_unit "integer" 2 0 + (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro")) + 1 0) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") + (and (eq_attr "type" "integer,binary,test,compare") + (eq_attr "memory" "!load"))) + 1 0) + +;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles) +;; and a register operation (1 cycle). +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") + (and (eq_attr "type" "integer,binary,test,compare") + (eq_attr "memory" "load"))) + 3 0) + +;; Multiplies use one of the integer units +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul")) + 11 11) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "imul")) + 2 2) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv")) + 25 25) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv")) + 17 17) + +;; Pentium Pro and K6 have a separate load unit. +(define_function_unit "load" 1 0 + (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load")) + 3 0) + +(define_function_unit "load" 1 0 + (and (eq_attr "cpu" "k6") (eq_attr "memory" "load")) + 2 0) + +;; Pentium Pro and K6 have a separate store unit. +(define_function_unit "store" 1 0 + (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store")) + 1 0) + +;; lea executes in the K6 store unit with 1 cycle latency +(define_function_unit "store" 1 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "lea")) + 1 0) ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". @@ -140,7 +234,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in i386.h. -(define_attr "cpu" "i386,i486,pentium,pentiumpro" +(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6" (const (symbol_ref "ix86_cpu"))) (define_insn "tstsi_1" @@ -154,7 +248,8 @@ operands[1] = const0_rtx; return AS2 (cmp%L0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tstsi" [(set (cc0) @@ -179,7 +274,8 @@ operands[1] = const0_rtx; return AS2 (cmp%W0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tsthi" [(set (cc0) @@ -204,7 +300,8 @@ operands[1] = const0_rtx; return AS2 (cmp%B0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tstqi" [(set (cc0) @@ -234,7 +331,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -268,7 +366,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -302,7 +401,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -328,7 +428,8 @@ (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r") (match_operand:SI 1 "general_operand" "ri,mr")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%L0,%1,%0);") + "* return AS2 (cmp%L0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmpsi" [(set (cc0) @@ -351,7 +452,8 @@ (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r") (match_operand:HI 1 "general_operand" "ri,mr")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%W0,%1,%0);") + "* return AS2 (cmp%W0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmphi" [(set (cc0) @@ -374,7 +476,8 @@ (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq") (match_operand:QI 1 "general_operand" "qm,nq")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%B0,%1,%0);") + "* return AS2 (cmp%B0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmpqi" [(set (cc0) @@ -403,27 +506,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "register_operand" "f") - (float:XF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:XF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:XF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -433,7 +517,8 @@ (match_operand:DF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -443,7 +528,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -453,7 +539,8 @@ (match_operand:SF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -463,7 +550,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -471,7 +559,8 @@ (match_operand:XF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -481,27 +570,8 @@ (clobber (match_scratch:HI 3 "=a,a"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:DF 0 "register_operand" "f") - (float:DF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:DF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:DF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -511,7 +581,8 @@ (match_operand:SF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -521,7 +592,8 @@ (match_operand:DF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -531,7 +603,8 @@ (match_operand:DF 1 "nonimmediate_operand" "fm")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -539,7 +612,8 @@ (match_operand:DF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) ;; These two insns will never be generated by combine due to the mode of ;; the COMPARE. @@ -561,7 +635,7 @@ ; "TARGET_80387" ; "* return output_float_compare (insn, operands);") -(define_insn "cmpsf_cc_1" +(define_insn "*cmpsf_cc_1" [(set (cc0) (match_operator 2 "VOIDmode_compare_op" [(match_operand:SF 0 "nonimmediate_operand" "f,fm") @@ -569,27 +643,8 @@ (clobber (match_scratch:HI 3 "=a,a"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:SF 0 "register_operand" "f") - (float:SF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:SF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:SF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -597,7 +652,8 @@ (match_operand:SF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_expand "cmpxf" [(set (cc0) @@ -711,7 +767,10 @@ /* For small integers, we may actually use testb. */ if (GET_CODE (operands[1]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) + && (! REG_P (operands[0]) || QI_REG_P (operands[0])) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { /* We may set the sign bit spuriously. */ @@ -757,7 +816,8 @@ return AS2 (test%L0,%1,%0); return AS2 (test%L1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) (define_insn "" [(set (cc0) @@ -805,7 +865,8 @@ return AS2 (test%W0,%1,%0); return AS2 (test%W1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) (define_insn "" [(set (cc0) @@ -818,7 +879,8 @@ return AS2 (test%B0,%1,%0); return AS2 (test%B1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) ;; move instructions. ;; There is one for each machine mode, @@ -829,13 +891,15 @@ [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "nonmemory_operand" "rn"))] "flag_pic" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "memory" "store")]) (define_insn "" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "nonmemory_operand" "ri"))] "!flag_pic" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "memory" "store")]) ;; On a 386, it is faster to push MEM directly. @@ -843,7 +907,9 @@ [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "memory_operand" "m"))] "TARGET_PUSH_MEMORY" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "load")]) ;; General case of fullword move. @@ -863,7 +929,7 @@ /* Don't generate memory->memory moves, go through a register */ else if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -874,18 +940,24 @@ ;; On i486, incl reg is faster than movl $1,reg. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g,r") - (match_operand:SI 1 "general_operand" "rn,im"))] + [(set (match_operand:SI 0 "general_operand" "=g,r,r") + (match_operand:SI 1 "general_operand" "rn,i,m"))] "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)) && flag_pic" "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) + + /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes + longer. */ + if ((ix86_cpu != PROCESSOR_K6 || optimize_size) + && operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%L0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -901,7 +973,9 @@ return AS2 (lea%L0,%a1,%0); return AS2 (mov%L0,%1,%0); -}") +}" + [(set_attr "type" "integer,integer,memory") + (set_attr "memory" "*,*,load")]) (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g,r") @@ -912,10 +986,18 @@ "* { rtx link; + + /* Use of xor was disabled for AMD K6 as recommended by the Optimization + Manual. My test shows, that this generally hurts the performance, because + mov is longer and takes longer to decode and decoding is the main + bottleneck of K6 when executing GCC code. */ + if (operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%L0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -928,19 +1010,25 @@ return AS1 (inc%L0,%0); return AS2 (mov%L0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") (match_operand:HI 1 "nonmemory_operand" "ri"))] "" - "* return AS1 (push%W0,%1);") + "* return AS1 (push%W0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "store")]) (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") (match_operand:HI 1 "memory_operand" "m"))] "TARGET_PUSH_MEMORY" - "* return AS1 (push%W0,%1);") + "* return AS1 (push%W0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "load")]) ;; On i486, an incl and movl are both faster than incw and movw. @@ -952,7 +1040,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -971,6 +1059,8 @@ return AS2 (xor%L0,%k0,%k0); if (REG_P (operands[0]) && operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -989,7 +1079,7 @@ operands[1] = i386_sext16_if_const (operands[1]); return AS2 (mov%L0,%k1,%k0); } - if (TARGET_PENTIUMPRO) + if (! TARGET_ZERO_EXTEND_WITH_AND) { /* movzwl is faster than movw on the Pentium Pro, * although not as fast as an aligned movl. */ @@ -1002,7 +1092,9 @@ } return AS2 (mov%W0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) (define_expand "movstricthi" [(set (strict_low_part (match_operand:HI 0 "general_operand" "")) @@ -1012,7 +1104,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1027,10 +1119,18 @@ "* { rtx link; + + /* Use of xor was disabled for AMD K6 as recommended by the Optimization + Manual. My test shows, that this generally hurts the performance, because + mov is longer and takes longer to decode and decoding is the main + bottleneck of K6 when executing GCC code. */ + if (operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%W0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -1043,7 +1143,8 @@ return AS1 (inc%W0,%0); return AS2 (mov%W0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory")]) ;; emit_push_insn when it calls move_by_pieces ;; requires an insn to "push a byte". @@ -1078,7 +1179,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1093,10 +1194,12 @@ "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%L0,%k0,%k0); + + /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. + It is at least as fast as xor on any processor except a Pentium. */ if (operands[1] == const1_rtx + && TARGET_PENTIUM && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -1138,7 +1241,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1153,10 +1256,11 @@ "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%B0,%0,%0); + + /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */ if (operands[1] == const1_rtx + && TARGET_PENTIUM && ! NON_QI_REG_P (operands[0]) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ @@ -1182,7 +1286,8 @@ (define_insn "movsf_push" [(set (match_operand:SF 0 "push_operand" "=<,<") (match_operand:SF 1 "general_operand" "*rfF,m"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1209,11 +1314,15 @@ return AS1 (push%L0,%1); }") -(define_insn "movsf_push_memory" - [(set (match_operand:SF 0 "push_operand" "=<") - (match_operand:SF 1 "memory_operand" "m"))] - "TARGET_PUSH_MEMORY" - "* return AS1 (push%L0,%1);") +(define_split + [(set (match_operand:SF 0 "push_operand" "") + (match_operand:SF 1 "general_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 4))) + (set (mem:SF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") @@ -1223,7 +1332,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1231,34 +1340,21 @@ } /* If we are loading a floating point constant that isn't 0 or 1 - into a register, indicate we need the pic register loaded. This could - be optimized into stores of constants if the target eventually moves - to memory, but better safe than sorry. */ + into a register, force the value to memory now, since we'll + get better code out the back end. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (SFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (SFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); } }") ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm") - (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m") + (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* { @@ -1274,20 +1370,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1327,10 +1409,12 @@ return AS1 (fxch,%0); }") + (define_insn "movdf_push" [(set (match_operand:DF 0 "push_operand" "=<,<") (match_operand:DF 1 "general_operand" "*rfF,o"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1357,11 +1441,15 @@ return output_move_double (operands); }") -(define_insn "movdf_push_memory" - [(set (match_operand:DF 0 "push_operand" "=<") - (match_operand:DF 1 "memory_operand" "o"))] - "TARGET_PUSH_MEMORY" - "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);") +(define_split + [(set (match_operand:DF 0 "push_operand" "") + (match_operand:DF 1 "register_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 8))) + (set (mem:DF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") @@ -1371,7 +1459,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1383,30 +1471,18 @@ optimized into stores of constants if the target eventually moves to memory, but better safe than sorry. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (DFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (DFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); } }") ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") - (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o") + (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1423,20 +1499,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1480,7 +1542,8 @@ (define_insn "movxf_push" [(set (match_operand:XF 0 "push_operand" "=<,<") (match_operand:XF 1 "general_operand" "*rfF,o"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1506,11 +1569,15 @@ return output_move_double (operands); }") -(define_insn "movxf_push_memory" - [(set (match_operand:XF 0 "push_operand" "=<") - (match_operand:XF 1 "memory_operand" "o"))] - "TARGET_PUSH_MEMORY" - "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);") +(define_split + [(set (match_operand:XF 0 "push_operand" "") + (match_operand:XF 1 "register_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 12))) + (set (mem:XF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movxf" [(set (match_operand:XF 0 "general_operand" "") @@ -1520,7 +1587,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1532,30 +1599,18 @@ be optimized into stores of constants if the target eventually moves to memory, but better safe than sorry. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (XFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (XFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (XFmode, operands[1])); } }") (define_insn "" - [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") - (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o") + (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1572,20 +1627,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1644,7 +1685,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1657,8 +1698,44 @@ (match_operand:DI 1 "general_operand" "riF,m"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* return output_move_double (operands);") + "* return output_move_double (operands);" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) + +(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (match_operand:DI 1 "general_operand" ""))] + "reload_completed + && (offsettable_memref_p (operands[0]) + || nonmemory_operand (operands[0], DImode)) + && (offsettable_memref_p (operands[1]) + || nonmemory_operand (operands[1], DImode)) + && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]), + operands[1]) + || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]), + operands[1]))" + [(set (match_dup 2) + (match_dup 4)) + (set (match_dup 3) + (match_dup 5))] + " +{ + split_di (&operands[0], 1, &operands[2], &operands[3]); + split_di (&operands[1], 1, &operands[4], &operands[5]); + + if (reg_overlap_mentioned_p (operands[2], operands[1])) + { + rtx tmp; + tmp = operands[2]; + operands[2] = operands[3]; + operands[3] = tmp; + + tmp = operands[4]; + operands[4] = operands[5]; + operands[5] = tmp; + } +}") ;;- conversion instructions ;;- NONE @@ -1666,10 +1743,25 @@ ;;- zero extension instructions ;; See comments by `andsi' for when andl is faster than movzx. -(define_insn "zero_extendhisi2" +(define_expand "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] + "" + "") + +;; When optimizing for the PPro/PII or code size, always use movzwl. +;; We want to use a different pattern so we can use different constraints +;; than the generic pattern. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] + "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" + "* return AS2 (movz%W0%L0,%1,%0);") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1730,10 +1822,23 @@ (const_int 65535)))] "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") -(define_insn "zero_extendqihi2" +(define_expand "zero_extendqihi2" + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] + "" + "") + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" + + "* return AS2 (movz%B0%W0,%1,%0);") + +(define_insn "" [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1811,10 +1916,22 @@ FAIL; operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));") -(define_insn "zero_extendqisi2" +(define_expand "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] + "" + "") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" + "* return AS2 (movz%B0%L0,%1,%0);") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1899,58 +2016,105 @@ "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") (define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m") - (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") + (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))] "" - "* - { - rtx high[2], low[2], xops[4]; - - if (REG_P (operands[0]) && REG_P (operands[1]) - && REGNO (operands[0]) == REGNO (operands[1])) - { - operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - return AS2 (xor%L0,%0,%0); - } - - split_di (operands, 1, low, high); - xops[0] = low[0]; - xops[1] = operands[1]; - xops[2] = high[0]; - xops[3] = const0_rtx; - - output_asm_insn (AS2 (mov%L0,%1,%0), xops); - if (GET_CODE (low[0]) == MEM) - output_asm_insn (AS2 (mov%L2,%3,%2), xops); - else - output_asm_insn (AS2 (xor%L2,%2,%2), xops); + "#") - RET; -}") +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] + "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" + [(set (match_dup 4) (const_int 0))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") + +(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] + "reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (const_int 0))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") ;;- sign extension instructions (define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o") + (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r"))) + (clobber (match_scratch:SI 2 "=X,X,X,&r"))] "" - "* + "#") + +;; Extend to memory case when source register does die. +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "register_operand" ""))] + "(flow2_completed + && dead_or_set_p (insn, operands[1]) + && !reg_mentioned_p (operands[1], operands[0]))" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) + (set (match_dup 4) (match_dup 1))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") + +;; Extend to memory case when source register does not die. +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "register_operand" ""))] + "flow2_completed" + [(const_int 0)] + " { - if (REGNO (operands[0]) == 0) + split_di (&operands[0], 1, &operands[3], &operands[4]); + + emit_move_insn (operands[3], operands[1]); + + /* Generate a cltd if possible and doing so it profitable. */ + if (true_regnum (operands[1]) == 0 + && true_regnum (operands[2]) == 1 + && (optimize_size || !TARGET_PENTIUM)) { - /* This used to be cwtl, but that extends HI to SI somehow. */ -#ifdef INTEL_SYNTAX - return \"cdq\"; -#else - return \"cltd\"; -#endif + emit_insn (gen_ashrsi3_31 (operands[2], operands[1])); + } + else + { + emit_move_insn (operands[2], operands[1]); + emit_insn (gen_ashrsi3_31 (operands[2], operands[2])); + } + emit_move_insn (operands[4], operands[2]); + DONE; +}") + +;; Extend to register case. Optimize case where source and destination +;; registers match and cases where we can use cltd. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_scratch:SI 2 ""))] + "reload_completed" + [(const_int 0)] + " +{ + split_di (&operands[0], 1, &operands[3], &operands[4]); + + if (true_regnum (operands[3]) != true_regnum (operands[1])) + emit_move_insn (operands[3], operands[1]); + + /* Generate a cltd if possible and doing so it profitable. */ + if (true_regnum (operands[3]) == 0 + && (optimize_size || !TARGET_PENTIUM)) + { + emit_insn (gen_ashrsi3_31 (operands[4], operands[3])); + DONE; } - operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - output_asm_insn (AS2 (mov%L0,%0,%1), operands); + if (true_regnum (operands[4]) != true_regnum (operands[1])) + emit_move_insn (operands[4], operands[1]); - operands[0] = GEN_INT (31); - return AS2 (sar%L1,%0,%1); + emit_insn (gen_ashrsi3_31 (operands[4], operands[4])); + DONE; }") ;; Note that the i386 programmers' manual says that the opcodes @@ -1964,7 +2128,8 @@ "* { if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) + && REG_P (operands[1]) && REGNO (operands[1]) == 0 + && (optimize_size || ix86_cpu != PROCESSOR_K6)) #ifdef INTEL_SYNTAX return \"cwde\"; #else @@ -1985,7 +2150,8 @@ "* { if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) + && REG_P (operands[1]) && REGNO (operands[1]) == 0 + && (optimize_size || ix86_cpu != PROCESSOR_K6)) return \"cbtw\"; #ifdef INTEL_SYNTAX @@ -2069,110 +2235,237 @@ ;; Conversions between float and double. -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f") - (float_extend:DF - (match_operand:SF 1 "nonimmediate_operand" "f,fm")))] +(define_expand "extendsfdf2" + [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") + (float_extend:DF + (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] "TARGET_80387" - "* + " { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (SFmode, operands[1]); - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } + operands[2] = assign_386_stack_local (SFmode, 0); + operands[3] = assign_386_stack_local (DFmode, 0); +}") - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r") + (float_extend:DF + (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) + (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_extend:DF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:DF (match_dup 2)))] + "") - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); - } +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_extend:DF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:DF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") + +(define_split + [(set (match_operand:DF 0 "nonimmediate_operand" "") + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:DF (match_dup 1)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) + +(define_expand "extenddfxf2" + [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF + (match_operand:DF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] + "TARGET_80387" + " +{ + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (DFmode, operands[1]); - abort (); + operands[2] = assign_386_stack_local (DFmode, 0); + operands[3] = assign_386_stack_local (XFmode, 0); }") -(define_insn "extenddfxf2" - [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") (float_extend:XF - (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))] - "TARGET_80387" + (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m")) + (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:XF (match_dup 2)))] + "") - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:XF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:XF (match_dup 1)))] + "") - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") + (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) + +(define_expand "extendsfxf2" + [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF + (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] + "TARGET_80387" + " +{ + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (SFmode, operands[1]); - abort (); + operands[2] = assign_386_stack_local (SFmode, 0); + operands[3] = assign_386_stack_local (XFmode, 0); }") -(define_insn "extendsfxf2" - [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") (float_extend:XF - (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))] - "TARGET_80387" + (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) + (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:XF (match_dup 2)))] + "") - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:XF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } +(define_split + [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:XF (match_dup 1)))] + "") - abort (); -}") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") + (float_extend:XF + (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) (define_expand "truncdfsf2" [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") @@ -2185,480 +2478,764 @@ operands[2] = (rtx) assign_386_stack_local (SFmode, 0); }") -;; This cannot output into an f-reg because there is no way to be sure -;; of truncating in that case. Otherwise this is just like a simple move -;; insn. So we pretend we can output to a reg in order to get better -;; register preferencing, but we really use a stack slot. - (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m") + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") (float_truncate:SF - (match_operand:DF 1 "register_operand" "0,f"))) - (clobber (match_operand:SF 2 "memory_operand" "m,m"))] + (match_operand:DF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[1]; - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - return AS1 (fst%z0,%0); - } - else if (STACK_TOP_P (operands[0])) - { - output_asm_insn (AS1 (fstp%z2,%y2), operands); - return AS1 (fld%z2,%y2); - } + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; + + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); else - abort (); -}") + output_asm_insn (AS1 (fst%z0,%0), xops); -(define_insn "truncxfsf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r") - (float_truncate:SF - (match_operand:XF 1 "register_operand" "f,f")))] + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + return AS2 (mov%L0,%2,%0); + + return \"\"; +}" + [(set_attr "type" "fpop")]) + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float_truncate:SF (match_operand:DF 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_split + [(set (match_operand:SF 0 "memory_operand" "") + (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:SF (match_dup 1)))] + "") + +;; This cannot output into an f-reg because there is no way to be sure +;; of truncating in that case. + +(define_insn "" + [(set (match_operand:SF 0 "memory_operand" "=m") + (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } + if (stack_top_dies) + return AS1 (fstp%z0,%0); else - abort (); + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +(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_80387" + " +{ + operands[2] = (rtx) assign_386_stack_local (SFmode, 0); }") -(define_insn "truncxfdf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r") - (float_truncate:DF - (match_operand:XF 1 "register_operand" "f,f")))] +(define_insn "" + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") + (float_truncate:SF + (match_operand:XF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[1]; - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; + + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); else - abort (); -}") + output_asm_insn (AS1 (fst%z0,%0), xops); - -;; The 387 requires that the stack top dies after converting to DImode. + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + return AS2 (mov%L0,%2,%0); -;; Represent an unsigned conversion from SImode to MODE_FLOAT by first -;; doing a signed conversion to DImode, and then taking just the low -;; part. + return \"\"; +}" + [(set_attr "type" "fpop")]) -(define_expand "fixuns_truncxfsi2" - [(set (match_dup 4) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:XF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] +(define_split + [(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 && reload_completed" + [(set (match_dup 2) + (float_truncate:SF (match_dup 1))) + (set (match_dup 0) + (match_dup 2))] + "") + +(define_split + [(set (match_operand:SF 0 "memory_operand" "") + (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:SF (match_dup 1)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "memory_operand" "=m") + (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] "TARGET_80387" - " + "* { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (XFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); -}") + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; -(define_expand "fixuns_truncdfsi2" - [(set (match_dup 4) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:DF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +(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_80387" " { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (DFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (DFmode, 0); }") -(define_expand "fixuns_truncsfsi2" - [(set (match_dup 4) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:SF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r") + (float_truncate:DF + (match_operand:XF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))] "TARGET_80387" - " + "* { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (SFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); -}") + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[2]; -;; Signed conversion to DImode. + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; -(define_expand "fix_truncxfdi2" + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); + else + output_asm_insn (AS1 (fst%z0,%0), xops); + + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + { + xops[0] = operands[0]; + xops[1] = operands[2]; + output_asm_insn (output_move_double (xops), xops); + } + + return \"\"; +}" + [(set_attr "type" "fpop")]) + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" [(set (match_dup 2) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:XF (match_dup 2)))) + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) + (match_dup 2))] + "") + +(define_split + [(set (match_operand:DF 0 "memory_operand" "") + (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:DF (match_dup 1)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "memory_operand" "=m") + (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] + "TARGET_80387" + "* +{ + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +;; Conversions between floating point and fix point. + +(define_expand "fix_truncsfsi2" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "")))) (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[1] = copy_to_mode_reg (XFmode, operands[1]); - operands[2] = gen_reg_rtx (XFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); }") -(define_expand "fix_truncdfdi2" - [(set (match_dup 2) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:DF (match_dup 2)))) +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] + "TARGET_80387" + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +(define_expand "fix_truncsfdi2" + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) + (clobber (match_dup 1)) (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[1] = copy_to_mode_reg (DFmode, operands[1]); - operands[2] = gen_reg_rtx (DFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); + operands[1] = copy_to_mode_reg (SFmode, operands[1]); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); }") -(define_expand "fix_truncsfdi2" - [(set (match_dup 2) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:SF (match_dup 2)))) +(define_insn "" + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) + (clobber (match_dup 1)) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] + "TARGET_80387" + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +(define_expand "fix_truncdfsi2" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "")))) (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[1] = copy_to_mode_reg (SFmode, operands[1]); - operands[2] = gen_reg_rtx (SFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); }") -;; These match a signed conversion of either DFmode or SFmode to DImode. - (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) -(define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] +(define_expand "fix_truncdfdi2" + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) + (clobber (match_dup 1)) + (clobber (match_dup 2)) + (clobber (match_dup 3)) + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + " +{ + operands[1] = copy_to_mode_reg (DFmode, operands[1]); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); +}") (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f")))) + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Signed MODE_FLOAT conversion to SImode. + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) (define_expand "fix_truncxfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:XF (match_operand:XF 1 "register_operand" "")))) + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "")))) (clobber (match_dup 2)) (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); }") -(define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:DF (match_operand:DF 1 "register_operand" "")))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - " -{ - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); -}") + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) -(define_expand "fix_truncsfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:SF (match_operand:SF 1 "register_operand" "")))) +(define_expand "fix_truncxfdi2" + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "")))) + (clobber (match_dup 1)) (clobber (match_dup 2)) (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); + operands[1] = copy_to_mode_reg (XFmode, operands[1]); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); }") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) + (clobber (match_dup 1)) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +;; Conversion between fixed point and floating point. -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] +;; ??? Possibly represent floatunssidf2 here in gcc2. + +(define_expand "floatsisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "operands[2] = assign_386_stack_local (SImode, 0);") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Conversion between fixed point and floating point. -;; The actual pattern that matches these is at the end of this file. + "#") -;; ??? Possibly represent floatunssidf2 here in gcc2. +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] + "") -(define_expand "floatsisf2" +(define_split [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] + (float:SF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floathisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" + "operands[2] = assign_386_stack_local (HImode, 0);") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] "") -(define_expand "floatdisf2" +(define_split [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] + (float:SF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:HI 1 "memory_operand" "m")))] "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] "") +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:DI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + (define_expand "floatsidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (SImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] + "") + +(define_split [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] + (float:DF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floathidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (HImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] "") -(define_expand "floatdidf2" +(define_split [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] + (float:DF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:HI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] "") +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:DI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + (define_expand "floatsixf2" - [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))] + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "") + "operands[2] = assign_386_stack_local (SImode, 0);") -(define_expand "floatdixf2" +(define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))] - "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96" + (float:XF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] "") -;; This will convert from SImode or DImode to MODE_FLOAT. +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") - (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))] + (float:XF (match_operand:SI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))] +(define_expand "floathixf2" + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "operands[2] = assign_386_stack_local (HImode, 0);") (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f,f") + (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "#") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:HI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdixf2" + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") - (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))] + (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "#") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:DI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) ;;- add instructions -(define_insn "addsidi3_1" +(define_insn "*addsidi3_1" [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o") (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o") (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri")))) @@ -2666,7 +3243,7 @@ "" "* { - rtx low[3], high[3], xops[7], temp; + rtx low[3], high[3], xops[7]; CC_STATUS_INIT; @@ -2703,8 +3280,11 @@ output_asm_insn (AS2 (add%L0,%2,%0), low); output_asm_insn (AS2 (adc%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "addsidi3_2" [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o") @@ -2714,7 +3294,7 @@ "" "* { - rtx low[3], high[3], xops[7], temp; + rtx low[3], high[3], xops[7]; CC_STATUS_INIT; @@ -2781,8 +3361,11 @@ output_asm_insn (AS2 (add%L0,%2,%0), low); output_asm_insn (AS2 (adc%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "adddi3" [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") @@ -2831,6 +3414,9 @@ } } + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) { xops[0] = high[0]; @@ -2855,7 +3441,8 @@ output_asm_insn (AS2 (add%L0,%2,%0), high); RET; -}") +}" + [(set_attr "type" "binary")]) ;; On a 486, it is faster to do movl/addl than to do a single leal if ;; operands[1] and operands[2] are both registers. @@ -2875,7 +3462,7 @@ "* { if (REG_P (operands[0]) && REG_P (operands[1]) - && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) && REGNO (operands[0]) != REGNO (operands[1])) { if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) @@ -2920,7 +3507,8 @@ } return AS2 (add%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) ;; addsi3 is faster, so put this after. @@ -2949,7 +3537,8 @@ CC_STATUS_INIT; return AS2 (lea%L0,%a1,%0); -}") +}" + [(set_attr "type" "lea")]) ;; ??? `lea' here, for three operand add? If leaw is used, only %bx, ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be @@ -2963,12 +3552,30 @@ "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);") (define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") + (match_operand:HI 2 "general_operand" "ri,rm,ri")))] "ix86_binary_operator_ok (PLUS, HImode, operands)" "* { + if (REG_P (operands[0]) && REG_P (operands[1]) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) + && REGNO (operands[0]) != REGNO (operands[1])) + { + if (operands[2] == stack_pointer_rtx) + abort (); + + CC_STATUS_INIT; + operands[1] + = gen_rtx_PLUS (SImode, + gen_rtx_REG (SImode, REGNO (operands[1])), + (! REG_P (operands[2]) + ? operands[2] + : gen_rtx_REG (SImode, REGNO (operands[2])))); + operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); + return AS2 (lea%L0,%a1,%0); + } + /* ??? what about offsettable memory references? */ if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */ && QI_REG_P (operands[0]) @@ -3019,7 +3626,8 @@ return AS1 (dec%W0,%0); return AS2 (add%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_expand "addqi3" [(set (match_operand:QI 0 "general_operand" "") @@ -3029,12 +3637,31 @@ "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);") (define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q") + (match_operand:QI 2 "general_operand" "qn,qmn,qn")))] "ix86_binary_operator_ok (PLUS, QImode, operands)" "* { + if (REG_P (operands[0]) && REG_P (operands[1]) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) + && (REGNO (operands[0]) != REGNO (operands[1]) + || NON_QI_REG_P (operands[1]) + || (REG_P (operands[2]) && NON_QI_REG_P (operands[2])))) + { + if (operands[2] == stack_pointer_rtx) + abort (); + + CC_STATUS_INIT; + operands[1] + = gen_rtx_PLUS (SImode, + gen_rtx_REG (SImode, REGNO (operands[1])), + (! REG_P (operands[2]) + ? operands[2] + : gen_rtx_REG (SImode, REGNO (operands[2])))); + operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); + return AS2 (lea%L0,%a1,%0); + } if (operands[2] == const1_rtx) return AS1 (inc%B0,%0); @@ -3044,7 +3671,8 @@ return AS1 (dec%B0,%0); return AS2 (add%B0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) ;Lennart Augustsson ;says this pattern just makes slower code: @@ -3141,8 +3769,12 @@ output_asm_insn (AS2 (sub%L0,%2,%0), low); output_asm_insn (AS2 (sbb%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "subdi3" [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o") @@ -3185,6 +3817,9 @@ } } + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + if (GET_CODE (operands[3]) == REG) { xops[0] = high[0]; @@ -3206,10 +3841,12 @@ } else - output_asm_insn (AS2 (sub%L0,%2,%0), high); + output_asm_insn (AS2 (sub%L0,%2,%0), high); + RET; -}") +}" + [(set_attr "type" "binary")]) (define_expand "subsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") @@ -3223,7 +3860,8 @@ (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") (match_operand:SI 2 "general_operand" "ri,rm")))] "ix86_binary_operator_ok (MINUS, SImode, operands)" - "* return AS2 (sub%L0,%2,%0);") + "* return AS2 (sub%L0,%2,%0);" + [(set_attr "type" "binary")]) (define_expand "subhi3" [(set (match_operand:HI 0 "general_operand" "") @@ -3248,7 +3886,8 @@ return AS2 (sub%L0,%k2,%k0); } return AS2 (sub%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_expand "subqi3" [(set (match_operand:QI 0 "general_operand" "") @@ -3262,7 +3901,8 @@ (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "ix86_binary_operator_ok (MINUS, QImode, operands)" - "* return AS2 (sub%B0,%2,%0);") + "* return AS2 (sub%B0,%2,%0);" + [(set_attr "type" "binary")]) ;; The patterns that match these are at the end of this file. @@ -3688,7 +4328,8 @@ word_zero_and_operation: } return AS2 (and%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "andhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -3766,14 +4407,16 @@ word_zero_and_operation: } return AS2 (and%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "andqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" - "* return AS2 (and%B0,%2,%0);") + "* return AS2 (and%B0,%2,%0);" + [(set_attr "type" "binary")]) /* I am nervous about these two.. add them later.. ;I presume this means that we have something in say op0= eax which is small @@ -3889,7 +4532,8 @@ byte_or_operation: } return AS2 (or%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "iorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -3973,14 +4617,16 @@ byte_or_operation: } return AS2 (or%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "iorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" - "* return AS2 (or%B0,%2,%0);") + "* return AS2 (or%B0,%2,%0);" + [(set_attr "type" "binary")]) ;;- xor instructions @@ -4016,7 +4662,10 @@ byte_or_operation: byte_xor_operation: CC_STATUS_INIT; - if (intval == 0xff) + if (intval == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%b0); if (intval != INTVAL (operands[2])) @@ -4032,7 +4681,10 @@ byte_xor_operation: if (REG_P (operands[0])) { CC_STATUS_INIT; - if (intval == 0xff) + if (intval == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%h0); operands[2] = GEN_INT (intval); @@ -4068,7 +4720,8 @@ byte_xor_operation: } return AS2 (xor%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -4088,7 +4741,10 @@ byte_xor_operation: if (INTVAL (operands[2]) & 0xffff0000) operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); - if (INTVAL (operands[2]) == 0xff) + if (INTVAL (operands[2]) == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%b0); return AS2 (xor%B0,%2,%b0); @@ -4102,7 +4758,10 @@ byte_xor_operation: CC_STATUS_INIT; operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - if (INTVAL (operands[2]) == 0xff) + if (INTVAL (operands[2]) == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%h0); return AS2 (xor%B0,%2,%h0); @@ -4129,115 +4788,55 @@ byte_xor_operation: } return AS2 (xor%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "xorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qm")))] "" - "* return AS2 (xor%B0,%2,%0);") + "* return AS2 (xor%B0,%2,%0);" + [(set_attr "type" "binary")]) ;; logical operations for DImode - (define_insn "anddi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (and:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (and:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") + "#" + [(set_attr "type" "binary")]) + (define_insn "iordi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (ior:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") - + "#" + [(set_attr "type" "binary")]) + (define_insn "xordi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (xor:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") + "#" + [(set_attr "type" "binary")]) (define_split - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (match_operator:DI 4 "ix86_logical_operator" - [(match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")])) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] - "reload_completed" - [(const_int 0)] - " -{ - rtx low[3], high[3], xops[7], temp; - rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3 - : GET_CODE (operands[4]) == IOR ? gen_iorsi3 - : GET_CODE (operands[4]) == XOR ? gen_xorsi3 - : 0); - - if (rtx_equal_p (operands[0], operands[2])) - { - temp = operands[1]; - operands[1] = operands[2]; - operands[2] = temp; - } - - split_di (operands, 3, low, high); - if (!rtx_equal_p (operands[0], operands[1])) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[1]; - xops[3] = low[1]; - - if (GET_CODE (operands[0]) != MEM) - { - emit_insn (gen_movsi (xops[1], xops[3])); - emit_insn (gen_movsi (xops[0], xops[2])); - } - else - { - xops[4] = high[2]; - xops[5] = low[2]; - xops[6] = operands[3]; - emit_insn (gen_movsi (xops[6], xops[3])); - emit_insn ((*genfunc) (xops[6], xops[6], xops[5])); - emit_insn (gen_movsi (xops[1], xops[6])); - emit_insn (gen_movsi (xops[6], xops[2])); - emit_insn ((*genfunc) (xops[6], xops[6], xops[4])); - emit_insn (gen_movsi (xops[0], xops[6])); - DONE; - } - } - - if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[2]; - xops[3] = low[2]; - xops[4] = operands[3]; - - emit_insn (gen_movsi (xops[4], xops[3])); - emit_insn ((*genfunc) (xops[1], xops[1], xops[4])); - emit_insn (gen_movsi (xops[4], xops[2])); - emit_insn ((*genfunc) (xops[0], xops[0], xops[4])); - } - - else - { - emit_insn ((*genfunc) (low[0], low[0], low[2])); - emit_insn ((*genfunc) (high[0], high[0], high[2])); - } - - DONE; -}") + [(set (match_operand:DI 0 "general_operand" "") + (match_operator:DI 3 "ix86_logical_operator" + [(match_operand:DI 1 "general_operand" "") + (match_operand:DI 2 "general_operand" "")]))] + "" + [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)])) + (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))] + "split_di (&operands[0], 1, &operands[4], &operands[5]); + split_di (&operands[1], 1, &operands[6], &operands[7]); + split_di (&operands[2], 1, &operands[8], &operands[9]);") ;;- negation instructions @@ -4271,7 +4870,13 @@ byte_xor_operation: [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" - "neg%W0 %0") + "* + if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS1(neg%L0,%k0); + } + return AS1(neg%W0,%0);") (define_insn "negqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") @@ -4283,31 +4888,36 @@ byte_xor_operation: [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (match_operand:DF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "negxf2" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (match_operand:XF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) ;; Absolute value instructions @@ -4443,19 +5053,88 @@ byte_xor_operation: [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] "" - "not%L0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xffffffff); + output_asm_insn (AS2 (xor%L0,%1,%0), xops); + RET; + } + else + return AS1 (not%L0,%0); +}") (define_insn "one_cmplhi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" - "not%W0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xffff); + if (REG_P (operands[0]) + && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + output_asm_insn (AS2 (xor%L0,%1,%k0), xops); + } + else + output_asm_insn (AS2 (xor%W0,%1,%0), xops); + RET; + } + else + { + if (REG_P (operands[0]) + && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS1 (not%L0,%k0); + } + return AS1 (not%W0,%0); + } +}") (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] "" - "not%B0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xff); + output_asm_insn (AS2 (xor%B0,%1,%0), xops); + RET; + } + else + return AS1 (not%B0,%0); +}") ;;- arithmetic shift instructions @@ -4566,79 +5245,79 @@ byte_xor_operation: RET; }") -;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg" -;; On i486, movl/sall appears slightly faster than leal, but the leal -;; is smaller - use leal for now unless the shift count is 1. +(define_expand "ashlsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")))] + "" + "") -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") - (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0") - (match_operand:SI 2 "nonmemory_operand" "M,cI")))] +(define_expand "ashlhi3" + [(set (match_operand:HI 0 "nonimmediate_operand" "") + (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "nonmemory_operand" "")))] "" - "* -{ - if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) - { - if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - return AS2 (add%L0,%1,%0); - } - else - { - CC_STATUS_INIT; + "") - if (operands[1] == stack_pointer_rtx) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - operands[1] = operands[0]; - } - operands[1] = gen_rtx_MULT (SImode, operands[1], - GEN_INT (1 << INTVAL (operands[2]))); - return AS2 (lea%L0,%a1,%0); - } - } +(define_expand "ashlqi3" + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] + "" + "") - if (REG_P (operands[2])) - return AS2 (sal%L0,%b2,%0); +;; Pattern for shifts which can be encoded into an lea instruction. +;; This is kept as a separate pattern so that regmove can optimize cases +;; where we know the source and destination must match. +;; +;; Do not expose this pattern when optimizing for size since we never want +;; to use lea when optimizing for size since mov+sal is smaller than lea. - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%L0,%0,%0); +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r") + (match_operand:SI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") - return AS2 (sal%L0,%2,%0); -}") +;; Generic left shift pattern to catch all cases not handled by the +;; shift pattern above. +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "cI")))] + "" + "* return output_ashl (insn, operands);") -(define_insn "ashlhi3" +(define_insn "" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") + (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r") + (match_operand:HI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") + +(define_insn "" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%W0,%b2,%0); + "* return output_ashl (insn, operands);") - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%W0,%0,%0); - - return AS2 (sal%W0,%2,%0); -}") +(define_insn "" + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q") + (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q") + (match_operand:QI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") -(define_insn "ashlqi3" +;; Generic left shift pattern to catch all cases not handled by the +;; shift pattern above. +(define_insn "" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%B0,%b2,%0); - - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%B0,%0,%0); - - return AS2 (sal%B0,%2,%0); -}") + "* return output_ashl (insn, operands);") ;; See comment above `ashldi3' about how this works. @@ -4755,6 +5434,15 @@ byte_xor_operation: RET; }") +(define_insn "ashrsi3_31" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d") + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a") + (const_int 31)))] + "!TARGET_PENTIUM || optimize_size" + "@ + sar%L0 $31,%0 + cltd") + (define_insn "ashrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") @@ -5177,7 +5865,10 @@ byte_xor_operation: mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); operands[1] = GEN_INT (mask); - if (QI_REG_P (operands[0])) + if (QI_REG_P (operands[0]) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { if ((mask & ~0xff) == 0) { @@ -5211,7 +5902,10 @@ byte_xor_operation: mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); operands[1] = GEN_INT (mask); - if (! REG_P (operands[0]) || QI_REG_P (operands[0])) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { if ((mask & ~0xff) == 0) { @@ -5261,10 +5955,6 @@ byte_xor_operation: ;; For all sCOND expanders, also expand the compare or test insn that ;; generates cc0. Generate an equality comparison if `seq' or `sne'. -;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may -;; not have any input reloads. A MEM write might need an input reload -;; for the address of the MEM. So don't allow MEM as the SET_DEST. - (define_expand "seq" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5279,18 +5969,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (eq:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setnb,%0); - else - return AS1 (sete,%0); -}") - (define_expand "sne" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5302,54 +5980,22 @@ byte_xor_operation: && GET_MODE_CLASS (GET_MODE (i386_compare_op0)) == MODE_FLOAT) operands[1] = (*i386_compare_gen_eq)(i386_compare_op0, i386_compare_op1); else - operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); -}") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ne:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setb,%0); - else - return AS1 (setne,%0); -} -") - -(define_expand "sgt" - [(match_dup 1) - (set (match_operand:QI 0 "register_operand" "") - (gt:QI (cc0) (const_int 0)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (gt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR); + operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_expand "sgtu" +(define_expand "sgt" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") - (gtu:QI (cc0) (const_int 0)))] + (gt:QI (cc0) (const_int 0)))] "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") +(define_expand "sgtu" + [(match_dup 1) + (set (match_operand:QI 0 "register_operand" "") (gtu:QI (cc0) (const_int 0)))] "" - "* return \"seta %0\"; ") + "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_expand "slt" [(match_dup 1) @@ -5358,19 +6004,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (lt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); -}") - (define_expand "sltu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5378,12 +6011,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ltu:QI (cc0) (const_int 0)))] - "" - "* return \"setb %0\"; ") - (define_expand "sge" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5391,19 +6018,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ge:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); -}") - (define_expand "sgeu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5411,12 +6025,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (geu:QI (cc0) (const_int 0)))] - "" - "* return \"setae %0\"; ") - (define_expand "sle" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5424,19 +6032,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (le:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (setb,%0); - - OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR); -}") - (define_expand "sleu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5444,11 +6039,69 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (leu:QI (cc0) (const_int 0)))] - "" - "* return \"setbe %0\"; ") +;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may +;; not have any input reloads. A MEM write might need an input reload +;; for the address of the MEM. So don't allow MEM as the SET_DEST. + +(define_insn "*setcc" + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))] + "reload_completed || register_operand (operands[0], QImode)" + "* +{ + enum rtx_code code = GET_CODE (operands[1]); + if (cc_prev_status.flags & CC_TEST_AX) + { + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 0; + break; + case NE: + c = 0x4000; + eq = 1; + break; + case GT: + c = 0x4100; + eq = 1; + break; + case LT: + c = 0x100; + eq = 0; + break; + case GE: + c = 0x100; + eq = 1; + break; + case LE: + c = 0x4100; + eq = 0; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (sete,%0) : AS1 (setne, %0); + } + + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; + return AS1(set%D1,%0); +}") + ;; Basic conditional jump instructions. ;; We ignore the overflow flag for signed branch instructions. @@ -5473,29 +6126,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - - return \"je %l0\"; -}") - (define_expand "bne" [(match_dup 1) (set (pc) @@ -5513,28 +6143,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - - return \"jne %l0\"; -}") (define_expand "bgt" [(match_dup 1) @@ -5546,29 +6154,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") - (define_expand "bgtu" [(match_dup 1) (set (pc) @@ -5579,15 +6164,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "ja %l0") - (define_expand "blt" [(match_dup 1) (set (pc) @@ -5598,28 +6174,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); -}") (define_expand "bltu" [(match_dup 1) @@ -5631,289 +6185,169 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jb %l0") - -(define_expand "bge" - [(match_dup 1) - (set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") - -(define_expand "bgeu" - [(match_dup 1) - (set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jae %l0") - -(define_expand "ble" - [(match_dup 1) - (set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jb,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); -}") - -(define_expand "bleu" - [(match_dup 1) - (set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jbe %l0") - -;; Negated conditional jump instructions. - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - return \"jne %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - return \"je %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) +(define_expand "bge" + [(match_dup 1) + (set (pc) + (if_then_else (ge (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 0 "" "")) + (pc)))] "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); -}") + "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) +(define_expand "bgeu" + [(match_dup 1) + (set (pc) + (if_then_else (geu (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 0 "" "")) + (pc)))] "" - "jbe %l0") + "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) +(define_expand "ble" + [(match_dup 1) + (set (pc) + (if_then_else (le (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 0 "" "")) + (pc)))] "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") + "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) +(define_expand "bleu" + [(match_dup 1) + (set (pc) + (if_then_else (leu (cc0) (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 0 "" "")) + (pc)))] "" - "jae %l0") + "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") (define_insn "" [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] + (if_then_else (match_operator 0 "comparison_operator" + [(cc0) (const_int 0)]) + (label_ref (match_operand 1 "" "")) + (pc)))] "" "* { - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); + enum rtx_code code = GET_CODE (operands[0]); if (cc_prev_status.flags & CC_TEST_AX) { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 0; + break; + case NE: + c = 0x4000; + eq = 1; + break; + case GT: + c = 0x4100; + eq = 1; + break; + case LT: + c = 0x100; + eq = 0; + break; + case GE: + c = 0x100; + eq = 1; + break; + case LE: + c = 0x4100; + eq = 0; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (je,%l1) : AS1 (jne, %l1); } - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); -}") + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jb %l0") + return AS1(j%D0,%l1); +}") (define_insn "" [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) + (if_then_else (match_operator 0 "comparison_operator" + [(cc0) (const_int 0)]) (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 1 "" ""))))] "" "* { - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jae,%l0); - + enum rtx_code code = GET_CODE (operands[0]); if (cc_prev_status.flags & CC_TEST_AX) { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 1; + break; + case NE: + c = 0x4000; + eq = 0; + break; + case GT: + c = 0x4100; + eq = 0; + break; + case LT: + c = 0x100; + eq = 1; + break; + case GE: + c = 0x100; + eq = 0; + break; + case LE: + c = 0x4100; + eq = 1; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (je,%l1) : AS1 (jne, %l1); } - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "ja %l0") + return AS1(j%d0,%l1); +}") ;; Unconditional and other jump instructions @@ -5921,7 +6355,8 @@ byte_xor_operation: [(set (pc) (label_ref (match_operand 0 "" "")))] "" - "jmp %l0") + "jmp %l0" + [(set_attr "memory" "none")]) (define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] @@ -5931,7 +6366,8 @@ byte_xor_operation: CC_STATUS_INIT; return AS1 (jmp,%*%0); -}") +}" + [(set_attr "memory" "none")]) ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); ;; if S does not change i @@ -5952,7 +6388,7 @@ byte_xor_operation: (define_insn "" [(set (pc) (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") + [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m") (match_operand:SI 2 "general_operand" "rmi,ri")) (const_int 0)]) (label_ref (match_operand 3 "" "")) @@ -5964,6 +6400,11 @@ byte_xor_operation: "* { CC_STATUS_INIT; + + if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 && + operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6) + return \"loop %l3\"; + if (operands[2] == constm1_rtx) output_asm_insn (AS1 (dec%L1,%1), operands); @@ -6228,6 +6669,12 @@ byte_xor_operation: { rtx addr; + if (operands[3] == const0_rtx) + { + emit_insn (gen_call (operands[0], operands[1])); + DONE; + } + if (flag_pic) current_function_uses_pic_offset_table = 1; @@ -6330,6 +6777,12 @@ byte_xor_operation: { rtx addr; + if (operands[4] == const0_rtx) + { + emit_insn (gen_call_value (operands[0], operands[1], operands[2])); + DONE; + } + if (flag_pic) current_function_uses_pic_offset_table = 1; @@ -6469,7 +6922,8 @@ byte_xor_operation: (define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" - "") + "" + [(set_attr "memory" "none")]) ;; Insn emitted into the body of a function to return from a function. ;; This is only done if the function's epilogue is known to be simple. @@ -6483,18 +6937,21 @@ byte_xor_operation: (define_insn "return_internal" [(return)] "reload_completed" - "ret") + "ret" + [(set_attr "memory" "none")]) (define_insn "return_pop_internal" [(return) (use (match_operand:SI 0 "const_int_operand" ""))] "reload_completed" - "ret %0") + "ret %0" + [(set_attr "memory" "none")]) (define_insn "nop" [(const_int 0)] "" - "nop") + "nop" + [(set_attr "memory" "none")]) (define_expand "prologue" [(const_int 1)] @@ -6521,7 +6978,8 @@ byte_xor_operation: xops[1] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L1,%0,%1), xops); RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "prologue_set_got" [(set (match_operand:SI 0 "" "") @@ -6553,15 +7011,14 @@ byte_xor_operation: "" "* { - char buffer[64]; - output_asm_insn (AS1 (call,%X1), operands); if (! TARGET_DEEP_BRANCH_PREDICTION) { ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); } RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "prologue_get_pc_and_set_got" [(unspec_volatile [(match_operand:SI 0 "" "")] 3)] @@ -6573,9 +7030,10 @@ byte_xor_operation: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); output_asm_insn (AS1 (pop%L0,%0), operands); - output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); + output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); RET; -}") +}" + [(set_attr "memory" "none")]) (define_expand "epilogue" [(const_int 1)] @@ -6598,14 +7056,16 @@ byte_xor_operation: xops[1] = stack_pointer_rtx; output_asm_insn (AS2 (mov%L0,%0,%1), xops); RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "leave" [(const_int 2) (clobber (reg:SI 6)) (clobber (reg:SI 7))] "" - "leave") + "leave" + [(set_attr "memory" "none")]) (define_insn "pop" [(set (match_operand:SI 0 "register_operand" "r") @@ -6616,7 +7076,8 @@ byte_xor_operation: { output_asm_insn (AS1 (pop%L0,%P0), operands); RET; -}") +}" + [(set_attr "memory" "load")]) (define_expand "movstrsi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") @@ -6698,7 +7159,7 @@ byte_xor_operation: "" " { - rtx addr0, addr1; + rtx addr0; if (GET_CODE (operands[1]) != CONST_INT) FAIL; @@ -6715,7 +7176,7 @@ byte_xor_operation: ;; But strength reduction might offset the MEM expression. So we let ;; reload put the address into %edi. -(define_insn "" +(define_insn "*bzero" [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) (const_int 0)) (use (match_operand:SI 1 "const_int_operand" "n")) @@ -6731,17 +7192,35 @@ byte_xor_operation: output_asm_insn (\"cld\", operands); if (GET_CODE (operands[1]) == CONST_INT) { - if (INTVAL (operands[1]) & ~0x03) + unsigned int count = INTVAL (operands[1]) & 0xffffffff; + if (count & ~0x03) { - xops[0] = GEN_INT ((INTVAL (operands[1]) >> 2) & 0x3fffffff); + xops[0] = GEN_INT (count / 4); xops[1] = operands[4]; - output_asm_insn (AS2 (mov%L1,%0,%1), xops); + /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles. + 80386: 4/5+5n (+2 for set of ecx) + 80486: 5/7+5n (+1 for set of ecx) + */ + if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6)) + { + do +#ifdef INTEL_SYNTAX + output_asm_insn (\"stosd\", xops); +#else + output_asm_insn (\"stosl\", xops); +#endif + while ((count -= 4) > 3); + } + else + { + output_asm_insn (AS2 (mov%L1,%0,%1), xops); #ifdef INTEL_SYNTAX - output_asm_insn (\"rep stosd\", xops); + output_asm_insn (\"rep stosd\", xops); #else - output_asm_insn (\"rep\;stosl\", xops); + output_asm_insn (\"rep\;stosl\", xops); #endif + } } if (INTVAL (operands[1]) & 0x02) output_asm_insn (\"stosw\", operands); @@ -6910,9 +7389,7 @@ byte_xor_operation: ;; mulM3 and divM3. There are three patterns for each of DFmode and ;; SFmode. The first is the normal insn, the second the same insn but ;; with one operand a conversion, and the third the same insn but with -;; the other operand a conversion. The conversion may be SFmode or -;; SImode if the target mode DFmode, but only SImode if the target mode -;; is SFmode. +;; the other operand a conversion. (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") @@ -6932,23 +7409,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:DF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(match_operand:XF 1 "register_operand" "0,f") @@ -6966,23 +7426,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:XF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) @@ -7000,23 +7443,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "register_operand" "0") - (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(match_operand:XF 1 "register_operand" "0,f") @@ -7052,23 +7478,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "register_operand" "0") - (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") (match_operator:DF 3 "binary_387_op" [(match_operand:DF 1 "register_operand" "0,f") @@ -7102,40 +7511,6 @@ byte_xor_operation: (const_string "fpop") ) )]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:SF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(match_operand:SF 1 "register_operand" "0") - (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) (define_expand "strlensi" [(parallel [(set (match_dup 4) @@ -7258,12 +7633,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:SI 0 "register_operand" "=r,r") + [(set (match_operand:SI 0 "register_operand" "") (if_then_else:SI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:SI 3 "nonimmediate_operand" "rm,0") - (match_operand:SI 4 "nonimmediate_operand" "0,rm")))] + (match_operand:SI 3 "nonimmediate_operand" "") + (match_operand:SI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7273,12 +7648,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:SI 0 "register_operand" "=r,r") + [(set (match_operand:SI 0 "register_operand" "") (if_then_else:SI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:SI 4 "nonimmediate_operand" "rm,0") - (match_operand:SI 5 "nonimmediate_operand" "0,rm")))] + (match_operand:SI 4 "nonimmediate_operand" "") + (match_operand:SI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7332,12 +7707,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:HI 0 "register_operand" "=r,r") + [(set (match_operand:HI 0 "register_operand" "") (if_then_else:HI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:HI 3 "nonimmediate_operand" "rm,0") - (match_operand:HI 4 "nonimmediate_operand" "0,rm")))] + (match_operand:HI 3 "nonimmediate_operand" "") + (match_operand:HI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7347,12 +7722,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:HI 0 "register_operand" "=r,r") + [(set (match_operand:HI 0 "register_operand" "") (if_then_else:HI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:HI 4 "nonimmediate_operand" "rm,0") - (match_operand:HI 5 "nonimmediate_operand" "0,rm")))] + (match_operand:HI 4 "nonimmediate_operand" "") + (match_operand:HI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) @@ -7435,12 +7810,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "") + (match_operand:SF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7450,12 +7825,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:SF 4 "register_operand" "f,0") - (match_operand:SF 5 "register_operand" "0,f")))] + (match_operand:SF 4 "register_operand" "") + (match_operand:SF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7537,12 +7912,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:DF 0 "register_operand" "=f,f") + [(set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:DF 3 "register_operand" "f,0") - (match_operand:DF 4 "register_operand" "0,f")))] + (match_operand:DF 3 "register_operand" "") + (match_operand:DF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7552,12 +7927,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:DF 0 "register_operand" "=f,f") + [(set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:DF 4 "register_operand" "f,0") - (match_operand:DF 5 "register_operand" "0,f")))] + (match_operand:DF 4 "register_operand" "") + (match_operand:DF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7639,12 +8014,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "") (if_then_else:XF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:XF 3 "register_operand" "f,0") - (match_operand:XF 4 "register_operand" "0,f")))] + (match_operand:XF 3 "register_operand" "") + (match_operand:XF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7654,12 +8029,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "") (if_then_else:XF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:XF 4 "register_operand" "f,0") - (match_operand:XF 5 "register_operand" "0,f")))] + (match_operand:XF 4 "register_operand" "") + (match_operand:XF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7713,42 +8088,43 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:DI 0 "register_operand" "=&r,&r") + [(set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:DI 3 "nonimmediate_operand" "ro,0") - (match_operand:DI 4 "nonimmediate_operand" "0,ro")))] + (match_operand:DI 3 "nonimmediate_operand" "") + (match_operand:DI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) - (set (match_dup 0) - (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)]) - (match_dup 3) (match_dup 4)))] - "") + (set (match_dup 5) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 7) (match_dup 9))) + (set (match_dup 6) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 8) (match_dup 10)))] + "split_di (&operands[0], 1, &operands[5], &operands[6]); + split_di (&operands[3], 1, &operands[7], &operands[8]); + split_di (&operands[4], 1, &operands[9], &operands[10]);") (define_split - [(set (match_operand:DI 0 "register_operand" "=&r,&r") + [(set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:DI 4 "nonimmediate_operand" "ro,0") - (match_operand:DI 5 "nonimmediate_operand" "0,ro")))] + (match_operand:DI 4 "nonimmediate_operand" "") + (match_operand:DI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) - (set (match_dup 0) - (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)]) - (match_dup 4) (match_dup 5)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r,&r") - (if_then_else:DI (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (match_operand:DI 2 "nonimmediate_operand" "ro,0") - (match_operand:DI 3 "nonimmediate_operand" "0,ro")))] - "TARGET_CMOVE && reload_completed" - "* return output_int_conditional_move (which_alternative, operands);") + (set (match_dup 6) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 8) (match_dup 10))) + (set (match_dup 7) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 9) (match_dup 11)))] + "split_di (&operands[0], 1, &operands[6], &operands[7]); + split_di (&operands[4], 1, &operands[8], &operands[9]); + split_di (&operands[5], 1, &operands[10], &operands[11]);") (define_insn "strlensi_unroll" [(set (match_operand:SI 0 "register_operand" "=&r,&r") @@ -7785,7 +8161,8 @@ byte_xor_operation: (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) (clobber (match_dup 0))] "TARGET_STACK_PROBE" - "* return AS1(call,__alloca);") + "* return AS1(call,__alloca);" + [(set_attr "memory" "none")]) (define_expand "allocate_stack" [(set (match_operand:SI 0 "register_operand" "=r") diff --git a/contrib/gcc/config/i386/interix.c b/contrib/gcc/config/i386/interix.c new file mode 100644 index 0000000..40062c7 --- /dev/null +++ b/contrib/gcc/config/i386/interix.c @@ -0,0 +1,110 @@ +/* Subroutines for insn-output.c for Windows NT. + Copyright (C) 1998, 1999 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. */ + +#include "config.h" +#include "system.h" +#include "rtl.h" +#include "regs.h" +#include "hard-reg-set.h" +#include "output.h" +#include "tree.h" +#include "flags.h" + +/* Return string which is the former assembler name modified with a + suffix consisting of an atsign (@) followed by the number of bytes of + arguments */ + +char * +gen_stdcall_suffix (decl) + tree decl; +{ + int total = 0; + /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead + of DECL_ASSEMBLER_NAME. */ + 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)); + + while (TREE_VALUE (formal_type) != void_type_node) + { + 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); + } + } + + newsym = xmalloc (strlen (asmname) + 10); + sprintf (newsym, "%s@%d", asmname, total/BITS_PER_UNIT); + return IDENTIFIER_POINTER (get_identifier (newsym)); +} + +#if 0 +/* Turn this back on when the linker is updated to handle grouped + .data$ sections correctly. See corresponding note in i386/interix.h. + MK. */ + +/* Cover function for UNIQUE_SECTION. */ + +void +i386_pe_unique_section (decl, reloc) + tree decl; + int reloc; +{ + int len; + char *name,*string,*prefix; + + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + /* Strip off any encoding in fnname. */ + STRIP_NAME_ENCODING (name, name); + + /* 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 + bug when .rdata$* grouped sections are used in code + without a .rdata section. */ + if (TREE_CODE (decl) == FUNCTION_DECL) + prefix = ".text$"; + else if (DECL_READONLY_SECTION (decl, reloc)) +#ifdef READONLY_DATA_SECTION + prefix = ".rdata$"; +#else + prefix = ".text$"; +#endif + else + prefix = ".data$"; + len = strlen (name) + strlen (prefix); + string = alloca (len + 1); + sprintf (string, "%s%s", prefix, name); + + DECL_SECTION_NAME (decl) = build_string (len, string); +} + +#endif /* 0 */ diff --git a/contrib/gcc/config/i386/isc.h b/contrib/gcc/config/i386/isc.h index 5c39896..6c1c4c7 100644 --- a/contrib/gcc/config/i386/isc.h +++ b/contrib/gcc/config/i386/isc.h @@ -59,7 +59,7 @@ So don't make TARGET_IEEE_FP default for ISC. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 +#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS) /* The ISC 2.0.2 software FPU emulator apparently can't handle 80-bit XFmode insns, so don't generate them. */ @@ -72,20 +72,23 @@ message. */ #undef ASM_FILE_START -#define ASM_FILE_START(FILE) \ - do { \ - char c; \ - int max = 0; \ - char *string = dump_base_name; \ - \ - fputs ("\t.file\t\"", FILE); \ - \ - while ((c = *string++) != 0 && max++ < 14) { \ - if (c == '\"' || c == '\\') \ - putc ('\\', FILE); \ - putc (c, FILE); \ - } \ - fputs ("\"\n", FILE); \ +#define ASM_FILE_START(FILE) \ + do { \ + int len = strlen (main_input_filename); \ + char *na = main_input_filename + len; \ + char shorter[15]; \ + /* NA gets MAIN_INPUT_FILENAME sans directory names. */\ + while (na > main_input_filename) \ + { \ + if (na[-1] == '/') \ + break; \ + na--; \ + } \ + strncpy (shorter, na, 14); \ + shorter[14] = 0; \ + fprintf (FILE, "\t.file\t"); \ + output_quoted_string (FILE, shorter); \ + fprintf (FILE, "\n"); \ } while (0) /* Work around assembler forward label references generated in exception diff --git a/contrib/gcc/config/i386/isccoff.h b/contrib/gcc/config/i386/isccoff.h index 383b981..595c7d9 100644 --- a/contrib/gcc/config/i386/isccoff.h +++ b/contrib/gcc/config/i386/isccoff.h @@ -1,8 +1,8 @@ /* Definitions for Intel 386 running Interactive Unix System V. Specifically, this is for recent versions that support POSIX; for version 2.0.2, use configuration option i386-sysv instead. - (But set TARGET_DEFAULT to 0201 if you do that, - if you don't have a real 80387.) */ + (But set TARGET_DEFAULT to (MASK_80307 | MASK_FLOAT_RETURNS) + if you do that, if you don't have a real 80387.) */ /* Mostly it's like AT&T Unix System V. */ diff --git a/contrib/gcc/config/i386/linux.h b/contrib/gcc/config/i386/linux.h index 8e84bb5..7b368f8 100644 --- a/contrib/gcc/config/i386/linux.h +++ b/contrib/gcc/config/i386/linux.h @@ -150,9 +150,8 @@ Boston, MA 02111-1307, USA. */ #undef WCHAR_TYPE_SIZE #define WCHAR_TYPE_SIZE BITS_PER_WORD -/* The egcs-1.1 branch is the last time we will have -Di386. -D__i386__ is the thing to use. */ #undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D__ELF__ -Dunix -Di386 -D__i386__ -Dlinux -Asystem(posix)" +#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__i386__ -Dlinux -Asystem(posix)" #undef CPP_SPEC #ifdef USE_GNULIBC_1 @@ -227,8 +226,11 @@ Boston, MA 02111-1307, USA. */ This is used to align code labels according to Intel recommendations. */ #ifdef HAVE_GAS_MAX_SKIP_P2ALIGN -#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)) +#define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ + do { \ + 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)); \ + } \ + } while (0) #endif diff --git a/contrib/gcc/config/i386/mingw32.h b/contrib/gcc/config/i386/mingw32.h index cd4d3e6..552cbcd 100644 --- a/contrib/gcc/config/i386/mingw32.h +++ b/contrib/gcc/config/i386/mingw32.h @@ -2,7 +2,7 @@ hosting on 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) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -21,17 +21,17 @@ 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. */ -/* Most of this is the same as for Cygwin32, except for changing some +/* Most of this is the same as for cygwin, except for changing some specs. */ -#include "i386/cygwin32.h" +#include "i386/cygwin.h" /* Please keep changes to CPP_PREDEFINES in sync with i386/crtdll. The only difference between the two should be __MSVCRT__ needed to distinguish MSVC from CRTDLL runtime in mingw headers. */ #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Di386 -D_WIN32 -DWIN32 -D__WIN32__ \ - -D__MINGW32__ -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\ + -D__MINGW32__=0.2 -D__MSVCRT__ -DWINNT -D_X86_=1 -D__STDC__=1\ -D__stdcall=__attribute__((__stdcall__)) \ -D_stdcall=__attribute__((__stdcall__)) \ -D__cdecl=__attribute__((__cdecl__)) \ @@ -44,25 +44,24 @@ Boston, MA 02111-1307, USA. */ #define STANDARD_INCLUDE_COMPONENT "MINGW32" +#undef CPP_SPEC +#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE}" + /* For Windows applications, include more libraries, but always include kernel32. */ #undef LIB_SPEC -#define LIB_SPEC \ -"%{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32 -lshell32" +#define LIB_SPEC "%{mwindows:-lgdi32 -lcomdlg32} \ + -luser32 -lkernel32 -ladvapi32 -lshell32" /* Include in the mingw32 libraries with libgcc */ #undef LIBGCC_SPEC #define LIBGCC_SPEC "-lmingw32 -lgcc -lmoldname -lmsvcrt" -/* Specify a different entry point when linking a DLL */ -#undef LINK_SPEC -#define LINK_SPEC \ -"%{mwindows:--subsystem windows} %{mdll:--dll -e _DllMainCRTStartup@12}" - #undef STARTFILE_SPEC #define STARTFILE_SPEC "%{mdll:dllcrt2%O%s} %{!mdll:crt2%O%s}" -#define MATH_LIBRARY "-lmsvcrt" +/* MS runtime does not need a separate math library. */ +#define MATH_LIBRARY "" /* Output STRING, a string representing a filename, to FILE. We canonicalize it to be in MS-DOS format. */ diff --git a/contrib/gcc/config/i386/moss.h b/contrib/gcc/config/i386/moss.h index dadf3d8..d2548e3 100644 --- a/contrib/gcc/config/i386/moss.h +++ b/contrib/gcc/config/i386/moss.h @@ -16,7 +16,8 @@ GNU General Public License for more details. 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. */ +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* I believe in reuse... */ #include "i386/linux.h" diff --git a/contrib/gcc/config/i386/netbsd.h b/contrib/gcc/config/i386/netbsd.h index 5978aec..d9f0646 100644 --- a/contrib/gcc/config/i386/netbsd.h +++ b/contrib/gcc/config/i386/netbsd.h @@ -1,6 +1,3 @@ -/* This goes away when the math-emulator is fixed */ -#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */ - /* This is tested by i386gas.h. */ #define YES_UNDERSCORES @@ -12,6 +9,11 @@ /* Get generic NetBSD definitions. */ #include +/* This goes away when the math-emulator is fixed */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387) + #undef CPP_PREDEFINES #define CPP_PREDEFINES "-Dunix -Di386 -D__NetBSD__ -Asystem(unix) -Asystem(NetBSD) -Acpu(i386) -Amachine(i386)" diff --git a/contrib/gcc/config/i386/next.h b/contrib/gcc/config/i386/next.h index 65f7402..bbc0e6b 100644 --- a/contrib/gcc/config/i386/next.h +++ b/contrib/gcc/config/i386/next.h @@ -1,5 +1,5 @@ /* Target definitions for GNU compiler for Intel x86 CPU running NeXTSTEP - Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1993, 1995, 1996, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA. */ /* By default, target has a 80387, with IEEE FP. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT (1|0100) +#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP) /* Implicit library calls should use memcpy, not bcopy, etc. */ diff --git a/contrib/gcc/config/i386/openbsd.h b/contrib/gcc/config/i386/openbsd.h index 1b56262..dc84f89 100644 --- a/contrib/gcc/config/i386/openbsd.h +++ b/contrib/gcc/config/i386/openbsd.h @@ -31,6 +31,11 @@ Boston, MA 02111-1307, USA. */ #define OBSD_OLD_GAS #include +/* This goes away when the math-emulator is fixed */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_NO_FANCY_MATH_387) + /* Run-time target specifications */ #define CPP_PREDEFINES "-D__unix__ -D__i386__ -D__OpenBSD__ -Asystem(unix) -Asystem(OpenBSD) -Acpu(i386) -Amachine(i386)" @@ -120,9 +125,10 @@ Boston, MA 02111-1307, USA. */ #ifdef HAVE_GAS_MAX_SKIP_P2ALIGN #define ASM_OUTPUT_MAX_SKIP_ALIGN(FILE,LOG,MAX_SKIP) \ do { \ - if ((LOG) != 0) \ + 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)); \ + } \ } while (0) #endif diff --git a/contrib/gcc/config/i386/osf1elf.h b/contrib/gcc/config/i386/osf1elf.h index da61e8b..003400b 100644 --- a/contrib/gcc/config/i386/osf1elf.h +++ b/contrib/gcc/config/i386/osf1elf.h @@ -121,8 +121,8 @@ extern char *sys_siglist[]; #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ - { "mcount", -MASK_NO_MCOUNT}, \ - { "no-mcount", MASK_NO_MCOUNT}, + { "mcount", -MASK_NO_MCOUNT, "Profiling uses mcount" }, \ + { "no-mcount", MASK_NO_MCOUNT, "" }, /* This macro generates the assembly code for function entry. FILE is a stdio stream to output the code to. diff --git a/contrib/gcc/config/i386/osfrose.h b/contrib/gcc/config/i386/osfrose.h index 9cfe187..9ad9f95 100644 --- a/contrib/gcc/config/i386/osfrose.h +++ b/contrib/gcc/config/i386/osfrose.h @@ -1,6 +1,6 @@ /* Definitions of target machine for GNU compiler. Intel 386 (OSF/1 with OSF/rose) version. - Copyright (C) 1991, 1992, 1993, 1996 Free Software Foundation, Inc. + Copyright (C) 1991, 1992, 1993, 1996, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -43,7 +43,6 @@ Boston, MA 02111-1307, USA. */ #define MASK_HALF_PIC 010000000000 /* Mask for half-pic code */ #define MASK_HALF_PIC_DEBUG 004000000000 /* Debug flag */ #define MASK_ELF 002000000000 /* ELF not rose */ -#define MASK_NO_IDENT 001000000000 /* suppress .ident */ #define MASK_NO_UNDERSCORES 000400000000 /* suppress leading _ */ #define MASK_LARGE_ALIGN 000200000000 /* align to >word boundaries */ #define MASK_NO_MCOUNT 000100000000 /* profiling uses mcount_ptr */ @@ -53,28 +52,25 @@ Boston, MA 02111-1307, USA. */ #define HALF_PIC_DEBUG TARGET_DEBUG #define TARGET_ELF (target_flags & MASK_ELF) #define TARGET_ROSE ((target_flags & MASK_ELF) == 0) -#define TARGET_IDENT ((target_flags & MASK_NO_IDENT) == 0) #define TARGET_UNDERSCORES ((target_flags & MASK_NO_UNDERSCORES) == 0) #define TARGET_LARGE_ALIGN (target_flags & MASK_LARGE_ALIGN) #define TARGET_MCOUNT ((target_flags & MASK_NO_MCOUNT) == 0) #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ - { "half-pic", MASK_HALF_PIC}, \ - { "no-half-pic", -MASK_HALF_PIC}, \ - { "debug-half-pic", MASK_HALF_PIC_DEBUG}, \ - { "debugb", MASK_HALF_PIC_DEBUG}, \ - { "elf", MASK_ELF}, \ - { "rose", -MASK_ELF}, \ - { "ident", -MASK_NO_IDENT}, \ - { "no-ident", MASK_NO_IDENT}, \ - { "underscores", -MASK_NO_UNDERSCORES}, \ - { "no-underscores", MASK_NO_UNDERSCORES}, \ - { "large-align", MASK_LARGE_ALIGN}, \ - { "no-large-align", -MASK_LARGE_ALIGN}, \ - { "mcount", -MASK_NO_MCOUNT}, \ - { "mcount-ptr", MASK_NO_MCOUNT}, \ - { "no-mcount", MASK_NO_MCOUNT}, + { "half-pic", MASK_HALF_PIC, "Emit half-PIC code" }, \ + { "no-half-pic", -MASK_HALF_PIC, "" } \ + { "debug-half-pic", MASK_HALF_PIC_DEBUG, 0 /* intentionally undoc */ }, \ + { "debugb", MASK_HALF_PIC_DEBUG, 0 /* intentionally undoc */ }, \ + { "elf", MASK_ELF, "Emit ELF object code" }, \ + { "rose", -MASK_ELF, "Emit ROSE object code" }, \ + { "underscores", -MASK_NO_UNDERSCORES, "Symbols have a leading underscore" }, \ + { "no-underscores", MASK_NO_UNDERSCORES, "" }, \ + { "large-align", MASK_LARGE_ALIGN, "Align to >word boundaries" }, \ + { "no-large-align", -MASK_LARGE_ALIGN, "" }, \ + { "mcount", -MASK_NO_MCOUNT, "Use mcount for profiling" }, \ + { "mcount-ptr", MASK_NO_MCOUNT, "Use mcount_ptr for profiling" }, \ + { "no-mcount", MASK_NO_MCOUNT, "" }, /* OSF/rose uses stabs, not dwarf. */ #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG @@ -752,7 +748,7 @@ do \ if (HALF_PIC_P ()) \ HALF_PIC_FINISH (STREAM); \ \ - if (TARGET_IDENT) \ + if (!flag_no_ident) \ { \ char *fstart = main_input_filename; \ char *fname; \ diff --git a/contrib/gcc/config/i386/sco.h b/contrib/gcc/config/i386/sco.h index 016e0a0..55af641 100644 --- a/contrib/gcc/config/i386/sco.h +++ b/contrib/gcc/config/i386/sco.h @@ -1,5 +1,5 @@ /* Definitions for Intel 386 running SCO Unix System V. - Copyright (C) 1988, 1992, 1994, 1995 Free, 1996 Software Foundation, Inc. + Copyright (C) 1988, 92, 94, 95, 96, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA. */ So don't make TARGET_IEEE_FP default for SCO. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 +#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS) /* Let's guess that the SCO software FPU emulator can't handle 80-bit XFmode insns, so don't generate them. */ diff --git a/contrib/gcc/config/i386/sco5.h b/contrib/gcc/config/i386/sco5.h index 74fb891..ac4e7e1 100644 --- a/contrib/gcc/config/i386/sco5.h +++ b/contrib/gcc/config/i386/sco5.h @@ -1,5 +1,5 @@ /* Definitions for Intel 386 running SCO Unix System V 3.2 Version 5. - Copyright (C) 1992, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 95-98, 1999 Free Software Foundation, Inc. Contributed by Kean Johnston (hug@netcom.com) This file is part of GNU CC. @@ -211,8 +211,9 @@ do { \ #undef ASM_FILE_END #define ASM_FILE_END(FILE) \ do { \ - fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \ - IDENT_ASM_OP, version_string); \ + if (!flag_no_ident) \ + fprintf ((FILE), "%s\t\"GCC: (GNU) %s\"\n", \ + IDENT_ASM_OP, version_string); \ } while (0) #undef ASM_FINISH_DECLARE_OBJECT @@ -689,7 +690,9 @@ dtors_section () \ #undef SELECT_SECTION #define SELECT_SECTION(DECL,RELOC) \ { \ - if (TREE_CODE (DECL) == STRING_CST) \ + if (TARGET_ELF && flag_pic && RELOC) \ + data_section (); \ + else if (TREE_CODE (DECL) == STRING_CST) \ { \ if (! flag_writable_strings) \ const_section (); \ @@ -698,11 +701,7 @@ dtors_section () \ } \ else if (TREE_CODE (DECL) == VAR_DECL) \ { \ - if ((TARGET_ELF && flag_pic && RELOC) \ - || !TREE_READONLY (DECL) || TREE_SIDE_EFFECTS (DECL) \ - || !DECL_INITIAL (DECL) \ - || (DECL_INITIAL (DECL) != error_mark_node \ - && !TREE_CONSTANT (DECL_INITIAL (DECL)))) \ + if (! DECL_READONLY_SECTION (DECL, RELOC)) \ data_section (); \ else \ const_section (); \ @@ -726,11 +725,19 @@ dtors_section () \ && strcmp (STR, "Tbss")) #undef TARGET_DEFAULT -#define TARGET_DEFAULT 0301 +#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS) #undef HANDLE_SYSV_PRAGMA #define HANDLE_SYSV_PRAGMA 1 +/* Though OpenServer support .weak in COFF, g++ doesn't play nice with it + * so we'll punt on it for now + */ +#define SUPPORTS_WEAK (TARGET_ELF) +#define ASM_WEAKEN_LABEL(FILE,NAME) \ + do { fputs ("\t.weak\t", FILE); assemble_name (FILE, NAME); \ + fputc ('\n', FILE); } while (0) + #undef SCCS_DIRECTIVE #define SCCS_DIRECTIVE 1 @@ -904,11 +911,23 @@ dtors_section () \ #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ - { "coff", MASK_COFF }, \ - { "elf", -MASK_COFF }, + { "coff", MASK_COFF, "Generate COFF output" }, \ + { "elf", -MASK_COFF, "Generate ELF output" }, #define NO_DOLLAR_IN_LABEL +/* Implicit library calls should use memcpy, not bcopy, etc. They are + faster on OpenServer libraries. */ + +#define TARGET_MEM_FUNCTIONS + +/* Biggest alignment supported by the object file format of this + machine. Use this macro to limit the alignment which can be + specified using the `__attribute__ ((aligned (N)))' construct. If + not defined, the default value is `BIGGEST_ALIGNMENT'. */ + +#define MAX_OFILE_ALIGNMENT (32768*8) + /* Here comes some major hackery to get the crt stuff to compile properly. Since we can (and do) compile for both COFF and ELF environments, we diff --git a/contrib/gcc/config/i386/scodbx.h b/contrib/gcc/config/i386/scodbx.h index a2581d4..d7d03f8 100644 --- a/contrib/gcc/config/i386/scodbx.h +++ b/contrib/gcc/config/i386/scodbx.h @@ -1,6 +1,6 @@ /* Definitions for Intel 386 running SCO Unix System V, using dbx-in-coff encapsulation. - Copyright (C) 1992, 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1992, 1995, 1996, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -32,7 +32,7 @@ Boston, MA 02111-1307, USA. */ So don't make TARGET_IEEE_FP default for SCO. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 +#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS) /* Use crt1.o as a startup file and crtn.o as a closing file. */ diff --git a/contrib/gcc/config/i386/sequent.h b/contrib/gcc/config/i386/sequent.h index 4d76c38..8613ad7 100644 --- a/contrib/gcc/config/i386/sequent.h +++ b/contrib/gcc/config/i386/sequent.h @@ -1,5 +1,5 @@ /* Definitions for Sequent Intel 386. - Copyright (C) 1988, 1994 Free Software Foundation, Inc. + Copyright (C) 1988, 1994, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -26,11 +26,10 @@ Boston, MA 02111-1307, USA. */ /* By default, don't use IEEE compatible arithmetic comparisons because the assembler can't handle the fucom insn. - Return float values in the 387. - (TARGET_80387 | TARGET_FLOAT_RETURNS_IN_80387) */ + Return float values in the 387. */ #undef TARGET_DEFAULT -#define TARGET_DEFAULT 0201 +#define TARGET_DEFAULT (MASK_80387 | MASK_FLOAT_RETURNS) /* Specify predefined symbols in preprocessor. */ diff --git a/contrib/gcc/config/i386/sol2.h b/contrib/gcc/config/i386/sol2.h index 8fc3e61..cc5a089 100644 --- a/contrib/gcc/config/i386/sol2.h +++ b/contrib/gcc/config/i386/sol2.h @@ -93,3 +93,6 @@ Boston, MA 02111-1307, USA. */ || (CHAR) == 'z') #define STDC_0_IN_SYSTEM_HEADERS + +#undef LOCAL_LABEL_PREFIX +#define LOCAL_LABEL_PREFIX "." diff --git a/contrib/gcc/config/i386/sun386.h b/contrib/gcc/config/i386/sun386.h index 4d4d66c..4302ec4 100644 --- a/contrib/gcc/config/i386/sun386.h +++ b/contrib/gcc/config/i386/sun386.h @@ -59,11 +59,11 @@ do \ do { \ extern char *version_string, *language_string; \ { \ - int len = strlen (dump_base_name); \ - char *na = dump_base_name + len; \ + int len = strlen (main_input_filename); \ + char *na = main_input_filename + len; \ char shorter[15]; \ - /* NA gets DUMP_BASE_NAME sans directory names. */\ - while (na > dump_base_name) \ + /* NA gets MAIN_INPUT_FILENAME sans directory names. */\ + while (na > main_input_filename) \ { \ if (na[-1] == '/') \ break; \ diff --git a/contrib/gcc/config/i386/sysv5.h b/contrib/gcc/config/i386/sysv5.h new file mode 100644 index 0000000..09a3bbe --- /dev/null +++ b/contrib/gcc/config/i386/sysv5.h @@ -0,0 +1,35 @@ +/* Definitions for Intel 386 running System V Release 5 (i.e. UnixWare 7) + Copyright (C) 1999 Free Software Foundation, Inc. + Contributed by Robert Lipe (robertlipe@usa.net) + +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. */ + + +#include "i386/sysv4.h" + +/* Dwarf2 is supported by native debuggers */ + +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + +/* Add -lcrt for Dwarf2 abbreviation table */ +#undef LIB_SPEC +#define LIB_SPEC "%{pthread:-lthread} %{!shared:%{!symbolic:-lc -lcrt}}" + +#undef CPP_SPEC +#define CPP_SPEC "%{pthread:-D_REENTRANT}" diff --git a/contrib/gcc/config/i386/t-cygwin b/contrib/gcc/config/i386/t-cygwin new file mode 100644 index 0000000..175f66b --- /dev/null +++ b/contrib/gcc/config/i386/t-cygwin @@ -0,0 +1,16 @@ +LIBGCC1 = libgcc1-asm.a +CROSS_LIBGCC1 = libgcc1-asm.a +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 + +# 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 + +winnt.o: $(srcdir)/config/i386/winnt.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/winnt.c diff --git a/contrib/gcc/config/i386/t-dgux b/contrib/gcc/config/i386/t-dgux index 292331f..1bf024a 100644 --- a/contrib/gcc/config/i386/t-dgux +++ b/contrib/gcc/config/i386/t-dgux @@ -1,4 +1,8 @@ # # target makefile for dgux # -EXTRA_PARTS=crtbegin.o crtend.o +EXTRA_PARTS=crti.o crtbegin.o crtend.o + +crti.o: $(srcdir)/config/i386/sol2-ci.asm $(GCC_PASSES) + sed -e '/^!/d' <$(srcdir)/config/i386/sol2-ci.asm >crti.s + $(GCC_FOR_TARGET) -c -o crti.o crti.s diff --git a/contrib/gcc/config/i386/t-djgpp b/contrib/gcc/config/i386/t-djgpp new file mode 100644 index 0000000..6160b7e --- /dev/null +++ b/contrib/gcc/config/i386/t-djgpp @@ -0,0 +1,2 @@ +LIBGCC1 = libgcc1.null +CROSS_LIBGCC1 = libgcc1.null diff --git a/contrib/gcc/config/i386/t-interix b/contrib/gcc/config/i386/t-interix new file mode 100644 index 0000000..4c6d84f --- /dev/null +++ b/contrib/gcc/config/i386/t-interix @@ -0,0 +1,16 @@ +# t-interix +LIBGCC1 = libgcc1-asm.a +CROSS_LIBGCC1 = libgcc1-asm.a + +LIB1ASMSRC = i386/cygwin.asm +LIB1ASMFUNCS = _chkstk + +interix.o: $(srcdir)/config/i386/interix.c + $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/i386/interix.c + +# System headers will track gcc's needs. +# Even LANG_EXTRA_HEADERS may be temporary. +USER_H=$(LANG_EXTRA_HEADERS) + +# We don't want this one either. +INSTALL_ASSERT_H= diff --git a/contrib/gcc/config/i386/t-udk b/contrib/gcc/config/i386/t-udk new file mode 100644 index 0000000..96e1864 --- /dev/null +++ b/contrib/gcc/config/i386/t-udk @@ -0,0 +1,2 @@ +# Tell fixincludes to work on this set of headers +SYSTEM_HEADER_DIR = /udk/usr/include diff --git a/contrib/gcc/config/i386/t-uwin b/contrib/gcc/config/i386/t-uwin new file mode 100644 index 0000000..8e59868 --- /dev/null +++ b/contrib/gcc/config/i386/t-uwin @@ -0,0 +1,5 @@ +# +# This is included *after* t-cygwin to override LIB1ASMSRC. +# +LIB1ASMSRC = i386/uwin.asm + diff --git a/contrib/gcc/config/i386/udk.h b/contrib/gcc/config/i386/udk.h new file mode 100644 index 0000000..8e03abf --- /dev/null +++ b/contrib/gcc/config/i386/udk.h @@ -0,0 +1,30 @@ +/* Configuration for i386 interfacing with SCO's Universal Development Kit + probably running on OpenServer 5, Unixware 2, or Unixware 5 + */ + + +/* We're very much the SVR4 target with "/udk" prepended to everything that's + interesting */ + +#include "i386/sysv5.h" + +#undef MD_EXEC_PREFIX +#define MD_EXEC_PREFIX "/udk/usr/ccs/bin/" + +#undef MD_STARTFILE_PREFIX +#define MD_STARTFILE_PREFIX "/udk/usr/ccs/lib/" + +#define STANDARD_INCLUDE_DIR "/udk/usr/include" + +#undef LINK_SPEC +#define LINK_SPEC "%{h*} %{v:-V} \ + %{b} %{Wl,*:%*} \ + %{static:-dn -Bstatic} \ + %{shared:-G -dy -z text} \ + %{symbolic:-Bsymbolic -G -dy -z text} \ + %{G:-G} \ + %{YP,*} \ + %{!YP,*:%{p:-Y P,/udk/usr/ccs/lib/libp:/udk/usr/lib/libp:/udk/usr/ccs/lib:/udk/usr/lib} \ + %{!p:-Y P,/udk/usr/ccs/lib:/udk/usr/lib}} \ + %{Qy:} %{!Qn:-Qy}" + diff --git a/contrib/gcc/config/i386/unix.h b/contrib/gcc/config/i386/unix.h index 47440dd..771d802 100644 --- a/contrib/gcc/config/i386/unix.h +++ b/contrib/gcc/config/i386/unix.h @@ -1,5 +1,5 @@ /* Definitions for Unix assembler syntax for the Intel 80386. - Copyright (C) 1988, 1994 Free Software Foundation, Inc. + Copyright (C) 1988, 1994, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -131,10 +131,9 @@ Boston, MA 02111-1307, USA. */ (fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE)) /* By default, target has a 80387, uses IEEE compatible arithmetic, - and returns float values in the 387, ie, - (TARGET_80387 | TARGET_IEEE_FP | TARGET_FLOAT_RETURNS_IN_80387) */ + and returns float values in the 387. */ -#define TARGET_DEFAULT 0301 +#define TARGET_DEFAULT (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS) /* Floating-point return values come in the FP register. */ @@ -177,7 +176,7 @@ do { \ output_asm_insn (AS1 (call,%P1), xops); \ ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", CODE_LABEL_NUMBER (xops[1])); \ output_asm_insn (AS1 (pop%L0,%0), xops); \ - output_asm_insn ("addl $_GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops); \ + output_asm_insn ("addl $%__GLOBAL_OFFSET_TABLE_+[.-%P1],%0", xops); \ fprintf (FILE, "\tmovl "); \ assemble_name (FILE, XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0)); \ fprintf (FILE, "@GOT(%%ebx),%%ecx\n\tpopl %%ebx\n\tjmp *%%ecx\n"); \ diff --git a/contrib/gcc/config/i386/uwin.asm b/contrib/gcc/config/i386/uwin.asm new file mode 100644 index 0000000..6268343 --- /dev/null +++ b/contrib/gcc/config/i386/uwin.asm @@ -0,0 +1,32 @@ +/* stuff needed for libgcc1 on win32. */ + +#ifdef L_chkstk + + .global __chkstk + .global __alloca +__chkstk: +__alloca: + pushl %ecx /* save temp */ + movl %esp,%ecx /* get sp */ + addl $0x8,%ecx /* and point to return addr */ + +probe: cmpl $0x1000,%eax /* > 4k ?*/ + jb done + + subl $0x1000,%ecx /* yes, move pointer down 4k*/ + orl $0x0,(%ecx) /* probe there */ + subl $0x1000,%eax /* decrement count */ + jmp probe /* and do it again */ + +done: subl %eax,%ecx + orl $0x0,(%ecx) /* less that 4k, just peek here */ + + movl %esp,%eax + movl %ecx,%esp /* decrement stack */ + + movl (%eax),%ecx /* recover saved temp */ + movl 4(%eax),%eax /* get return address */ + jmp *%eax + + +#endif diff --git a/contrib/gcc/config/i386/uwin.h b/contrib/gcc/config/i386/uwin.h new file mode 100644 index 0000000..73e04ad --- /dev/null +++ b/contrib/gcc/config/i386/uwin.h @@ -0,0 +1,93 @@ +/* Operating system specific defines to be used when targeting GCC for + 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 Free Software Foundation, Inc. + Contributed by Mumit Khan . + +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. */ + +/* Most of this is the same as for Cygwin32, except for changing some + specs. */ + +#include "i386/cygwin.h" + +#define STANDARD_INCLUDE_COMPONENT "UWIN" +#define SYSTEM_INCLUDE_DIR "/usr/gnu/include" + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-D__i386__ -D_WIN32 -D__WIN32__ \ + -D_UWIN -DWINNT -D_X86_=1 -D__STDC__=1 \ + -D__UWIN__ -D__MSVCRT__ \ + -D_STD_INCLUDE_DIR=mingw32 \ + -D__stdcall=__attribute__((__stdcall__)) \ + _D_stdcall=__attribute__((__stdcall__)) \ + -D__cdecl=__attribute__((__cdecl__)) \ + -D__declspec(x)=__attribute__((x)) \ + -Asystem(winnt) -Acpu(i386) -Amachine(i386)" + +#undef CPP_SPEC +#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} \ + -include /usr/include/astwin32.h \ + -idirafter /usr/gnu/include/mingw32" + +/* For Windows applications, include more libraries, but always include + kernel32. */ +#undef LIB_SPEC +#define LIB_SPEC \ + "%{mwindows:-luser32 -lgdi32 -lcomdlg32} -lkernel32 -ladvapi32" + +/* This is needed in g77spec.c for now. Will be removed in the future. */ +#define WIN32_UWIN_TARGET 1 + +/* Include in the mingw32 libraries with libgcc */ +#undef LIBGCC_SPEC +#define LIBGCC_SPEC "-lgnuwin -lposix -lgcc -last -lmoldname -lmsvcrt" + +/* Specify a different entry point when linking a DLL */ +#undef LINK_SPEC +#define LINK_SPEC \ + "%{mwindows:--subsystem windows} %{mdll:--dll -e _DllMainCRTStartup@12}" + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{mdll:dllcrt2%O%s} %{!mdll:crt2%O%s}" + +/* These are PE BFD bug workarounds. Should go away eventually. */ + +#undef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + do \ + { \ + if (i386_pe_dllexport_name_p (NAME)) \ + { \ + drectve_section (); \ + fprintf ((FILE), "\t.ascii \" -export:%s\"\n", \ + I386_PE_STRIP_ENCODING (NAME)); \ + function_section (DECL); \ + } \ + /* disable i386_pe_declare_function_type for UWIN */ \ + if (0 && write_symbols != SDB_DEBUG) \ + i386_pe_declare_function_type (FILE, NAME, TREE_PUBLIC (DECL)); \ + ASM_OUTPUT_LABEL (FILE, NAME); \ + } \ + while (0) + +#undef ASM_OUTPUT_EXTERNAL +#undef ASM_OUTPUT_EXTERNAL_LIBCALL +#undef ASM_FILE_END + diff --git a/contrib/gcc/config/i386/vxi386.h b/contrib/gcc/config/i386/vxi386.h index 1044286..0bd27b4 100644 --- a/contrib/gcc/config/i386/vxi386.h +++ b/contrib/gcc/config/i386/vxi386.h @@ -18,6 +18,45 @@ 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. */ +#undef CPP_CPU_SPEC +#define CPP_CPU_SPEC "\ +-Asystem(unix) -Acpu(i386) -Amachine(i386) \ +%{!ansi:-Di386} -D__i386 -D__i386__ \ +%{march=i386:-DCPU=I80386} \ +%{march=i486:-DCPU=I80486 %(cpp_486)} \ +%{march=pentium:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUM %(cpp_586)} \ +%{march=pentiumpro:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUMPRO %(cpp_686)} \ +%{!march=*: \ + %{mcpu=i386:-DCPU=I80386} \ + %{mcpu=i486:-DCPU=I80486 %(cpp_486)} %{m486:-DCPU=I80486 %(cpp_486)} \ + %{mpentium:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUM %(cpp_586)} \ + %{mcpu=pentium:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUM %(cpp_586)} \ + %{mpentiumpro:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUMPRO %(cpp_686)} \ + %{mcpu=pentiumpro:-DCPU=PENTIUM -DCPU_VARIANT=PENTIUMPRO %(cpp_686)} \ + %{!mcpu*:%{!m486:%{!mpentium*:-DCPU=I80386 %(cpp_cpu_default)}}}}" + #include "i386/i386-aout.h" #define HANDLE_SYSV_PRAGMA + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-D__vxworks -D__i386__" + +/* 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 "" diff --git a/contrib/gcc/config/i386/win-nt.h b/contrib/gcc/config/i386/win-nt.h index 60c0bb6..97f10c3 100644 --- a/contrib/gcc/config/i386/win-nt.h +++ b/contrib/gcc/config/i386/win-nt.h @@ -131,9 +131,7 @@ while (0) #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"); \ + do { output_file_directive (FILE, main_input_filename); \ fprintf (FILE, ".global\t__fltused\n"); \ } while (0) diff --git a/contrib/gcc/config/i386/win32.h b/contrib/gcc/config/i386/win32.h new file mode 100644 index 0000000..d62abbf --- /dev/null +++ b/contrib/gcc/config/i386/win32.h @@ -0,0 +1,280 @@ +/* Operating system specific defines to be used when targeting GCC for + hosting on Windows NT 3.x, using a Unix style C library and tools, + 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) 1995-1998 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 YES_UNDERSCORES + +/* Enable parsing of #pragma pack(push,) and #pragma pack(pop). */ +#define HANDLE_PRAGMA_PACK_PUSH_POP 1 + +#define DBX_DEBUGGING_INFO +#define SDB_DEBUGGING_INFO +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + +#include "i386/gas.h" +#include "dbxcoff.h" + +/* Augment TARGET_SWITCHES with the cygwin/win32 options. */ +#define MASK_WIN32 0x40000000 /* Use -lming32 interface */ +#define MASK_CYGWIN 0x20000000 /* Use -lcygwin interface */ +#define MASK_WINDOWS 0x10000000 /* Use windows interface */ +#define MASK_DLL 0x08000000 /* Use dll interface */ +#define MASK_NOP_FUN_DLLIMPORT 0x20000 /* Ignore dllimport for functions */ + +#define TARGET_WIN32 (target_flags & MASK_WIN32) +#define TARGET_CYGWIN (target_flags & MASK_CYGWIN) +#define TARGET_WINDOWS (target_flags & MASK_WINDOWS) +#define TARGET_DLL (target_flags & MASK_DLL) +#define TARGET_NOP_FUN_DLLIMPORT (target_flags & MASK_NOP_FUN_DLLIMPORT) + +#undef SUBTARGET_SWITCHES +#define SUBTARGET_SWITCHES \ + { "win32", MASK_WIN32, "Use Mingw32 interface" }, \ + { "cygwin", MASK_CYGWIN, "Use Cygwin interface" }, \ + { "windows", MASK_WINDOWS, "Use bare Windows interface" }, \ + { "dll", MASK_DLL, "Generate code for a DLL" }, \ + { "nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, "Ignore dllimport for functions" }, \ + { "no-nop-fun-dllimport", MASK_NOP_FUN_DLLIMPORT, "" }, + + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-D_WIN32 \ + -DWINNT -D_X86_=1 -D__STDC__=1\ + -D__stdcall=__attribute__((__stdcall__)) \ + -D__cdecl=__attribute__((__cdecl__)) \ + -Asystem(winnt)" + +#undef STARTFILE_SPEC + +#define STARTFILE_SPEC "%{mdll:dllcrt0%O%s} %{!mdll: %{!mcygwin:mcrt0%O%s} \ + %{mcygwin:crt0%O%s} %{pg:gcrt0%O%s}}" + +#undef CPP_SPEC +#define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \ + %{!mcygwin:-iwithprefixbefore include/mingw32 -D__MINGW32__} \ + %{mcygwin:-D__CYGWIN32__ -D__CYGWIN__}" + +/* 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 + 'libcygwin.a'. For Windows applications, include more libraries, but + always include kernel32. We'd like to specific subsystem windows to + ld, but that doesn't work just yet. */ + +#undef LIB_SPEC +#define LIB_SPEC "%{pg:-lgmon} \ + %{!mcygwin:-lmingw32 -lmoldname -lmsvcrt -lcrtdll} \ + %{mcygwin:-lcygwin} %{mwindows:-luser32 -lgdi32 -lcomdlg32} \ + -lkernel32 -ladvapi32 -lshell32" + +#define LINK_SPEC "%{mwindows:--subsystem windows} \ + %{mdll:--dll -e _DllMainCRTStartup@12}" + +#define SIZE_TYPE "unsigned int" +#define PTRDIFF_TYPE "int" +#define WCHAR_UNSIGNED 1 +#define WCHAR_TYPE_SIZE 16 +#define WCHAR_TYPE "short unsigned int" +/* Currently we do not have the atexit() function, + so take that from libgcc2.c */ + +#define NEED_ATEXIT 1 +#define HAVE_ATEXIT 1 + +#undef EXTRA_SECTIONS +#define EXTRA_SECTIONS in_ctor, in_dtor + +#undef EXTRA_SECTION_FUNCTIONS +#define EXTRA_SECTION_FUNCTIONS \ + CTOR_SECTION_FUNCTION \ + DTOR_SECTION_FUNCTION + +#define CTOR_SECTION_FUNCTION \ +void \ +ctor_section () \ +{ \ + if (in_section != in_ctor) \ + { \ + fprintf (asm_out_file, "\t.section .ctor\n"); \ + in_section = in_ctor; \ + } \ +} + +#define DTOR_SECTION_FUNCTION \ +void \ +dtor_section () \ +{ \ + if (in_section != in_dtor) \ + { \ + fprintf (asm_out_file, "\t.section .dtor\n"); \ + in_section = in_dtor; \ + } \ +} + +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtor_section (); \ + fprintf (FILE, "%s\t", ASM_LONG); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } 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, if using PIC, mark a SYMBOL_REF for a non-global symbol + so that we may access it directly in the GOT. + + 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. */ + +#ifdef ENCODE_SECTION_INFO +#undef ENCODE_SECTION_INFO +#define ENCODE_SECTION_INFO(DECL) \ +do \ + { \ + if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + 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)); \ + } \ +while (0) +#endif + +/* This macro gets just the user-specified name + out of the string in a SYMBOL_REF. Discard + trailing @[NUM] encoded by ENCODE_SECTION_INFO. + Do we need the stripping of leading '*'? */ +#undef STRIP_NAME_ENCODING +#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \ +do { \ + char *_p; \ + char *_name = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*')); \ + for (_p = _name; *_p && *_p != '@'; ++_p) \ + ; \ + if (*_p == '@') \ + { \ + int _len = _p - _name; \ + (VAR) = (char *) alloca (_len + 1); \ + strncpy ((VAR), _name, _len); \ + (VAR)[_len] = '\0'; \ + } \ + else \ + (VAR) = _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, + and returns float values in the 387 and needs stack probes */ +#undef TARGET_DEFAULT + +#define TARGET_DEFAULT \ + (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS | MASK_STACK_PROBE) + +/* 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 + +#define UNIQUE_SECTION_P(DECL) DECL_ONE_ONLY (DECL) +extern void i386_pe_unique_section (); +#define UNIQUE_SECTION(DECL,RELOC) i386_pe_unique_section (DECL, RELOC) + +#define SUPPORTS_ONE_ONLY 1 + +/* A C statement to output something to the assembler file to switch to section + NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or + NULL_TREE. Some target formats do not support arbitrary sections. Do not + define this macro in such cases. */ +#undef ASM_OUTPUT_SECTION_NAME +#define ASM_OUTPUT_SECTION_NAME(STREAM, DECL, NAME, RELOC) \ +do { \ + if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \ + fprintf (STREAM, "\t.section %s,\"x\"\n", (NAME)); \ + else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \ + fprintf (STREAM, "\t.section %s,\"\"\n", (NAME)); \ + else \ + fprintf (STREAM, "\t.section %s,\"w\"\n", (NAME)); \ + /* Functions may have been compiled at various levels of \ + optimization so we can't use `same_size' here. Instead, \ + have the linker pick one. */ \ + if ((DECL) && DECL_ONE_ONLY (DECL)) \ + fprintf (STREAM, "\t.linkonce %s\n", \ + TREE_CODE (DECL) == FUNCTION_DECL \ + ? "discard" : "same_size"); \ +} while (0) + +#undef ASM_COMMENT_START +#define ASM_COMMENT_START " #" + +/* DWARF2 Unwinding doesn't work with exception handling yet. */ +#define DWARF2_UNWIND_INFO 0 + +/* Don't assume anything about the header files. */ +#define NO_IMPLICIT_EXTERN_C + +#define SUBTARGET_PROLOGUE \ + if (profile_flag \ + && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),\ + "main") == 0) \ + { \ + rtx xops[1]; \ + xops[0] = gen_rtx_MEM (FUNCTION_MODE, \ + gen_rtx (SYMBOL_REF, Pmode, "_monstartup")); \ + if (do_rtl) \ + emit_call_insn (gen_rtx (CALL, VOIDmode, xops[0], const0_rtx)); \ + else \ + output_asm_insn (AS1 (call,%P1), xops); \ + } diff --git a/contrib/gcc/config/i386/winnt.c b/contrib/gcc/config/i386/winnt.c index 0058eb7..24d8617 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 Free Software Foundation, Inc. + Copyright (C) 1995, 1997, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -493,7 +493,7 @@ i386_pe_unique_section (decl, reloc) } /* The Microsoft linker requires that every function be marked as - DT_FCN. When using gas on cygwin32, we must emit appropriate .type + DT_FCN. When using gas on cygwin, we must emit appropriate .type directives. */ #include "gsyms.h" @@ -545,8 +545,29 @@ i386_pe_record_external_function (name) extern_head = p; } +static struct extern_list *exports_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 + linkonce. */ + +void +i386_pe_record_exported_symbol (name) + char *name; +{ + struct extern_list *p; + + p = (struct extern_list *) permalloc (sizeof *p); + p->next = exports_head; + p->name = name; + exports_head = p; +} + /* This is called at the end of assembly. For each external function - which has not been defined, we output a declaration now. */ + which has not been defined, we output a declaration now. We also + output the .drectve section. */ void i386_pe_asm_file_end (file) @@ -567,4 +588,13 @@ i386_pe_asm_file_end (file) i386_pe_declare_function_type (file, p->name, TREE_PUBLIC (decl)); } } + + if (exports_head) + drectve_section (); + for (p = exports_head; p != NULL; p = p->next) + { + fprintf (file, "\t.ascii \" -export:%s\"\n", + I386_PE_STRIP_ENCODING (p->name)); + } } + diff --git a/contrib/gcc/config/i386/x-cygwin b/contrib/gcc/config/i386/x-cygwin new file mode 100644 index 0000000..f251835 --- /dev/null +++ b/contrib/gcc/config/i386/x-cygwin @@ -0,0 +1,4 @@ +# Don't run fixproto +STMP_FIXPROTO = +# prefix.c wants to poke around the Registry +CLIB = -ladvapi32 diff --git a/contrib/gcc/config/i386/x-djgpp b/contrib/gcc/config/i386/x-djgpp new file mode 100644 index 0000000..89f31ff --- /dev/null +++ b/contrib/gcc/config/i386/x-djgpp @@ -0,0 +1,24 @@ +# translate the version string, so it can be used on DJGPP, where only +# one dot in filename is allowed + +# to avoid recursion when redefining $(version) +_version:=$(version) +__version=$(subst ., ,$(_version)) +version=$(word 1,$(__version))$(word 2,$(__version)).$(word 3,$(__version)) + +SYSTEM_HEADER_DIR=$(DJDIR)/include +X_CPPFLAGS=-DSTANDARD_INCLUDE_DIR=\"\$$DJDIR/include\" \ + -DSTANDARD_INCLUDE_COMPONENT=\"\" + +# when building a native compiler for DJGPP, make the target_alias +# a shorter name, since otherwise it will produce some problems, when +# using the same gcc once with long filenames and once with short (8+3) +# filenames +ifeq ($(findstring -pc-msdosdjgpp,$(target_alias)),-pc-msdosdjgpp) +target_alias=djgpp +endif + +# on DJGPP the 'ln -s' does not work correctly +LN = cp -p +LN_S = cp -p + diff --git a/contrib/gcc/config/i386/xm-cygwin.h b/contrib/gcc/config/i386/xm-cygwin.h new file mode 100644 index 0000000..ab59627 --- /dev/null +++ b/contrib/gcc/config/i386/xm-cygwin.h @@ -0,0 +1,58 @@ +/* Configuration for GNU C-compiler for hosting on Windows NT. + using a unix style C library. + Copyright (C) 1995, 1996, 1997, 1998, 1999 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 EXECUTABLE_SUFFIX ".exe" +#define NO_SYS_SIGLIST 1 + +/* 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. */ +#define DIR_SEPARATOR '/' +#define DIR_SEPARATOR_2 '\\' + +/* Convert win32 style path lists to POSIX style for consistency. */ +#undef GET_ENV_PATH_LIST +#define GET_ENV_PATH_LIST(VAR,NAME) \ +do { \ + char *_epath; \ + char *_posixepath; \ + _epath = _posixepath = getenv (NAME); \ + /* if we have a posix path list, convert to posix path list */ \ + if (_epath != NULL && *_epath != 0 \ + && ! cygwin_posix_path_list_p (_epath)) \ + { \ + char *p; \ + _posixepath = (char *) xmalloc \ + (cygwin_win32_to_posix_path_list_buf_size (_epath)); \ + cygwin_win32_to_posix_path_list (_epath, _posixepath); \ + } \ + (VAR) = _posixepath; \ +} while (0) + +#define PATH_SEPARATOR ':' + +/* This is needed so that protoize will compile. */ +#ifndef POSIX +#define POSIX +#endif diff --git a/contrib/gcc/config/i386/xm-djgpp.h b/contrib/gcc/config/i386/xm-djgpp.h new file mode 100644 index 0000000..ccf6e3c --- /dev/null +++ b/contrib/gcc/config/i386/xm-djgpp.h @@ -0,0 +1,44 @@ +/* Configuration for GNU C-compiler for Intel 80386 running DJGPP. + Copyright (C) 1988, 1996, 1998, 1999 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 __MSDOS__ 1 + +#include "i386/xm-i386.h" + +/* Use semicolons to separate elements of a path. */ +#define PATH_SEPARATOR ';' + +#define 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_FILESYSTEM + +#define LIBSTDCXX "-lstdcxx" + +/* System dependant initialization for collect2 + to tell system() to act like Unix. */ +#define COLLECT2_HOST_INITIALIZATION \ + do { __system_flags |= (__system_allow_multiple_cmds \ + | __system_emulate_chdir); } while (0) + diff --git a/contrib/gcc/config/i386/xm-dos.h b/contrib/gcc/config/i386/xm-dos.h index a734a81..4e1cb42 100644 --- a/contrib/gcc/config/i386/xm-dos.h +++ b/contrib/gcc/config/i386/xm-dos.h @@ -1,3 +1,23 @@ +/* Configuration for GNU C-compiler for Intel 80386 running DOS. + Copyright (C) 1998, 1999 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. */ + #include "i386/xm-i386.h" /* Use semicolons to separate elements of a path. */ @@ -5,6 +25,10 @@ /* Use backslashs to separate levels of directory. */ #define DIR_SEPARATOR '\\' +#define DIR_SEPARATOR_2 '/' + +/* Allow checks for drive names. */ +#define HAVE_DOS_BASED_FILE_SYSTEM /* Suffix for executable file names. */ #define EXECUTABLE_SUFFIX ".exe" diff --git a/contrib/gcc/config/i386/xm-i386-interix.h b/contrib/gcc/config/i386/xm-i386-interix.h new file mode 100644 index 0000000..8bfd5e2 --- /dev/null +++ b/contrib/gcc/config/i386/xm-i386-interix.h @@ -0,0 +1,34 @@ +/* Configuration for GNU compiler + for an Intel i386 or later processor running Interix. + Copyright (C) 1999 Free Software Foundation, Inc. + Contributed by Donn Terry (donn@interix.com) + Derived from code by Douglas B. Rupp (drupp@cs.washington.edu) + +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. */ + +#include + +#define HOST_BITS_PER_WIDEST_INT HOST_BITS_PER_LONGLONG +#ifdef __GNUC__ +# define HOST_WIDEST_INT long long +#else +# define HOST_WIDEST_INT __int64 +#endif +#define HOST_WIDEST_INT_PRINT_DEC "%lld" +#define HOST_WIDEST_INT_PRINT_UNSIGNED "%llu" +#define HOST_WIDEST_INT_PRINT_HEX "0x%llx" diff --git a/contrib/gcc/config/i386/xm-mingw32.h b/contrib/gcc/config/i386/xm-mingw32.h index d818142..6872580 100644 --- a/contrib/gcc/config/i386/xm-mingw32.h +++ b/contrib/gcc/config/i386/xm-mingw32.h @@ -1,6 +1,6 @@ /* Configuration for GNU C-compiler for hosting on Windows32. using GNU tools and the Windows32 API Library. - Copyright (C) 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -36,6 +36,12 @@ 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 + #define EXECUTABLE_SUFFIX ".exe" #undef PATH_SEPARATOR diff --git a/contrib/gcc/config/i386/xm-os2.h b/contrib/gcc/config/i386/xm-os2.h index aed925e..b8a5ad0 100644 --- a/contrib/gcc/config/i386/xm-os2.h +++ b/contrib/gcc/config/i386/xm-os2.h @@ -1,6 +1,6 @@ /* Configuration for GNU compiler for an Intel i386 or later processor running OS/2 2.x. - Copyright (C) 1993, 1994, 1995, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by Samuel Figueroa (figueroa@apple.com) This file is part of GNU CC. @@ -54,6 +54,12 @@ int spawnvp (int modeflag, char *path, char *argv[]); #ifndef DIR_SEPARATOR #define DIR_SEPARATOR '\\' #endif +#ifndef DIR_SEPARATOR_2 +#define DIR_SEPARATOR_2 '/' +#endif + +/* Allow handling of drive names. */ +#define HAVE_DOS_BASED_FILE_SYSTEM #define EXECUTABLE_SUFFIX ".exe" diff --git a/contrib/gcc/config/i386/xm-uwin.h b/contrib/gcc/config/i386/xm-uwin.h new file mode 100644 index 0000000..2e1ecde --- /dev/null +++ b/contrib/gcc/config/i386/xm-uwin.h @@ -0,0 +1,39 @@ +/* Configuration for GNU C-compiler for hosting on Windows32. + using GNU tools and the Windows32 API Library. + Copyright (C) 1999 Free Software Foundation, Inc. + Contributed by Mumit Khan . + +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 ONLY_INT_FIELD +#define ONLY_INT_FIELDS 1 +#endif + +#ifndef USE_PROTOTYPES +#define USE_PROTOTYPES 1 +#endif + +/* U/WIN system calls only support '/' */ +#undef DIR_SEPARATOR +#define DIR_SEPARATOR '/' +#undef EXECUTABLE_SUFFIX +#define EXECUTABLE_SUFFIX ".exe" + +#undef PATH_SEPARATOR +#define PATH_SEPARATOR ':' + diff --git a/contrib/gcc/config/interix.h b/contrib/gcc/config/interix.h new file mode 100644 index 0000000..9cef8b3 --- /dev/null +++ b/contrib/gcc/config/interix.h @@ -0,0 +1,107 @@ +/* Operating system specific defines to be used when targeting GCC for + Interix + Copyright (C) 1994, 1995, 1999 Free Software Foundation, Inc. + Donn Terry, Softway Systems, Inc. (donn@softway.com) + Modified from code + Contributed by Douglas B. Rupp (drupp@cs.washington.edu). + +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 TARGET_MEM_FUNCTIONS + +/* POSIX/Uni-thread only for now. Look at the winnt version +for windows/multi thread */ + +/* We need multiple -lc -lcpsx because they mutually refer; + that should go away someday */ + +#undef LIB_SPEC +#define LIB_SPEC "\ + %{!shared:%{!dynamic:-lc -lcpsx -lc -lcpsx %$INTERIX_ROOT/usr/lib/psxdll.a \ + %$INTERIX_ROOT/usr/lib/psxdll2.a \ + }} \ + %{!G:%{!dynamic:-lc -lcpsx -lc -lcpsx %$INTERIX_ROOT/usr/lib/psxdll.a \ + %$INTERIX_ROOT/usr/lib/psxdll2.a \ + }} \ + %{dynamic:-lc %$INTERIX_ROOT/usr/lib/psxdll.a \ + %$INTERIX_ROOT/usr/lib/psxdll2.a \ + } \ + %{v}" + +#undef LINK_SPEC +#define LINK_SPEC "%{!shared:-stack 0x400000,0x10000} \ + -subsystem posix \ + %{g} \ + %{dynamic:-Bdynamic} \ + %{static:-Bstatic} \ + %{shared:--shared -Bdynamic} \ + %{G:--shared -Bdynamic} \ + %{symbolic:--shared -Bsymbolic -Bdynamic} \ + %{soname*:--soname %*} \ + %{rpath*:--rpath %*} \ + " + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC \ + "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}} %{shared:crti%O%s}" + +#undef WORD_SWITCH_TAKES_ARG +#define WORD_SWITCH_TAKES_ARG(STR) \ + ((DEFAULT_WORD_SWITCH_TAKES_ARG (STR) \ + || !strcmp(STR, "rpath")) \ + && strcmp (STR, "Tdata") && strcmp (STR, "Ttext") \ + && 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 */ + +#undef STDC_VALUE +#define STDC_VALUE 0 + +#define HANDLE_SYSV_PRAGMA +#undef HANDLE_PRAGMA_WEAK /* until the link format can handle it */ + +/* Names to predefine in the preprocessor for this target machine. */ + +#define DBX_DEBUGGING_INFO +#define SDB_DEBUGGING_INFO +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG + + +/* TARGET_DEFAULT from configure */ + +#undef WCHAR_TYPE +#undef WCHAR_TYPE_SIZE +#define WCHAR_UNSIGNED 1 +#define WCHAR_TYPE "short unsigned int" +#define WCHAR_TYPE_SIZE 16 + +/* For the sake of libgcc2.c, indicate target supports atexit. */ +#define HAVE_ATEXIT diff --git a/contrib/gcc/config/nextstep.c b/contrib/gcc/config/nextstep.c index e909a94..1c658fb 100644 --- a/contrib/gcc/config/nextstep.c +++ b/contrib/gcc/config/nextstep.c @@ -45,12 +45,12 @@ extern char *get_directive_line (); The result is 1 if the pragma was handled. */ int -handle_pragma (finput, node) - FILE *finput; - tree node; +handle_pragma (p_getc, p_ungetc, pname) + int (* p_getc) PROTO ((void)); + void (* p_ungetc) PROTO ((int)); + char * pname; { int retval = 0; - register char *pname; /* Record initial setting of optimize flag, so we can restore it. */ if (!pragma_initialized) @@ -59,11 +59,6 @@ handle_pragma (finput, node) initial_optimize_flag = optimize; } - if (TREE_CODE (node) != IDENTIFIER_NODE) - return 0; - - pname = IDENTIFIER_POINTER (node); - if (strcmp (pname, "CC_OPT_ON") == 0) { optimize = 1, obey_regdecls = 0; diff --git a/contrib/gcc/config/nextstep.h b/contrib/gcc/config/nextstep.h index 96435fc..59050a1 100644 --- a/contrib/gcc/config/nextstep.h +++ b/contrib/gcc/config/nextstep.h @@ -167,7 +167,12 @@ Boston, MA 02111-1307, USA. */ %{!p:-lcrt0.o}}}\ %{posix*:%{pg:-lgposixcrt0.o}%{!pg: \ %{p:%e-p profiling is no longer supported. Use -pg instead.} \ - %{!p:-lposixcrt0.o}}}" + %{!p:-lposixcrt0.o}}} \ + -lcrtbegin.o" + +#undef ENDFILE_SPEC +#define ENDFILE_SPEC \ + "-lcrtend.o" /* Allow #sscs (but don't do anything). */ @@ -203,6 +208,9 @@ Boston, MA 02111-1307, USA. */ "\t.text\n\t.stabs \"%s\",%d,0,0,Letext\nLetext:\n", \ "" , N_SO) +/* Define our object format type for crtstuff.c */ +#define OBJECT_FORMAT_MACHO + /* Don't use .gcc_compiled symbols to communicate with GDB; They interfere with numerically sorted symbol lists. */ @@ -232,6 +240,8 @@ Boston, MA 02111-1307, USA. */ fprintf (FILE, ".reference .destructors_used\n"); \ } while (0) +#define EH_FRAME_SECTION_ASM_OP ".section __TEXT,__eh_frame,regular" + /* Don't output a .file directive. That is only used by the assembler for error reporting. */ #undef ASM_FILE_START @@ -252,7 +262,8 @@ Boston, MA 02111-1307, USA. */ /* How to parse #pragma's */ #undef HANDLE_PRAGMA -#define HANDLE_PRAGMA(FINPUT, NODE) handle_pragma (FINPUT, NODE) +#define HANDLE_PRAGMA(GETC, UNGETC, NAME) handle_pragma (GETC, UNGETC, NAME) +extern int handle_pragma (); /* Give methods pretty symbol names on NeXT. */ @@ -280,7 +291,7 @@ Boston, MA 02111-1307, USA. */ else if (!strncmp (NAME, "_OBJC_", 6)) fprintf (FILE, "L%s", NAME); \ else if (!strncmp (NAME, ".objc_class_name_", 17)) \ fprintf (FILE, "%s", NAME); \ - else fprintf (FILE, "%s%s", USER_LABEL_PREFIX, NAME); } while (0) + else asm_fprintf (FILE, "%U%s", NAME); } while (0) #undef ALIGN_ASM_OP #define ALIGN_ASM_OP ".align" diff --git a/contrib/gcc/config/openbsd.h b/contrib/gcc/config/openbsd.h index af8358e..30f2494 100644 --- a/contrib/gcc/config/openbsd.h +++ b/contrib/gcc/config/openbsd.h @@ -300,3 +300,9 @@ do { \ #pragma weak. */ #define GTHREAD_USE_WEAK 0 +/* bug work around: we don't want to support #pragma weak, but the current + code layout needs HANDLE_PRAGMA_WEAK asserted for __attribute((weak)) to + work. On the other hand, we don't define HANDLE_PRAGMA_WEAK directly, + as this depends on a few other details as well... */ +#define HANDLE_SYSV_PRAGMA + diff --git a/contrib/gcc/config/ptx4.h b/contrib/gcc/config/ptx4.h index aa31924..b1eaabe 100644 --- a/contrib/gcc/config/ptx4.h +++ b/contrib/gcc/config/ptx4.h @@ -1,6 +1,6 @@ /* Operating system specific defines to be used when targeting GCC for some generic System V Release 4 system. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@monkeys.com). Renamed and changed to suit Dynix/ptx v4 and later. Modified by Tim Wright (timw@sequent.com). @@ -183,8 +183,9 @@ Boston, MA 02111-1307, USA. #define ASM_FILE_END(FILE) \ do { \ - fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ - IDENT_ASM_OP, version_string); \ + if (!flag_no_ident) \ + fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ + IDENT_ASM_OP, version_string); \ } while (0) /* Allow #sccs in preprocessor. */ diff --git a/contrib/gcc/config/sparc/elf.h b/contrib/gcc/config/sparc/elf.h index 70cb26a..635238f 100644 --- a/contrib/gcc/config/sparc/elf.h +++ b/contrib/gcc/config/sparc/elf.h @@ -40,3 +40,19 @@ Boston, MA 02111-1307, USA. */ /* FIXME: until fixed */ #undef LONG_DOUBLE_TYPE_SIZE #define LONG_DOUBLE_TYPE_SIZE 64 + +/* This solaris2 define does not apply. */ +#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 diff --git a/contrib/gcc/config/sparc/gmon-sol2.c b/contrib/gcc/config/sparc/gmon-sol2.c index 2a5b898..a6abcab 100644 --- a/contrib/gcc/config/sparc/gmon-sol2.c +++ b/contrib/gcc/config/sparc/gmon-sol2.c @@ -35,16 +35,8 @@ * for Cygnus Support, July 1992. */ -#ifndef lint -static char sccsid[] = "@(#)gmon.c 5.3 (Berkeley) 5/22/91"; -#endif /* not lint */ - -#include -#include -#include -#include -#include -#include +#include "config.h" +#include "system.h" #if 0 #include "sparc/gmon.h" @@ -96,7 +88,9 @@ static int s_scale; #define MSG "No space for profiling buffer(s)\n" -static void moncontrol(); +static void moncontrol PROTO ((int)); +extern void monstartup PROTO ((char *, char *)); +extern void _mcleanup PROTO ((void)); void monstartup(lowpc, highpc) char *lowpc; @@ -185,7 +179,7 @@ _mcleanup() int toindex; struct rawarc rawarc; char *profdir; - char *proffile; + const char *proffile; char *progname; char buf[PATH_MAX]; extern char **___Argv; @@ -275,6 +269,8 @@ _mcleanup() * -- [eichin:19920702.1107EST] */ +static void internal_mcount PROTO((char *, unsigned short *)) ATTRIBUTE_UNUSED; + /* i7 == last ret, -> frompcindex */ /* o7 == current ret, -> selfpc */ /* Solaris 2 libraries use _mcount. */ @@ -297,9 +293,9 @@ static void internal_mcount(selfpc, frompcindex) */ if(!already_setup) { - extern etext(); + extern char etext[]; already_setup = 1; - monstartup(0, etext); + monstartup(0, (char *)etext); #ifdef USE_ONEXIT on_exit(_mcleanup, 0); #else diff --git a/contrib/gcc/config/sparc/hal.h b/contrib/gcc/config/sparc/hal.h new file mode 100644 index 0000000..0222b81 --- /dev/null +++ b/contrib/gcc/config/sparc/hal.h @@ -0,0 +1,33 @@ +/* Definitions of target machine for GNU compiler, for HAL + SPARC running Solaris 2 HALOS + Copyright 1998 Free Software Foundation, Inc. + Contributed by Carol LePage (carolo@hal.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. */ + +/* Need different command line for assembler */ + +#undef ASM_SPEC +#define ASM_SPEC \ + "%{V} %{v:%{!V:-V}} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Wa,*:%*} -e1 \ + %{fpic:-K PIC} %{fPIC:-K PIC}" + +/* Need DWARF for debuggers. */ + +#undef PREFERRED_DEBUGGING_TYPE +#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG diff --git a/contrib/gcc/config/sparc/linux.h b/contrib/gcc/config/sparc/linux.h index 7bbbfa4..d967b01 100644 --- a/contrib/gcc/config/sparc/linux.h +++ b/contrib/gcc/config/sparc/linux.h @@ -103,7 +103,7 @@ Boston, MA 02111-1307, USA. */ #define WCHAR_TYPE_SIZE BITS_PER_WORD #undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D__ELF__ -Dunix -Dsparc -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)" +#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)" #undef CPP_SUBTARGET_SPEC #ifdef USE_GNULIBC_1 diff --git a/contrib/gcc/config/sparc/linux64.h b/contrib/gcc/config/sparc/linux64.h index 77bc668..705b5ca 100644 --- a/contrib/gcc/config/sparc/linux64.h +++ b/contrib/gcc/config/sparc/linux64.h @@ -19,9 +19,7 @@ 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. */ -/* ??? bi-architecture support will require changes to the linker - related specs, among perhaps other things (multilibs). */ -/* #define SPARC_BI_ARCH */ +#define SPARC_BI_ARCH #define LINUX_DEFAULT_ELF @@ -36,6 +34,16 @@ 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 +/* A 64 bit v9 compiler with stack-bias, + in a Medium/Low code model environment. */ + +#undef TARGET_DEFAULT +#define TARGET_DEFAULT \ + (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \ + + MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU) +#endif + /* Output at beginning of assembler file. */ /* The .file command should always begin the output. */ #undef ASM_FILE_START @@ -54,11 +62,37 @@ Boston, MA 02111-1307, USA. */ object constructed before entering `main'. */ #undef STARTFILE_SPEC -#define STARTFILE_SPEC \ + +#define STARTFILE_SPEC32 \ "%{!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}" +#define STARTFILE_SPEC64 \ + "%{!shared: \ + %{pg:/usr/lib64/gcrt1.o%s} %{!pg:%{p:/usr/lib64/gcrt1.o%s} %{!p:/usr/lib64/crt1.o%s}}}\ + /usr/lib64/crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}" + +#ifdef SPARC_BI_ARCH + +#if DEFAULT_ARCH32_P +#define STARTFILE_SPEC "\ +%{m32:" STARTFILE_SPEC32 "} \ +%{m64:" STARTFILE_SPEC64 "} \ +%{!m32:%{!m64:" STARTFILE_SPEC32 "}}" +#else +#define STARTFILE_SPEC "\ +%{m32:" STARTFILE_SPEC32 "} \ +%{m64:" STARTFILE_SPEC64 "} \ +%{!m32:%{!m64:" STARTFILE_SPEC64 "}}" +#endif + +#else + +#define STARTFILE_SPEC STARTFILE_SPEC64 + +#endif + /* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on the GNU/Linux magical crtend.o file (see crtstuff.c) which provides part of the support for getting C++ file-scope static @@ -66,23 +100,39 @@ Boston, MA 02111-1307, USA. */ GNU/Linux "finalizer" file, `crtn.o'. */ #undef ENDFILE_SPEC -#define ENDFILE_SPEC \ + +#define ENDFILE_SPEC32 \ "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s" -#undef TARGET_VERSION -#define TARGET_VERSION fprintf (stderr, " (sparc64 GNU/Linux with ELF)"); +#define ENDFILE_SPEC64 \ + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} /usr/lib64/crtn.o%s" + +#ifdef SPARC_BI_ARCH -/* A 64 bit v9 compiler with stack-bias, - in a Medium/Anywhere code model environment. */ +#if DEFAULT_ARCH32_P +#define ENDFILE_SPEC "\ +%{m32:" ENDFILE_SPEC32 "} \ +%{m64:" ENDFILE_SPEC64 "} \ +%{!m32:%{!m64:" ENDFILE_SPEC32 "}}" +#else +#define ENDFILE_SPEC "\ +%{m32:" ENDFILE_SPEC32 "} \ +%{m64:" ENDFILE_SPEC64 "} \ +%{!m32:%{!m64:" ENDFILE_SPEC64 "}}" +#endif -#undef TARGET_DEFAULT -#define TARGET_DEFAULT \ - (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ \ - + MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU) +#else + +#define ENDFILE_SPEC ENDFILE_SPEC64 + +#endif + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (sparc64 GNU/Linux with ELF)"); /* The default code model. */ #undef SPARC_DEFAULT_CMODEL -#define SPARC_DEFAULT_CMODEL CM_MEDANY +#define SPARC_DEFAULT_CMODEL CM_MEDLOW #undef WCHAR_TYPE #define WCHAR_TYPE "long int" @@ -92,9 +142,9 @@ Boston, MA 02111-1307, USA. */ #undef LONG_DOUBLE_TYPE_SIZE #define LONG_DOUBLE_TYPE_SIZE 128 - + #undef CPP_PREDEFINES -#define CPP_PREDEFINES "-D__ELF__ -Dunix -D_LONGLONG -Dsparc -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)" +#define CPP_PREDEFINES "-D__ELF__ -Dunix -D_LONGLONG -D__sparc__ -Dlinux -Asystem(unix) -Asystem(posix)" #undef CPP_SUBTARGET_SPEC #define CPP_SUBTARGET_SPEC "\ @@ -126,17 +176,88 @@ Boston, MA 02111-1307, USA. */ /* If ELF is the default format, we should not use /lib/elf. */ +#ifdef SPARC_BI_ARCH + +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "link_arch32", LINK_ARCH32_SPEC }, \ + { "link_arch64", LINK_ARCH64_SPEC }, \ + { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ + { "link_arch", LINK_ARCH_SPEC }, + +#define LINK_ARCH32_SPEC "-m elf32_sparc -Y P,/usr/lib %{shared:-shared} \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \ + %{static:-static}}} \ +" + +#define LINK_ARCH64_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ + %{!shared: \ + %{!ibcs: \ + %{!static: \ + %{rdynamic:-export-dynamic} \ + %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \ + %{static:-static}}} \ +" + +#define LINK_ARCH_SPEC "\ +%{m32:%(link_arch32)} \ +%{m64:%(link_arch64)} \ +%{!m32:%{!m64:%(link_arch_default)}} \ +" + +#define LINK_ARCH_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? LINK_ARCH32_SPEC : LINK_ARCH64_SPEC) + #undef LINK_SPEC -#define LINK_SPEC "-m elf64_sparc -Y P,/usr/lib %{shared:-shared} \ +#define LINK_SPEC "\ +%(link_arch) \ +%{mlittle-endian:-EL} \ +" + +#undef CC1_SPEC +#if DEFAULT_ARCH32_P +#define CC1_SPEC "\ +%{sun4:} %{target:} \ +%{mcypress:-mcpu=cypress} \ +%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ +%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ +%{m64:-mptr64 -mcpu=ultrasparc -mstack-bias} \ +" +#else +#define CC1_SPEC "\ +%{sun4:} %{target:} \ +%{mcypress:-mcpu=cypress} \ +%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ +%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ +%{m32:-mptr32 -mcpu=cypress -mno-stack-bias} \ +" +#endif + +#if DEFAULT_ARCH32_P +#define MULTILIB_DEFAULTS { "m32" } +#else +#define MULTILIB_DEFAULTS { "m64" } +#endif + +#else /* !SPARC_BI_ARCH */ + +#undef LINK_SPEC +#define LINK_ARCH_SPEC "-m elf64_sparc -Y P,/usr/lib64 %{shared:-shared} \ %{!shared: \ %{!ibcs: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{!dynamic-linker:-dynamic-linker /lib/ld-linux64.so.2}} \ + %{!dynamic-linker:-dynamic-linker /lib64/ld-linux.so.2}} \ %{static:-static}}} \ %{mlittle-endian:-EL} \ " +#endif /* !SPARC_BI_ARCH */ + /* 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 diff --git a/contrib/gcc/config/sparc/pbd.h b/contrib/gcc/config/sparc/pbd.h index 459bffd..b70fdcb 100644 --- a/contrib/gcc/config/sparc/pbd.h +++ b/contrib/gcc/config/sparc/pbd.h @@ -144,35 +144,7 @@ Boston, MA 02111-1307, USA. */ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ fprintf (FILE, "\t.word .L%d\n", VALUE) -/* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. */ - -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tsethi %%hi(.LP%d),%%o0\n\tcall mcount\n\tor %%lo(.LP%d),%%o0,%%o0\n", \ - (LABELNO), (LABELNO)) - -/* Output assembler code to FILE to initialize this source file's - basic block profiling info, if that has not already been done. */ - -#undef FUNCTION_BLOCK_PROFILER -#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tsethi %%hi(.LPBX0),%%o0\n\tld [%%lo(.LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne .LPY%d\n\tnop\n\tcall ___bb_init_func\n\tnop\n.LPY%d:\n", \ - (LABELNO), (LABELNO)) - -/* Output assembler code to FILE to increment the entry-count for - the BLOCKNO'th basic block in this source file. */ - -#undef BLOCK_PROFILER -#define BLOCK_PROFILER(FILE, BLOCKNO) \ -{ \ - int blockn = (BLOCKNO); \ - fprintf (FILE, "\tsethi %%hi(.LPBX2+%d),%%g1\n\tld [%%lo(.LPBX2+%d)+%%g1],%%g2\n\ -\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(.LPBX2+%d)+%%g1]\n", \ - 4 * blockn, 4 * blockn, 4 * blockn); \ - CC_STATUS_INIT; /* We have clobbered %g1. Also %g2. */ \ -} -/* This is needed for SunOS 4.0, and should not hurt for 3.2 +/* This is needed for SunOS 4.0, and should not hurt for 3.2 versions either. */ #undef ASM_OUTPUT_SOURCE_LINE(file, line) #define ASM_OUTPUT_SOURCE_LINE(file, line) \ diff --git a/contrib/gcc/config/sparc/sol2-c1.asm b/contrib/gcc/config/sparc/sol2-c1.asm index 618d698..894a8c3 100644 --- a/contrib/gcc/config/sparc/sol2-c1.asm +++ b/contrib/gcc/config/sparc/sol2-c1.asm @@ -1,4 +1,4 @@ -! crt1.s for solaris 2.0. +! crt1.s for sparc & sparcv9 (SunOS 5) ! Copyright (C) 1992 Free Software Foundation, Inc. ! Written By David Vinayak Henkel-Wallace, June 1992 @@ -37,43 +37,67 @@ ! in section 3 of the SVr4 ABI. ! This file is the first thing linked into any executable. +#ifdef __sparcv9 +#define CPTRSIZE 8 +#define CPTRSHIFT 3 +#define STACK_BIAS 2047 +#define ldn ldx +#define stn stx +#define setn(s, scratch, dst) setx s, scratch, dst +#else +#define CPTRSIZE 4 +#define CPTRSHIFT 2 +#define STACK_BIAS 0 +#define ldn ld +#define stn st +#define setn(s, scratch, dst) set s, dst +#endif + .section ".text" .proc 022 .global _start _start: mov 0, %fp ! Mark bottom frame pointer - ld [%sp + 64], %l0 ! argc - add %sp, 68, %l1 ! argv + ldn [%sp + (16 * CPTRSIZE) + STACK_BIAS], %l0 ! argc + add %sp, (17 * CPTRSIZE) + STACK_BIAS, %l1 ! argv ! Leave some room for a call. Sun leaves 32 octets (to sit on ! a cache line?) so we do too. +#ifdef __sparcv9 + sub %sp, 48, %sp +#else sub %sp, 32, %sp +#endif ! %g1 may contain a function to be registered w/atexit orcc %g0, %g1, %g0 +#ifdef __sparcv9 + be %xcc, .nope +#else be .nope +#endif mov %g1, %o0 call atexit nop .nope: ! Now make sure constructors and destructors are handled. - set _fini, %o0 + setn(_fini, %o1, %o0) call atexit, 1 nop call _init, 0 nop - ! We ignore the auxiliary vector; there's no defined way to + ! We ignore the auxiliary vector; there is no defined way to ! access those data anyway. Instead, go straight to main: mov %l0, %o0 ! argc mov %l1, %o1 ! argv ! Skip argc words past argv, to env: - sll %l0, 2, %o2 - add %o2, 4, %o2 + sll %l0, CPTRSHIFT, %o2 + add %o2, CPTRSIZE, %o2 add %l1, %o2, %o2 ! env - set _environ, %o3 - st %o2, [%o3] ! *_environ + setn(_environ, %o4, %o3) + stn %o2, [%o3] ! *_environ call main, 4 nop call exit, 0 diff --git a/contrib/gcc/config/sparc/sol2-ci.asm b/contrib/gcc/config/sparc/sol2-ci.asm index dd09a34..3dc793c 100644 --- a/contrib/gcc/config/sparc/sol2-ci.asm +++ b/contrib/gcc/config/sparc/sol2-ci.asm @@ -48,7 +48,11 @@ .type _init,#function .align 4 _init: +#ifdef __sparcv9 + save %sp, -176, %sp +#else save %sp, -96, %sp +#endif .section ".fini" @@ -57,4 +61,8 @@ _init: .type _fini,#function .align 4 _fini: +#ifdef __sparcv9 + save %sp, -176, %sp +#else save %sp, -96, %sp +#endif diff --git a/contrib/gcc/config/sparc/sol2-cn.asm b/contrib/gcc/config/sparc/sol2-cn.asm index 3c5d508..49e070f 100644 --- a/contrib/gcc/config/sparc/sol2-cn.asm +++ b/contrib/gcc/config/sparc/sol2-cn.asm @@ -51,4 +51,4 @@ ret restore -! Th-th-th-that's all folks! +! Th-th-th-that is all folks! diff --git a/contrib/gcc/config/sparc/sol2-sld-64.h b/contrib/gcc/config/sparc/sol2-sld-64.h new file mode 100644 index 0000000..c2518d8 --- /dev/null +++ b/contrib/gcc/config/sparc/sol2-sld-64.h @@ -0,0 +1,363 @@ +/* Definitions of target machine for GNU compiler, for 64-bit SPARC + running Solaris 2 using the system linker. */ + +#define SPARC_BI_ARCH + +#include "sparc/sol2.h" + +/* At least 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. */ + +#define LINKER_DOES_NOT_WORK_WITH_DWARF2 + +/* A 64 bit v9 compiler with stack-bias */ + +#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc +#undef TARGET_DEFAULT +#define TARGET_DEFAULT \ + (MASK_V9 + MASK_PTR64 + MASK_64BIT /* + MASK_HARD_QUAD */ + \ + MASK_STACK_BIAS + MASK_APP_REGS + MASK_EPILOGUE + MASK_FPU) +#endif + +/* The default code model. */ +#undef SPARC_DEFAULT_CMODEL +#define SPARC_DEFAULT_CMODEL CM_MEDANY + +#undef LONG_DOUBLE_TYPE_SIZE +#define LONG_DOUBLE_TYPE_SIZE 128 + +#undef ASM_CPU32_DEFAULT_SPEC +#define ASM_CPU32_DEFAULT_SPEC "" +#undef ASM_CPU64_DEFAULT_SPEC +#define ASM_CPU64_DEFAULT_SPEC "-xarch=v9" + +#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 +#undef CPP_CPU64_DEFAULT_SPEC +#define CPP_CPU64_DEFAULT_SPEC "" +#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 "" +#undef ASM_CPU32_DEFAULT_SPEC +#define ASM_CPU32_DEFAULT_SPEC "-xarch=v8plusa" +#undef ASM_CPU64_DEFAULT_SPEC +#define ASM_CPU64_DEFAULT_SPEC "-xarch=v9a" +#endif + +/* 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} \ +%(asm_cpu)\ +" + +#if DEFAULT_ARCH32_P +#define DEF_ARCH32_SPEC(__str) "%{!m64:" __str "}" +#define DEF_ARCH64_SPEC(__str) "%{m64:" __str "}" +#else +#define DEF_ARCH32_SPEC(__str) "%{m32:" __str "}" +#define DEF_ARCH64_SPEC(__str) "%{!m32:" __str "}" +#endif + +#undef CPP_CPU_SPEC +#define CPP_CPU_SPEC "\ +%{mcypress:} \ +%{msparclite:-D__sparclite__} \ +%{mf930:-D__sparclite__} %{mf934:-D__sparclite__} \ +%{mv8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \ +%{msupersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \ +%{mcpu=sparclet:-D__sparclet__} %{mcpu=tsc701:-D__sparclet__} \ +%{mcpu=sparclite:-D__sparclite__} \ +%{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \ +%{mcpu=v8:" DEF_ARCH32_SPEC("-D__sparcv8") "} \ +%{mcpu=supersparc:-D__supersparc__ " DEF_ARCH32_SPEC("-D__sparcv8") "} \ +%{mcpu=v9:" DEF_ARCH32_SPEC("-D__sparcv8") "} \ +%{mcpu=ultrasparc:" 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("-xarch=v9a") "} \ +%{mcpu=v9:" DEF_ARCH32_SPEC("-xarch=v8plus") DEF_ARCH64_SPEC("-xarch=v9") "} \ +%{!mcpu=ultrasparc:%{!mcpu=v9:%{mcpu*:" DEF_ARCH32_SPEC("-xarch=v8") DEF_ARCH64_SPEC("-xarch=v9") "}}} \ +%{!mcpu*:%(asm_cpu_default)} \ +" + +#define STARTFILE_SPEC32 "\ +%{ansi:values-Xc.o%s} \ +%{!ansi: \ + %{traditional:values-Xt.o%s} \ + %{!traditional:values-Xa.o%s}}" + +#define STARTFILE_SPEC64 "\ +%{ansi:/usr/lib/sparcv9/values-Xc.o%s} \ +%{!ansi: \ + %{traditional:/usr/lib/sparcv9/values-Xt.o%s} \ + %{!traditional:/usr/lib/sparcv9/values-Xa.o%s}}" + +#ifdef SPARC_BI_ARCH + +#if DEFAULT_ARCH32_P +#define STARTFILE_ARCH_SPEC "\ +%{m32:" STARTFILE_SPEC32 "} \ +%{m64:" STARTFILE_SPEC64 "} \ +%{!m32:%{!m64:" STARTFILE_SPEC32 "}}" +#else +#define STARTFILE_ARCH_SPEC "\ +%{m32:" STARTFILE_SPEC32 "} \ +%{m64:" STARTFILE_SPEC64 "} \ +%{!m32:%{!m64:" STARTFILE_SPEC64 "}}" +#endif + +#else /* !SPARC_BI_ARCH */ + +/* In this case we define MD_STARTFILE_PREFIX to /usr/lib/sparcv9/ */ +#define STARTFILE_ARCH_SPEC STARTFILE_SPEC32 + +#endif /* !SPARC_BI_ARCH */ + +#undef STARTFILE_SPEC +#define STARTFILE_SPEC "%{!shared: \ + %{!symbolic: \ + %{p:mcrt1.o%s} \ + %{!p: \ + %{pg:gcrt1.o%s gmon.o%s} \ + %{!pg:crt1.o%s}}}} \ + crti.o%s" STARTFILE_ARCH_SPEC " \ + crtbegin.o%s" + +#ifdef SPARC_BI_ARCH + +#undef CPP_CPU_DEFAULT_SPEC +#define CPP_CPU_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? "\ +%{m64:" CPP_CPU64_DEFAULT_SPEC "} \ +%{!m64:" CPP_CPU32_DEFAULT_SPEC "} \ +" : "\ +%{m32:" CPP_CPU32_DEFAULT_SPEC "} \ +%{!m32:" CPP_CPU64_DEFAULT_SPEC "} \ +") + +#undef ASM_CPU_DEFAULT_SPEC +#define ASM_CPU_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? "\ +%{m64:" ASM_CPU64_DEFAULT_SPEC "} \ +%{!m64:" ASM_CPU32_DEFAULT_SPEC "} \ +" : "\ +%{m32:" ASM_CPU32_DEFAULT_SPEC "} \ +%{!m32:" ASM_CPU64_DEFAULT_SPEC "} \ +") + +#undef CPP_ARCH32_SPEC +#define CPP_ARCH32_SPEC "-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int \ +-D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc)" +#undef CPP_ARCH64_SPEC +#define CPP_ARCH64_SPEC "-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int \ +-D__arch64__ -Acpu(sparc64) -Amachine(sparcv9) -D__sparcv9" + +#undef CPP_ARCH_SPEC +#define CPP_ARCH_SPEC "\ +%{m32:%(cpp_arch32)} \ +%{m64:%(cpp_arch64)} \ +%{!m32:%{!m64:%(cpp_arch_default)}} \ +" + +#undef ASM_ARCH_SPEC +#define ASM_ARCH_SPEC "" + +#undef ASM_ARCH32_SPEC +#define ASM_ARCH32_SPEC "" + +#undef ASM_ARCH64_SPEC +#define ASM_ARCH64_SPEC "" + +#undef ASM_ARCH_DEFAULT_SPEC +#define ASM_ARCH_DEFAULT_SPEC "" + +#undef SUBTARGET_EXTRA_SPECS +#define SUBTARGET_EXTRA_SPECS \ + { "link_arch32", LINK_ARCH32_SPEC }, \ + { "link_arch64", LINK_ARCH64_SPEC }, \ + { "link_arch_default", LINK_ARCH_DEFAULT_SPEC }, \ + { "link_arch", LINK_ARCH_SPEC }, + +/* This should be the same as in svr4.h, except with -R added. */ +#define LINK_ARCH32_SPEC \ + "%{G:-G} \ + %{YP,*} \ + %{R*} \ + %{compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{pg:-Y P,/usr/ucblib:/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{!p:%{!pg:-Y P,/usr/ucblib:/usr/ccs/lib:/usr/lib}}} \ + -R /usr/ucblib} \ + %{!compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{pg:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \ + %{!p:%{!pg:-Y P,/usr/ccs/lib:/usr/lib}}}}" + +#define LINK_ARCH64_SPEC \ + "%{mcmodel=medlow:-M /usr/lib/ld/sparcv9/map.below4G} \ + %{G:-G} \ + %{YP,*} \ + %{R*} \ + %{compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{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} \ + %{!compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}}" + +#define LINK_ARCH_SPEC "\ +%{m32:%(link_arch32)} \ +%{m64:%(link_arch64)} \ +%{!m32:%{!m64:%(link_arch_default)}} \ +" + +#define LINK_ARCH_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? LINK_ARCH32_SPEC : LINK_ARCH64_SPEC) + +#undef LINK_SPEC +#define LINK_SPEC \ + "%{h*} %{v:-V} \ + %{b} %{Wl,*:%*} \ + %{static:-dn -Bstatic} \ + %{shared:-G -dy %{!mimpure-text:-z text}} \ + %{symbolic:-Bsymbolic -G -dy -z text} \ + %(link_arch) \ + %{Qy:} %{!Qn:-Qy}" + +#undef CC1_SPEC +#if DEFAULT_ARCH32_P +#define CC1_SPEC "\ +%{sun4:} %{target:} \ +%{mcypress:-mcpu=cypress} \ +%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ +%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ +%{m64:-mptr64 -mcpu=v9 -mstack-bias -mno-v8plus} \ +" +#else +#define CC1_SPEC "\ +%{sun4:} %{target:} \ +%{mcypress:-mcpu=cypress} \ +%{msparclite:-mcpu=sparclite} %{mf930:-mcpu=f930} %{mf934:-mcpu=f934} \ +%{mv8:-mcpu=v8} %{msupersparc:-mcpu=supersparc} \ +%{m32:-mptr32 -mcpu=cypress -mno-stack-bias} \ +%{mv8plus:-m32 -mptr32 -mcpu=cypress -mno-stack-bias} \ +" +#endif + +#if DEFAULT_ARCH32_P +#define MULTILIB_DEFAULTS { "m32" } +#else +#define MULTILIB_DEFAULTS { "m64" } +#endif + +#else /* !SPARC_BI_ARCH */ + +/* + * This should be the same as in sol2-sld.h, except with "/sparcv9" + * appended to the paths and /usr/ccs/lib is no longer necessary + */ +#undef LINK_SPEC +#define LINK_SPEC \ + "%{h*} %{v:-V} \ + %{b} %{Wl,*:%*} \ + %{static:-dn -Bstatic} \ + %{shared:-G -dy %{!mimpure-text:-z text}} \ + %{symbolic:-Bsymbolic -G -dy -z text} \ + %{mcmodel=medlow:-M /usr/lib/ld/sparcv9/map.below4G} \ + %{G:-G} \ + %{YP,*} \ + %{R*} \ + %{compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/ucblib/sparcv9:/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{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} \ + %{!compat-bsd: \ + %{!YP,*:%{p:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{pg:-Y P,/usr/lib/libp/sparcv9:/usr/lib/sparcv9} \ + %{!p:%{!pg:-Y P,/usr/lib/sparcv9}}}} \ + %{Qy:} %{!Qn:-Qy}" + +#undef MD_STARTFILE_PREFIX +#define MD_STARTFILE_PREFIX "/usr/lib/sparcv9/" + +#endif /* ! SPARC_BI_ARCH */ + +/* + * 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 bits 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. + * + */ + +#define TRANSFER_FROM_TRAMPOLINE \ +static int need_enable_exec_stack; \ + \ +static void check_enabling(void) __attribute__ ((constructor)); \ +static void check_enabling(void) \ +{ \ + extern long sysconf(int); \ + \ + int prot = (int) sysconf(515 /*_SC_STACK_PROT */); \ + if (prot != 7) \ + need_enable_exec_stack = 1; \ +} \ + \ +void \ +__enable_execute_stack (addr) \ + void *addr; \ +{ \ + if (!need_enable_exec_stack) \ + return; \ + else { \ + long size = getpagesize (); \ + long mask = ~(size-1); \ + char *page = (char *) (((long) addr) & mask); \ + char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); \ + \ + /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ \ + if (mprotect (page, end - page, 7) < 0) \ + perror ("mprotect of trampoline code"); \ + } \ +} + +/* A C statement (sans semicolon) to output an element in the table of + global constructors. */ +#undef ASM_OUTPUT_CONSTRUCTOR +#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ + do { \ + ctors_section (); \ + fprintf (FILE, "\t%s\t ", TARGET_ARCH64 ? ASM_LONGLONG : INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* A C statement (sans semicolon) to output an element in the table of + global destructors. */ +#undef ASM_OUTPUT_DESTRUCTOR +#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \ + do { \ + dtors_section (); \ + fprintf (FILE, "\t%s\t ", TARGET_ARCH64 ? ASM_LONGLONG : INT_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, "\n"); \ + } while (0) + diff --git a/contrib/gcc/config/sparc/sol2.h b/contrib/gcc/config/sparc/sol2.h index a0fa4a8..9274f9d 100644 --- a/contrib/gcc/config/sparc/sol2.h +++ b/contrib/gcc/config/sparc/sol2.h @@ -195,10 +195,14 @@ Boston, MA 02111-1307, USA. */ #undef INIT_SUBTARGET_OPTABS #define INIT_SUBTARGET_OPTABS \ - fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ftoll"); \ - fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__ftoull"); \ - fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__dtoll"); \ - fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, "__dtoull") + fixsfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, \ + TARGET_ARCH64 ? "__ftol" : "__ftoll"); \ + fixunssfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, \ + TARGET_ARCH64 ? "__ftoul" : "__ftoull"); \ + fixdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, \ + TARGET_ARCH64 ? "__dtol" : "__dtoll"); \ + fixunsdfdi_libfunc = gen_rtx_SYMBOL_REF (Pmode, \ + TARGET_ARCH64 ? "__dtoul" : "__dtoull") /* No weird SPARC variants on Solaris */ #undef TARGET_LIVE_G0 diff --git a/contrib/gcc/config/sparc/sp64-elf.h b/contrib/gcc/config/sparc/sp64-elf.h index 2482866..4fd81c5 100644 --- a/contrib/gcc/config/sparc/sp64-elf.h +++ b/contrib/gcc/config/sparc/sp64-elf.h @@ -80,8 +80,8 @@ crtbegin.o%s \ /* V9 chips can handle either endianness. */ #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ -{"big-endian", -MASK_LITTLE_ENDIAN}, \ -{"little-endian", MASK_LITTLE_ENDIAN}, +{"big-endian", -MASK_LITTLE_ENDIAN, "Generate code for big endian" }, \ +{"little-endian", MASK_LITTLE_ENDIAN, "Generate code for little endian" }, #undef BYTES_BIG_ENDIAN #define BYTES_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) @@ -102,9 +102,10 @@ crtbegin.o%s \ /* The medium/anywhere code model practically requires us to put jump tables in the text section as gcc is unable to distinguish LABEL_REF's of jump tables from other label refs (when we need to). */ -/* ??? Revisit this. */ +/* But we now defer the tables to the end of the function, so we make + this 0 to not confuse the branch shortening code. */ #undef JUMP_TABLES_IN_TEXT_SECTION -#define JUMP_TABLES_IN_TEXT_SECTION 1 +#define JUMP_TABLES_IN_TEXT_SECTION 0 /* System V Release 4 uses DWARF debugging info. GDB doesn't support 64 bit stabs yet and the desired debug format is DWARF diff --git a/contrib/gcc/config/sparc/sparc.c b/contrib/gcc/config/sparc/sparc.c index e350729..ad12ec3 100644 --- a/contrib/gcc/config/sparc/sparc.c +++ b/contrib/gcc/config/sparc/sparc.c @@ -1,5 +1,5 @@ /* Subroutines for insn-output.c for Sun SPARC. - Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92-98, 1999 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. @@ -98,20 +98,28 @@ char leaf_reg_remap[] = this is "%sp+something". We record "something" separately as it may be too big for reg+constant addressing. */ -static char *frame_base_name; +static const char *frame_base_name; static int frame_base_offset; static rtx pic_setup_code PROTO((void)); -static rtx find_addr_reg PROTO((rtx)); static void sparc_init_modes PROTO((void)); -static int save_regs PROTO((FILE *, int, int, char *, +static int save_regs PROTO((FILE *, int, int, const char *, int, int, int)); -static int restore_regs PROTO((FILE *, int, int, char *, int, int)); -static void build_big_number PROTO((FILE *, int, char *)); +static int restore_regs PROTO((FILE *, int, int, const char *, int, int)); +static void build_big_number PROTO((FILE *, int, const char *)); static int function_arg_slotno PROTO((const CUMULATIVE_ARGS *, enum machine_mode, tree, int, int, int *, int *)); +static int supersparc_adjust_cost PROTO((rtx, rtx, rtx, int)); +static int hypersparc_adjust_cost PROTO((rtx, rtx, rtx, int)); +static int ultrasparc_adjust_cost PROTO((rtx, rtx, rtx, int)); + +static void sparc_output_addr_vec PROTO((rtx)); +static void sparc_output_addr_diff_vec PROTO((rtx)); +static void sparc_output_deferred_case_vectors PROTO((void)); + + #ifdef DWARF2_DEBUGGING_INFO extern char *dwarf2out_cfi_label (); #endif @@ -119,14 +127,14 @@ extern char *dwarf2out_cfi_label (); /* Option handling. */ /* Code model option as passed by user. */ -char *sparc_cmodel_string; +const char *sparc_cmodel_string; /* Parsed value. */ enum cmodel sparc_cmodel; /* Record alignment options as passed by user. */ -char *sparc_align_loops_string; -char *sparc_align_jumps_string; -char *sparc_align_funcs_string; +const char *sparc_align_loops_string; +const char *sparc_align_jumps_string; +const char *sparc_align_funcs_string; /* Parsed values, as a power of two. */ int sparc_align_loops; @@ -152,7 +160,7 @@ void sparc_override_options () { static struct code_model { - char *name; + const char *name; int value; } cmodels[] = { { "32", CM_32 }, @@ -166,13 +174,15 @@ sparc_override_options () /* Map TARGET_CPU_DEFAULT to value for -m{arch,tune}=. */ static struct cpu_default { int cpu; - char *name; + const char *name; } cpu_default[] = { /* There must be one entry here for each TARGET_CPU value. */ { TARGET_CPU_sparc, "cypress" }, { TARGET_CPU_sparclet, "tsc701" }, { TARGET_CPU_sparclite, "f930" }, { TARGET_CPU_v8, "v8" }, + { TARGET_CPU_hypersparc, "hypersparc" }, + { TARGET_CPU_sparclite86x, "sparclite86x" }, { TARGET_CPU_supersparc, "supersparc" }, { TARGET_CPU_v9, "v9" }, { TARGET_CPU_ultrasparc, "ultrasparc" }, @@ -181,7 +191,7 @@ sparc_override_options () struct cpu_default *def; /* Table of values for -m{cpu,tune}=. */ static struct cpu_table { - char *name; + const char *name; enum processor_type processor; int disable; int enable; @@ -196,6 +206,8 @@ sparc_override_options () The Fujitsu MB86934 is the recent sparclite chip, with an fpu. */ { "f930", PROCESSOR_F930, MASK_ISA|MASK_FPU, MASK_SPARCLITE }, { "f934", PROCESSOR_F934, MASK_ISA, MASK_SPARCLITE|MASK_FPU }, + { "hypersparc", PROCESSOR_HYPERSPARC, MASK_ISA, MASK_V8|MASK_FPU }, + { "sparclite86x", PROCESSOR_SPARCLITE86X, MASK_ISA|MASK_FPU, MASK_V8 }, { "sparclet", PROCESSOR_SPARCLET, MASK_ISA, MASK_SPARCLET }, /* TEMIC sparclet */ { "tsc701", PROCESSOR_TSC701, MASK_ISA, MASK_SPARCLET }, @@ -207,7 +219,7 @@ sparc_override_options () struct cpu_table *cpu; struct sparc_cpu_select *sel; int fpu; - + #ifndef SPARC_BI_ARCH /* Check for unsupported architecture size. */ if (! TARGET_64BIT != DEFAULT_ARCH32_P) @@ -217,8 +229,25 @@ sparc_override_options () } #endif + /* At the moment we don't allow different pointer size and architecture */ + if (! TARGET_64BIT != ! TARGET_PTR64) + { + error ("-mptr%d not allowed on -m%d", + TARGET_PTR64 ? 64 : 32, TARGET_64BIT ? 64 : 32); + if (TARGET_64BIT) + target_flags |= MASK_PTR64; + else + target_flags &= ~MASK_PTR64; + } + /* Code model selection. */ sparc_cmodel = SPARC_DEFAULT_CMODEL; + +#ifdef SPARC_BI_ARCH + if (TARGET_ARCH32) + sparc_cmodel = CM_32; +#endif + if (sparc_cmodel_string != NULL) { if (TARGET_ARCH64) @@ -277,13 +306,17 @@ sparc_override_options () if (TARGET_V9 && TARGET_ARCH32) target_flags |= MASK_DEPRECATED_V8_INSNS; - /* V8PLUS requires V9 */ - if (! TARGET_V9) + /* V8PLUS requires V9, makes no sense in 64 bit mode. */ + if (! TARGET_V9 || TARGET_ARCH64) target_flags &= ~MASK_V8PLUS; /* Don't use stack biasing in 32 bit mode. */ if (TARGET_ARCH32) target_flags &= ~MASK_STACK_BIAS; + + /* Don't allow -mvis if FPU is disabled. */ + if (! TARGET_FPU) + target_flags &= ~MASK_VIS; /* Validate -malign-loops= value, or provide default. */ if (sparc_align_loops_string) @@ -332,6 +365,12 @@ sparc_override_options () /* Do various machine dependent initializations. */ sparc_init_modes (); + + if ((profile_flag || profile_block_flag) + && sparc_cmodel != CM_MEDLOW) + { + error ("profiling does not support code models other than medlow"); + } } /* Miscellaneous utilities. */ @@ -347,14 +386,6 @@ v9_regcmp_p (code) || code == LE || code == GT); } -/* 32 bit registers are zero extended so only zero/non-zero comparisons - work. */ -int -v8plus_regcmp_p (code) - enum rtx_code code; -{ - return (code == EQ || code == NE); -} /* Operand constraints. */ @@ -637,56 +668,6 @@ reg_or_nonsymb_mem_operand (op, mode) } int -sparc_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX) - return 1; - if (GET_CODE (op) == CONST_INT) - return SMALL_INT (op); - if (GET_MODE (op) != mode) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) != MEM) - return 0; - - op = XEXP (op, 0); - if (GET_CODE (op) == LO_SUM) - return (GET_CODE (XEXP (op, 0)) == REG - && symbolic_operand (XEXP (op, 1), Pmode)); - return memory_address_p (mode, op); -} - -int -move_operand (op, mode) - rtx op; - enum machine_mode mode; -{ - if (mode == DImode && arith_double_operand (op, mode)) - return 1; - if (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX) - return 1; - if (GET_CODE (op) == CONST_INT) - return SMALL_INT (op) || SPARC_SETHI_P (INTVAL (op)); - - if (GET_MODE (op) != mode) - return 0; - if (GET_CODE (op) == SUBREG) - op = SUBREG_REG (op); - if (GET_CODE (op) != MEM) - return 0; - op = XEXP (op, 0); - if (GET_CODE (op) == LO_SUM) - return (register_operand (XEXP (op, 0), Pmode) - && CONSTANT_P (XEXP (op, 1))); - return memory_address_p (mode, op); -} - -int splittable_symbolic_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED; @@ -775,17 +756,6 @@ v9_regcmp_op (op, mode) return v9_regcmp_p (code); } -/* ??? Same as eq_or_neq. */ -int -v8plus_regcmp_op (op, mode) - register rtx op; - enum machine_mode mode ATTRIBUTE_UNUSED; -{ - enum rtx_code code = GET_CODE (op); - - return (code == EQ || code == NE); -} - /* Return 1 if this is a SIGN_EXTEND or ZERO_EXTEND operation. */ int @@ -837,8 +807,7 @@ arith_operand (op, mode) enum machine_mode mode; { int val; - if (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX) + if (register_operand (op, mode)) return 1; if (GET_CODE (op) != CONST_INT) return 0; @@ -846,6 +815,72 @@ arith_operand (op, mode) return SPARC_SIMM13_P (val); } +/* Return true if OP is a constant 4096 */ + +int +arith_4096_operand (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + int val; + if (GET_CODE (op) != CONST_INT) + return 0; + val = INTVAL (op) & 0xffffffff; + return val == 4096; +} + +/* Return true if OP is suitable as second operand for add/sub */ + +int +arith_add_operand (op, mode) + rtx op; + enum machine_mode mode; +{ + return arith_operand (op, mode) || arith_4096_operand (op, mode); +} + +/* Return true if OP is a CONST_INT or a CONST_DOUBLE which can fit in the + 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; +{ + return ((GET_CODE (op) == CONST_INT + && SPARC_SIMM13_P (INTVAL (op))) +#if HOST_BITS_PER_WIDE_INT != 64 + || (GET_CODE (op) == CONST_DOUBLE + && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op)) + && (CONST_DOUBLE_HIGH (op) == + ((CONST_DOUBLE_LOW (op) & 0x80000000) != 0 ? + (HOST_WIDE_INT)0xffffffff : 0))) +#endif + ); +} + +/* The same, but only for sethi instructions. */ +int +const64_high_operand (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; +{ + return ((GET_CODE (op) == CONST_INT + && (INTVAL (op) & 0xfffffc00) != 0 + && SPARC_SETHI_P (INTVAL (op)) +#if HOST_BITS_PER_WIDE_INT != 64 + /* Must be positive on non-64bit host else the + optimizer is fooled into thinking that sethi + sign extends, even though it does not. */ + && INTVAL (op) >= 0 +#endif + ) + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && (CONST_DOUBLE_LOW (op) & 0xfffffc00) != 0 + && SPARC_SETHI_P (CONST_DOUBLE_LOW (op)))); +} + /* Return true if OP is a register, or is a CONST_INT that can fit in a signed 11 bit immediate field. This is an acceptable SImode operand for the movcc instructions. */ @@ -856,7 +891,6 @@ arith11_operand (op, mode) enum machine_mode mode; { return (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX || (GET_CODE (op) == CONST_INT && SPARC_SIMM11_P (INTVAL (op)))); } @@ -870,7 +904,6 @@ arith10_operand (op, mode) enum machine_mode mode; { return (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX || (GET_CODE (op) == CONST_INT && SPARC_SIMM10_P (INTVAL (op)))); } @@ -887,7 +920,6 @@ arith_double_operand (op, mode) enum machine_mode mode; { return (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX || (GET_CODE (op) == CONST_INT && SMALL_INT (op)) || (! TARGET_ARCH64 && GET_CODE (op) == CONST_DOUBLE @@ -902,6 +934,30 @@ arith_double_operand (op, mode) && (CONST_DOUBLE_LOW (op) & 0x1000) == 0)))); } +/* 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; +{ + return (TARGET_ARCH64 && + ((GET_CODE (op) == CONST_INT && INTVAL (op) == 4096) || + (GET_CODE (op) == CONST_DOUBLE && + CONST_DOUBLE_LOW (op) == 4096 && + CONST_DOUBLE_HIGH (op) == 0))); +} + +/* 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; +{ + return arith_double_operand (op, mode) || arith_double_4096_operand (op, mode); +} + /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that can fit in an 11 bit immediate field. This is an acceptable DImode operand for the movcc instructions. */ @@ -913,7 +969,6 @@ arith11_double_operand (op, mode) enum machine_mode mode; { return (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX || (GET_CODE (op) == CONST_DOUBLE && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) && (unsigned HOST_WIDE_INT) (CONST_DOUBLE_LOW (op) + 0x400) < 0x800 @@ -937,7 +992,6 @@ arith10_double_operand (op, mode) enum machine_mode mode; { return (register_operand (op, mode) - || GET_CODE (op) == CONSTANT_P_RTX || (GET_CODE (op) == CONST_DOUBLE && (GET_MODE (op) == mode || GET_MODE (op) == VOIDmode) && (unsigned) (CONST_DOUBLE_LOW (op) + 0x200) < 0x400 @@ -959,8 +1013,18 @@ small_int (op, mode) 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; +{ return ((GET_CODE (op) == CONST_INT && SMALL_INT (op)) - || GET_CODE (op) == CONSTANT_P_RTX); + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op)))); } /* Recognize operand values for the umul instruction. That instruction sign @@ -974,16 +1038,15 @@ uns_small_int (op, mode) { #if HOST_BITS_PER_WIDE_INT > 32 /* All allowed constants will fit a CONST_INT. */ - return ((GET_CODE (op) == CONST_INT - && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) - || (INTVAL (op) >= 0xFFFFF000 && INTVAL (op) < 0x100000000L))) - || GET_CODE (op) == CONSTANT_P_RTX); + return (GET_CODE (op) == CONST_INT + && ((INTVAL (op) >= 0 && INTVAL (op) < 0x1000) + || (INTVAL (op) >= 0xFFFFF000 + && INTVAL (op) < 0x100000000))); #else - return (((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) - || (GET_CODE (op) == CONST_DOUBLE - && CONST_DOUBLE_HIGH (op) == 0 - && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)) - || GET_CODE (op) == CONSTANT_P_RTX); + return ((GET_CODE (op) == CONST_INT && (unsigned) INTVAL (op) < 0x1000) + || (GET_CODE (op) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (op) == 0 + && (unsigned) CONST_DOUBLE_LOW (op) - 0xFFFFF000 < 0x1000)); #endif } @@ -1003,1750 +1066,1639 @@ clobbered_register (op, mode) { return (GET_CODE (op) == REG && call_used_regs[REGNO (op)]); } - -/* X and Y are two things to compare using CODE. Emit the compare insn and - return the rtx for the cc reg in the proper mode. */ -rtx -gen_compare_reg (code, x, y) - enum rtx_code code; - rtx x, y; +/* Return 1 if OP is const0_rtx, used for TARGET_LIVE_G0 insns. */ + +int +zero_operand (op, mode) + rtx op; + enum machine_mode mode ATTRIBUTE_UNUSED; { - enum machine_mode mode = SELECT_CC_MODE (code, x, y); - rtx cc_reg; + return op == const0_rtx; +} - /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the - fcc regs (cse can't tell they're really call clobbered regs and will - remove a duplicate comparison even if there is an intervening function - call - it will then try to reload the cc reg via an int reg which is why - we need the movcc patterns). It is possible to provide the movcc - patterns by using the ldxfsr/stxfsr v9 insns. I tried it: you need two - registers (say %g1,%g5) and it takes about 6 insns. A better fix would be - to tell cse that CCFPE mode registers (even pseudos) are call - clobbered. */ +/* Return 1 if OP is a valid operand for the source of a move insn. */ - /* ??? This is an experiment. Rather than making changes to cse which may - or may not be easy/clean, we do our own cse. This is possible because - we will generate hard registers. Cse knows they're call clobbered (it - doesn't know the same thing about pseudos). If we guess wrong, no big - deal, but if we win, great! */ +int +input_operand (op, mode) + 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; - if (TARGET_V9 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) -#if 1 /* experiment */ + /* 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) + return 1; + + /* Allow any one instruction integer constant, and all CONST_INT + variants when we are working in DImode and !arch64. */ + if (GET_MODE_CLASS (mode) == MODE_INT + && ((GET_CODE (op) == CONST_INT + && ((SPARC_SETHI_P (INTVAL (op)) + && (! TARGET_ARCH64 + || (INTVAL (op) >= 0) + || mode == SImode)) + || SPARC_SIMM13_P (INTVAL (op)) + || (mode == DImode + && ! TARGET_ARCH64))) + || (TARGET_ARCH64 + && GET_CODE (op) == CONST_DOUBLE + && ((CONST_DOUBLE_HIGH (op) == 0 + && SPARC_SETHI_P (CONST_DOUBLE_LOW (op))) + || +#if HOST_BITS_PER_WIDE_INT == 64 + (CONST_DOUBLE_HIGH (op) == 0 + && SPARC_SIMM13_P (CONST_DOUBLE_LOW (op))) +#else + (SPARC_SIMM13_P (CONST_DOUBLE_LOW (op)) + && (((CONST_DOUBLE_LOW (op) & 0x80000000) == 0 + && CONST_DOUBLE_HIGH (op) == 0) + || (CONST_DOUBLE_HIGH (op) == -1))) +#endif + )))) + return 1; + + /* If !arch64 and this is a DImode const, allow it so that + the splits can be generated. */ + if (! TARGET_ARCH64 + && mode == DImode + && GET_CODE (op) == CONST_DOUBLE) + return 1; + + if (register_operand (op, mode)) + return 1; + + /* If this is a SUBREG, look inside so that we handle + paradoxical ones. */ + if (GET_CODE (op) == SUBREG) + op = SUBREG_REG (op); + + /* Check for valid MEM forms. */ + if (GET_CODE (op) == MEM) { - int reg; - /* We cycle through the registers to ensure they're all exercised. */ - static int next_fcc_reg = 0; - /* Previous x,y for each fcc reg. */ - static rtx prev_args[4][2]; + rtx inside = XEXP (op, 0); - /* Scan prev_args for x,y. */ - for (reg = 0; reg < 4; reg++) - if (prev_args[reg][0] == x && prev_args[reg][1] == y) - break; - if (reg == 4) + if (GET_CODE (inside) == LO_SUM) { - reg = next_fcc_reg; - prev_args[reg][0] = x; - prev_args[reg][1] = y; - next_fcc_reg = (next_fcc_reg + 1) & 3; + /* We can't allow these because all of the splits + (eventually as they trickle down into DFmode + splits) require offsettable memory references. */ + if (! TARGET_V9 + && GET_MODE (op) == TFmode) + return 0; + + return (register_operand (XEXP (inside, 0), Pmode) + && CONSTANT_P (XEXP (inside, 1))); } - cc_reg = gen_rtx_REG (mode, reg + SPARC_FIRST_V9_FCC_REG); + return memory_address_p (mode, inside); } -#else - cc_reg = gen_reg_rtx (mode); -#endif /* ! experiment */ - else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) - cc_reg = gen_rtx_REG (mode, SPARC_FCC_REG); - else - cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG); - if (TARGET_V8PLUS && mode == CCXmode) + return 0; +} + + +/* We know it can't be done in one insn when we get here, + the movsi expander guarentees this. */ +void +sparc_emit_set_const32 (op0, op1) + rtx op0; + rtx op1; +{ + enum machine_mode mode = GET_MODE (op0); + rtx temp; + + if (GET_CODE (op1) == CONST_INT) { - emit_insn (gen_cmpdi_v8plus (x, y)); + HOST_WIDE_INT value = INTVAL (op1); + + if (SPARC_SETHI_P (value) + || SPARC_SIMM13_P (value)) + abort (); } + + /* Full 2-insn decomposition is needed. */ + if (reload_in_progress || reload_completed) + temp = op0; else + temp = gen_reg_rtx (mode); + + if (GET_CODE (op1) == CONST_INT) { - emit_insn (gen_rtx_SET (VOIDmode, cc_reg, - gen_rtx_COMPARE (mode, x, y))); + /* Emit them as real moves instead of a HIGH/LO_SUM, + this way CSE can see everything and reuse intermediate + values if it wants. */ + if (TARGET_ARCH64 + && HOST_BITS_PER_WIDE_INT != 64 + && (INTVAL (op1) & 0x80000000) != 0) + { + emit_insn (gen_rtx_SET (VOIDmode, + temp, + gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, + INTVAL (op1) & 0xfffffc00, 0))); + } + else + { + emit_insn (gen_rtx_SET (VOIDmode, + temp, + GEN_INT (INTVAL (op1) & 0xfffffc00))); + } + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_IOR (mode, + temp, + GEN_INT (INTVAL (op1) & 0x3ff)))); } + else + { + /* A symbol, emit in the traditional way. */ + emit_insn (gen_rtx_SET (VOIDmode, + temp, + gen_rtx_HIGH (mode, + op1))); + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_LO_SUM (mode, + temp, + op1))); - return cc_reg; + } } -/* This function is used for v9 only. - CODE is the code for an Scc's comparison. - OPERANDS[0] is the target of the Scc insn. - OPERANDS[1] is the value we compare against const0_rtx (which hasn't - been generated yet). + +/* Sparc-v9 code-model support. */ +void +sparc_emit_set_symbolic_const64 (op0, op1, temp1) + rtx op0; + rtx op1; + rtx temp1; +{ + switch (sparc_cmodel) + { + case CM_MEDLOW: + /* The range spanned by all instructions in the object is less + than 2^31 bytes (2GB) and the distance from any instruction + to the location of the label _GLOBAL_OFFSET_TABLE_ is less + than 2^31 bytes (2GB). - This function is needed to turn + The executable must be in the low 4TB of the virtual address + space. - (set (reg:SI 110) - (gt (reg:CCX 100 %icc) - (const_int 0))) - into - (set (reg:SI 110) - (gt:DI (reg:CCX 100 %icc) - (const_int 0))) + sethi %hi(symbol), %temp + or %temp, %lo(symbol), %reg */ + 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; - IE: The instruction recognizer needs to see the mode of the comparison to - find the right instruction. We could use "gt:DI" right in the - define_expand, but leaving it out allows us to handle DI, SI, etc. + case CM_MEDMID: + /* The range spanned by all instructions in the object is less + than 2^31 bytes (2GB) and the distance from any instruction + to the location of the label _GLOBAL_OFFSET_TABLE_ is less + than 2^31 bytes (2GB). + + The executable must be in the low 16TB of the virtual address + space. + + sethi %h44(symbol), %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)); + break; - We refer to the global sparc compare operands sparc_compare_op0 and - sparc_compare_op1. */ + case CM_MEDANY: + /* The range spanned by all instructions in the object is less + than 2^31 bytes (2GB) and the distance from any instruction + to the location of the label _GLOBAL_OFFSET_TABLE_ is less + than 2^31 bytes (2GB). + + The executable can be placed anywhere in the virtual address + space. + + 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 */ + + /* Getting this right wrt. reloading is really tricky. + We _MUST_ have a seperate temporary at this point, + if we don't barf immediately instead of generating + incorrect code. */ + if (temp1 == op0) + abort (); -int -gen_v9_scc (compare_code, operands) - enum rtx_code compare_code; - register rtx *operands; -{ - rtx temp, op0, op1; + 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)); + break; - if (! TARGET_ARCH64 - && (GET_MODE (sparc_compare_op0) == DImode - || GET_MODE (operands[0]) == DImode)) - return 0; + case CM_EMBMEDANY: + /* Old old old backwards compatibility kruft here. + Essentially it is MEDLOW with a fixed 64-bit + virtual base added to all data segment addresses. + Text-segment stuff is computed like MEDANY, we can't + reuse the code above because the relocation knobs + 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 */ + if (data_segment_operand (op1, GET_MODE (op1))) + { + emit_insn (gen_embmedany_sethi (temp1, op1)); + emit_insn (gen_embmedany_brsum (op0, temp1)); + emit_insn (gen_embmedany_losum (op0, op0, op1)); + } + else + { + /* Getting this right wrt. reloading is really tricky. + We _MUST_ have a seperate temporary at this point, + so we barf immediately instead of generating + incorrect code. */ + if (temp1 == op0) + abort (); - /* Handle the case where operands[0] == sparc_compare_op0. - We "early clobber" the result. */ - if (REGNO (operands[0]) == REGNO (sparc_compare_op0)) - { - op0 = gen_reg_rtx (GET_MODE (sparc_compare_op0)); - emit_move_insn (op0, sparc_compare_op0); + 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)); + } + break; + + default: + abort(); } +} + +/* 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 PROTO ((rtx, HOST_WIDE_INT)); +static rtx gen_safe_SET64 PROTO ((rtx, HOST_WIDE_INT)); +static rtx gen_safe_OR64 PROTO ((rtx, HOST_WIDE_INT)); +static rtx gen_safe_XOR64 PROTO ((rtx, HOST_WIDE_INT)); + +#if HOST_BITS_PER_WIDE_INT == 64 +#define GEN_HIGHINT64(__x) GEN_INT ((__x) & 0xfffffc00) +#define GEN_INT64(__x) GEN_INT (__x) +#else +#define GEN_HIGHINT64(__x) \ + gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, \ + (__x) & 0xfffffc00, 0) +#define GEN_INT64(__x) \ + gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, \ + (__x) & 0xffffffff, \ + ((__x) & 0x80000000 \ + ? 0xffffffff : 0)) +#endif + +/* The optimizer is not to assume anything about exactly + which bits are set for a HIGH, they are unspecified. + Unfortunately this leads to many missed optimizations + 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; +{ + emit_insn (gen_rtx_SET (VOIDmode, dest, GEN_HIGHINT64 (val))); +} + +static rtx +gen_safe_SET64 (dest, val) + 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; +{ + return gen_rtx_IOR (DImode, src, GEN_INT64 (val)); +} + +static rtx +gen_safe_XOR64 (src, val) + rtx src; + HOST_WIDE_INT val; +{ + return gen_rtx_XOR (DImode, src, GEN_INT64 (val)); +} + +/* Worker routines for 64-bit constant formation on arch64. + One of the key things to be doing in these emissions is + to create as many temp REGs as possible. This makes it + possible for half-built constants to be used later when + such values are similar to something required later on. + Without doing this, the optimizer cannot see such + opportunities. */ + +static void sparc_emit_set_const64_quick1 + PROTO((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; +{ + unsigned HOST_WIDE_INT high_bits; + + if (is_neg) + high_bits = (~low_bits) & 0xffffffff; else - op0 = sparc_compare_op0; - /* For consistency in the following. */ - op1 = sparc_compare_op1; + high_bits = low_bits; - /* Try to use the movrCC insns. */ - if (TARGET_ARCH64 - && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT - && op1 == const0_rtx - && v9_regcmp_p (compare_code)) + sparc_emit_set_safe_HIGH64 (temp, high_bits); + if (!is_neg) { - /* Special case for op0 != 0. This can be done with one instruction if - operands[0] == sparc_compare_op0. We don't assume they are equal - now though. */ - - if (compare_code == NE - && GET_MODE (operands[0]) == DImode - && GET_MODE (op0) == DImode) + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_safe_OR64 (temp, (high_bits & 0x3ff)))); + } + else + { + /* If we are XOR'ing with -1, then we should emit a one's complement + instead. This way the combiner will notice logical operations + such as ANDN later on and substitute. */ + if ((low_bits & 0x3ff) == 0x3ff) { - emit_insn (gen_rtx_SET (VOIDmode, operands[0], op0)); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_IF_THEN_ELSE (DImode, - gen_rtx_fmt_ee (compare_code, DImode, - op0, const0_rtx), - const1_rtx, - operands[0]))); - return 1; + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_NOT (DImode, temp))); } - - emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx)); - if (GET_MODE (op0) != DImode) + else { - temp = gen_reg_rtx (DImode); - convert_move (temp, op0, 0); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_safe_XOR64 (temp, + (-0x400 | (low_bits & 0x3ff))))); } + } +} + +static void sparc_emit_set_const64_quick2 + PROTO((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; +{ + rtx temp2 = op0; + + if ((high_bits & 0xfffffc00) != 0) + { + sparc_emit_set_safe_HIGH64 (temp, high_bits); + if ((high_bits & ~0xfffffc00) != 0) + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_safe_OR64 (temp, (high_bits & 0x3ff)))); else - temp = op0; - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), - gen_rtx_fmt_ee (compare_code, DImode, - temp, const0_rtx), - const1_rtx, - operands[0]))); - return 1; + temp2 = temp; } else { - operands[1] = gen_compare_reg (compare_code, op0, op1); - - switch (GET_MODE (operands[1])) - { - case CCmode : - case CCXmode : - case CCFPEmode : - case CCFPmode : - break; - default : - abort (); - } - emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx)); - emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), - gen_rtx_fmt_ee (compare_code, - GET_MODE (operands[1]), - operands[1], const0_rtx), - const1_rtx, operands[0]))); - return 1; + emit_insn (gen_safe_SET64 (temp, high_bits)); + temp2 = temp; } -} -/* Emit a conditional jump insn for the v9 architecture using comparison code - CODE and jump target LABEL. - This function exists to take advantage of the v9 brxx insns. */ + /* Now shift it up into place. */ + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_ASHIFT (DImode, temp2, + GEN_INT (shift_count)))); -void -emit_v9_brxx_insn (code, op0, label) - enum rtx_code code; - rtx op0, label; -{ - emit_jump_insn (gen_rtx_SET (VOIDmode, - pc_rtx, - gen_rtx_IF_THEN_ELSE (VOIDmode, - gen_rtx_fmt_ee (code, GET_MODE (op0), - op0, const0_rtx), - gen_rtx_LABEL_REF (VOIDmode, label), - pc_rtx))); -} - -/* Return nonzero if a return peephole merging return with - setting of output register is ok. */ -int -leaf_return_peephole_ok () -{ - return (actual_fsize == 0); + /* If there is a low immediate part piece, finish up by + putting that in as well. */ + if (low_immediate != 0) + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_safe_OR64 (op0, low_immediate))); } -/* Return nonzero if TRIAL can go into the function epilogue's - delay slot. SLOT is the slot we are trying to fill. */ +static void sparc_emit_set_const64_longway + PROTO((rtx, rtx, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT)); -int -eligible_for_epilogue_delay (trial, slot) - rtx trial; - int slot; +/* 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; { - rtx pat, src; + rtx sub_temp; - if (slot >= 1) - return 0; + if (reload_in_progress || reload_completed) + sub_temp = op0; + else + sub_temp = gen_reg_rtx (DImode); - if (GET_CODE (trial) != INSN || GET_CODE (PATTERN (trial)) != SET) - return 0; + if ((high_bits & 0xfffffc00) != 0) + { + sparc_emit_set_safe_HIGH64 (temp, high_bits); + if ((high_bits & ~0xfffffc00) != 0) + emit_insn (gen_rtx_SET (VOIDmode, + sub_temp, + gen_safe_OR64 (temp, (high_bits & 0x3ff)))); + else + sub_temp = temp; + } + else + { + emit_insn (gen_safe_SET64 (temp, high_bits)); + sub_temp = temp; + } - if (get_attr_length (trial) != 1) - return 0; + if (!reload_in_progress && !reload_completed) + { + rtx temp2 = gen_reg_rtx (DImode); + rtx temp3 = gen_reg_rtx (DImode); + rtx temp4 = gen_reg_rtx (DImode); - /* If %g0 is live, there are lots of things we can't handle. - Rather than trying to find them all now, let's punt and only - optimize things as necessary. */ - if (TARGET_LIVE_G0) - return 0; + emit_insn (gen_rtx_SET (VOIDmode, temp4, + gen_rtx_ASHIFT (DImode, sub_temp, + GEN_INT (32)))); - /* In the case of a true leaf function, anything can go into the delay slot. - A delay slot only exists however if the frame size is zero, otherwise - we will put an insn to adjust the stack after the return. */ - if (leaf_function) - { - if (leaf_return_peephole_ok ()) - return ((get_attr_in_uncond_branch_delay (trial) - == IN_BRANCH_DELAY_TRUE)); - return 0; + sparc_emit_set_safe_HIGH64 (temp2, low_bits); + if ((low_bits & ~0xfffffc00) != 0) + { + emit_insn (gen_rtx_SET (VOIDmode, temp3, + gen_safe_OR64 (temp2, (low_bits & 0x3ff)))); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_PLUS (DImode, temp4, temp3))); + } + else + { + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_PLUS (DImode, temp4, temp2))); + } } + else + { + rtx low1 = GEN_INT ((low_bits >> (32 - 12)) & 0xfff); + rtx low2 = GEN_INT ((low_bits >> (32 - 12 - 12)) & 0xfff); + rtx low3 = GEN_INT ((low_bits >> (32 - 12 - 12 - 8)) & 0x0ff); + int to_shift = 12; - /* If only trivial `restore' insns work, nothing can go in the - delay slot. */ - else if (TARGET_BROKEN_SAVERESTORE) - return 0; + /* We are in the middle of reload, so this is really + painful. However we do still make an attempt to + avoid emitting truly stupid code. */ + if (low1 != const0_rtx) + { + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_ASHIFT (DImode, sub_temp, + GEN_INT (to_shift)))); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_IOR (DImode, op0, low1))); + sub_temp = op0; + to_shift = 12; + } + else + { + to_shift += 12; + } + if (low2 != const0_rtx) + { + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_ASHIFT (DImode, sub_temp, + GEN_INT (to_shift)))); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_IOR (DImode, op0, low2))); + sub_temp = op0; + to_shift = 8; + } + else + { + to_shift += 8; + } + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_ASHIFT (DImode, sub_temp, + GEN_INT (to_shift)))); + if (low3 != const0_rtx) + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_IOR (DImode, op0, low3))); + /* phew... */ + } +} - pat = PATTERN (trial); +/* Analyze a 64-bit constant for certain properties. */ +static void analyze_64bit_constant + PROTO((unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT, + int *, int *, int *)); - /* Otherwise, only operations which can be done in tandem with - a `restore' insn can go into the delay slot. */ - if (GET_CODE (SET_DEST (pat)) != REG - || REGNO (SET_DEST (pat)) >= 32 - || REGNO (SET_DEST (pat)) < 24) - return 0; +static void +analyze_64bit_constant (high_bits, low_bits, hbsp, lbsp, abbasp) + unsigned HOST_WIDE_INT high_bits, low_bits; + int *hbsp, *lbsp, *abbasp; +{ + int lowest_bit_set, highest_bit_set, all_bits_between_are_set; + int i; - /* The set of insns matched here must agree precisely with the set of - patterns paired with a RETURN in sparc.md. */ + lowest_bit_set = highest_bit_set = -1; + i = 0; + do + { + if ((lowest_bit_set == -1) + && ((low_bits >> i) & 1)) + lowest_bit_set = i; + if ((highest_bit_set == -1) + && ((high_bits >> (32 - i - 1)) & 1)) + highest_bit_set = (64 - i - 1); + } + while (++i < 32 + && ((highest_bit_set == -1) + || (lowest_bit_set == -1))); + if (i == 32) + { + i = 0; + do + { + if ((lowest_bit_set == -1) + && ((high_bits >> i) & 1)) + lowest_bit_set = i + 32; + if ((highest_bit_set == -1) + && ((low_bits >> (32 - i - 1)) & 1)) + highest_bit_set = 32 - i - 1; + } + while (++i < 32 + && ((highest_bit_set == -1) + || (lowest_bit_set == -1))); + } + /* If there are no bits set this should have gone out + as one instruction! */ + if (lowest_bit_set == -1 + || highest_bit_set == -1) + abort (); + all_bits_between_are_set = 1; + for (i = lowest_bit_set; i <= highest_bit_set; i++) + { + if (i < 32) + { + if ((low_bits & (1 << i)) != 0) + continue; + } + else + { + if ((high_bits & (1 << (i - 32))) != 0) + continue; + } + all_bits_between_are_set = 0; + break; + } + *hbsp = highest_bit_set; + *lbsp = lowest_bit_set; + *abbasp = all_bits_between_are_set; +} - src = SET_SRC (pat); +static int const64_is_2insns + PROTO((unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT)); - /* This matches "*return_[qhs]i". */ - if (arith_operand (src, GET_MODE (src))) - return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); - - /* This matches "*return_di". */ - else if (arith_double_operand (src, GET_MODE (src))) - return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); +static int +const64_is_2insns (high_bits, low_bits) + unsigned HOST_WIDE_INT high_bits, low_bits; +{ + int highest_bit_set, lowest_bit_set, all_bits_between_are_set; - /* This matches "*return_sf_no_fpu". */ - else if (! TARGET_FPU && restore_operand (SET_DEST (pat), SFmode) - && register_operand (src, SFmode)) + if (high_bits == 0 + || high_bits == 0xffffffff) return 1; - /* This matches "*return_addsi". */ - else if (GET_CODE (src) == PLUS - && arith_operand (XEXP (src, 0), SImode) - && arith_operand (XEXP (src, 1), SImode) - && (register_operand (XEXP (src, 0), SImode) - || register_operand (XEXP (src, 1), SImode))) + analyze_64bit_constant (high_bits, low_bits, + &highest_bit_set, &lowest_bit_set, + &all_bits_between_are_set); + + if ((highest_bit_set == 63 + || lowest_bit_set == 0) + && all_bits_between_are_set != 0) return 1; - /* This matches "*return_adddi". */ - else if (GET_CODE (src) == PLUS - && arith_double_operand (XEXP (src, 0), DImode) - && arith_double_operand (XEXP (src, 1), DImode) - && (register_operand (XEXP (src, 0), DImode) - || register_operand (XEXP (src, 1), DImode))) + if ((highest_bit_set - lowest_bit_set) < 21) return 1; return 0; } -static int -check_return_regs (x) - rtx x; +static unsigned HOST_WIDE_INT create_simple_focus_bits + PROTO((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; { - switch (GET_CODE (x)) - { - case REG: - return IN_OR_GLOBAL_P (x); + HOST_WIDE_INT hi, lo; - case CONST_INT: - case CONST_DOUBLE: - case CONST: - case SYMBOL_REF: - case LABEL_REF: - return 1; - - case SET: - case IOR: - case AND: - case XOR: - case PLUS: - case MINUS: - if (check_return_regs (XEXP (x, 1)) == 0) - return 0; - case NOT: - case NEG: - case MEM: - return check_return_regs (XEXP (x, 0)); - - default: - return 0; + if (lowest_bit_set < 32) + { + lo = (low_bits >> lowest_bit_set) << shift; + hi = ((high_bits << (32 - lowest_bit_set)) << shift); } - + else + { + lo = 0; + hi = ((high_bits >> (lowest_bit_set - 32)) << shift); + } + if (hi & lo) + abort (); + return (hi | lo); } -/* Return 1 if TRIAL references only in and global registers. */ -int -eligible_for_return_delay (trial) - rtx trial; +/* Here we are sure to be arch64 and this is an integer constant + being loaded into a register. Emit the most efficient + 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; { - if (GET_CODE (PATTERN (trial)) != SET) - return 0; - - return check_return_regs (PATTERN (trial)); -} + unsigned HOST_WIDE_INT high_bits, low_bits; + int lowest_bit_set, highest_bit_set; + int all_bits_between_are_set; + rtx temp; -int -short_branch (uid1, uid2) - int uid1, uid2; -{ - unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2]; - if (delta + 1024 < 2048) - return 1; - /* warning ("long branch, distance %d", delta); */ - return 0; -} + /* Sanity check that we know what we are working with. */ + if (! TARGET_ARCH64 + || GET_CODE (op0) != REG + || (REGNO (op0) >= SPARC_FIRST_FP_REG + && REGNO (op0) <= SPARC_LAST_V9_FP_REG)) + abort (); -/* Return non-zero if REG is not used after INSN. - 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; -{ - enum rtx_code code, prev_code = UNKNOWN; + if (reload_in_progress || reload_completed) + temp = op0; + else + temp = gen_reg_rtx (DImode); - while ((insn = NEXT_INSN (insn))) + if (GET_CODE (op1) != CONST_DOUBLE + && GET_CODE (op1) != CONST_INT) { - if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)]) - return 1; - - code = GET_CODE (insn); - if (GET_CODE (insn) == CODE_LABEL) - return 1; - - if (GET_RTX_CLASS (code) == 'i') - { - rtx set = single_set (insn); - int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set)); - if (set && in_src) - return 0; - if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) - return 1; - if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) - return 0; - } - prev_code = code; + sparc_emit_set_symbolic_const64 (op0, op1, temp); + return; } - return 1; -} - -/* The table we use to reference PIC data. */ -static rtx global_offset_table; - -/* The function we use to get at it. */ -static rtx get_pc_symbol; -static 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; -{ - switch (flag_pic) + if (GET_CODE (op1) == CONST_DOUBLE) { - case 1: - if (GET_CODE (recog_operand[i]) == SYMBOL_REF - || (GET_CODE (recog_operand[i]) == CONST - && ! (GET_CODE (XEXP (recog_operand[i], 0)) == MINUS - && (XEXP (XEXP (recog_operand[i], 0), 0) - == global_offset_table) - && (GET_CODE (XEXP (XEXP (recog_operand[i], 0), 1)) - == CONST)))) - abort (); - case 2: - default: - return 1; +#if HOST_BITS_PER_WIDE_INT == 64 + high_bits = (CONST_DOUBLE_LOW (op1) >> 32) & 0xffffffff; + low_bits = CONST_DOUBLE_LOW (op1) & 0xffffffff; +#else + high_bits = CONST_DOUBLE_HIGH (op1); + low_bits = CONST_DOUBLE_LOW (op1); +#endif + } + else + { +#if HOST_BITS_PER_WIDE_INT == 64 + high_bits = ((INTVAL (op1) >> 32) & 0xffffffff); + low_bits = (INTVAL (op1) & 0xffffffff); +#else + high_bits = ((INTVAL (op1) < 0) ? + 0xffffffff : + 0x00000000); + low_bits = INTVAL (op1); +#endif } -} - -/* Return true if X is an address which needs a temporary register when - reloaded while generating PIC code. */ -int -pic_address_needs_scratch (x) - 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 - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT - && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) - return 1; + /* low_bits bits 0 --> 31 + high_bits bits 32 --> 63 */ - return 0; -} + analyze_64bit_constant (high_bits, low_bits, + &highest_bit_set, &lowest_bit_set, + &all_bits_between_are_set); -/* 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 non zero, otherwise we allocate register(s) as - necessary. */ + /* First try for a 2-insn sequence. */ -rtx -legitimize_pic_address (orig, mode, reg) - rtx orig; - enum machine_mode mode ATTRIBUTE_UNUSED; - rtx reg; -{ - if (GET_CODE (orig) == SYMBOL_REF - || GET_CODE (orig) == LABEL_REF) + /* These situations are preferred because the optimizer can + * do more things with them: + * 1) mov -1, %reg + * sllx %reg, shift, %reg + * 2) mov -1, %reg + * srlx %reg, shift, %reg + * 3) mov some_small_const, %reg + * sllx %reg, shift, %reg + */ + if (((highest_bit_set == 63 + || lowest_bit_set == 0) + && all_bits_between_are_set != 0) + || ((highest_bit_set - lowest_bit_set) < 12)) { - rtx pic_ref, address; - rtx insn; + HOST_WIDE_INT the_const = -1; + int shift = lowest_bit_set; - if (reg == 0) + if ((highest_bit_set != 63 + && lowest_bit_set != 0) + || all_bits_between_are_set == 0) { - if (reload_in_progress || reload_completed) - abort (); - else - reg = gen_reg_rtx (Pmode); + the_const = + create_simple_focus_bits (high_bits, low_bits, + lowest_bit_set, 0); } + else if (lowest_bit_set == 0) + shift = -(63 - highest_bit_set); - if (flag_pic == 2) - { - /* If not during reload, allocate another temp reg here for loading - in the address, so that these instructions can be optimized - properly. */ - rtx temp_reg = ((reload_in_progress || reload_completed) - ? reg : gen_reg_rtx (Pmode)); + if (! SPARC_SIMM13_P (the_const)) + abort (); - /* Must put the SYMBOL_REF inside an UNSPEC here so that cse - won't get confused into thinking that these two instructions - are loading in the true address of the symbol. If in the - future a PIC rtx exists, that should be used instead. */ - emit_insn (gen_pic_sethi_si (temp_reg, orig)); - emit_insn (gen_pic_lo_sum_si (temp_reg, temp_reg, orig)); + emit_insn (gen_safe_SET64 (temp, the_const)); + if (shift > 0) + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_ASHIFT (DImode, + temp, + GEN_INT (shift)))); + else if (shift < 0) + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_LSHIFTRT (DImode, + temp, + GEN_INT (-shift)))); + else + abort (); + return; + } - address = temp_reg; - } + /* Now a range of 22 or less bits set somewhere. + * 1) sethi %hi(focus_bits), %reg + * sllx %reg, shift, %reg + * 2) sethi %hi(focus_bits), %reg + * srlx %reg, shift, %reg + */ + if ((highest_bit_set - lowest_bit_set) < 21) + { + unsigned HOST_WIDE_INT focus_bits = + create_simple_focus_bits (high_bits, low_bits, + lowest_bit_set, 10); + + if (! SPARC_SETHI_P (focus_bits)) + abort (); + + sparc_emit_set_safe_HIGH64 (temp, focus_bits); + + /* If lowest_bit_set == 10 then a sethi alone could have done it. */ + if (lowest_bit_set < 10) + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_LSHIFTRT (DImode, temp, + GEN_INT (10 - lowest_bit_set)))); + else if (lowest_bit_set > 10) + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_rtx_ASHIFT (DImode, temp, + GEN_INT (lowest_bit_set - 10)))); else - address = orig; + abort (); + return; + } - pic_ref = gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - pic_offset_table_rtx, address)); - current_function_uses_pic_offset_table = 1; - RTX_UNCHANGING_P (pic_ref) = 1; - insn = emit_move_insn (reg, pic_ref); - /* Put a REG_EQUAL note on this insn, so that it can be optimized - by loop. */ - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, - REG_NOTES (insn)); - return reg; + /* 1) sethi %hi(low_bits), %reg + * or %reg, %lo(low_bits), %reg + * 2) sethi %hi(~low_bits), %reg + * xor %reg, %lo(-0x400 | (low_bits & 0x3ff)), %reg + */ + if (high_bits == 0 + || high_bits == 0xffffffff) + { + sparc_emit_set_const64_quick1 (op0, temp, low_bits, + (high_bits == 0xffffffff)); + return; } - else if (GET_CODE (orig) == CONST) + + /* Now, try 3-insn sequences. */ + + /* 1) sethi %hi(high_bits), %reg + * or %reg, %lo(high_bits), %reg + * sllx %reg, 32, %reg + */ + if (low_bits == 0) { - rtx base, offset; + sparc_emit_set_const64_quick2 (op0, temp, high_bits, 0, 32); + return; + } - if (GET_CODE (XEXP (orig, 0)) == PLUS - && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) - return orig; + /* We may be able to do something quick + when the constant is negated, so try that. */ + if (const64_is_2insns ((~high_bits) & 0xffffffff, + (~low_bits) & 0xfffffc00)) + { + /* NOTE: The trailing bits get XOR'd so we need the + non-negated bits, not the negated ones. */ + unsigned HOST_WIDE_INT trailing_bits = low_bits & 0x3ff; - if (reg == 0) + if ((((~high_bits) & 0xffffffff) == 0 + && ((~low_bits) & 0x80000000) == 0) + || (((~high_bits) & 0xffffffff) == 0xffffffff + && ((~low_bits) & 0x80000000) != 0)) { - if (reload_in_progress || reload_completed) - abort (); + int fast_int = (~low_bits & 0xffffffff); + + if ((SPARC_SETHI_P (fast_int) + && (~high_bits & 0xffffffff) == 0) + || SPARC_SIMM13_P (fast_int)) + emit_insn (gen_safe_SET64 (temp, fast_int)); else - reg = gen_reg_rtx (Pmode); + sparc_emit_set_const64 (temp, GEN_INT64 (fast_int)); + } + else + { + rtx negated_const; +#if HOST_BITS_PER_WIDE_INT == 64 + negated_const = GEN_INT (((~low_bits) & 0xfffffc00) | + (((HOST_WIDE_INT)((~high_bits) & 0xffffffff))<<32)); +#else + negated_const = gen_rtx_CONST_DOUBLE (DImode, const0_rtx, + (~low_bits) & 0xfffffc00, + (~high_bits) & 0xffffffff); +#endif + sparc_emit_set_const64 (temp, negated_const); } - if (GET_CODE (XEXP (orig, 0)) == PLUS) + /* If we are XOR'ing with -1, then we should emit a one's complement + instead. This way the combiner will notice logical operations + such as ANDN later on and substitute. */ + if (trailing_bits == 0x3ff) { - base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); - offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, - base == reg ? 0 : reg); + emit_insn (gen_rtx_SET (VOIDmode, op0, + gen_rtx_NOT (DImode, temp))); } else - abort (); - - if (GET_CODE (offset) == CONST_INT) { - if (SMALL_INT (offset)) - return plus_constant_for_output (base, INTVAL (offset)); - else if (! reload_in_progress && ! reload_completed) - offset = force_reg (Pmode, offset); - else - /* If we reach here, then something is seriously wrong. */ - abort (); + emit_insn (gen_rtx_SET (VOIDmode, + op0, + gen_safe_XOR64 (temp, + (-0x400 | trailing_bits)))); } - return gen_rtx_PLUS (Pmode, base, offset); + return; } - return orig; -} + /* 1) sethi %hi(xxx), %reg + * or %reg, %lo(xxx), %reg + * sllx %reg, yyy, %reg + * + * ??? This is just a generalized version of the low_bits==0 + * thing above, FIXME... + */ + if ((highest_bit_set - lowest_bit_set) < 32) + { + unsigned HOST_WIDE_INT focus_bits = + create_simple_focus_bits (high_bits, low_bits, + lowest_bit_set, 0); -/* Set up PIC-specific rtl. This should not cause any insns - to be emitted. */ + /* We can't get here in this state. */ + if (highest_bit_set < 32 + || lowest_bit_set >= 32) + abort (); -void -initialize_pic () -{ + /* So what we know is that the set bits straddle the + middle of the 64-bit word. */ + sparc_emit_set_const64_quick2 (op0, temp, + focus_bits, 0, + lowest_bit_set); + return; + } + + /* 1) sethi %hi(high_bits), %reg + * or %reg, %lo(high_bits), %reg + * sllx %reg, 32, %reg + * or %reg, low_bits, %reg + */ + if (SPARC_SIMM13_P(low_bits) + && ((int)low_bits > 0)) + { + sparc_emit_set_const64_quick2 (op0, temp, high_bits, low_bits, 32); + return; + } + + /* The easiest way when all else fails, is full decomposition. */ +#if 0 + printf ("sparc_emit_set_const64: Hard constant [%08lx%08lx] neg[%08lx%08lx]\n", + high_bits, low_bits, ~high_bits, ~low_bits); +#endif + sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits); } -/* Return the RTX for insns to set the PIC register. */ +/* X and Y are two things to compare using CODE. Emit the compare insn and + return the rtx for the cc reg in the proper mode. */ -static rtx -pic_setup_code () +rtx +gen_compare_reg (code, x, y) + enum rtx_code code; + rtx x, y; { - rtx seq; + enum machine_mode mode = SELECT_CC_MODE (code, x, y); + rtx cc_reg; - start_sequence (); - emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table, - get_pc_symbol)); - seq = gen_sequence (); - end_sequence (); - - return seq; -} - -/* Emit special PIC prologues and epilogues. */ - -void -finalize_pic () -{ - /* Labels to get the PC in the prologue of this function. */ - int orig_flag_pic = flag_pic; - rtx insn; - - if (current_function_uses_pic_offset_table == 0) - return; + /* ??? We don't have movcc patterns so we cannot generate pseudo regs for the + fcc regs (cse can't tell they're really call clobbered regs and will + remove a duplicate comparison even if there is an intervening function + call - it will then try to reload the cc reg via an int reg which is why + we need the movcc patterns). It is possible to provide the movcc + patterns by using the ldxfsr/stxfsr v9 insns. I tried it: you need two + registers (say %g1,%g5) and it takes about 6 insns. A better fix would be + to tell cse that CCFPE mode registers (even pseudos) are call + clobbered. */ - if (! flag_pic) - abort (); + /* ??? This is an experiment. Rather than making changes to cse which may + or may not be easy/clean, we do our own cse. This is possible because + we will generate hard registers. Cse knows they're call clobbered (it + doesn't know the same thing about pseudos). If we guess wrong, no big + deal, but if we win, great! */ - /* If we havn't emitted the special get_pc helper function, do so now. */ - if (get_pc_symbol_name[0] == 0) + if (TARGET_V9 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) +#if 1 /* experiment */ { - ASM_GENERATE_INTERNAL_LABEL (get_pc_symbol_name, "LGETPC", 0); + int reg; + /* We cycle through the registers to ensure they're all exercised. */ + static int next_fcc_reg = 0; + /* Previous x,y for each fcc reg. */ + static rtx prev_args[4][2]; - text_section (); - ASM_OUTPUT_ALIGN (asm_out_file, 3); - ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "LGETPC", 0); - fputs ("\tretl\n\tadd %o7,%l7,%l7\n", asm_out_file); + /* Scan prev_args for x,y. */ + for (reg = 0; reg < 4; reg++) + if (prev_args[reg][0] == x && prev_args[reg][1] == y) + break; + if (reg == 4) + { + reg = next_fcc_reg; + prev_args[reg][0] = x; + prev_args[reg][1] = y; + next_fcc_reg = (next_fcc_reg + 1) & 3; + } + cc_reg = gen_rtx_REG (mode, reg + SPARC_FIRST_V9_FCC_REG); } +#else + cc_reg = gen_reg_rtx (mode); +#endif /* ! experiment */ + else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT) + cc_reg = gen_rtx_REG (mode, SPARC_FCC_REG); + else + cc_reg = gen_rtx_REG (mode, SPARC_ICC_REG); - /* Initialize every time through, since we can't easily - know this to be permanent. */ - global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); - get_pc_symbol = gen_rtx_SYMBOL_REF (Pmode, get_pc_symbol_name); - flag_pic = 0; + emit_insn (gen_rtx_SET (VOIDmode, cc_reg, + gen_rtx_COMPARE (mode, x, y))); - emit_insn_after (pic_setup_code (), get_insns ()); + return cc_reg; +} - /* Insert the code in each nonlocal goto receiver. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE - && XINT (PATTERN (insn), 1) == 4) - emit_insn_after (pic_setup_code (), insn); +/* This function is used for v9 only. + CODE is the code for an Scc's comparison. + OPERANDS[0] is the target of the Scc insn. + OPERANDS[1] is the value we compare against const0_rtx (which hasn't + been generated yet). - flag_pic = orig_flag_pic; + This function is needed to turn - /* Need to emit this whether or not we obey regdecls, - since setjmp/longjmp can cause life info to screw up. - ??? In the case where we don't obey regdecls, this is not sufficient - since we may not fall out the bottom. */ - emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); -} - -/* Emit insns to move operands[1] into operands[0]. + (set (reg:SI 110) + (gt (reg:CCX 100 %icc) + (const_int 0))) + into + (set (reg:SI 110) + (gt:DI (reg:CCX 100 %icc) + (const_int 0))) + + IE: The instruction recognizer needs to see the mode of the comparison to + find the right instruction. We could use "gt:DI" right in the + define_expand, but leaving it out allows us to handle DI, SI, etc. - Return 1 if we have written out everything that needs to be done to - do the move. Otherwise, return 0 and the caller will emit the move - normally. */ + We refer to the global sparc compare operands sparc_compare_op0 and + sparc_compare_op1. */ int -emit_move_sequence (operands, mode) - rtx *operands; - enum machine_mode mode; +gen_v9_scc (compare_code, operands) + enum rtx_code compare_code; + register rtx *operands; { - register rtx operand0 = operands[0]; - register rtx operand1 = operands[1]; + rtx temp, op0, op1; - if (CONSTANT_P (operand1) && flag_pic - && pic_address_needs_scratch (operand1)) - operands[1] = operand1 = legitimize_pic_address (operand1, mode, 0); + if (! TARGET_ARCH64 + && (GET_MODE (sparc_compare_op0) == DImode + || GET_MODE (operands[0]) == DImode)) + return 0; - /* Handle most common case first: storing into a register. */ - if (register_operand (operand0, mode)) + /* Handle the case where operands[0] == sparc_compare_op0. + We "early clobber" the result. */ + if (REGNO (operands[0]) == REGNO (sparc_compare_op0)) { - /* Integer constant to FP register. */ - if (GET_CODE (operand0) == REG - && REGNO (operand0) >= 32 - && REGNO (operand0) < FIRST_PSEUDO_REGISTER - && CONSTANT_P (operand1)) - { - operand1 = validize_mem (force_const_mem (GET_MODE (operand0), operand1)); - } - - if (register_operand (operand1, mode) - || (GET_CODE (operand1) == CONST_INT && SMALL_INT (operand1)) - || (GET_CODE (operand1) == CONST_DOUBLE - && arith_double_operand (operand1, DImode)) - || (GET_CODE (operand1) == HIGH && GET_MODE (operand1) != DImode) - /* Only `general_operands' can come here, so MEM is ok. */ - || GET_CODE (operand1) == MEM) - { - /* Run this case quickly. */ - emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1)); - return 1; - } + op0 = gen_reg_rtx (GET_MODE (sparc_compare_op0)); + emit_move_insn (op0, sparc_compare_op0); } - else if (GET_CODE (operand0) == MEM) + else + op0 = sparc_compare_op0; + /* For consistency in the following. */ + op1 = sparc_compare_op1; + + /* Try to use the movrCC insns. */ + if (TARGET_ARCH64 + && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT + && op1 == const0_rtx + && v9_regcmp_p (compare_code)) { - if (register_operand (operand1, mode) - || (operand1 == const0_rtx && ! TARGET_LIVE_G0)) + /* Special case for op0 != 0. This can be done with one instruction if + operands[0] == sparc_compare_op0. We don't assume they are equal + now though. */ + + if (compare_code == NE + && GET_MODE (operands[0]) == DImode + && GET_MODE (op0) == DImode) { - /* Run this case quickly. */ - emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1)); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], op0)); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (DImode, + gen_rtx_fmt_ee (compare_code, DImode, + op0, const0_rtx), + const1_rtx, + operands[0]))); return 1; } - if (! reload_in_progress) + + emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx)); + if (GET_MODE (op0) != DImode) { - operands[0] = validize_mem (operand0); - operands[1] = operand1 = force_reg (mode, operand1); + temp = gen_reg_rtx (DImode); + convert_move (temp, op0, 0); } - } - - /* DImode HIGH values in sparc64 need a clobber added. */ - if (TARGET_ARCH64 - && GET_CODE (operand1) == HIGH && GET_MODE (operand1) == DImode) - { - emit_insn (gen_sethi_di_sp64 (operand0, XEXP (operand1, 0))); + else + temp = op0; + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), + gen_rtx_fmt_ee (compare_code, DImode, + temp, const0_rtx), + const1_rtx, + operands[0]))); return 1; } - /* Simplify the source if we need to. */ - else if (GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode)) + else { - if (flag_pic && symbolic_operand (operand1, mode)) - { - rtx temp_reg = reload_in_progress ? operand0 : 0; + operands[1] = gen_compare_reg (compare_code, op0, op1); - operands[1] = legitimize_pic_address (operand1, mode, temp_reg); - } - else if (GET_CODE (operand1) == CONST_INT - ? (! SMALL_INT (operand1) - && INTVAL (operand1) != -4096 - && ! SPARC_SETHI_P (INTVAL (operand1))) - : GET_CODE (operand1) == CONST_DOUBLE - ? ! arith_double_operand (operand1, DImode) - : 1) + switch (GET_MODE (operands[1])) { - /* For DImode values, temp must be operand0 because of the way - HI and LO_SUM work. The LO_SUM operator only copies half of - the LSW from the dest of the HI operator. If the LO_SUM dest is - not the same as the HI dest, then the MSW of the LO_SUM dest will - never be set. - - ??? The real problem here is that the ...(HI:DImode pattern emits - multiple instructions, and the ...(LO_SUM:DImode pattern emits - one instruction. This fails, because the compiler assumes that - LO_SUM copies all bits of the first operand to its dest. Better - would be to have the HI pattern emit one instruction and the - LO_SUM pattern multiple instructions. Even better would be - to use four rtl insns. */ - rtx temp = ((reload_in_progress || mode == DImode) - ? operand0 : gen_reg_rtx (mode)); - - if (mode == SImode) - { - if (GET_CODE (operand1) == CONST_INT) - operand1 = GEN_INT (INTVAL (operand1) & 0xffffffff); - else if (GET_CODE (operand1) == CONST_DOUBLE) - operand1 = GEN_INT (CONST_DOUBLE_LOW (operand1) & 0xffffffff); - } - - if (TARGET_ARCH64 && mode == DImode) - emit_insn (gen_sethi_di_sp64 (temp, operand1)); - else - emit_insn (gen_rtx_SET (VOIDmode, temp, - gen_rtx_HIGH (mode, operand1))); - - operands[1] = gen_rtx_LO_SUM (mode, temp, operand1); + case CCmode : + case CCXmode : + case CCFPEmode : + case CCFPmode : + break; + default : + abort (); } + emit_insn (gen_rtx_SET (VOIDmode, operands[0], const0_rtx)); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_IF_THEN_ELSE (GET_MODE (operands[0]), + gen_rtx_fmt_ee (compare_code, + GET_MODE (operands[1]), + operands[1], const0_rtx), + const1_rtx, operands[0]))); + return 1; } - - /* Now have insn-emit do whatever it normally does. */ - return 0; } - -/* Return the best assembler insn template - for moving operands[1] into operands[0] as a 4 byte quantity. - This isn't intended to be very smart. It is up to the caller to - choose the best way to do things. - - Note that OPERANDS may be modified to suit the returned string. */ +/* Emit a conditional jump insn for the v9 architecture using comparison code + CODE and jump target LABEL. + This function exists to take advantage of the v9 brxx insns. */ -char * -singlemove_string (operands) - rtx *operands; +void +emit_v9_brxx_insn (code, op0, label) + enum rtx_code code; + rtx op0, label; { - if (GET_CODE (operands[0]) == MEM) - { - if (GET_CODE (operands[1]) != MEM) - return "st %r1,%0"; - else - abort (); - } - else if (GET_CODE (operands[1]) == MEM) - return "ld %1,%0"; - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - REAL_VALUE_TYPE r; - long i; - - /* Must be SFmode, otherwise this doesn't make sense. */ - if (GET_MODE (operands[1]) != SFmode) - abort (); + emit_jump_insn (gen_rtx_SET (VOIDmode, + pc_rtx, + gen_rtx_IF_THEN_ELSE (VOIDmode, + gen_rtx_fmt_ee (code, GET_MODE (op0), + op0, const0_rtx), + gen_rtx_LABEL_REF (VOIDmode, label), + pc_rtx))); +} + +/* Return nonzero if a return peephole merging return with + setting of output register is ok. */ +int +leaf_return_peephole_ok () +{ + return (actual_fsize == 0); +} - REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); - REAL_VALUE_TO_TARGET_SINGLE (r, i); - operands[1] = GEN_INT (i); +/* Return nonzero if TRIAL can go into the function epilogue's + delay slot. SLOT is the slot we are trying to fill. */ - if (CONST_OK_FOR_LETTER_P (i, 'I')) - return "mov %1,%0"; - else if ((i & 0x000003FF) != 0) - return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; - else - return "sethi %%hi(%a1),%0"; - } - else if (GET_CODE (operands[1]) == CONST_INT) - { - /* Only consider the low 32 bits of the constant. */ - int i = INTVAL (operands[1]) & 0xffffffff; +int +eligible_for_epilogue_delay (trial, slot) + rtx trial; + int slot; +{ + rtx pat, src; - if (SPARC_SIMM13_P (i)) - return "mov %1,%0"; + if (slot >= 1) + return 0; - if (i == 4096) - return "sub %%g0,-4096,%0"; + if (GET_CODE (trial) != INSN || GET_CODE (PATTERN (trial)) != SET) + return 0; - /* If all low order 10 bits are clear, then we only need a single - sethi insn to load the constant. */ - /* FIXME: Use SETHI_P. */ - if ((i & 0x000003FF) != 0) - return "sethi %%hi(%a1),%0\n\tor %0,%%lo(%a1),%0"; - else - return "sethi %%hi(%a1),%0"; - } - /* Operand 1 must be a register, or a 'I' type CONST_INT. */ - return "mov %1,%0"; -} + if (get_attr_length (trial) != 1) + return 0; -/* Return the best assembler insn template - for moving operands[1] into operands[0] as an 8 byte quantity. + /* If %g0 is live, there are lots of things we can't handle. + Rather than trying to find them all now, let's punt and only + optimize things as necessary. */ + if (TARGET_LIVE_G0) + return 0; - This isn't intended to be very smart. It is up to the caller to - choose the best way to do things. - - Note that OPERANDS may be modified to suit the returned string. */ - -char * -doublemove_string (operands) - rtx *operands; -{ - rtx op0 = operands[0], op1 = operands[1]; - - if (GET_CODE (op0) == MEM) - { - if (GET_CODE (op1) == REG) - { - if (FP_REG_P (op1)) - return "std %1,%0"; - return TARGET_ARCH64 ? "stx %1,%0" : "std %1,%0"; - } - if (TARGET_ARCH64 - && (op1 == const0_rtx - || (GET_MODE (op1) != VOIDmode - && op1 == CONST0_RTX (GET_MODE (op1))))) - return "stx %r1,%0"; - abort (); - } - else if (GET_CODE (op1) == MEM) - { - if (GET_CODE (op0) != REG) - abort (); - if (FP_REG_P (op0)) - return "ldd %1,%0"; - return TARGET_ARCH64 ? "ldx %1,%0" : "ldd %1,%0"; - } - else if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - /* ??? Unfinished, and maybe not needed. */ - abort (); - } - else if (GET_CODE (operands[1]) == CONST_INT - && ! CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) + /* In the case of a true leaf function, anything can go into the delay slot. + A delay slot only exists however if the frame size is zero, otherwise + we will put an insn to adjust the stack after the return. */ + if (current_function_uses_only_leaf_regs) { - /* ??? Unfinished, and maybe not needed. */ - abort (); + if (leaf_return_peephole_ok ()) + return ((get_attr_in_uncond_branch_delay (trial) + == IN_BRANCH_DELAY_TRUE)); + return 0; } - /* Operand 1 must be a register, or a 'I' type CONST_INT. */ - return "mov %1,%0"; -} -/* Return non-zero if it is OK to assume that the given memory operand is - aligned at least to a 8-byte boundary. This should only be called - for memory accesses whose size is 8 bytes or larger. */ + /* If only trivial `restore' insns work, nothing can go in the + delay slot. */ + else if (TARGET_BROKEN_SAVERESTORE) + return 0; -int -mem_aligned_8 (mem) - register rtx mem; -{ - register rtx addr; - register rtx base; - register rtx offset; + pat = PATTERN (trial); - if (GET_CODE (mem) != MEM) - return 0; /* It's gotta be a MEM! */ + /* Otherwise, only operations which can be done in tandem with + a `restore' insn can go into the delay slot. */ + if (GET_CODE (SET_DEST (pat)) != REG + || REGNO (SET_DEST (pat)) >= 32 + || REGNO (SET_DEST (pat)) < 24) + return 0; - addr = XEXP (mem, 0); + /* The set of insns matched here must agree precisely with the set of + patterns paired with a RETURN in sparc.md. */ - /* Now that all misaligned double parms are copied on function entry, - we can assume any 64-bit object is 64-bit aligned except those which - are at unaligned offsets from the stack or frame pointer. If the - TARGET_UNALIGNED_DOUBLES switch is given, we do not make this - assumption. */ + src = SET_SRC (pat); - /* See what register we use in the address. */ - base = offset = 0; - if (GET_CODE (addr) == PLUS) - { - if (GET_CODE (XEXP (addr, 0)) == REG - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - { - base = XEXP (addr, 0); - offset = XEXP (addr, 1); - } - } - else if (GET_CODE (addr) == REG) + /* This matches "*return_[qhs]i" or even "*return_di" on TARGET_ARCH64. */ + if (arith_operand (src, GET_MODE (src))) { - base = addr; - offset = const0_rtx; + if (TARGET_ARCH64) + return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); + else + return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (SImode); } + + /* This matches "*return_di". */ + else if (arith_double_operand (src, GET_MODE (src))) + return GET_MODE_SIZE (GET_MODE (src)) <= GET_MODE_SIZE (DImode); - /* If it's the stack or frame pointer, check offset alignment. - We can have improper alignment in the function entry code. */ - if (base - && (REGNO (base) == FRAME_POINTER_REGNUM - || REGNO (base) == STACK_POINTER_REGNUM)) - { - if (((INTVAL (offset) - SPARC_STACK_BIAS) & 0x7) == 0) - return 1; - } - /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES - is true, in which case we can only assume that an access is aligned if - it is to a constant address, or the address involves a LO_SUM. + /* This matches "*return_sf_no_fpu". */ + else if (! TARGET_FPU && restore_operand (SET_DEST (pat), SFmode) + && register_operand (src, SFmode)) + return 1; - We used to assume an address was aligned if MEM_IN_STRUCT_P was true. - That assumption was deleted so that gcc generated code can be used with - memory allocators that only guarantee 4 byte alignment. */ - else if (! TARGET_UNALIGNED_DOUBLES || CONSTANT_P (addr) - || GET_CODE (addr) == LO_SUM) + /* This matches "*return_addsi". */ + else if (GET_CODE (src) == PLUS + && arith_operand (XEXP (src, 0), SImode) + && arith_operand (XEXP (src, 1), SImode) + && (register_operand (XEXP (src, 0), SImode) + || register_operand (XEXP (src, 1), SImode))) + return 1; + + /* This matches "*return_adddi". */ + else if (GET_CODE (src) == PLUS + && arith_double_operand (XEXP (src, 0), DImode) + && arith_double_operand (XEXP (src, 1), DImode) + && (register_operand (XEXP (src, 0), DImode) + || register_operand (XEXP (src, 1), DImode))) return 1; - /* An obviously unaligned address. */ return 0; } -enum optype { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }; - -/* Output assembler code to perform a doubleword move insn - with operands OPERANDS. This is very similar to the following - output_move_quad function. */ - -char * -output_move_double (operands) - rtx *operands; +static int +check_return_regs (x) + rtx x; { - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - register enum optype optype0; - register enum optype optype1; - rtx latehalf[2]; - rtx addreg0 = 0; - rtx addreg1 = 0; - int highest_first = 0; - int no_addreg1_decrement = 0; - - /* First classify both operands. */ - - if (REG_P (op0)) - optype0 = REGOP; - else if (offsettable_memref_p (op0)) - optype0 = OFFSOP; - else if (GET_CODE (op0) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (op1)) - optype1 = REGOP; - else if (CONSTANT_P (op1)) - optype1 = CNSTOP; - else if (offsettable_memref_p (op1)) - optype1 = OFFSOP; - else if (GET_CODE (op1) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; - - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ + switch (GET_CODE (x)) + { + case REG: + return IN_OR_GLOBAL_P (x); - if (optype0 == RNDOP || optype1 == RNDOP - || (optype0 == MEM && optype1 == MEM)) - abort (); + case CONST_INT: + case CONST_DOUBLE: + case CONST: + case SYMBOL_REF: + case LABEL_REF: + return 1; - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the second word. */ + case SET: + case IOR: + case AND: + case XOR: + case PLUS: + case MINUS: + if (check_return_regs (XEXP (x, 1)) == 0) + return 0; + case NOT: + case NEG: + case MEM: + return check_return_regs (XEXP (x, 0)); + + default: + return 0; + } - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (op0, 0)); +} - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (op1, 0)); +/* Return 1 if TRIAL references only in and global registers. */ +int +eligible_for_return_delay (trial) + rtx trial; +{ + if (GET_CODE (PATTERN (trial)) != SET) + return 0; - /* Ok, we can do one word at a time. - Set up in LATEHALF the operands to use for the - high-numbered (least significant) word and in some cases alter the - operands in OPERANDS to be suitable for the low-numbered word. */ + return check_return_regs (PATTERN (trial)); +} - if (optype0 == REGOP) - latehalf[0] = gen_rtx_REG (SImode, REGNO (op0) + 1); - else if (optype0 == OFFSOP) - latehalf[0] = adj_offsettable_operand (op0, 4); - else - latehalf[0] = op0; +int +short_branch (uid1, uid2) + int uid1, uid2; +{ + unsigned int delta = insn_addresses[uid1] - insn_addresses[uid2]; + if (delta + 1024 < 2048) + return 1; + /* warning ("long branch, distance %d", delta); */ + return 0; +} - if (optype1 == REGOP) - latehalf[1] = gen_rtx_REG (SImode, REGNO (op1) + 1); - else if (optype1 == OFFSOP) - latehalf[1] = adj_offsettable_operand (op1, 4); - else if (optype1 == CNSTOP) - { - if (TARGET_ARCH64) - { - if (arith_double_operand (op1, DImode)) - { - operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); - return "mov %1,%0"; - } - else - { - /* The only way to handle CONST_DOUBLEs or other 64 bit - constants here is to use a temporary, such as is done - for the V9 DImode sethi insn pattern. This is not - a practical solution, so abort if we reach here. - The md file should always force such constants to - memory. */ - abort (); - } - } - else - split_double (op1, &operands[1], &latehalf[1]); - } - else - latehalf[1] = op1; +/* Return non-zero if REG is not used after INSN. + 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; +{ + enum rtx_code code, prev_code = UNKNOWN; - /* Easy case: try moving both words at once. Check for moving between - an even/odd register pair and a memory location. */ - if ((optype0 == REGOP && optype1 != REGOP && optype1 != CNSTOP - && (TARGET_ARCH64 || (REGNO (op0) & 1) == 0)) - || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP - && (TARGET_ARCH64 || (REGNO (op1) & 1) == 0))) + while ((insn = NEXT_INSN (insn))) { - register rtx mem,reg; + if (prev_code == CALL_INSN && call_used_regs[REGNO (reg)]) + return 1; - if (optype0 == REGOP) - mem = op1, reg = op0; - else - mem = op0, reg = op1; - - /* In v9, ldd can be used for word aligned addresses, so technically - some of this logic is unneeded. We still avoid ldd if the address - is obviously unaligned though. - - Integer ldd/std are deprecated in V9 and are slow on UltraSPARC. - Use them only if the access is volatile or not offsettable. */ - - if ((mem_aligned_8 (mem) - && (REGNO (reg) >= 32 - || MEM_VOLATILE_P (mem) - || ! ((optype0 == OFFSOP || optype1 == OFFSOP) - && (sparc_cpu == PROCESSOR_ULTRASPARC - || sparc_cpu == PROCESSOR_V9)))) - /* If this is a floating point register higher than %f31, - then we *must* use an aligned load, since `ld' will not accept - the register number. */ - || (TARGET_V9 && REGNO (reg) >= 64) - /* Even if two instructions would otherwise be better than ldd/std, - if this insn was put in a delay slot because reorg thought it - was only one machine instruction, make sure it is only one - instruction. */ - || dbr_sequence_length () != 0) - { - if (FP_REG_P (reg) || ! TARGET_ARCH64) - return (mem == op1 ? "ldd %1,%0" : "std %1,%0"); - else - return (mem == op1 ? "ldx %1,%0" : "stx %1,%0"); - } - } + code = GET_CODE (insn); + if (GET_CODE (insn) == CODE_LABEL) + return 1; - if (TARGET_ARCH64) - { - if (optype0 == REGOP && optype1 == REGOP) + if (GET_RTX_CLASS (code) == 'i') { - if (FP_REG_P (op0)) - return "fmovd %1,%0"; - else - return "mov %1,%0"; + rtx set = single_set (insn); + int in_src = set && reg_overlap_mentioned_p (reg, SET_SRC (set)); + if (set && in_src) + return 0; + if (set && reg_overlap_mentioned_p (reg, SET_DEST (set))) + return 1; + if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn))) + return 0; } + prev_code = code; } + return 1; +} + +/* The table we use to reference PIC data. */ +static rtx global_offset_table; + +/* The function we use to get at it. */ +static rtx get_pc_symbol; +static char get_pc_symbol_name[256]; - /* If the first move would clobber the source of the second one, - do them in the other order. */ +/* Ensure that we are not using patterns that are not OK with PIC. */ - /* Overlapping registers. */ - if (optype0 == REGOP && optype1 == REGOP - && REGNO (op0) == REGNO (latehalf[1])) - { - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - /* Do low-numbered word. */ - return singlemove_string (operands); - } - /* Loading into a register which overlaps a register used in the address. */ - else if (optype0 == REGOP && optype1 != REGOP - && reg_overlap_mentioned_p (op0, op1)) +int +check_pic (i) + int i; +{ + switch (flag_pic) { - /* If both halves of dest are used in the src memory address, - add the two regs and put them in the low reg (op0). - Then it works to load latehalf first. */ - if (reg_mentioned_p (op0, XEXP (op1, 0)) - && reg_mentioned_p (latehalf[0], XEXP (op1, 0))) - { - rtx xops[2]; - xops[0] = latehalf[0]; - xops[1] = op0; - output_asm_insn ("add %1,%0,%1", xops); - operands[1] = gen_rtx_MEM (DImode, op0); - latehalf[1] = adj_offsettable_operand (operands[1], 4); - addreg1 = 0; - highest_first = 1; - } - /* Only one register in the dest is used in the src memory address, - and this is the first register of the dest, so we want to do - the late half first here also. */ - else if (! reg_mentioned_p (latehalf[0], XEXP (op1, 0))) - highest_first = 1; - /* Only one register in the dest is used in the src memory address, - and this is the second register of the dest, so we want to do - the late half last. If addreg1 is set, and addreg1 is the same - register as latehalf, then we must suppress the trailing decrement, - because it would clobber the value just loaded. */ - else if (addreg1 && reg_mentioned_p (addreg1, latehalf[0])) - no_addreg1_decrement = 1; + case 1: + if (GET_CODE (recog_operand[i]) == SYMBOL_REF + || (GET_CODE (recog_operand[i]) == CONST + && ! (GET_CODE (XEXP (recog_operand[i], 0)) == MINUS + && (XEXP (XEXP (recog_operand[i], 0), 0) + == global_offset_table) + && (GET_CODE (XEXP (XEXP (recog_operand[i], 0), 1)) + == CONST)))) + abort (); + case 2: + default: + return 1; } - - /* Normal case: do the two words, low-numbered first. - Overlap case (highest_first set): do high-numbered word first. */ - - if (! highest_first) - output_asm_insn (singlemove_string (operands), operands); - - /* Make any unoffsettable addresses point at high-numbered word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - - /* Do that word. */ - output_asm_insn (singlemove_string (latehalf), latehalf); - - /* Undo the adds we just did. */ - if (addreg0) - output_asm_insn ("add %0,-0x4,%0", &addreg0); - if (addreg1 && ! no_addreg1_decrement) - output_asm_insn ("add %0,-0x4,%0", &addreg1); - - if (highest_first) - output_asm_insn (singlemove_string (operands), operands); - - return ""; } -/* Output assembler code to perform a quadword move insn - with operands OPERANDS. This is very similar to the preceding - output_move_double function. */ +/* Return true if X is an address which needs a temporary register when + reloaded while generating PIC code. */ -char * -output_move_quad (operands) - rtx *operands; +int +pic_address_needs_scratch (x) + rtx x; { - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - register enum optype optype0; - register enum optype optype1; - rtx wordpart[4][2]; - rtx load_late[4]; - int load_late_half[2]; - rtx addreg0 = 0; - rtx addreg1 = 0; - - load_late_half[0] = 0; load_late_half[1] = 0; - load_late[0] = 0; load_late[1] = 0; load_late[2] = 0; - load_late[3] = 0; - - wordpart[0][0] = NULL; wordpart[1][0] = NULL; wordpart[2][0] = NULL; - wordpart[3][0] = NULL; - - /* First classify both operands. */ - - if (REG_P (op0)) - optype0 = REGOP; - else if (offsettable_memref_p (op0)) - optype0 = OFFSOP; - else if (GET_CODE (op0) == MEM) - optype0 = MEMOP; - else - optype0 = RNDOP; - - if (REG_P (op1)) - optype1 = REGOP; - else if (CONSTANT_P (op1)) - optype1 = CNSTOP; - else if (offsettable_memref_p (op1)) - optype1 = OFFSOP; - else if (GET_CODE (op1) == MEM) - optype1 = MEMOP; - else - optype1 = RNDOP; + /* 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 + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF + && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT + && ! SMALL_INT (XEXP (XEXP (x, 0), 1))) + return 1; - /* Check for the cases that the operand constraints are not - supposed to allow to happen. Abort if we get one, - because generating code for these cases is painful. */ + return 0; +} - if (optype0 == RNDOP || optype1 == RNDOP - || (optype0 == MEM && optype1 == MEM)) - abort (); +/* 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 non zero, otherwise we allocate register(s) as + necessary. */ - if (optype0 == REGOP) +rtx +legitimize_pic_address (orig, mode, reg) + rtx orig; + enum machine_mode mode ATTRIBUTE_UNUSED; + rtx reg; +{ + if (GET_CODE (orig) == SYMBOL_REF) { - wordpart[0][0] = gen_rtx_REG (word_mode, REGNO (op0) + 0); - if (TARGET_ARCH64 && FP_REG_P (op0) - && REGNO (op0) < SPARC_FIRST_V9_FP_REG) - wordpart[1][0] = gen_rtx_REG (word_mode, REGNO (op0) + 2); - else - wordpart[1][0] = gen_rtx_REG (word_mode, REGNO (op0) + 1); + rtx pic_ref, address; + rtx insn; - if (TARGET_ARCH32) + if (reg == 0) { - wordpart[2][0] = gen_rtx_REG (word_mode, REGNO (op0) + 2); - wordpart[3][0] = gen_rtx_REG (word_mode, REGNO (op0) + 3); + if (reload_in_progress || reload_completed) + abort (); + else + reg = gen_reg_rtx (Pmode); } - - /* Loading into a register which overlaps a register used in the - address. */ - if (optype1 != REGOP && reg_overlap_mentioned_p (op0, op1)) - { - int i; - int count; - count = 0; + if (flag_pic == 2) + { + /* If not during reload, allocate another temp reg here for loading + in the address, so that these instructions can be optimized + properly. */ + rtx temp_reg = ((reload_in_progress || reload_completed) + ? reg : gen_reg_rtx (Pmode)); - for (i = 0; i < 4 && wordpart[i][0] != NULL; i++) - { - if (reg_mentioned_p (wordpart[i][0], op1)) - { - load_late[i] = wordpart[i][0]; - load_late_half[TARGET_ARCH64 ? i : i/2] = 1; - count++; - } - } - if (count > 2) + /* Must put the SYMBOL_REF inside an UNSPEC here so that cse + won't get confused into thinking that these two instructions + are loading in the true address of the symbol. If in the + future a PIC rtx exists, that should be used instead. */ + if (Pmode == SImode) { - /* Not sure what to do here. Multiple adds? Can't happen. */ - abort (); + emit_insn (gen_movsi_high_pic (temp_reg, orig)); + emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig)); } - else if (count == 2) + else { - /* We have a two-address source operand, and both registers - overlap with the dest quad. Add them together and - store the result into the last register of the quad being - loaded, then generate an appropriate MEM insn. */ - rtx temp[3]; - int place = 0; - - for (i = 0; i < 4; i++) - { - if (load_late[i]) - { - temp[place++] = load_late[i]; - load_late[i] = 0; - } - } - temp[2] = wordpart[3][0]; - output_asm_insn ("add %0, %1, %2", temp); - load_late_half[0] = 0; - load_late_half[1] = 1; - op1 = gen_rtx_MEM (TFmode, wordpart[3][0]); - operands[1] = op1; - optype1 = OFFSOP; + emit_insn (gen_movdi_high_pic (temp_reg, orig)); + emit_insn (gen_movdi_lo_sum_pic (temp_reg, temp_reg, orig)); } - } - } - - /* If an operand is an unoffsettable memory ref, find a register - we can increment temporarily to make it refer to the later words. */ - - if (optype0 == MEMOP) - addreg0 = find_addr_reg (XEXP (op0, 0)); - - if (optype1 == MEMOP) - addreg1 = find_addr_reg (XEXP (op1, 0)); - - /* Ok, we can do one word at a time. - Set up in wordpart the operands to use for each word of the arguments. */ - - if (optype0 == OFFSOP) - { - wordpart[0][0] = adj_offsettable_operand (op0, 0); - if (TARGET_ARCH32) - { - wordpart[1][0] = adj_offsettable_operand (op0, 4); - wordpart[2][0] = adj_offsettable_operand (op0, 8); - wordpart[3][0] = adj_offsettable_operand (op0, 12); + address = temp_reg; } else - wordpart[1][0] = adj_offsettable_operand (op0, 8); + address = orig; + + pic_ref = gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, + pic_offset_table_rtx, address)); + current_function_uses_pic_offset_table = 1; + RTX_UNCHANGING_P (pic_ref) = 1; + insn = emit_move_insn (reg, pic_ref); + /* Put a REG_EQUAL note on this insn, so that it can be optimized + by loop. */ + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, + REG_NOTES (insn)); + return reg; } - else if (optype0 != REGOP) + else if (GET_CODE (orig) == CONST) { - wordpart[0][0] = op0; - wordpart[1][0] = op0; - wordpart[2][0] = op0; - wordpart[3][0] = op0; - } + rtx base, offset; - if (optype1 == REGOP) - { - wordpart[0][1] = gen_rtx_REG (word_mode, REGNO (op1) + 0); - if (TARGET_ARCH64 && FP_REG_P (op1) - && REGNO (op1) < SPARC_FIRST_V9_FP_REG) - wordpart[1][1] = gen_rtx_REG (word_mode, REGNO (op1) + 2); - else - wordpart[1][1] = gen_rtx_REG (word_mode, REGNO (op1) + 1); + if (GET_CODE (XEXP (orig, 0)) == PLUS + && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx) + return orig; - if (TARGET_ARCH32) + if (reg == 0) { - wordpart[2][1] = gen_rtx_REG (word_mode, REGNO (op1) + 2); - wordpart[3][1] = gen_rtx_REG (word_mode, REGNO (op1) + 3); + if (reload_in_progress || reload_completed) + abort (); + else + reg = gen_reg_rtx (Pmode); } - } - else if (optype1 == OFFSOP) - { - wordpart[0][1] = adj_offsettable_operand (op1, 0); - if (TARGET_ARCH32) + + if (GET_CODE (XEXP (orig, 0)) == PLUS) { - wordpart[1][1] = adj_offsettable_operand (op1, 4); - wordpart[2][1] = adj_offsettable_operand (op1, 8); - wordpart[3][1] = adj_offsettable_operand (op1, 12); + base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg); + offset = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode, + base == reg ? 0 : reg); } else - wordpart[1][1] = adj_offsettable_operand (op1, 8); - } - else if (optype1 == CNSTOP) - { - REAL_VALUE_TYPE r; - long l[4]; - - /* This only works for TFmode floating point constants. */ - if (GET_CODE (op1) != CONST_DOUBLE || GET_MODE (op1) != TFmode) abort (); - REAL_VALUE_FROM_CONST_DOUBLE (r, op1); - REAL_VALUE_TO_TARGET_LONG_DOUBLE (r, l); - - wordpart[0][1] = GEN_INT (l[0]); - wordpart[1][1] = GEN_INT (l[1]); - wordpart[2][1] = GEN_INT (l[2]); - wordpart[3][1] = GEN_INT (l[3]); - } - else - { - wordpart[0][1] = op1; - wordpart[1][1] = op1; - wordpart[2][1] = op1; - wordpart[3][1] = op1; + if (GET_CODE (offset) == CONST_INT) + { + if (SMALL_INT (offset)) + return plus_constant_for_output (base, INTVAL (offset)); + else if (! reload_in_progress && ! reload_completed) + offset = force_reg (Pmode, offset); + else + /* If we reach here, then something is seriously wrong. */ + abort (); + } + return gen_rtx_PLUS (Pmode, base, offset); } + else if (GET_CODE (orig) == LABEL_REF) + /* ??? Why do we do this? */ + /* Now movsi_pic_label_ref uses it, but we ought to be checking that + the register is live instead, in case it is eliminated. */ + current_function_uses_pic_offset_table = 1; - /* Easy case: try moving the quad as two pairs. Check for moving between - an even/odd register pair and a memory location. - Also handle new v9 fp regs here. */ - /* ??? Should also handle the case of non-offsettable addresses here. - We can at least do the first pair as a ldd/std, and then do the third - and fourth words individually. */ - if ((optype0 == REGOP && optype1 == OFFSOP && (REGNO (op0) & 1) == 0) - || (optype0 == OFFSOP && optype1 == REGOP && (REGNO (op1) & 1) == 0)) - { - rtx mem, reg; - int use_ldx; + return orig; +} - if (optype0 == REGOP) - mem = op1, reg = op0; - else - mem = op0, reg = op1; - - if (mem_aligned_8 (mem) - /* If this is a floating point register higher than %f31, - then we *must* use an aligned load, since `ld' will not accept - the register number. */ - || (TARGET_V9 && REGNO (reg) >= SPARC_FIRST_V9_FP_REG)) - { - static char * const mov_by_64[2][2][2] = { - { { "std %S1,%2;std %1,%0", "stx %R1,%2;stx %1,%0" }, - { "ldd %2,%S0;ldd %1,%0", "ldx %2,%R0;ldx %1,%0" } }, - { { "std %1,%0;std %S1,%2", "stx %1,%0;stx %R1,%2" }, - { "ldd %1,%0;ldd %2,%S0", "ldx %1,%0;ldx %2,%R0" } } - }; - - if (TARGET_V9 && FP_REG_P (reg) && TARGET_HARD_QUAD) - { - /* Only abort if the register # requires that we use ldq. */ - if ((REGNO (reg) & 3) == 0) - { - /* ??? Can `mem' have an inappropriate alignment here? */ - return (mem == op1 ? "ldq %1,%0" : "stq %1,%0"); - } - else - { - if (REGNO (reg) >= SPARC_FIRST_V9_FP_REG) - abort(); - } - } - operands[2] = adj_offsettable_operand (mem, 8); +/* Return the RTX for insns to set the PIC register. */ - /* Do the loads in the right order; can't overwrite our address - register. */ - use_ldx = TARGET_ARCH64 && !FP_REG_P (reg); - return mov_by_64[!load_late_half[0]][mem == op1][use_ldx]; - } - } +static rtx +pic_setup_code () +{ + rtx seq; - /* If the first move would clobber the source of the second one, - do them in the other order. */ + start_sequence (); + emit_insn (gen_get_pc (pic_offset_table_rtx, global_offset_table, + get_pc_symbol)); + seq = gen_sequence (); + end_sequence (); - /* Overlapping registers? */ - if (TARGET_ARCH32) - { - if (optype0 == REGOP && optype1 == REGOP - && (REGNO (op0) == REGNO (wordpart[1][3]) - || REGNO (op0) == REGNO (wordpart[1][2]) - || REGNO (op0) == REGNO (wordpart[1][1]))) - { - /* Do fourth word. */ - output_asm_insn (singlemove_string (wordpart[3]), wordpart[3]); - /* Do the third word. */ - output_asm_insn (singlemove_string (wordpart[2]), wordpart[2]); - /* Do the second word. */ - output_asm_insn (singlemove_string (wordpart[1]), wordpart[1]); - /* Do lowest-numbered word. */ - output_asm_insn (singlemove_string (wordpart[0]), wordpart[0]); - return ""; - } - } - else /* TARGET_ARCH64 */ - { - if (optype0 == REGOP && optype1 == REGOP - && REGNO (op0) == REGNO (wordpart[1][1])) - { - output_asm_insn ("mov %1,%0", wordpart[1]); - output_asm_insn ("mov %1,%0", wordpart[0]); - return ""; - } - } + return seq; +} - /* Normal case: move the words in lowest to highest address order. - There may have an overlapping register; in that case, skip and go - back. */ +/* Emit special PIC prologues and epilogues. */ - if (TARGET_ARCH32) - { - int i; - int offset = 0xc; - rtx temp[2]; +void +finalize_pic () +{ + /* Labels to get the PC in the prologue of this function. */ + int orig_flag_pic = flag_pic; + rtx insn; - for (i = 0; i < 4; i++) - { - if (! load_late[i]) - output_asm_insn (singlemove_string (wordpart[i]), wordpart[i]); + if (current_function_uses_pic_offset_table == 0) + return; - if (i != 3) - { - /* Make any unoffsettable addresses point at the next word. */ - if (addreg0) - output_asm_insn ("add %0,0x4,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x4,%0", &addreg1); - } - } - for (i = 0; i < 4; i++) - { - if (load_late[i]) - { - int fix = offset - i * 4; + if (! flag_pic) + abort (); - /* Back up to the appropriate place. */ - temp[1] = GEN_INT (-fix); - if (addreg0) - { - temp[0] = addreg0; - output_asm_insn ("add %0,%1,%0", temp); - } - if (addreg1) - { - temp[0] = addreg1; - output_asm_insn ("add %0,%1,%0", temp); - } - output_asm_insn (singlemove_string (wordpart[i]), - wordpart[i]); - /* Don't modify the register that's the destination of the - move. */ - temp[0] = GEN_INT (-(offset - fix)); - if (addreg0 && REGNO (addreg0) != REGNO (wordpart[i][0])) - { - temp[1] = addreg0; - output_asm_insn("add %0,%1,%0", temp); - } - if (addreg1 && REGNO (addreg1) != REGNO (wordpart[i][0])) - { - temp[1] = addreg1; - output_asm_insn("add %0,%1,%0",temp); - } - offset = 0; - break; - } - } - if (offset) - { - temp[1] = GEN_INT (-offset); - /* Undo the adds we just did. */ - if (addreg0) - { - temp[0] = addreg0; - output_asm_insn ("add %0,%1,%0", temp); - } - if (addreg1) - { - temp[0] = addreg1; - output_asm_insn ("add %0,%1,%0", temp); - } - } - } - else /* TARGET_ARCH64 */ + /* If we havn't emitted the special get_pc helper function, do so now. */ + if (get_pc_symbol_name[0] == 0) { - if (load_late_half[0]) - { - /* Load the second half first. */ - if (addreg0) - output_asm_insn ("add %0,0x8,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x8,%0", &addreg1); + int align; - output_asm_insn (doublemove_string (wordpart[1]), wordpart[1]); + ASM_GENERATE_INTERNAL_LABEL (get_pc_symbol_name, "LGETPC", 0); + text_section (); - /* Undo the adds we just did. */ - if (addreg0) - output_asm_insn ("add %0,-0x8,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,-0x8,%0", &addreg1); + 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); + fputs ("\tretl\n\tadd %o7,%l7,%l7\n", asm_out_file); + } - output_asm_insn (doublemove_string (wordpart[0]), wordpart[0]); - } - else - { - output_asm_insn (doublemove_string (wordpart[0]), wordpart[0]); + /* Initialize every time through, since we can't easily + know this to be permanent. */ + global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_"); + get_pc_symbol = gen_rtx_SYMBOL_REF (Pmode, get_pc_symbol_name); + flag_pic = 0; - if (addreg0) - output_asm_insn ("add %0,0x8,%0", &addreg0); - if (addreg1) - output_asm_insn ("add %0,0x8,%0", &addreg1); + emit_insn_after (pic_setup_code (), get_insns ()); - /* Do the second word. */ - output_asm_insn (doublemove_string (wordpart[1]), wordpart[1]); + /* Insert the code in each nonlocal goto receiver. + If you make changes here or to the nonlocal_goto_receiver + pattern, make sure the unspec_volatile numbers still + match. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE + && XINT (PATTERN (insn), 1) == 5) + emit_insn_after (pic_setup_code (), insn); - /* Undo the adds we just did. But don't modify the dest of - the move. */ - if (addreg0 && REGNO (addreg0) != REGNO (wordpart[1][0])) - output_asm_insn ("add %0,-0x8,%0", &addreg0); - if (addreg1 && REGNO (addreg1) != REGNO (wordpart[1][0])) - output_asm_insn ("add %0,-0x8,%0", &addreg1); - } - } - - return ""; + flag_pic = orig_flag_pic; + + /* Need to emit this whether or not we obey regdecls, + since setjmp/longjmp can cause life info to screw up. + ??? In the case where we don't obey regdecls, this is not sufficient + since we may not fall out the bottom. */ + emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); } -/* Output assembler code to perform a doubleword move insn with operands - OPERANDS, one of which must be a floating point register. */ +/* Return 1 if RTX is a MEM which is known to be aligned to at + least an 8 byte boundary. */ -char * -output_fp_move_double (operands) - rtx *operands; +int +mem_min_alignment (mem, desired) + rtx mem; + int desired; { - if (FP_REG_P (operands[0])) + rtx addr, base, offset; + + /* If it's not a MEM we can't accept it. */ + if (GET_CODE (mem) != MEM) + return 0; + + addr = XEXP (mem, 0); + base = offset = NULL_RTX; + if (GET_CODE (addr) == PLUS) { - if (FP_REG_P (operands[1])) + if (GET_CODE (XEXP (addr, 0)) == REG) { - if (TARGET_V9) - return "fmovd %1,%0"; + base = XEXP (addr, 0); + + /* What we are saying here is that if the base + REG is aligned properly, the compiler will make + sure any REG based index upon it will be so + as well. */ + if (GET_CODE (XEXP (addr, 1)) == CONST_INT) + offset = XEXP (addr, 1); else - return "fmovs %1,%0\n\tfmovs %R1,%R0"; + offset = const0_rtx; } - else if (GET_CODE (operands[1]) == REG) - abort (); - else - return output_move_double (operands); } - else if (FP_REG_P (operands[1])) + else if (GET_CODE (addr) == REG) { - if (GET_CODE (operands[0]) == REG) - abort (); - else - return output_move_double (operands); + base = addr; + offset = const0_rtx; } - else abort (); -} - -/* When doing a quad-register move, determine the drection in which - the move needs to be performed. SRC and DST are the source and - destination registers. - - A value of -1 indicates that the move needs to be done from the - highest register to the lowest. */ - -static int -move_quad_direction (src, dst) - rtx src, dst; -{ - if ((REGNO (dst) > REGNO (src)) - && (REGNO (dst) < (REGNO (src) + 4))) - return -1; - else - return 1; -} - -/* Output assembler code to perform a quadword move insn with operands - OPERANDS, one of which must be a floating point register. */ - -char * -output_fp_move_quad (operands) - rtx *operands; -{ - register rtx op0 = operands[0]; - register rtx op1 = operands[1]; - if (FP_REG_P (op0)) + if (base != NULL_RTX) { - if (FP_REG_P (op1)) + int regno = REGNO (base); + + if (regno != FRAME_POINTER_REGNUM + && regno != STACK_POINTER_REGNUM) { - if (TARGET_V9 && TARGET_HARD_QUAD) - return "fmovq %1,%0"; - else if (TARGET_V9) - { - int dir = move_quad_direction (op1, op0); - if (dir > 0) - return "fmovd %1,%0\n\tfmovd %S1,%S0"; - else - return "fmovd %S1,%S0\n\tfmovd %1,%0"; - } - else - { - int dir = move_quad_direction (op0, op1); - if (dir > 0) - return "fmovs %1,%0\n\tfmovs %R1,%R0\n\tfmovs %S1,%S0\n\tfmovs %T1,%T0"; - else - return "fmovs %T1,%T0\n\tfmovs %S1,%S0\n\tfmovs %R1,%R0\n\tfmovs %1,%0"; - } + /* Check if the compiler has recorded some information + about the alignment of the base REG. If reload has + completed, we already matched with proper alignments. */ + if (((regno_pointer_align != NULL + && REGNO_POINTER_ALIGN (regno) >= desired) + || reload_completed) + && ((INTVAL (offset) & (desired - 1)) == 0)) + return 1; } - else if (GET_CODE (op1) == REG) - abort (); else - return output_move_quad (operands); + { + if (((INTVAL (offset) - SPARC_STACK_BIAS) & (desired - 1)) == 0) + return 1; + } } - else if (FP_REG_P (op1)) + else if (! TARGET_UNALIGNED_DOUBLES + || CONSTANT_P (addr) + || GET_CODE (addr) == LO_SUM) { - if (GET_CODE (op0) == REG) - abort (); - else - return output_move_quad (operands); + /* Anything else we know is properly aligned unless TARGET_UNALIGNED_DOUBLES + is true, in which case we can only assume that an access is aligned if + it is to a constant address, or the address involves a LO_SUM. */ + return 1; } - else - abort (); + + /* An obviously unaligned address. */ + return 0; } - -/* Return a REG that occurs in ADDR with coefficient 1. - ADDR can be effectively incremented by incrementing REG. */ -static rtx -find_addr_reg (addr) - rtx addr; -{ - while (GET_CODE (addr) == PLUS) - { - /* We absolutely can not fudge the frame pointer here, because the - frame pointer must always be 8 byte aligned. It also confuses - debuggers. */ - if (GET_CODE (XEXP (addr, 0)) == REG - && REGNO (XEXP (addr, 0)) != FRAME_POINTER_REGNUM) - addr = XEXP (addr, 0); - else if (GET_CODE (XEXP (addr, 1)) == REG - && REGNO (XEXP (addr, 1)) != FRAME_POINTER_REGNUM) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 0))) - addr = XEXP (addr, 1); - else if (CONSTANT_P (XEXP (addr, 1))) - addr = XEXP (addr, 0); - else - abort (); - } - if (GET_CODE (addr) == REG) - return addr; - abort (); -} -/* Output reasonable peephole for set-on-condition-code insns. - Note that these insns assume a particular way of defining - labels. Therefore, *both* sparc.h and this function must - be changed if a new syntax is needed. */ - -char * -output_scc_insn (operands, insn) - rtx operands[]; - rtx insn; -{ - static char string[100]; - rtx label = 0, next = insn; - int need_label = 0; - - /* This code used to be called with final_sequence nonzero (for fpcc - delay slots), but that is no longer allowed. */ - if (final_sequence) - abort (); - - /* On UltraSPARC a conditional moves blocks until 3 cycles after prior loads - complete. It might be beneficial here to use branches if any recent - instructions were loads. */ - if (TARGET_V9 && REGNO (operands[1]) == SPARC_ICC_REG) - return "mov 0,%0\n\tmov%C2 %x1,1,%0"; - - /* Try doing a jump optimization which jump.c can't do for us - because we did not expose that setcc works by using branches. - - If this scc insn is followed by an unconditional branch, then have - the jump insn emitted here jump to that location, instead of to - the end of the scc sequence as usual. */ - - do - { - if (GET_CODE (next) == CODE_LABEL) - label = next; - next = NEXT_INSN (next); - } - while (next && (GET_CODE (next) == NOTE || GET_CODE (next) == CODE_LABEL)); - - if (next && GET_CODE (next) == JUMP_INSN && simplejump_p (next)) - label = JUMP_LABEL (next); - - /* If not optimizing, jump label fields are not set. To be safe, always - check here to whether label is still zero. */ - if (label == 0) - { - label = gen_label_rtx (); - need_label = 1; - } - - LABEL_NUSES (label) += 1; - - /* operands[3] is an unused slot. */ - operands[3] = label; - - strcpy (string, output_cbranch (operands[2], 3, 0, 1, 0, 0)); - strcat (string, "\n\tmov 1,%0\n\tmov 0,%0"); - - if (need_label) - strcat (string, "\n%l3:"); - - return string; -} - -/* Vectors to keep interesting information about registers where it can easily - be got. We use to use the actual mode value as the bit number, but there - are more than 32 modes now. Instead we use two tables: one indexed by - hard register number, and one indexed by mode. */ +/* Vectors to keep interesting information about registers where it can easily + be got. We use to use the actual mode value as the bit number, but there + are more than 32 modes now. Instead we use two tables: one indexed by + hard register number, and one indexed by mode. */ /* The purpose of sparc_mode_class is to shrink the range of modes so that they all fit (as bit numbers) in a 32 bit word (again). Each real mode is @@ -2940,7 +2892,7 @@ static int save_regs (file, low, high, base, offset, n_regs, real_offset) FILE *file; int low, high; - char *base; + const char *base; int offset; int n_regs; int real_offset; @@ -2953,7 +2905,7 @@ save_regs (file, low, high, base, offset, n_regs, real_offset) { if (regs_ever_live[i] && ! call_used_regs[i]) { - fprintf (file, "\tstx %s,[%s+%d]\n", + fprintf (file, "\tstx\t%s, [%s+%d]\n", reg_names[i], base, offset + 4 * n_regs); if (dwarf2out_do_frame ()) dwarf2out_reg_save ("", i, real_offset + 4 * n_regs); @@ -2969,7 +2921,7 @@ save_regs (file, low, high, base, offset, n_regs, real_offset) { if (regs_ever_live[i+1] && ! call_used_regs[i+1]) { - fprintf (file, "\tstd %s,[%s+%d]\n", + fprintf (file, "\tstd\t%s, [%s+%d]\n", reg_names[i], base, offset + 4 * n_regs); if (dwarf2out_do_frame ()) { @@ -2981,7 +2933,7 @@ save_regs (file, low, high, base, offset, n_regs, real_offset) } else { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", reg_names[i], base, offset + 4 * n_regs); if (dwarf2out_do_frame ()) dwarf2out_reg_save ("", i, real_offset + 4 * n_regs); @@ -2992,7 +2944,7 @@ save_regs (file, low, high, base, offset, n_regs, real_offset) { if (regs_ever_live[i+1] && ! call_used_regs[i+1]) { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", reg_names[i+1], base, offset + 4 * n_regs + 4); if (dwarf2out_do_frame ()) dwarf2out_reg_save ("", i + 1, real_offset + 4 * n_regs + 4); @@ -3013,7 +2965,7 @@ static int restore_regs (file, low, high, base, offset, n_regs) FILE *file; int low, high; - char *base; + const char *base; int offset; int n_regs; { @@ -3024,7 +2976,7 @@ restore_regs (file, low, high, base, offset, n_regs) for (i = low; i < high; i++) { if (regs_ever_live[i] && ! call_used_regs[i]) - fprintf (file, "\tldx [%s+%d], %s\n", + fprintf (file, "\tldx\t[%s+%d], %s\n", base, offset + 4 * n_regs, reg_names[i]), n_regs += 2; } @@ -3035,15 +2987,15 @@ restore_regs (file, low, high, base, offset, n_regs) { if (regs_ever_live[i] && ! call_used_regs[i]) if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tldd [%s+%d], %s\n", + fprintf (file, "\tldd\t[%s+%d], %s\n", base, offset + 4 * n_regs, reg_names[i]), n_regs += 2; else - fprintf (file, "\tld [%s+%d],%s\n", + fprintf (file, "\tld\t[%s+%d],%s\n", base, offset + 4 * n_regs, reg_names[i]), n_regs += 2; else if (regs_ever_live[i+1] && ! call_used_regs[i+1]) - fprintf (file, "\tld [%s+%d],%s\n", + fprintf (file, "\tld\t[%s+%d],%s\n", base, offset + 4 * n_regs + 4, reg_names[i+1]), n_regs += 2; } @@ -3128,13 +3080,13 @@ static void build_big_number (file, num, reg) FILE *file; int num; - char *reg; + const char *reg; { if (num >= 0 || ! TARGET_ARCH64) { - fprintf (file, "\tsethi %%hi(%d),%s\n", num, reg); + fprintf (file, "\tsethi\t%%hi(%d), %s\n", num, reg); if ((num & 0x3ff) != 0) - fprintf (file, "\tor %s,%%lo(%d),%s\n", reg, num, reg); + fprintf (file, "\tor\t%s, %%lo(%d), %s\n", reg, num, reg); } else /* num < 0 && TARGET_ARCH64 */ { @@ -3147,7 +3099,7 @@ build_big_number (file, num, reg) int inv = ~asize; int low = -0x400 + (asize & 0x3FF); - fprintf (file, "\tsethi %%hi(%d),%s\n\txor %s,%d,%s\n", + fprintf (file, "\tsethi\t%%hi(%d), %s\n\txor\t%s, %d, %s\n", inv, reg, reg, low, reg); } } @@ -3183,16 +3135,16 @@ output_function_prologue (file, size, leaf_function) else if (! leaf_function && ! TARGET_BROKEN_SAVERESTORE) { if (actual_fsize <= 4096) - fprintf (file, "\tsave %%sp,-%d,%%sp\n", actual_fsize); + fprintf (file, "\tsave\t%%sp, -%d, %%sp\n", actual_fsize); else if (actual_fsize <= 8192) { - fprintf (file, "\tsave %%sp,-4096,%%sp\n"); - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); + fprintf (file, "\tsave\t%%sp, -4096, %%sp\n"); + fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096); } else { build_big_number (file, -actual_fsize, "%g1"); - fprintf (file, "\tsave %%sp,%%g1,%%sp\n"); + fprintf (file, "\tsave\t%%sp, %%g1, %%sp\n"); } } else if (! leaf_function && TARGET_BROKEN_SAVERESTORE) @@ -3203,31 +3155,31 @@ output_function_prologue (file, size, leaf_function) fprintf (file, "\tsave\n"); if (actual_fsize <= 4096) - fprintf (file, "\tadd %%fp,-%d,%%sp\n", actual_fsize); + fprintf (file, "\tadd\t%%fp, -%d, %%sp\n", actual_fsize); else if (actual_fsize <= 8192) { - fprintf (file, "\tadd %%fp,-4096,%%sp\n"); - fprintf (file, "\tadd %%fp,-%d,%%sp\n", actual_fsize - 4096); + fprintf (file, "\tadd\t%%fp, -4096, %%sp\n"); + fprintf (file, "\tadd\t%%fp, -%d, %%sp\n", actual_fsize - 4096); } else { build_big_number (file, -actual_fsize, "%g1"); - fprintf (file, "\tadd %%fp,%%g1,%%sp\n"); + fprintf (file, "\tadd\t%%fp, %%g1, %%sp\n"); } } else /* leaf function */ { if (actual_fsize <= 4096) - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize); + fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize); else if (actual_fsize <= 8192) { - fprintf (file, "\tadd %%sp,-4096,%%sp\n"); - fprintf (file, "\tadd %%sp,-%d,%%sp\n", actual_fsize - 4096); + fprintf (file, "\tadd\t%%sp, -4096, %%sp\n"); + fprintf (file, "\tadd\t%%sp, -%d, %%sp\n", actual_fsize - 4096); } else { build_big_number (file, -actual_fsize, "%g1"); - fprintf (file, "\tadd %%sp,%%g1,%%sp\n"); + fprintf (file, "\tadd\t%%sp, %%g1, %%sp\n"); } } @@ -3260,7 +3212,7 @@ output_function_prologue (file, size, leaf_function) if (num_gfregs) { int offset, real_offset, n_regs; - char *base; + const char *base; real_offset = -apparent_fsize; offset = -apparent_fsize + frame_base_offset; @@ -3273,7 +3225,7 @@ output_function_prologue (file, size, leaf_function) output_function_epilogue will lose (the result will get clobbered). */ build_big_number (file, offset, "%g1"); - fprintf (file, "\tadd %s,%%g1,%%g1\n", frame_base_name); + fprintf (file, "\tadd\t%s, %%g1, %%g1\n", frame_base_name); base = "%g1"; offset = 0; } @@ -3311,7 +3263,7 @@ output_function_epilogue (file, size, leaf_function) int size ATTRIBUTE_UNUSED; int leaf_function; { - char *ret; + const char *ret; if (leaf_label) { @@ -3328,25 +3280,26 @@ output_function_epilogue (file, size, leaf_function) else if (current_function_epilogue_delay_list == 0) { - /* If code does not drop into the epilogue, do nothing. */ + /* If code does not drop into the epilogue, we need + do nothing except output pending case vectors. */ rtx insn = get_last_insn (); if (GET_CODE (insn) == NOTE) insn = prev_nonnote_insn (insn); if (insn && GET_CODE (insn) == BARRIER) - return; + goto output_vectors; } /* Restore any call saved registers. */ if (num_gfregs) { int offset, n_regs; - char *base; + const char *base; offset = -apparent_fsize + frame_base_offset; if (offset < -4096 || offset + num_gfregs * 4 > 4096 - 8 /*double*/) { build_big_number (file, offset, "%g1"); - fprintf (file, "\tadd %s,%%g1,%%g1\n", frame_base_name); + fprintf (file, "\tadd\t%s, %%g1, %%g1\n", frame_base_name); base = "%g1"; offset = 0; } @@ -3368,9 +3321,9 @@ output_function_epilogue (file, size, leaf_function) /* Work out how to skip the caller's unimp instruction if required. */ if (leaf_function) - ret = (SKIP_CALLERS_UNIMP_P ? "jmp %o7+12" : "retl"); + ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%o7+12" : "retl"); else - ret = (SKIP_CALLERS_UNIMP_P ? "jmp %i7+12" : "ret"); + ret = (SKIP_CALLERS_UNIMP_P ? "jmp\t%i7+12" : "ret"); if (TARGET_EPILOGUE || leaf_label) { @@ -3391,7 +3344,7 @@ output_function_epilogue (file, size, leaf_function) final_scan_insn (insn, file, 1, 0, 1); } else if (TARGET_V9 && ! SKIP_CALLERS_UNIMP_P) - fputs ("\treturn %i7+8\n\tnop\n", file); + fputs ("\treturn\t%i7+8\n\tnop\n", file); else fprintf (file, "\t%s\n\trestore\n", ret); } @@ -3413,18 +3366,21 @@ output_function_epilogue (file, size, leaf_function) else if (actual_fsize == 0) fprintf (file, "\t%s\n\tnop\n", ret); else if (actual_fsize <= 4096) - fprintf (file, "\t%s\n\tsub %%sp,-%d,%%sp\n", ret, actual_fsize); + fprintf (file, "\t%s\n\tsub\t%%sp, -%d, %%sp\n", ret, actual_fsize); else if (actual_fsize <= 8192) - fprintf (file, "\tsub %%sp,-4096,%%sp\n\t%s\n\tsub %%sp,-%d,%%sp\n", + fprintf (file, "\tsub\t%%sp, -4096, %%sp\n\t%s\n\tsub\t%%sp, -%d, %%sp\n", ret, actual_fsize - 4096); else if ((actual_fsize & 0x3ff) == 0) - fprintf (file, "\tsethi %%hi(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", + fprintf (file, "\tsethi\t%%hi(%d), %%g1\n\t%s\n\tadd\t%%sp, %%g1, %%sp\n", actual_fsize, ret); else - fprintf (file, "\tsethi %%hi(%d),%%g1\n\tor %%g1,%%lo(%d),%%g1\n\t%s\n\tadd %%sp,%%g1,%%sp\n", + 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); target_flags |= old_target_epilogue; } + + output_vectors: + sparc_output_deferred_case_vectors (); } /* Functions for handling argument passing. @@ -3661,6 +3617,13 @@ struct function_arg_record_value_parms int nregs, intoffset; }; +static void function_arg_record_value_3 + PROTO((int, struct function_arg_record_value_parms *)); +static void function_arg_record_value_2 + PROTO((tree, int, struct function_arg_record_value_parms *)); +static rtx function_arg_record_value + PROTO((tree, enum machine_mode, int, int, int)); + static void function_arg_record_value_1 (type, startbitpos, parms) tree type; @@ -3902,7 +3865,7 @@ function_arg_record_value (type, mode, slotno, named, regbase) nregs = SPARC_INT_ARG_MAX - slotno; } if (nregs == 0) - abort(); + abort (); parms.ret = gen_rtx_PARALLEL (mode, rtvec_alloc (nregs)); @@ -4278,6 +4241,12 @@ function_value (type, mode, incoming_p) mode = mode_for_size (bytes * BITS_PER_UNIT, MODE_INT, 0); } } + + if (TARGET_ARCH64 + && GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) < UNITS_PER_WORD + && type && TREE_CODE (type) != UNION_TYPE) + mode = DImode; if (incoming_p) regno = BASE_RETURN_VALUE_REG (mode); @@ -4314,7 +4283,7 @@ sparc_builtin_saveregs (arglist) GEN_INT (STACK_POINTER_OFFSET + UNITS_PER_WORD * first_reg)); - if (flag_check_memory_usage + if (current_function_check_memory_usage && first_reg < NPARM_REGS (word_mode)) emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, address, ptr_mode, @@ -4346,16 +4315,16 @@ output_cbranch (op, label, reversed, annul, noop, insn) int reversed, annul, noop; rtx insn; { - static char string[20]; + static char string[32]; enum rtx_code code = GET_CODE (op); rtx cc_reg = XEXP (op, 0); enum machine_mode mode = GET_MODE (cc_reg); - static char v8_labelno[] = " %lX"; - static char v9_icc_labelno[] = " %%icc,%lX"; - static char v9_xcc_labelno[] = " %%xcc,%lX"; - static char v9_fcc_labelno[] = " %%fccX,%lY"; + static char v8_labelno[] = "%lX"; + static char v9_icc_labelno[] = "%%icc, %lX"; + static char v9_xcc_labelno[] = "%%xcc, %lX"; + static char v9_fcc_labelno[] = "%%fccX, %lY"; char *labelno; - int labeloff; + int labeloff, spaces = 8; /* ??? !v9: FP branches cannot be preceded by another floating point insn. Because there is currently no concept of pre-delay slots, we can fix @@ -4376,16 +4345,28 @@ output_cbranch (op, label, reversed, annul, noop, insn) { case NE: if (mode == CCFPmode || mode == CCFPEmode) - strcat (string, "fbne"); + { + strcat (string, "fbne"); + spaces -= 4; + } else - strcpy (string, "bne"); + { + strcpy (string, "bne"); + spaces -= 3; + } break; case EQ: if (mode == CCFPmode || mode == CCFPEmode) - strcat (string, "fbe"); + { + strcat (string, "fbe"); + spaces -= 3; + } else - strcpy (string, "be"); + { + strcpy (string, "be"); + spaces -= 2; + } break; case GE: @@ -4395,23 +4376,39 @@ output_cbranch (op, label, reversed, annul, noop, insn) strcat (string, "fbul"); else strcat (string, "fbge"); + spaces -= 4; } else if (mode == CC_NOOVmode) - strcpy (string, "bpos"); + { + strcpy (string, "bpos"); + spaces -= 4; + } else - strcpy (string, "bge"); + { + strcpy (string, "bge"); + spaces -= 3; + } break; case GT: if (mode == CCFPmode || mode == CCFPEmode) { if (reversed) - strcat (string, "fbule"); + { + strcat (string, "fbule"); + spaces -= 5; + } else - strcat (string, "fbg"); + { + strcat (string, "fbg"); + spaces -= 3; + } } else - strcpy (string, "bg"); + { + strcpy (string, "bg"); + spaces -= 2; + } break; case LE: @@ -4421,52 +4418,75 @@ output_cbranch (op, label, reversed, annul, noop, insn) strcat (string, "fbug"); else strcat (string, "fble"); + spaces -= 4; } else - strcpy (string, "ble"); + { + strcpy (string, "ble"); + spaces -= 3; + } break; case LT: if (mode == CCFPmode || mode == CCFPEmode) { if (reversed) - strcat (string, "fbuge"); + { + strcat (string, "fbuge"); + spaces -= 5; + } else - strcat (string, "fbl"); + { + strcat (string, "fbl"); + spaces -= 3; + } } else if (mode == CC_NOOVmode) - strcpy (string, "bneg"); + { + strcpy (string, "bneg"); + spaces -= 4; + } else - strcpy (string, "bl"); + { + strcpy (string, "bl"); + spaces -= 2; + } break; case GEU: strcpy (string, "bgeu"); + spaces -= 4; break; case GTU: strcpy (string, "bgu"); + spaces -= 3; break; case LEU: strcpy (string, "bleu"); + spaces -= 4; break; case LTU: strcpy (string, "blu"); + spaces -= 3; break; default: - break; + abort (); } /* Now add the annulling, the label, and a possible noop. */ if (annul) - strcat (string, ",a"); + { + strcat (string, ",a"); + spaces -= 2; + } if (! TARGET_V9) { - labeloff = 3; + labeloff = 2; labelno = v8_labelno; } else @@ -4474,7 +4494,11 @@ output_cbranch (op, label, reversed, annul, noop, insn) rtx note; if (insn && (note = find_reg_note (insn, REG_BR_PRED, NULL_RTX))) - strcat (string, INTVAL (XEXP (note, 0)) & ATTR_FLAG_likely ? ",pt" : ",pn"); + { + strcat (string, + INTVAL (XEXP (note, 0)) & ATTR_FLAG_likely ? ",pt" : ",pn"); + spaces -= 3; + } labeloff = 9; if (mode == CCFPmode || mode == CCFPEmode) @@ -4482,7 +4506,7 @@ output_cbranch (op, label, reversed, annul, noop, insn) labeloff = 10; labelno = v9_fcc_labelno; /* Set the char indicating the number of the fcc reg to use. */ - labelno[6] = REGNO (cc_reg) - SPARC_FIRST_V9_FCC_REG + '0'; + labelno[5] = REGNO (cc_reg) - SPARC_FIRST_V9_FCC_REG + '0'; } else if (mode == CCXmode || mode == CCX_NOOVmode) labelno = v9_xcc_labelno; @@ -4492,6 +4516,10 @@ output_cbranch (op, label, reversed, annul, noop, insn) /* Set the char indicating the number of the operand containing the label_ref. */ labelno[labeloff] = label + '0'; + if (spaces > 0) + strcat (string, "\t"); + else + strcat (string, " "); strcat (string, labelno); if (noop) @@ -4512,15 +4540,18 @@ output_cbranch (op, label, reversed, annul, noop, insn) NOOP is non-zero if we have to follow this branch by a noop. */ char * -output_v9branch (op, reg, label, reversed, annul, noop) +output_v9branch (op, reg, label, reversed, annul, noop, insn) rtx op; int reg, label; int reversed, annul, noop; + rtx insn; { static char string[20]; enum rtx_code code = GET_CODE (op); enum machine_mode mode = GET_MODE (XEXP (op, 0)); - static char labelno[] = " %X,%lX"; + static char labelno[] = "%X, %lX"; + rtx note; + int spaces = 8; /* If not floating-point or if EQ or NE, we can just reverse the code. */ if (reversed) @@ -4536,26 +4567,32 @@ output_v9branch (op, reg, label, reversed, annul, noop) { case NE: strcpy (string, "brnz"); + spaces -= 4; break; case EQ: strcpy (string, "brz"); + spaces -= 3; break; case GE: strcpy (string, "brgez"); + spaces -= 5; break; case LT: strcpy (string, "brlz"); + spaces -= 4; break; case LE: strcpy (string, "brlez"); + spaces -= 5; break; case GT: strcpy (string, "brgz"); + spaces -= 4; break; default: @@ -4564,12 +4601,24 @@ output_v9branch (op, reg, label, reversed, annul, noop) /* Now add the annulling, reg, label, and nop. */ if (annul) - strcat (string, ",a"); + { + strcat (string, ",a"); + spaces -= 2; + } - /* ??? Optional prediction bit ",pt" or ",pf" goes here. */ + if (insn && (note = find_reg_note (insn, REG_BR_PRED, NULL_RTX))) + { + strcat (string, + INTVAL (XEXP (note, 0)) & ATTR_FLAG_likely ? ",pt" : ",pn"); + spaces -= 3; + } - labelno[2] = reg + '0'; + labelno[1] = reg + '0'; labelno[6] = label + '0'; + if (spaces > 0) + strcat (string, "\t"); + else + strcat (string, " "); strcat (string, labelno); if (noop) @@ -4626,13 +4675,13 @@ epilogue_renumber (where) default: debug_rtx (*where); - abort(); + abort (); } } /* Output assembler code to return from a function. */ -char * +const char * output_return (operands) rtx *operands; { @@ -4643,7 +4692,7 @@ output_return (operands) operands[0] = leaf_label; return "b%* %l0%("; } - else if (leaf_function) + else if (current_function_uses_only_leaf_regs) { /* No delay slot in a leaf function. */ if (delay) @@ -4661,24 +4710,24 @@ output_return (operands) if (actual_fsize <= 4096) { if (SKIP_CALLERS_UNIMP_P) - return "jmp %%o7+12\n\tsub %%sp,-%0,%%sp"; + return "jmp\t%%o7+12\n\tsub\t%%sp, -%0, %%sp"; else - return "retl\n\tsub %%sp,-%0,%%sp"; + return "retl\n\tsub\t%%sp, -%0, %%sp"; } else if (actual_fsize <= 8192) { operands[0] = GEN_INT (actual_fsize - 4096); if (SKIP_CALLERS_UNIMP_P) - return "sub %%sp,-4096,%%sp\n\tjmp %%o7+12\n\tsub %%sp,-%0,%%sp"; + return "sub\t%%sp, -4096, %%sp\n\tjmp\t%%o7+12\n\tsub\t%%sp, -%0, %%sp"; else - return "sub %%sp,-4096,%%sp\n\tretl\n\tsub %%sp,-%0,%%sp"; + return "sub\t%%sp, -4096, %%sp\n\tretl\n\tsub\t%%sp, -%0, %%sp"; } else if (SKIP_CALLERS_UNIMP_P) { if ((actual_fsize & 0x3ff) != 0) - return "sethi %%hi(%a0),%%g1\n\tor %%g1,%%lo(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; + return "sethi\t%%hi(%a0), %%g1\n\tor\t%%g1, %%lo(%a0), %%g1\n\tjmp\t%%o7+12\n\tadd\t%%sp, %%g1, %%sp"; else - return "sethi %%hi(%a0),%%g1\n\tjmp %%o7+12\n\tadd %%sp,%%g1,%%sp"; + return "sethi\t%%hi(%a0), %%g1\n\tjmp\t%%o7+12\n\tadd\t%%sp, %%g1, %%sp"; } else { @@ -4696,16 +4745,16 @@ output_return (operands) epilogue_renumber (&SET_SRC (PATTERN (delay))); } if (SKIP_CALLERS_UNIMP_P) - return "return %%i7+12%#"; + return "return\t%%i7+12%#"; else - return "return %%i7+8%#"; + return "return\t%%i7+8%#"; } else { if (delay) abort (); if (SKIP_CALLERS_UNIMP_P) - return "jmp %%i7+12\n\trestore"; + return "jmp\t%%i7+12\n\trestore"; else return "ret\n\trestore"; } @@ -4736,6 +4785,53 @@ order_regs_for_local_alloc () } } +/* Return 1 if REG and MEM are legitimate enough to allow the various + mem<-->reg splits to be run. */ + +int +sparc_splitdi_legitimate (reg, mem) + rtx reg; + rtx mem; +{ + /* Punt if we are here by mistake. */ + if (! reload_completed) + abort (); + + /* We must have an offsettable memory reference. */ + if (! offsettable_memref_p (mem)) + return 0; + + /* If we have legitimate args for ldd/std, we do not want + the split to happen. */ + if ((REGNO (reg) % 2) == 0 + && mem_min_alignment (mem, 8)) + return 0; + + /* Success. */ + return 1; +} + +/* Return 1 if x and y are some kind of REG and they refer to + different hard registers. This test is guarenteed to be + run after reload. */ + +int +sparc_absnegfloat_split_legitimate (x, y) + rtx x, y; +{ + if (GET_CODE (x) == SUBREG) + x = alter_subreg (x); + if (GET_CODE (x) != REG) + return 0; + if (GET_CODE (y) == SUBREG) + y = alter_subreg (y); + if (GET_CODE (y) != REG) + return 0; + if (REGNO (x) == REGNO (y)) + return 0; + return 1; +} + /* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1. This makes them candidates for using ldd and std insns. @@ -4866,7 +4962,7 @@ print_operand (file, x, code) case '#': /* Output a 'nop' if there's nothing for the delay slot. */ if (dbr_sequence_length () == 0) - fputs ("\n\tnop", file); + fputs ("\n\t nop", file); return; case '*': /* Output an annul flag if there's nothing for the delay slot and we @@ -4884,7 +4980,7 @@ print_operand (file, x, code) not optimizing. This is always used with '*' above. */ if (dbr_sequence_length () == 0 && ! (optimize && (int)sparc_cpu < PROCESSOR_V9)) - fputs ("\n\tnop", file); + fputs ("\n\t nop", file); return; case '_': /* Output the Embedded Medium/Anywhere code model base register. */ @@ -5086,7 +5182,10 @@ print_operand (file, x, code) else if (GET_CODE (x) == LO_SUM) { print_operand (file, XEXP (x, 0), 0); - fputs ("+%lo(", file); + if (TARGET_CM_MEDMID) + fputs ("+%l44(", file); + else + fputs ("+%lo(", file); output_addr_const (file, XEXP (x, 1)); fputc (')', file); } @@ -5152,7 +5251,7 @@ output_double_int (file, value) || GET_CODE (value) == CODE_LABEL || GET_CODE (value) == MINUS))) { - if (!TARGET_V9 || TARGET_CM_MEDLOW) + if (! TARGET_V9) { ASM_OUTPUT_INT (file, const0_rtx); ASM_OUTPUT_INT (file, value); @@ -5335,14 +5434,18 @@ sparc_initialize_trampoline (tramp, fnaddr, cxt) { /* SPARC 32 bit trampoline: - sethi %hi(fn),%g1 - sethi %hi(static),%g2 - jmp %g1+%lo(fn) - or %g2,%lo(static),%g2 + sethi %hi(fn), %g1 + sethi %hi(static), %g2 + jmp %g1+%lo(fn) + or %g2, %lo(static), %g2 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"), + 0, VOIDmode, 1, tramp, Pmode); +#endif emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 0)), expand_binop (SImode, ior_optab, @@ -5386,11 +5489,16 @@ void sparc64_initialize_trampoline (tramp, fnaddr, cxt) rtx tramp, fnaddr, cxt; { +#ifdef TRANSFER_FROM_TRAMPOLINE + emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "__enable_execute_stack"), + 0, VOIDmode, 1, tramp, Pmode); +#endif + /* - rd %pc,%g1 - ldx [%g1+24],%g5 - jmp %g5 - ldx [%g1+16],%g5 + rd %pc, %g1 + ldx [%g1+24], %g5 + jmp %g5 + ldx [%g1+16], %g5 +16 bytes data */ @@ -5399,12 +5507,13 @@ sparc64_initialize_trampoline (tramp, fnaddr, cxt) emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 4)), GEN_INT (0xca586018)); emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 8)), - GEN_INT (0x81c04000)); + GEN_INT (0x81c14000)); emit_move_insn (gen_rtx_MEM (SImode, plus_constant (tramp, 12)), GEN_INT (0xca586010)); emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, 16)), cxt); - emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, 20)), fnaddr); + emit_move_insn (gen_rtx_MEM (DImode, plus_constant (tramp, 24)), fnaddr); emit_insn (gen_flush (validize_mem (gen_rtx_MEM (DImode, tramp)))); + if (sparc_cpu != PROCESSOR_ULTRASPARC) emit_insn (gen_flush (validize_mem (gen_rtx_MEM (DImode, plus_constant (tramp, 8))))); } @@ -5525,18 +5634,23 @@ sparc_flat_compute_frame_size (size) /* This is the size of the 16 word reg save area, 1 word struct addr area, and 4 word fp/alu register copy area. */ - extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0); - var_size = size; - /* Also include the size needed for the 6 parameter registers. */ - args_size = current_function_outgoing_args_size + 24; - total_size = var_size + args_size + extra_size; - gp_reg_size = 0; - fp_reg_size = 0; - gmask = 0; - fmask = 0; - reg_offset = 0; + extra_size = -STARTING_FRAME_OFFSET + FIRST_PARM_OFFSET(0); + var_size = size; + gp_reg_size = 0; + fp_reg_size = 0; + gmask = 0; + fmask = 0; + reg_offset = 0; need_aligned_p = 0; + args_size = 0; + if (!leaf_function_p ()) + { + /* Also include the size needed for the 6 parameter registers. */ + args_size = current_function_outgoing_args_size + 24; + } + total_size = var_size + args_size; + /* Calculate space needed for gp registers. */ for (regno = 1; regno <= 31; regno++) { @@ -5585,9 +5699,13 @@ sparc_flat_compute_frame_size (size) total_size += gp_reg_size + fp_reg_size; } - /* ??? This looks a little suspicious. Clarify. */ - if (total_size == extra_size) - total_size = extra_size = 0; + /* If we must allocate a stack frame at all, we must also allocate + room for register window spillage, so as to be binary compatible + with libraries and operating systems that do not use -mflat. */ + if (total_size > 0) + total_size += extra_size; + else + extra_size = 0; total_size = SPARC_STACK_ALIGN (total_size); @@ -5656,7 +5774,7 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, if (word_op[0] == 's') { - fprintf (file, "\t%s %s,[%s+%d]\n", + fprintf (file, "\t%s\t%s, [%s+%d]\n", doubleword_op, reg_names[regno], base_reg, offset); if (dwarf2out_do_frame ()) @@ -5668,7 +5786,7 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, } } else - fprintf (file, "\t%s [%s+%d],%s\n", + fprintf (file, "\t%s\t[%s+%d], %s\n", doubleword_op, base_reg, offset, reg_names[regno]); @@ -5679,14 +5797,14 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, { if (word_op[0] == 's') { - fprintf (file, "\t%s %s,[%s+%d]\n", + fprintf (file, "\t%s\t%s, [%s+%d]\n", word_op, reg_names[regno], base_reg, offset); if (dwarf2out_do_frame ()) dwarf2out_reg_save ("", regno, offset + base_offset); } else - fprintf (file, "\t%s [%s+%d],%s\n", + fprintf (file, "\t%s\t[%s+%d], %s\n", word_op, base_reg, offset, reg_names[regno]); offset += UNITS_PER_WORD; @@ -5703,14 +5821,14 @@ sparc_flat_save_restore (file, base_reg, offset, gmask, fmask, word_op, { if (word_op[0] == 's') { - fprintf (file, "\t%s %s,[%s+%d]\n", + fprintf (file, "\t%s\t%s, [%s+%d]\n", word_op, reg_names[regno], base_reg, offset); if (dwarf2out_do_frame ()) dwarf2out_reg_save ("", regno, offset + base_offset); } else - fprintf (file, "\t%s [%s+%d],%s\n", + fprintf (file, "\t%s\t[%s+%d], %s\n", word_op, base_reg, offset, reg_names[regno]); offset += UNITS_PER_WORD; @@ -5764,7 +5882,7 @@ sparc_flat_output_function_prologue (file, size) { unsigned int reg_offset = current_frame_info.reg_offset; char *fp_str = reg_names[FRAME_POINTER_REGNUM]; - char *t1_str = "%g1"; + const char *t1_str = "%g1"; /* Things get a little tricky if local variables take up more than ~4096 bytes and outgoing arguments take up more than ~4096 bytes. When that @@ -5782,26 +5900,26 @@ sparc_flat_output_function_prologue (file, size) { if (size <= 4096) { - fprintf (file, "\tadd %s,%d,%s\n", + fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, -size, sp_str); if (gmask & FRAME_POINTER_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", fp_str, sp_str, reg_offset); - fprintf (file, "\tsub %s,%d,%s\t%s# set up frame pointer\n", + fprintf (file, "\tsub\t%s, %d, %s\t%s# set up frame pointer\n", sp_str, -size, fp_str, ASM_COMMENT_START); reg_offset += 4; } } else { - fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", + fprintf (file, "\tset\t%d, %s\n\tsub\t%s, %s, %s\n", size, t1_str, sp_str, t1_str, sp_str); if (gmask & FRAME_POINTER_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", fp_str, sp_str, reg_offset); - fprintf (file, "\tadd %s,%s,%s\t%s# set up frame pointer\n", + fprintf (file, "\tadd\t%s, %s, %s\t%s# set up frame pointer\n", sp_str, t1_str, fp_str, ASM_COMMENT_START); reg_offset += 4; } @@ -5820,7 +5938,7 @@ sparc_flat_output_function_prologue (file, size) } if (gmask & RETURN_ADDR_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", reg_names[RETURN_ADDR_REGNUM], sp_str, reg_offset); if (dwarf2out_do_frame ()) dwarf2out_return_save ("", reg_offset - size); @@ -5842,11 +5960,11 @@ sparc_flat_output_function_prologue (file, size) if (size1 <= 4096) { - fprintf (file, "\tadd %s,%d,%s\n", + fprintf (file, "\tadd\t%s, %d, %s\n", sp_str, -size1, sp_str); if (gmask & FRAME_POINTER_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n\tsub %s,%d,%s\t%s# set up frame pointer\n", + fprintf (file, "\tst\t%s, [%s+%d]\n\tsub\t%s, %d, %s\t%s# set up frame pointer\n", fp_str, sp_str, offset, sp_str, -size1, fp_str, ASM_COMMENT_START); offset += 4; @@ -5854,11 +5972,11 @@ sparc_flat_output_function_prologue (file, size) } else { - fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", + fprintf (file, "\tset\t%d, %s\n\tsub\t%s, %s, %s\n", size1, t1_str, sp_str, t1_str, sp_str); if (gmask & FRAME_POINTER_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n\tadd %s,%s,%s\t%s# set up frame pointer\n", + 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; @@ -5878,7 +5996,7 @@ sparc_flat_output_function_prologue (file, size) } if (gmask & RETURN_ADDR_MASK) { - fprintf (file, "\tst %s,[%s+%d]\n", + fprintf (file, "\tst\t%s, [%s+%d]\n", reg_names[RETURN_ADDR_REGNUM], sp_str, offset); if (dwarf2out_do_frame ()) /* offset - size1 == reg_offset - size @@ -5890,7 +6008,7 @@ sparc_flat_output_function_prologue (file, size) gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), current_frame_info.fmask, "st", "std", -size1); - fprintf (file, "\tset %d,%s\n\tsub %s,%s,%s\n", + fprintf (file, "\tset\t%d, %s\n\tsub\t%s, %s, %s\n", size - size1, t1_str, sp_str, t1_str, sp_str); if (dwarf2out_do_frame ()) if (! (gmask & FRAME_POINTER_MASK)) @@ -5898,396 +6016,1251 @@ sparc_flat_output_function_prologue (file, size) } } - fprintf (file, "\t%s#PROLOGUE# 1\n", ASM_COMMENT_START); + fprintf (file, "\t%s#PROLOGUE# 1\n", ASM_COMMENT_START); +} + +/* Do any necessary cleanup after a function to restore stack, frame, + and regs. */ + +void +sparc_flat_output_function_epilogue (file, size) + FILE *file; + int size; +{ + rtx epilogue_delay = current_function_epilogue_delay_list; + int noepilogue = FALSE; + + /* This is only for the human reader. */ + fprintf (file, "\t%s#EPILOGUE#\n", ASM_COMMENT_START); + + /* The epilogue does not depend on any registers, but the stack + registers, so we assume that if we have 1 pending nop, it can be + ignored, and 2 it must be filled (2 nops occur for integer + multiply and divide). */ + + size = SPARC_STACK_ALIGN (size); + size = (!current_frame_info.initialized + ? sparc_flat_compute_frame_size (size) + : current_frame_info.total_size); + + if (size == 0 && epilogue_delay == 0) + { + rtx insn = get_last_insn (); + + /* If the last insn was a BARRIER, we don't have to write any code + because a jump (aka return) was put there. */ + if (GET_CODE (insn) == NOTE) + insn = prev_nonnote_insn (insn); + if (insn && GET_CODE (insn) == BARRIER) + noepilogue = TRUE; + } + + if (!noepilogue) + { + unsigned int reg_offset = current_frame_info.reg_offset; + unsigned int size1; + char *sp_str = reg_names[STACK_POINTER_REGNUM]; + char *fp_str = reg_names[FRAME_POINTER_REGNUM]; + const char *t1_str = "%g1"; + + /* In the reload sequence, we don't need to fill the load delay + 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%d, %s\n", size, t1_str); + + if (frame_pointer_needed) + { + if (size > 4095) + 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, size, sp_str, ASM_COMMENT_START); + } + + /* Is the entire register save area offsettable from %sp? */ + if (reg_offset < 4096 - 64 * UNITS_PER_WORD) + { + size1 = 0; + } + else + { + /* Restore %sp in two steps, but make sure there is always a + 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; + /* Offset to register save area from %sp. */ + reg_offset = size1 - reg_offset; + + fprintf (file, "\tset\t%d, %s\n\tadd\t%s, %s, %s\n", + size1, t1_str, sp_str, t1_str, sp_str); + } + + /* We must restore the frame pointer and return address reg first + because they are treated specially by the prologue output code. */ + if (current_frame_info.gmask & FRAME_POINTER_MASK) + { + fprintf (file, "\tld\t[%s+%d], %s\n", + 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, reg_offset, reg_names[RETURN_ADDR_REGNUM]); + reg_offset += 4; + } + + /* Restore any remaining saved registers. */ + sparc_flat_save_restore (file, sp_str, reg_offset, + current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), + current_frame_info.fmask, + "ld", "ldd", 0); + + /* If we had to increment %sp in two steps, record it so the second + restoration in the epilogue finishes up. */ + if (size1 > 0) + { + size -= size1; + if (size > 4095) + fprintf (file, "\tset\t%d, %s\n", + size, t1_str); + } + + if (current_function_returns_struct) + fprintf (file, "\tjmp\t%%o7+12\n"); + else + fprintf (file, "\tretl\n"); + + /* If the only register saved is the return address, we need a + nop, unless we have an instruction to put into it. Otherwise + we don't since reloading multiple registers doesn't reference + the register being loaded. */ + + if (epilogue_delay) + { + if (size) + abort (); + final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1); + } + + else if (size > 4095) + 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, size, sp_str); + + else + fprintf (file, "\tnop\n"); + } + + /* Reset state info for each function. */ + current_frame_info = zero_frame_info; + + sparc_output_deferred_case_vectors (); +} + +/* Define the number of delay slots needed for the function epilogue. + + On the sparc, we need a slot if either no stack has been allocated, + or the only register saved is the return register. */ + +int +sparc_flat_epilogue_delay_slots () +{ + if (!current_frame_info.initialized) + (void) sparc_flat_compute_frame_size (get_frame_size ()); + + if (current_frame_info.total_size == 0) + return 1; + + return 0; +} + +/* Return true is TRIAL is a valid insn for the epilogue delay slot. + Any single length instruction which doesn't reference the stack or frame + pointer is OK. */ + +int +sparc_flat_eligible_for_epilogue_delay (trial, slot) + rtx trial; + int slot ATTRIBUTE_UNUSED; +{ + rtx pat = PATTERN (trial); + + if (get_attr_length (trial) != 1) + return 0; + + /* If %g0 is live, there are lots of things we can't handle. + Rather than trying to find them all now, let's punt and only + optimize things as necessary. */ + if (TARGET_LIVE_G0) + return 0; + + if (! reg_mentioned_p (stack_pointer_rtx, pat) + && ! reg_mentioned_p (frame_pointer_rtx, pat)) + return 1; + + return 0; +} + +/* 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 +supersparc_adjust_cost (insn, link, dep_insn, cost) + rtx insn; + rtx link; + rtx dep_insn; + int cost; +{ + enum attr_type insn_type; + + if (! recog_memoized (insn)) + return 0; + + insn_type = get_attr_type (insn); + + if (REG_NOTE_KIND (link) == 0) + { + /* Data dependency; DEP_INSN writes a register that INSN reads some + cycles later. */ + + /* if a load, then the dependence must be on the memory address; + add an extra "cycle". Note that the cost could be two cycles + if the reg was written late in an instruction group; we ca not tell + here. */ + if (insn_type == TYPE_LOAD || insn_type == TYPE_FPLOAD) + return cost + 3; + + /* Get the delay only if the address of the store is the dependence. */ + if (insn_type == TYPE_STORE || insn_type == TYPE_FPSTORE) + { + rtx pat = PATTERN(insn); + rtx dep_pat = PATTERN (dep_insn); + + if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) + return cost; /* This should not happen! */ + + /* The dependency between the two instructions was on the data that + is being stored. Assume that this implies that the address of the + store is not dependent. */ + if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) + return cost; + + return cost + 3; /* An approximation. */ + } + + /* A shift instruction cannot receive its data from an instruction + in the same cycle; add a one cycle penalty. */ + if (insn_type == TYPE_SHIFT) + return cost + 3; /* Split before cascade into shift. */ + } + else + { + /* Anti- or output- dependency; DEP_INSN reads/writes a register that + INSN writes some cycles later. */ + + /* These are only significant for the fpu unit; writing a fp reg before + the fpu has finished with it stalls the processor. */ + + /* Reusing an integer register causes no problems. */ + if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT) + return 0; + } + + return cost; +} + +static int +hypersparc_adjust_cost (insn, link, dep_insn, cost) + rtx insn; + rtx link; + rtx dep_insn; + int cost; +{ + enum attr_type insn_type, dep_type; + rtx pat = PATTERN(insn); + rtx dep_pat = PATTERN (dep_insn); + + if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) + return cost; + + insn_type = get_attr_type (insn); + dep_type = get_attr_type (dep_insn); + + switch (REG_NOTE_KIND (link)) + { + case 0: + /* Data dependency; DEP_INSN writes a register that INSN reads some + cycles later. */ + + switch (insn_type) + { + case TYPE_STORE: + case TYPE_FPSTORE: + /* Get the delay iff the address of the store is the dependence. */ + if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) + return cost; + + if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) + return cost; + return cost + 3; + + case TYPE_LOAD: + case TYPE_SLOAD: + case TYPE_FPLOAD: + /* If a load, then the dependence must be on the memory address. If + the addresses aren't equal, then it might be a false dependency */ + if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE) + { + if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET + || GET_CODE (SET_DEST (dep_pat)) != MEM + || GET_CODE (SET_SRC (pat)) != MEM + || ! rtx_equal_p (XEXP (SET_DEST (dep_pat), 0), + XEXP (SET_SRC (pat), 0))) + return cost + 2; + + return cost + 8; + } + break; + + case TYPE_BRANCH: + /* Compare to branch latency is 0. There is no benefit from + separating compare and branch. */ + if (dep_type == TYPE_COMPARE) + return 0; + /* Floating point compare to branch latency is less than + compare to conditional move. */ + if (dep_type == TYPE_FPCMP) + return cost - 1; + break; + default: + break; + } + break; + + case REG_DEP_ANTI: + /* Anti-dependencies only penalize the fpu unit. */ + if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT) + return 0; + break; + + default: + break; + } + + return cost; +} + +static int +ultrasparc_adjust_cost (insn, link, dep_insn, cost) + rtx insn; + rtx link; + rtx dep_insn; + int cost; +{ + enum attr_type insn_type, dep_type; + rtx pat = PATTERN(insn); + rtx dep_pat = PATTERN (dep_insn); + + if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) + return cost; + + insn_type = get_attr_type (insn); + dep_type = get_attr_type (dep_insn); + + /* Nothing issues in parallel with integer multiplies, so + mark as zero cost since the scheduler can not do anything + about it. */ + if (insn_type == TYPE_IMUL) + return 0; + +#define SLOW_FP(dep_type) \ +(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD) + + switch (REG_NOTE_KIND (link)) + { + case 0: + /* Data dependency; DEP_INSN writes a register that INSN reads some + cycles later. */ + + if (dep_type == TYPE_CMOVE) + { + /* Instructions that read the result of conditional moves cannot + be in the same group or the following group. */ + return cost + 1; + } + + switch (insn_type) + { + /* UltraSPARC can dual issue a store and an instruction setting + the value stored, except for divide and square root. */ + case TYPE_FPSTORE: + if (! SLOW_FP (dep_type)) + return 0; + return cost; + + case TYPE_STORE: + if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) + return cost; + + if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) + /* The dependency between the two instructions is on the data + that is being stored. Assume that the address of the store + is not also dependent. */ + return 0; + return cost; + + case TYPE_LOAD: + case TYPE_SLOAD: + case TYPE_FPLOAD: + /* A load does not return data until at least 11 cycles after + a store to the same location. 3 cycles are accounted for + in the load latency; add the other 8 here. */ + if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE) + { + /* If the addresses are not equal this may be a false + dependency because pointer aliasing could not be + determined. Add only 2 cycles in that case. 2 is + an arbitrary compromise between 8, which would cause + the scheduler to generate worse code elsewhere to + compensate for a dependency which might not really + exist, and 0. */ + if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET + || GET_CODE (SET_SRC (pat)) != MEM + || GET_CODE (SET_DEST (dep_pat)) != MEM + || ! rtx_equal_p (XEXP (SET_SRC (pat), 0), + XEXP (SET_DEST (dep_pat), 0))) + return cost + 2; + + return cost + 8; + } + return cost; + + case TYPE_BRANCH: + /* Compare to branch latency is 0. There is no benefit from + separating compare and branch. */ + if (dep_type == TYPE_COMPARE) + return 0; + /* Floating point compare to branch latency is less than + compare to conditional move. */ + if (dep_type == TYPE_FPCMP) + return cost - 1; + return cost; + + case TYPE_FPCMOVE: + /* FMOVR class instructions can not issue in the same cycle + or the cycle after an instruction which writes any + integer register. Model this as cost 2 for dependent + instructions. */ + if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY + || dep_type == TYPE_BINARY) + && cost < 2) + return 2; + /* Otherwise check as for integer conditional moves. */ + + case TYPE_CMOVE: + /* Conditional moves involving integer registers wait until + 3 cycles after loads return data. The interlock applies + to all loads, not just dependent loads, but that is hard + to model. */ + if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD) + return cost + 3; + return cost; + + default: + break; + } + break; + + case REG_DEP_ANTI: + /* Divide and square root lock destination registers for full latency. */ + if (! SLOW_FP (dep_type)) + return 0; + break; + + case REG_DEP_OUTPUT: + /* IEU and FPU instruction that have the same destination + register cannot be grouped together. */ + return cost + 1; + + default: + break; + } + + /* Other costs not accounted for: + - Single precision floating point loads lock the other half of + the even/odd register pair. + - Several hazards associated with ldd/std are ignored because these + instructions are rarely generated for V9. + - The floating point pipeline can not have both a single and double + precision operation active at the same time. Format conversions + and graphics instructions are given honorary double precision status. + - call and jmpl are always the first instruction in a group. */ + + return cost; + +#undef SLOW_FP +} + +int +sparc_adjust_cost(insn, link, dep, cost) + rtx insn; + rtx link; + rtx dep; + int cost; +{ + switch (sparc_cpu) + { + case PROCESSOR_SUPERSPARC: + cost = supersparc_adjust_cost (insn, link, dep, cost); + break; + case PROCESSOR_HYPERSPARC: + case PROCESSOR_SPARCLITE86X: + cost = hypersparc_adjust_cost (insn, link, dep, cost); + break; + case PROCESSOR_ULTRASPARC: + cost = ultrasparc_adjust_cost (insn, link, dep, cost); + break; + default: + break; + } + return cost; +} + +/* This describes the state of the UltraSPARC pipeline during + instruction scheduling. */ + +#define TMASK(__x) ((unsigned)1 << ((int)(__x))) +#define UMASK(__x) ((unsigned)1 << ((int)(__x))) + +enum ultra_code { NONE=0, /* no insn at all */ + IEU0, /* shifts and conditional moves */ + IEU1, /* condition code setting insns, calls+jumps */ + IEUN, /* all other single cycle ieu insns */ + LSU, /* loads and stores */ + CTI, /* branches */ + FPM, /* FPU pipeline 1, multiplies and divides */ + FPA, /* FPU pipeline 2, all other operations */ + SINGLE, /* single issue instructions */ + NUM_ULTRA_CODES }; + +static const char *ultra_code_names[NUM_ULTRA_CODES] = { + "NONE", "IEU0", "IEU1", "IEUN", "LSU", "CTI", + "FPM", "FPA", "SINGLE" }; + +struct ultrasparc_pipeline_state { + /* The insns in this group. */ + rtx group[4]; + + /* The code for each insn. */ + enum ultra_code codes[4]; + + /* Which insns in this group have been committed by the + scheduler. This is how we determine how many more + can issue this cycle. */ + char commit[4]; + + /* How many insns in this group. */ + char group_size; + + /* Mask of free slots still in this group. */ + char free_slot_mask; + + /* The slotter uses the following to determine what other + insn types can still make their way into this group. */ + char contents [NUM_ULTRA_CODES]; + char num_ieu_insns; +}; + +#define ULTRA_NUM_HIST 8 +static struct ultrasparc_pipeline_state ultra_pipe_hist[ULTRA_NUM_HIST]; +static int ultra_cur_hist; +static int ultra_cycles_elapsed; + +#define ultra_pipe (ultra_pipe_hist[ultra_cur_hist]) + +/* Given TYPE_MASK compute the ultra_code it has. */ +static enum ultra_code +ultra_code_from_mask (type_mask) + int type_mask; +{ + if (type_mask & (TMASK (TYPE_SHIFT) | TMASK (TYPE_CMOVE))) + return IEU0; + else if (type_mask & (TMASK (TYPE_COMPARE) | + TMASK (TYPE_CALL) | + TMASK (TYPE_UNCOND_BRANCH))) + return IEU1; + else if (type_mask & (TMASK (TYPE_IALU) | TMASK (TYPE_BINARY) | + TMASK (TYPE_MOVE) | TMASK (TYPE_UNARY))) + return IEUN; + else if (type_mask & (TMASK (TYPE_LOAD) | TMASK (TYPE_SLOAD) | + TMASK (TYPE_STORE) | TMASK (TYPE_FPLOAD) | + TMASK (TYPE_FPSTORE))) + return LSU; + else if (type_mask & (TMASK (TYPE_FPMUL) | TMASK (TYPE_FPDIVS) | + TMASK (TYPE_FPDIVD) | TMASK (TYPE_FPSQRT))) + return FPM; + else if (type_mask & (TMASK (TYPE_FPMOVE) | TMASK (TYPE_FPCMOVE) | + TMASK (TYPE_FP) | TMASK (TYPE_FPCMP))) + return FPA; + else if (type_mask & TMASK (TYPE_BRANCH)) + return CTI; + + return SINGLE; +} + +/* Check INSN (a conditional move) and make sure that it's + results are available at this cycle. Return 1 if the + results are in fact ready. */ +static int +ultra_cmove_results_ready_p (insn) + rtx insn; +{ + struct ultrasparc_pipeline_state *up; + int entry, slot; + + /* If this got dispatched in the previous + group, the results are not ready. */ + entry = (ultra_cur_hist - 1) % (ULTRA_NUM_HIST - 1); + up = &ultra_pipe_hist[entry]; + slot = 4; + while (--slot >= 0) + if (up->group[slot] == insn) + return 0; + + return 1; +} + +/* Walk backwards in pipeline history looking for FPU + operations which use a mode different than FPMODE and + will create a stall if an insn using FPMODE were to be + dispatched this cycle. */ +static int +ultra_fpmode_conflict_exists (fpmode) + enum machine_mode fpmode; +{ + int hist_ent; + int hist_lim; + + hist_ent = (ultra_cur_hist - 1) % (ULTRA_NUM_HIST - 1); + if (ultra_cycles_elapsed < 4) + hist_lim = ultra_cycles_elapsed; + else + hist_lim = 4; + while (hist_lim > 0) + { + struct ultrasparc_pipeline_state *up = &ultra_pipe_hist[hist_ent]; + int slot = 4; + + while (--slot >= 0) + { + rtx insn = up->group[slot]; + enum machine_mode this_mode; + rtx pat; + + if (! insn + || GET_CODE (insn) != INSN + || (pat = PATTERN (insn)) == 0 + || GET_CODE (pat) != SET) + continue; + + this_mode = GET_MODE (SET_DEST (pat)); + if ((this_mode != SFmode + && this_mode != DFmode) + || this_mode == fpmode) + continue; + + /* If it is not FMOV, FABS, FNEG, FDIV, or FSQRT then + we will get a stall. Loads and stores are independant + of these rules. */ + if (GET_CODE (SET_SRC (pat)) != ABS + && GET_CODE (SET_SRC (pat)) != NEG + && ((TMASK (get_attr_type (insn)) & + (TMASK (TYPE_FPDIVS) | TMASK (TYPE_FPDIVD) | + TMASK (TYPE_FPMOVE) | TMASK (TYPE_FPSQRT) | + TMASK (TYPE_LOAD) | TMASK (TYPE_STORE))) == 0)) + return 1; + } + hist_lim--; + hist_ent = (hist_ent - 1) % (ULTRA_NUM_HIST - 1); + } + + /* No conflicts, safe to dispatch. */ + return 0; } - -/* Do any necessary cleanup after a function to restore stack, frame, - and regs. */ -void -sparc_flat_output_function_epilogue (file, size) - FILE *file; - int size; -{ - rtx epilogue_delay = current_function_epilogue_delay_list; - int noepilogue = FALSE; +/* Find an instruction in LIST which has one of the + type attributes enumerated in TYPE_MASK. START + says where to begin the search. - /* This is only for the human reader. */ - fprintf (file, "\t%s#EPILOGUE#\n", ASM_COMMENT_START); + NOTE: This scheme depends upon the fact that we + have less than 32 distinct type attributes. */ - /* The epilogue does not depend on any registers, but the stack - registers, so we assume that if we have 1 pending nop, it can be - ignored, and 2 it must be filled (2 nops occur for integer - multiply and divide). */ +static int ultra_types_avail; - size = SPARC_STACK_ALIGN (size); - size = (!current_frame_info.initialized - ? sparc_flat_compute_frame_size (size) - : current_frame_info.total_size); +static rtx * +ultra_find_type (type_mask, list, start) + int type_mask; + rtx *list; + int start; +{ + int i; - if (size == 0 && epilogue_delay == 0) + /* Short circuit if no such insn exists in the ready + at the moment. */ + if ((type_mask & ultra_types_avail) == 0) + return 0; + + for (i = start; i >= 0; i--) { - rtx insn = get_last_insn (); + rtx insn = list[i]; - /* If the last insn was a BARRIER, we don't have to write any code - because a jump (aka return) was put there. */ - if (GET_CODE (insn) == NOTE) - insn = prev_nonnote_insn (insn); - if (insn && GET_CODE (insn) == BARRIER) - noepilogue = TRUE; - } + if (recog_memoized (insn) >= 0 + && (TMASK(get_attr_type (insn)) & type_mask)) + { + enum machine_mode fpmode = SFmode; + rtx pat = 0; + int slot; + int check_depend = 0; + int check_fpmode_conflict = 0; + + if (GET_CODE (insn) == INSN + && (pat = PATTERN(insn)) != 0 + && GET_CODE (pat) == SET + && !(type_mask & (TMASK (TYPE_STORE) | + TMASK (TYPE_FPSTORE)))) + { + check_depend = 1; + if (GET_MODE (SET_DEST (pat)) == SFmode + || GET_MODE (SET_DEST (pat)) == DFmode) + { + fpmode = GET_MODE (SET_DEST (pat)); + check_fpmode_conflict = 1; + } + } - if (!noepilogue) - { - unsigned int reg_offset = current_frame_info.reg_offset; - unsigned int size1; - char *sp_str = reg_names[STACK_POINTER_REGNUM]; - char *fp_str = reg_names[FRAME_POINTER_REGNUM]; - char *t1_str = "%g1"; + slot = 4; + while(--slot >= 0) + { + rtx slot_insn = ultra_pipe.group[slot]; + rtx slot_pat; + + /* Already issued, bad dependency, or FPU + mode conflict. */ + if (slot_insn != 0 + && (slot_pat = PATTERN (slot_insn)) != 0 + && ((insn == slot_insn) + || (check_depend == 1 + && GET_CODE (slot_insn) == INSN + && GET_CODE (slot_pat) == SET + && ((GET_CODE (SET_DEST (slot_pat)) == REG + && GET_CODE (SET_SRC (pat)) == REG + && REGNO (SET_DEST (slot_pat)) == + REGNO (SET_SRC (pat))) + || (GET_CODE (SET_DEST (slot_pat)) == SUBREG + && GET_CODE (SET_SRC (pat)) == SUBREG + && REGNO (SUBREG_REG (SET_DEST (slot_pat))) == + REGNO (SUBREG_REG (SET_SRC (pat))) + && SUBREG_WORD (SET_DEST (slot_pat)) == + SUBREG_WORD (SET_SRC (pat))))) + || (check_fpmode_conflict == 1 + && GET_CODE (slot_insn) == INSN + && GET_CODE (slot_pat) == SET + && (GET_MODE (SET_DEST (slot_pat)) == SFmode + || GET_MODE (SET_DEST (slot_pat)) == DFmode) + && GET_MODE (SET_DEST (slot_pat)) != fpmode))) + goto next; + } - /* In the reload sequence, we don't need to fill the load delay - slots for most of the loads, also see if we can fill the final - delay slot if not otherwise filled by the reload sequence. */ + /* Check for peculiar result availability and dispatch + interference situations. */ + if (pat != 0 + && ultra_cycles_elapsed > 0) + { + rtx link; - if (size > 4095) - fprintf (file, "\tset %d,%s\n", size, t1_str); + for (link = LOG_LINKS (insn); link; link = XEXP (link, 1)) + { + rtx link_insn = XEXP (link, 0); + if (GET_CODE (link_insn) == INSN + && recog_memoized (link_insn) >= 0 + && (TMASK (get_attr_type (link_insn)) & + (TMASK (TYPE_CMOVE) | TMASK (TYPE_FPCMOVE))) + && ! ultra_cmove_results_ready_p (link_insn)) + goto next; + } - if (frame_pointer_needed) - { - if (size > 4095) - fprintf (file,"\tsub %s,%s,%s\t\t%s# sp not trusted here\n", - fp_str, t1_str, sp_str, ASM_COMMENT_START); - else - fprintf (file,"\tsub %s,%d,%s\t\t%s# sp not trusted here\n", - fp_str, size, sp_str, ASM_COMMENT_START); - } + if (check_fpmode_conflict + && ultra_fpmode_conflict_exists (fpmode)) + goto next; + } - /* Is the entire register save area offsettable from %sp? */ - if (reg_offset < 4096 - 64 * UNITS_PER_WORD) - { - size1 = 0; + return &list[i]; } - else - { - /* Restore %sp in two steps, but make sure there is always a - 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; - /* Offset to register save area from %sp. */ - reg_offset = size1 - reg_offset; + next: + ; + } + return 0; +} - fprintf (file, "\tset %d,%s\n\tadd %s,%s,%s\n", - size1, t1_str, sp_str, t1_str, sp_str); - } +static void +ultra_build_types_avail (ready, n_ready) + rtx *ready; + int n_ready; +{ + int i = n_ready - 1; - /* We must restore the frame pointer and return address reg first - because they are treated specially by the prologue output code. */ - if (current_frame_info.gmask & FRAME_POINTER_MASK) - { - fprintf (file, "\tld [%s+%d],%s\n", - sp_str, reg_offset, fp_str); - reg_offset += 4; - } - if (current_frame_info.gmask & RETURN_ADDR_MASK) - { - fprintf (file, "\tld [%s+%d],%s\n", - sp_str, reg_offset, reg_names[RETURN_ADDR_REGNUM]); - reg_offset += 4; - } + ultra_types_avail = 0; + while(i >= 0) + { + rtx insn = ready[i]; - /* Restore any remaining saved registers. */ - sparc_flat_save_restore (file, sp_str, reg_offset, - current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), - current_frame_info.fmask, - "ld", "ldd", 0); + if (recog_memoized (insn) >= 0) + ultra_types_avail |= TMASK (get_attr_type (insn)); - /* If we had to increment %sp in two steps, record it so the second - restoration in the epilogue finishes up. */ - if (size1 > 0) - { - size -= size1; - if (size > 4095) - fprintf (file, "\tset %d,%s\n", - size, t1_str); - } + i -= 1; + } +} - if (current_function_returns_struct) - fprintf (file, "\tjmp %%o7+12\n"); - else - fprintf (file, "\tretl\n"); +/* Place insn pointed to my IP into the pipeline. + Make element THIS of READY be that insn if it + is not already. TYPE indicates the pipeline class + this insn falls into. */ +static void +ultra_schedule_insn (ip, ready, this, type) + rtx *ip; + rtx *ready; + int this; + enum ultra_code type; +{ + int pipe_slot; + char mask = ultra_pipe.free_slot_mask; - /* If the only register saved is the return address, we need a - nop, unless we have an instruction to put into it. Otherwise - we don't since reloading multiple registers doesn't reference - the register being loaded. */ + /* Obtain free slot. */ + for (pipe_slot = 0; pipe_slot < 4; pipe_slot++) + if ((mask & (1 << pipe_slot)) != 0) + break; + if (pipe_slot == 4) + abort (); - if (epilogue_delay) - { - if (size) - abort (); - final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1); - } + /* In it goes, and it hasn't been committed yet. */ + ultra_pipe.group[pipe_slot] = *ip; + ultra_pipe.codes[pipe_slot] = type; + ultra_pipe.contents[type] = 1; + if (UMASK (type) & + (UMASK (IEUN) | UMASK (IEU0) | UMASK (IEU1))) + ultra_pipe.num_ieu_insns += 1; - else if (size > 4095) - fprintf (file, "\tadd %s,%s,%s\n", sp_str, t1_str, sp_str); + ultra_pipe.free_slot_mask = (mask & ~(1 << pipe_slot)); + ultra_pipe.group_size += 1; + ultra_pipe.commit[pipe_slot] = 0; - else if (size > 0) - fprintf (file, "\tadd %s,%d,%s\n", sp_str, size, sp_str); + /* Update ready list. */ + if (ip != &ready[this]) + { + rtx temp = *ip; - else - fprintf (file, "\tnop\n"); + *ip = ready[this]; + ready[this] = temp; } +} - /* Reset state info for each function. */ - current_frame_info = zero_frame_info; +/* Advance to the next pipeline group. */ +static void +ultra_flush_pipeline () +{ + ultra_cur_hist = (ultra_cur_hist + 1) % (ULTRA_NUM_HIST - 1); + ultra_cycles_elapsed += 1; + bzero ((char *) &ultra_pipe, sizeof ultra_pipe); + ultra_pipe.free_slot_mask = 0xf; } - -/* Define the number of delay slots needed for the function epilogue. - On the sparc, we need a slot if either no stack has been allocated, - or the only register saved is the return register. */ +static int ultra_reorder_called_this_block; + +/* Init our data structures for this current block. */ +void +ultrasparc_sched_init (dump, sched_verbose) + FILE *dump ATTRIBUTE_UNUSED; + int sched_verbose ATTRIBUTE_UNUSED; +{ + bzero ((char *) ultra_pipe_hist, sizeof ultra_pipe_hist); + ultra_cur_hist = 0; + ultra_cycles_elapsed = 0; + ultra_reorder_called_this_block = 0; + ultra_pipe.free_slot_mask = 0xf; +} +/* INSN has been scheduled, update pipeline commit state + and return how many instructions are still to be + scheduled in this group. */ int -sparc_flat_epilogue_delay_slots () +ultrasparc_variable_issue (insn) + rtx insn; { - if (!current_frame_info.initialized) - (void) sparc_flat_compute_frame_size (get_frame_size ()); + struct ultrasparc_pipeline_state *up = &ultra_pipe; + int i, left_to_fire; - if (current_frame_info.total_size == 0) - return 1; + left_to_fire = 0; + for (i = 0; i < 4; i++) + { + if (up->group[i] == 0) + continue; - return 0; -} + if (up->group[i] == insn) + { + up->commit[i] = 1; + } + else if (! up->commit[i]) + left_to_fire++; + } -/* Return true is TRIAL is a valid insn for the epilogue delay slot. - Any single length instruction which doesn't reference the stack or frame - pointer is OK. */ + return left_to_fire; +} -int -sparc_flat_eligible_for_epilogue_delay (trial, slot) - rtx trial; - int slot ATTRIBUTE_UNUSED; +/* In actual_hazard_this_instance, we may have yanked some + instructions from the ready list due to conflict cost + adjustments. If so, and such an insn was in our pipeline + group, remove it and update state. */ +static void +ultra_rescan_pipeline_state (ready, n_ready) + rtx *ready; + int n_ready; { - rtx pat = PATTERN (trial); + struct ultrasparc_pipeline_state *up = &ultra_pipe; + int i; - if (get_attr_length (trial) != 1) - return 0; + for (i = 0; i < 4; i++) + { + rtx insn = up->group[i]; + int j; - /* If %g0 is live, there are lots of things we can't handle. - Rather than trying to find them all now, let's punt and only - optimize things as necessary. */ - if (TARGET_LIVE_G0) - return 0; + if (! insn) + continue; - if (! reg_mentioned_p (stack_pointer_rtx, pat) - && ! reg_mentioned_p (frame_pointer_rtx, pat)) - return 1; + /* If it has been committed, then it was removed from + the ready list because it was actually scheduled, + and that is not the case we are searching for here. */ + if (up->commit[i] != 0) + continue; - return 0; + for (j = n_ready - 1; j >= 0; j--) + if (ready[j] == insn) + break; + + /* If we didn't find it, toss it. */ + if (j < 0) + { + enum ultra_code ucode = up->codes[i]; + + up->group[i] = 0; + up->codes[i] = NONE; + up->contents[ucode] = 0; + if (UMASK (ucode) & + (UMASK (IEUN) | UMASK (IEU0) | UMASK (IEU1))) + up->num_ieu_insns -= 1; + + up->free_slot_mask |= (1 << i); + up->group_size -= 1; + up->commit[i] = 0; + } + } } - -/* 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. */ -int -supersparc_adjust_cost (insn, link, dep_insn, cost) - rtx insn; - rtx link; - rtx dep_insn; - int cost; +void +ultrasparc_sched_reorder (dump, sched_verbose, ready, n_ready) + FILE *dump; + int sched_verbose; + rtx *ready; + int n_ready; { - enum attr_type insn_type; + struct ultrasparc_pipeline_state *up = &ultra_pipe; + int i, this_insn; - if (! recog_memoized (insn)) - return 0; - - insn_type = get_attr_type (insn); - - if (REG_NOTE_KIND (link) == 0) + /* We get called once unnecessarily per block of insns + scheduled. */ + if (ultra_reorder_called_this_block == 0) { - /* Data dependency; DEP_INSN writes a register that INSN reads some - cycles later. */ + ultra_reorder_called_this_block = 1; + return; + } - /* if a load, then the dependence must be on the memory address; - add an extra 'cycle'. Note that the cost could be two cycles - if the reg was written late in an instruction group; we can't tell - here. */ - if (insn_type == TYPE_LOAD || insn_type == TYPE_FPLOAD) - return cost + 3; + if (sched_verbose) + { + int n; - /* Get the delay only if the address of the store is the dependence. */ - if (insn_type == TYPE_STORE || insn_type == TYPE_FPSTORE) + fprintf (dump, "\n;;\tUltraSPARC Looking at ["); + for (n = n_ready - 1; n >= 0; n--) { - rtx pat = PATTERN(insn); - rtx dep_pat = PATTERN (dep_insn); + rtx insn = ready[n]; + enum ultra_code ucode; + + if (recog_memoized (insn) < 0) + continue; + ucode = ultra_code_from_mask (TMASK (get_attr_type (insn))); + if (n != 0) + fprintf (dump, "%s(%d) ", + ultra_code_names[ucode], + INSN_UID (insn)); + else + fprintf (dump, "%s(%d)", + ultra_code_names[ucode], + INSN_UID (insn)); + } + fprintf (dump, "]\n"); + } - if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) - return cost; /* This shouldn't happen! */ + this_insn = n_ready - 1; - /* The dependency between the two instructions was on the data that - is being stored. Assume that this implies that the address of the - store is not dependent. */ - if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) - return cost; + /* Skip over junk we don't understand. */ + while ((this_insn >= 0) + && recog_memoized (ready[this_insn]) < 0) + this_insn--; - return cost + 3; /* An approximation. */ - } + ultra_build_types_avail (ready, this_insn + 1); - /* A shift instruction cannot receive its data from an instruction - in the same cycle; add a one cycle penalty. */ - if (insn_type == TYPE_SHIFT) - return cost + 3; /* Split before cascade into shift. */ - } - else - { - /* Anti- or output- dependency; DEP_INSN reads/writes a register that - INSN writes some cycles later. */ + while (this_insn >= 0) { + int old_group_size = up->group_size; - /* These are only significant for the fpu unit; writing a fp reg before - the fpu has finished with it stalls the processor. */ + if (up->group_size != 0) + { + int num_committed; + + num_committed = (up->commit[0] + up->commit[1] + + up->commit[2] + up->commit[3]); + /* If nothing has been commited from our group, or all of + them have. Clear out the (current cycle's) pipeline + state and start afresh. */ + if (num_committed == 0 + || num_committed == up->group_size) + { + ultra_flush_pipeline (); + up = &ultra_pipe; + old_group_size = 0; + } + else + { + /* OK, some ready list insns got requeued and thus removed + from the ready list. Account for this fact. */ + ultra_rescan_pipeline_state (ready, n_ready); + + /* Something "changed", make this look like a newly + formed group so the code at the end of the loop + knows that progress was in fact made. */ + if (up->group_size != old_group_size) + old_group_size = 0; + } + } - /* Reusing an integer register causes no problems. */ - if (insn_type == TYPE_IALU || insn_type == TYPE_SHIFT) - return 0; - } - - return cost; -} + if (up->group_size == 0) + { + /* If the pipeline is (still) empty and we have any single + group insns, get them out now as this is a good time. */ + rtx *ip = ultra_find_type ((TMASK (TYPE_RETURN) | TMASK (TYPE_ADDRESS) | + TMASK (TYPE_IMUL) | TMASK (TYPE_CMOVE) | + TMASK (TYPE_MULTI) | TMASK (TYPE_MISC)), + ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, SINGLE); + break; + } -int -ultrasparc_adjust_cost (insn, link, dep_insn, cost) - rtx insn; - rtx link; - rtx dep_insn; - int cost; -{ - enum attr_type insn_type, dep_type; - rtx pat = PATTERN(insn); - rtx dep_pat = PATTERN (dep_insn); + /* If we are not in the process of emptying out the pipe, try to + obtain an instruction which must be the first in it's group. */ + ip = ultra_find_type ((TMASK (TYPE_CALL) | + TMASK (TYPE_CALL_NO_DELAY_SLOT) | + TMASK (TYPE_UNCOND_BRANCH)), + ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, IEU1); + this_insn--; + } + else if ((ip = ultra_find_type ((TMASK (TYPE_FPDIVS) | + TMASK (TYPE_FPDIVD) | + TMASK (TYPE_FPSQRT)), + ready, this_insn)) != 0) + { + ultra_schedule_insn (ip, ready, this_insn, FPM); + this_insn--; + } + } - if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0) - return cost; + /* Try to fill the integer pipeline. First, look for an IEU0 specific + operation. We can't do more IEU operations if the first 3 slots are + all full or we have dispatched two IEU insns already. */ + if ((up->free_slot_mask & 0x7) != 0 + && up->num_ieu_insns < 2 + && up->contents[IEU0] == 0 + && up->contents[IEUN] == 0) + { + rtx *ip = ultra_find_type (TMASK(TYPE_SHIFT), ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, IEU0); + this_insn--; + } + } - insn_type = get_attr_type (insn); - dep_type = get_attr_type (dep_insn); + /* If we can, try to find an IEU1 specific or an unnamed + IEU instruction. */ + if ((up->free_slot_mask & 0x7) != 0 + && up->num_ieu_insns < 2) + { + rtx *ip = ultra_find_type ((TMASK (TYPE_IALU) | TMASK (TYPE_BINARY) | + TMASK (TYPE_MOVE) | TMASK (TYPE_UNARY) | + (up->contents[IEU1] == 0 ? TMASK (TYPE_COMPARE) : 0)), + ready, this_insn); + if (ip) + { + rtx insn = *ip; -#define SLOW_FP(dep_type) \ -(dep_type == TYPE_FPSQRT || dep_type == TYPE_FPDIVS || dep_type == TYPE_FPDIVD) + ultra_schedule_insn (ip, ready, this_insn, + (!up->contents[IEU1] + && get_attr_type (insn) == TYPE_COMPARE) + ? IEU1 : IEUN); + this_insn--; + } + } - switch (REG_NOTE_KIND (link)) - { - case 0: - /* Data dependency; DEP_INSN writes a register that INSN reads some - cycles later. */ + /* If only one IEU insn has been found, try to find another unnamed + IEU operation or an IEU1 specific one. */ + if ((up->free_slot_mask & 0x7) != 0 + && up->num_ieu_insns < 2) + { + rtx *ip; + int tmask = (TMASK (TYPE_IALU) | TMASK (TYPE_BINARY) | + TMASK (TYPE_MOVE) | TMASK (TYPE_UNARY)); + + if (!up->contents[IEU1]) + tmask |= TMASK (TYPE_COMPARE); + ip = ultra_find_type (tmask, ready, this_insn); + if (ip) + { + rtx insn = *ip; - switch (insn_type) - { - /* UltraSPARC can dual issue a store and an instruction setting - the value stored, except for divide and square root. */ - case TYPE_FPSTORE: - if (! SLOW_FP (dep_type)) - return 0; - return cost; + ultra_schedule_insn (ip, ready, this_insn, + (!up->contents[IEU1] + && get_attr_type (insn) == TYPE_COMPARE) + ? IEU1 : IEUN); + this_insn--; + } + } - case TYPE_STORE: - if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET) - return cost; + /* Try for a load or store, but such an insn can only be issued + if it is within' one of the first 3 slots. */ + if ((up->free_slot_mask & 0x7) != 0 + && up->contents[LSU] == 0) + { + rtx *ip = ultra_find_type ((TMASK (TYPE_LOAD) | TMASK (TYPE_SLOAD) | + TMASK (TYPE_STORE) | TMASK (TYPE_FPLOAD) | + TMASK (TYPE_FPSTORE)), ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, LSU); + this_insn--; + } + } - if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat))) - /* The dependency between the two instructions is on the data - that is being stored. Assume that the address of the store - is not also dependent. */ - return 0; - return cost; - - case TYPE_LOAD: - case TYPE_SLOAD: - case TYPE_FPLOAD: - /* A load does not return data until at least 11 cycles after - a store to the same location. 3 cycles are accounted for - in the load latency; add the other 8 here. */ - if (dep_type == TYPE_STORE || dep_type == TYPE_FPSTORE) - { - /* If the addresses are not equal this may be a false - dependency because pointer aliasing could not be - determined. Add only 2 cycles in that case. 2 is - an arbitrary compromise between 8, which would cause - the scheduler to generate worse code elsewhere to - compensate for a dependency which might not really - exist, and 0. */ - if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET - || GET_CODE (SET_SRC (pat)) != MEM - || GET_CODE (SET_DEST (dep_pat)) != MEM - || ! rtx_equal_p (XEXP (SET_SRC (pat), 0), - XEXP (SET_DEST (dep_pat), 0))) - return cost + 2; + /* Now find FPU operations, first FPM class. But not divisions or + square-roots because those will break the group up. Unlike all + the previous types, these can go in any slot. */ + if (up->free_slot_mask != 0 + && up->contents[FPM] == 0) + { + rtx *ip = ultra_find_type (TMASK (TYPE_FPMUL), ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, FPM); + this_insn--; + } + } + + /* Continue on with FPA class if we have not filled the group already. */ + if (up->free_slot_mask != 0 + && up->contents[FPA] == 0) + { + rtx *ip = ultra_find_type ((TMASK (TYPE_FPMOVE) | TMASK (TYPE_FPCMOVE) | + TMASK (TYPE_FP) | TMASK (TYPE_FPCMP)), + ready, this_insn); + if (ip) + { + ultra_schedule_insn (ip, ready, this_insn, FPA); + this_insn--; + } + } - return cost + 8; - } - return cost; + /* Finally, maybe stick a branch in here. */ + if (up->free_slot_mask != 0 + && up->contents[CTI] == 0) + { + rtx *ip = ultra_find_type (TMASK (TYPE_BRANCH), ready, this_insn); - case TYPE_BRANCH: - /* Compare to branch latency is 0. There is no benefit from - separating compare and branch. */ - if (dep_type == TYPE_COMPARE) - return 0; - /* Floating point compare to branch latency is less than - compare to conditional move. */ - if (dep_type == TYPE_FPCMP) - return cost - 1; - return cost; + /* Try to slip in a branch only if it is one of the + next 2 in the ready list. */ + if (ip && ((&ready[this_insn] - ip) < 2)) + { + ultra_schedule_insn (ip, ready, this_insn, CTI); + this_insn--; + } + } - case TYPE_FPCMOVE: - /* FMOVR class instructions can not issue in the same cycle - or the cycle after an instruction which writes any - integer register. Model this as cost 2 for dependent - instructions. */ - if ((dep_type == TYPE_IALU || dep_type == TYPE_UNARY - || dep_type == TYPE_BINARY) - && cost < 2) - return 2; - /* Otherwise check as for integer conditional moves. */ + up->group_size = 0; + for (i = 0; i < 4; i++) + if ((up->free_slot_mask & (1 << i)) == 0) + up->group_size++; - case TYPE_CMOVE: - /* Conditional moves involving integer registers wait until - 3 cycles after loads return data. The interlock applies - to all loads, not just dependent loads, but that is hard - to model. */ - if (dep_type == TYPE_LOAD || dep_type == TYPE_SLOAD) - return cost + 3; - return cost; + /* See if we made any progress... */ + if (old_group_size != up->group_size) + break; - default: - break; - } - break; + /* Clean out the (current cycle's) pipeline state + and try once more. If we placed no instructions + into the pipeline at all, it means a real hard + conflict exists with some earlier issued instruction + so we must advance to the next cycle to clear it up. */ + if (up->group_size == 0) + { + ultra_flush_pipeline (); + up = &ultra_pipe; + } + else + { + bzero ((char *) &ultra_pipe, sizeof ultra_pipe); + ultra_pipe.free_slot_mask = 0xf; + } + } - case REG_DEP_ANTI: - /* Divide and square root lock destination registers for full latency. */ - if (! SLOW_FP (dep_type)) - return 0; - break; + if (sched_verbose) + { + int n, gsize; - default: - break; - } + fprintf (dump, ";;\tUltraSPARC Launched ["); + gsize = up->group_size; + for (n = 0; n < 4; n++) + { + rtx insn = up->group[n]; - /* Other costs not accounted for: - - Multiply should be modeled as having no latency because there is - nothing the scheduler can do about it. - - Single precision floating point loads lock the other half of - the even/odd register pair. - - Several hazards associated with ldd/std are ignored because these - instructions are rarely generated for V9. - - A shift following an integer instruction which does not set the - condition codes can not issue in the same cycle. - - The floating point pipeline can not have both a single and double - precision operation active at the same time. Format conversions - and graphics instructions are given honorary double precision status. - - call and jmpl are always the first instruction in a group. */ + if (! insn) + continue; - return cost; -} + gsize -= 1; + if (gsize != 0) + fprintf (dump, "%s(%d) ", + ultra_code_names[up->codes[n]], + INSN_UID (insn)); + else + fprintf (dump, "%s(%d)", + ultra_code_names[up->codes[n]], + INSN_UID (insn)); + } + fprintf (dump, "]\n"); + } +} int sparc_issue_rate () @@ -6301,6 +7274,9 @@ sparc_issue_rate () return 2; case PROCESSOR_SUPERSPARC: return 3; + case PROCESSOR_HYPERSPARC: + case PROCESSOR_SPARCLITE86X: + return 2; case PROCESSOR_ULTRASPARC: return 4; } @@ -6322,8 +7298,6 @@ set_extends(x, insn) /* LO_SUM is used with sethi. sethi cleared the high bits and the values used with lo_sum are positive */ case LO_SUM: - /* UNSPEC is v8plus_clear_high */ - case UNSPEC: /* Store flag stores 0 or 1 */ case LT: case LTU: case GT: case GTU: @@ -6360,6 +7334,110 @@ set_extends(x, insn) } } +/* We _ought_ to have only one kind per function, but... */ +static rtx sparc_addr_diff_list; +static rtx sparc_addr_list; + +void +sparc_defer_case_vector (lab, vec, diff) + rtx lab, vec; + int diff; +{ + vec = gen_rtx_EXPR_LIST (VOIDmode, lab, vec); + if (diff) + sparc_addr_diff_list + = gen_rtx_EXPR_LIST (VOIDmode, vec, sparc_addr_diff_list); + else + sparc_addr_list = gen_rtx_EXPR_LIST (VOIDmode, vec, sparc_addr_list); +} + +static void +sparc_output_addr_vec (vec) + rtx vec; +{ + rtx lab = XEXP (vec, 0), body = XEXP (vec, 1); + int idx, vlen = XVECLEN (body, 0); + +#ifdef ASM_OUTPUT_ADDR_VEC_START + ASM_OUTPUT_ADDR_VEC_START (asm_out_file); +#endif + +#ifdef ASM_OUTPUT_CASE_LABEL + 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)); +#endif + + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_VEC_ELT + (asm_out_file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0))); + } + +#ifdef ASM_OUTPUT_ADDR_VEC_END + ASM_OUTPUT_ADDR_VEC_END (asm_out_file); +#endif +} + +static void +sparc_output_addr_diff_vec (vec) + rtx vec; +{ + rtx lab = XEXP (vec, 0), body = XEXP (vec, 1); + rtx base = XEXP (XEXP (body, 0), 0); + int idx, vlen = XVECLEN (body, 1); + +#ifdef ASM_OUTPUT_ADDR_VEC_START + ASM_OUTPUT_ADDR_VEC_START (asm_out_file); +#endif + +#ifdef ASM_OUTPUT_CASE_LABEL + 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)); +#endif + + for (idx = 0; idx < vlen; idx++) + { + ASM_OUTPUT_ADDR_DIFF_ELT + (asm_out_file, + body, + CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)), + CODE_LABEL_NUMBER (base)); + } + +#ifdef ASM_OUTPUT_ADDR_VEC_END + ASM_OUTPUT_ADDR_VEC_END (asm_out_file); +#endif +} + +static void +sparc_output_deferred_case_vectors () +{ + rtx t; + int align; + + if (sparc_addr_list == NULL_RTX + && sparc_addr_diff_list == NULL_RTX) + return; + + /* Align to cache line in the function's code section. */ + function_section (current_function_decl); + + align = floor_log2 (FUNCTION_BOUNDARY / BITS_PER_UNIT); + if (align > 0) + ASM_OUTPUT_ALIGN (asm_out_file, align); + + for (t = sparc_addr_list; t ; t = XEXP (t, 1)) + sparc_output_addr_vec (XEXP (t, 0)); + for (t = sparc_addr_diff_list; t ; t = XEXP (t, 1)) + sparc_output_addr_diff_vec (XEXP (t, 0)); + + sparc_addr_list = sparc_addr_diff_list = NULL_RTX; +} + /* Return 0 if the high 32 bits of X (the low word of X, if DImode) are unknown. Return 1 if the high bits are zero, -1 if the register is sign extended. */ @@ -6452,10 +7530,314 @@ sparc_return_peephole_ok (dest, src) { if (! TARGET_V9) return 0; - if (leaf_function) + if (current_function_uses_only_leaf_regs) return 0; if (GET_CODE (src) != CONST_INT && (GET_CODE (src) != REG || ! IN_OR_GLOBAL_P (src))) return 0; return IN_OR_GLOBAL_P (dest); } + +/* Output assembler code to FILE to increment profiler label # LABELNO + for profiling a function entry. + + 32 bit sparc uses %g2 as the STATIC_CHAIN_REGNUM which gets clobbered + during profiling so we need to save/restore it around the call to mcount. + We're guaranteed that a save has just been done, and we use the space + allocated for intreg/fpreg value passing. */ + +void +sparc_function_profiler (file, labelno) + FILE *file; + int labelno; +{ + char buf[32]; + ASM_GENERATE_INTERNAL_LABEL (buf, "LP", labelno); + + if (! TARGET_ARCH64) + fputs ("\tst\t%g2,[%fp-4]\n", file); + + fputs ("\tsethi\t%hi(", file); + assemble_name (file, buf); + fputs ("),%o0\n", file); + + fputs ("\tcall\t", file); + assemble_name (file, MCOUNT_FUNCTION); + putc ('\n', file); + + fputs ("\t or\t%o0,%lo(", file); + assemble_name (file, buf); + fputs ("),%o0\n", file); + + if (! TARGET_ARCH64) + fputs ("\tld\t[%fp-4],%g2\n", file); +} + + +/* The following macro shall output assembler code to FILE + to initialize basic-block profiling. + + If profile_block_flag == 2 + + Output code to call the subroutine `__bb_init_trace_func' + and pass two parameters to it. The first parameter is + the address of a block allocated in the object module. + The second parameter is the number of the first basic block + of the function. + + The name of the block is a local symbol made with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. + + The number of the first basic block of the function is + passed to the macro in BLOCK_OR_LABEL. + + If described in a virtual assembler language the code to be + output looks like: + + parameter1 <- LPBX0 + parameter2 <- BLOCK_OR_LABEL + call __bb_init_trace_func + + else if profile_block_flag != 0 + + Output code to call the subroutine `__bb_init_func' + and pass one single parameter to it, which is the same + as the first parameter to `__bb_init_trace_func'. + + The first word of this parameter is a flag which will be nonzero if + the object module has already been initialized. So test this word + first, and do not call `__bb_init_func' if the flag is nonzero. + Note: When profile_block_flag == 2 the test need not be done + but `__bb_init_trace_func' *must* be called. + + BLOCK_OR_LABEL may be used to generate a label number as a + branch destination in case `__bb_init_func' will not be called. + + If described in a virtual assembler language the code to be + output looks like: + + cmp (LPBX0),0 + jne local_label + parameter1 <- LPBX0 + call __bb_init_func + local_label: + +*/ + +void +sparc_function_block_profiler(file, block_or_label) + FILE *file; + int block_or_label; +{ + char LPBX[32]; + ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 0); + + if (profile_block_flag == 2) + { + fputs ("\tsethi\t%hi(", file); + assemble_name (file, LPBX); + fputs ("),%o0\n", file); + + fprintf (file, "\tsethi\t%%hi(%d),%%o1\n", block_or_label); + + fputs ("\tor\t%o0,%lo(", file); + assemble_name (file, LPBX); + fputs ("),%o0\n", file); + + fprintf (file, "\tcall\t%s__bb_init_trace_func\n", user_label_prefix); + + fprintf (file, "\t or\t%%o1,%%lo(%d),%%o1\n", block_or_label); + } + else if (profile_block_flag != 0) + { + char LPBY[32]; + ASM_GENERATE_INTERNAL_LABEL (LPBY, "LPBY", block_or_label); + + fputs ("\tsethi\t%hi(", file); + assemble_name (file, LPBX); + fputs ("),%o0\n", file); + + fputs ("\tld\t[%lo(", file); + assemble_name (file, LPBX); + fputs (")+%o0],%o1\n", file); + + fputs ("\ttst\t%o1\n", file); + + if (TARGET_V9) + { + fputs ("\tbne,pn\t%icc,", file); + assemble_name (file, LPBY); + putc ('\n', file); + } + else + { + fputs ("\tbne\t", file); + assemble_name (file, LPBY); + putc ('\n', file); + } + + fputs ("\t or\t%o0,%lo(", file); + assemble_name (file, LPBX); + fputs ("),%o0\n", file); + + fprintf (file, "\tcall\t%s__bb_init_func\n\t nop\n", user_label_prefix); + + ASM_OUTPUT_INTERNAL_LABEL (file, "LPBY", block_or_label); + } +} + +/* The following macro shall output assembler code to FILE + to increment a counter associated with basic block number BLOCKNO. + + If profile_block_flag == 2 + + Output code to initialize the global structure `__bb' and + call the function `__bb_trace_func' which will increment the + counter. + + `__bb' consists of two words. In the first word the number + of the basic block has to be stored. In the second word + the address of a block allocated in the object module + has to be stored. + + The basic block number is given by BLOCKNO. + + The address of the block is given by the label created with + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); + + by FUNCTION_BLOCK_PROFILER. + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. + + If described in a virtual assembler language the code to be + output looks like: + + move BLOCKNO -> (__bb) + move LPBX0 -> (__bb+4) + call __bb_trace_func + + Note that function `__bb_trace_func' must not change the + machine state, especially the flag register. To grant + this, you must output code to save and restore registers + either in this macro or in the macros MACHINE_STATE_SAVE + and MACHINE_STATE_RESTORE. The last two macros will be + used in the function `__bb_trace_func', so you must make + sure that the function prologue does not change any + register prior to saving it with MACHINE_STATE_SAVE. + + else if profile_block_flag != 0 + + Output code to increment the counter directly. + Basic blocks are numbered separately from zero within each + compiled object module. The count associated with block number + BLOCKNO is at index BLOCKNO in an array of words; the name of + this array is a local symbol made with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. + + If described in a virtual assembler language, the code to be + output looks like: + + inc (LPBX2+4*BLOCKNO) + +*/ + +void +sparc_block_profiler(file, blockno) + FILE *file; + int blockno; +{ + char LPBX[32]; + + if (profile_block_flag == 2) + { + ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 0); + + fprintf (file, "\tsethi\t%%hi(%s__bb),%%g1\n", user_label_prefix); + fprintf (file, "\tsethi\t%%hi(%d),%%g2\n", blockno); + fprintf (file, "\tor\t%%g1,%%lo(%s__bb),%%g1\n", user_label_prefix); + fprintf (file, "\tor\t%%g2,%%lo(%d),%%g2\n", blockno); + + fputs ("\tst\t%g2,[%g1]\n", file); + + fputs ("\tsethi\t%hi(", file); + assemble_name (file, LPBX); + fputs ("),%g2\n", file); + + fputs ("\tor\t%o2,%lo(", file); + assemble_name (file, LPBX); + fputs ("),%g2\n", file); + + fputs ("\tst\t%g2,[%g1+4]\n", file); + fputs ("\tmov\t%o7,%g2\n", file); + + fprintf (file, "\tcall\t%s__bb_trace_func\n\t nop\n", user_label_prefix); + + fputs ("\tmov\t%g2,%o7\n", file); + } + else if (profile_block_flag != 0) + { + ASM_GENERATE_INTERNAL_LABEL (LPBX, "LPBX", 2); + + fputs ("\tsethi\t%hi(", file); + assemble_name (file, LPBX); + fprintf (file, "+%d),%%g1\n", blockno*4); + + fputs ("\tld\t[%g1+%lo(", file); + assemble_name (file, LPBX); + fprintf (file, "+%d)],%%g2\n", blockno*4); + + fputs ("\tadd\t%g2,1,%g2\n", file); + + fputs ("\tst\t%g2,[%g1+%lo(", file); + assemble_name (file, LPBX); + fprintf (file, "+%d)]\n", blockno*4); + } +} + +/* The following macro shall output assembler code to FILE + to indicate a return from function during basic-block profiling. + + If profile_block_flag == 2: + + Output assembler code to call function `__bb_trace_ret'. + + Note that function `__bb_trace_ret' must not change the + machine state, especially the flag register. To grant + this, you must output code to save and restore registers + either in this macro or in the macros MACHINE_STATE_SAVE_RET + and MACHINE_STATE_RESTORE_RET. The last two macros will be + used in the function `__bb_trace_ret', so you must make + sure that the function prologue does not change any + register prior to saving it with MACHINE_STATE_SAVE_RET. + + else if profile_block_flag != 0: + + The macro will not be used, so it need not distinguish + these cases. +*/ + +void +sparc_function_block_profiler_exit(file) + FILE *file; +{ + if (profile_block_flag == 2) + fprintf (file, "\tcall\t%s__bb_trace_ret\n\t nop\n", user_label_prefix); + else + abort (); +} diff --git a/contrib/gcc/config/sparc/sparc.h b/contrib/gcc/config/sparc/sparc.h index e66f5e6..ad11d74 100644 --- a/contrib/gcc/config/sparc/sparc.h +++ b/contrib/gcc/config/sparc/sparc.h @@ -1,5 +1,5 @@ /* Definitions of target machine for GNU compiler, for Sun SPARC. - Copyright (C) 1987, 88, 89, 92, 94-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92, 94-98, 1999 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. @@ -34,10 +34,18 @@ Boston, MA 02111-1307, USA. */ architectures to compile for. We allow targets to choose compile time or runtime selection. */ #ifdef SPARC_BI_ARCH +#ifdef IN_LIBGCC2 +#if defined(__sparcv9) || defined(__sparcv_v9) || defined(__arch64__) +#define TARGET_ARCH32 0 +#else +#define TARGET_ARCH32 1 +#endif /* V9 sparc */ +#else #define TARGET_ARCH32 (! TARGET_64BIT) +#endif /* IN_LIBGCC2 */ #else #define TARGET_ARCH32 (DEFAULT_ARCH32_P) -#endif +#endif /* SPARC_BI_ARCH */ #define TARGET_ARCH64 (! TARGET_ARCH32) /* Code model selection. @@ -55,7 +63,8 @@ Boston, MA 02111-1307, USA. */ 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. + 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 @@ -78,7 +87,7 @@ enum cmodel { }; /* Value of -mcmodel specified by user. */ -extern char *sparc_cmodel_string; +extern const char *sparc_cmodel_string; /* One of CM_FOO. */ extern enum cmodel sparc_cmodel; @@ -97,44 +106,109 @@ extern enum cmodel sparc_cmodel; /* Values of TARGET_CPU_DEFAULT, set via -D in the Makefile, and specified by the user via --with-cpu=foo. This specifies the cpu implementation, not the architecture size. */ +/* Note that TARGET_CPU_v9 is assumed to start the list of 64-bit + capable cpu's. */ #define TARGET_CPU_sparc 0 #define TARGET_CPU_v7 0 /* alias for previous */ #define TARGET_CPU_sparclet 1 #define TARGET_CPU_sparclite 2 #define TARGET_CPU_v8 3 /* generic v8 implementation */ #define TARGET_CPU_supersparc 4 -#define TARGET_CPU_v9 5 /* generic v9 implementation */ -#define TARGET_CPU_sparc64 5 /* alias */ -#define TARGET_CPU_ultrasparc 6 +#define TARGET_CPU_hypersparc 5 +#define TARGET_CPU_sparc86x 6 +#define TARGET_CPU_sparclite86x 6 +#define TARGET_CPU_v9 7 /* generic v9 implementation */ +#define TARGET_CPU_sparcv9 7 /* alias */ +#define TARGET_CPU_sparc64 7 /* alias */ +#define TARGET_CPU_ultrasparc 8 + +#if TARGET_CPU_DEFAULT == TARGET_CPU_v9 \ + || TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc + +#define CPP_CPU32_DEFAULT_SPEC "" +#define ASM_CPU32_DEFAULT_SPEC "" -#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc || TARGET_CPU_DEFAULT == TARGET_CPU_v8 || TARGET_CPU_DEFAULT == TARGET_CPU_supersparc -#define CPP_CPU_DEFAULT_SPEC "" -#define ASM_CPU_DEFAULT_SPEC "" -#endif -#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclet -#define CPP_CPU_DEFAULT_SPEC "-D__sparclet__" -#define ASM_CPU_DEFAULT_SPEC "-Asparclet" -#endif -#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite -#define CPP_CPU_DEFAULT_SPEC "-D__sparclite__" -#define ASM_CPU_DEFAULT_SPEC "-Asparclite" -#endif #if TARGET_CPU_DEFAULT == TARGET_CPU_v9 /* ??? What does Sun's CC pass? */ -#define CPP_CPU_DEFAULT_SPEC "-D__sparc_v9__" +#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__" /* ??? It's not clear how other assemblers will handle this, so by default use GAS. Sun's Solaris assembler recognizes -xarch=v8plus, but this case is handled in sol2.h. */ -#define ASM_CPU_DEFAULT_SPEC "-Av9" +#define ASM_CPU64_DEFAULT_SPEC "-Av9" #endif #if TARGET_CPU_DEFAULT == TARGET_CPU_ultrasparc -#define CPP_CPU_DEFAULT_SPEC "-D__sparc_v9__" -#define ASM_CPU_DEFAULT_SPEC "-Av9a" +#define CPP_CPU64_DEFAULT_SPEC "-D__sparc_v9__" +#define ASM_CPU64_DEFAULT_SPEC "-Av9a" +#endif + +#else + +#define CPP_CPU64_DEFAULT_SPEC "" +#define ASM_CPU64_DEFAULT_SPEC "" + +#if TARGET_CPU_DEFAULT == TARGET_CPU_sparc \ + || TARGET_CPU_DEFAULT == TARGET_CPU_v8 +#define CPP_CPU32_DEFAULT_SPEC "" +#define ASM_CPU32_DEFAULT_SPEC "" +#endif + +#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclet +#define CPP_CPU32_DEFAULT_SPEC "-D__sparclet__" +#define ASM_CPU32_DEFAULT_SPEC "-Asparclet" #endif -#ifndef CPP_CPU_DEFAULT_SPEC + +#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite +#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite__" +#define ASM_CPU32_DEFAULT_SPEC "-Asparclite" +#endif + +#if TARGET_CPU_DEFAULT == TARGET_CPU_supersparc +#define CPP_CPU32_DEFAULT_SPEC "-D__supersparc__ -D__sparc_v8__" +#define ASM_CPU32_DEFAULT_SPEC "" +#endif + +#if TARGET_CPU_DEFAULT == TARGET_CPU_hypersparc +#define CPP_CPU32_DEFAULT_SPEC "-D__hypersparc__ -D__sparc_v8__" +#define ASM_CPU32_DEFAULT_SPEC "" +#endif + +#if TARGET_CPU_DEFAULT == TARGET_CPU_sparclite86x +#define CPP_CPU32_DEFAULT_SPEC "-D__sparclite86x__ -D__sparc_v8__" +#define ASM_CPU32_DEFAULT_SPEC "-Av8" +#endif + +#endif + +#if !defined(CPP_CPU32_DEFAULT_SPEC) || !defined(CPP_CPU64_DEFAULT_SPEC) Unrecognized value in TARGET_CPU_DEFAULT. #endif +#ifdef SPARC_BI_ARCH + +#define CPP_CPU_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? "\ +%{m64:" CPP_CPU64_DEFAULT_SPEC "} \ +%{!m64:" CPP_CPU32_DEFAULT_SPEC "} \ +" : "\ +%{m32:" CPP_CPU32_DEFAULT_SPEC "} \ +%{!m32:" CPP_CPU64_DEFAULT_SPEC "} \ +") +#define ASM_CPU_DEFAULT_SPEC \ +(DEFAULT_ARCH32_P ? "\ +%{m64:" ASM_CPU64_DEFAULT_SPEC "} \ +%{!m64:" ASM_CPU32_DEFAULT_SPEC "} \ +" : "\ +%{m32:" ASM_CPU32_DEFAULT_SPEC "} \ +%{!m32:" ASM_CPU64_DEFAULT_SPEC "} \ +") + +#else /* !SPARC_BI_ARCH */ + +#define CPP_CPU_DEFAULT_SPEC (DEFAULT_ARCH32_P ? CPP_CPU32_DEFAULT_SPEC : CPP_CPU64_DEFAULT_SPEC) +#define ASM_CPU_DEFAULT_SPEC (DEFAULT_ARCH32_P ? ASM_CPU32_DEFAULT_SPEC : ASM_CPU64_DEFAULT_SPEC) + +#endif /* !SPARC_BI_ARCH */ + /* 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 @@ -158,6 +232,8 @@ Unrecognized value in TARGET_CPU_DEFAULT. %{mcpu=f930:-D__sparclite__} %{mcpu=f934:-D__sparclite__} \ %{mcpu=v8:-D__sparc_v8__} \ %{mcpu=supersparc:-D__supersparc__ -D__sparc_v8__} \ +%{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \ +%{mcpu=sparclite86x:-D__sparclite86x__ -D__sparc_v8__} \ %{mcpu=v9:-D__sparc_v9__} \ %{mcpu=ultrasparc:-D__sparc_v9__} \ %{!mcpu*:%{!mcypress:%{!msparclite:%{!mf930:%{!mf934:%{!mv8:%{!msupersparc:%(cpp_cpu_default)}}}}}}} \ @@ -169,8 +245,20 @@ Unrecognized value in TARGET_CPU_DEFAULT. sparc64 in 32 bit environments, so for now we only use `sparc64' in 64 bit environments. */ +#ifdef SPARC_BI_ARCH + +#define CPP_ARCH32_SPEC "-D__SIZE_TYPE__=unsigned\\ int -D__PTRDIFF_TYPE__=int \ +-D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc)" +#define CPP_ARCH64_SPEC "-D__SIZE_TYPE__=long\\ unsigned\\ int -D__PTRDIFF_TYPE__=long\\ int \ +-D__arch64__ -Acpu(sparc64) -Amachine(sparc64)" + +#else + #define CPP_ARCH32_SPEC "-D__GCC_NEW_VARARGS__ -Acpu(sparc) -Amachine(sparc)" #define CPP_ARCH64_SPEC "-D__arch64__ -Acpu(sparc64) -Amachine(sparc64)" + +#endif + #define CPP_ARCH_DEFAULT_SPEC \ (DEFAULT_ARCH32_P ? CPP_ARCH32_SPEC : CPP_ARCH64_SPEC) @@ -181,7 +269,9 @@ Unrecognized value in TARGET_CPU_DEFAULT. " /* Macros to distinguish endianness. */ -#define CPP_ENDIAN_SPEC "%{mlittle-endian:-D__LITTLE_ENDIAN__}" +#define CPP_ENDIAN_SPEC "\ +%{mlittle-endian:-D__LITTLE_ENDIAN__} \ +%{mlittle-endian-data:-D__LITTLE_ENDIAN_DATA__}" /* Macros to distinguish the particular subtarget. */ #define CPP_SUBTARGET_SPEC "" @@ -254,20 +344,20 @@ Unrecognized value in TARGET_CPU_DEFAULT. Do not define this macro if it does not need to do anything. */ #define EXTRA_SPECS \ - { "cpp_cpu", CPP_CPU_SPEC }, \ - { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \ - { "cpp_arch32", CPP_ARCH32_SPEC }, \ - { "cpp_arch64", CPP_ARCH64_SPEC }, \ - { "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC }, \ - { "cpp_arch", CPP_ARCH_SPEC }, \ - { "cpp_endian", CPP_ENDIAN_SPEC }, \ - { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \ - { "asm_cpu", ASM_CPU_SPEC }, \ - { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \ - { "asm_arch32", ASM_ARCH32_SPEC }, \ - { "asm_arch64", ASM_ARCH64_SPEC }, \ - { "asm_arch_default", ASM_ARCH_DEFAULT_SPEC }, \ - { "asm_arch", ASM_ARCH_SPEC }, \ + { "cpp_cpu", CPP_CPU_SPEC }, \ + { "cpp_cpu_default", CPP_CPU_DEFAULT_SPEC }, \ + { "cpp_arch32", CPP_ARCH32_SPEC }, \ + { "cpp_arch64", CPP_ARCH64_SPEC }, \ + { "cpp_arch_default", CPP_ARCH_DEFAULT_SPEC },\ + { "cpp_arch", CPP_ARCH_SPEC }, \ + { "cpp_endian", CPP_ENDIAN_SPEC }, \ + { "cpp_subtarget", CPP_SUBTARGET_SPEC }, \ + { "asm_cpu", ASM_CPU_SPEC }, \ + { "asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \ + { "asm_arch32", ASM_ARCH32_SPEC }, \ + { "asm_arch64", ASM_ARCH64_SPEC }, \ + { "asm_arch_default", ASM_ARCH_DEFAULT_SPEC },\ + { "asm_arch", ASM_ARCH_SPEC }, \ SUBTARGET_EXTRA_SPECS #define SUBTARGET_EXTRA_SPECS @@ -299,7 +389,7 @@ void sparc_override_options (); { \ if (flag_pic) \ { \ - char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC"; \ + const char *pic_string = (flag_pic == 1) ? "-fpic" : "-fPIC";\ warning ("%s and profiling conflict: disabling %s", \ pic_string, pic_string); \ flag_pic = 0; \ @@ -411,8 +501,7 @@ extern int target_flags; /* 0x2000, 0x4000 are unused */ /* Nonzero if pointers are 64 bits. - This is not a user selectable option, though it may be one day - - so it is used to determine pointer size instead of an architecture flag. */ + At the moment it must follow architecture size flag. */ #define MASK_PTR64 0x8000 #define TARGET_PTR64 (target_flags & MASK_PTR64) @@ -480,44 +569,44 @@ extern int target_flags; An empty string NAME is used to identify the default VALUE. */ #define TARGET_SWITCHES \ - { {"fpu", MASK_FPU | MASK_FPU_SET}, \ - {"no-fpu", -MASK_FPU}, \ - {"no-fpu", MASK_FPU_SET}, \ - {"hard-float", MASK_FPU | MASK_FPU_SET}, \ - {"soft-float", -MASK_FPU}, \ - {"soft-float", MASK_FPU_SET}, \ - {"epilogue", MASK_EPILOGUE}, \ - {"no-epilogue", -MASK_EPILOGUE}, \ - {"unaligned-doubles", MASK_UNALIGNED_DOUBLES}, \ - {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES}, \ - {"impure-text", MASK_IMPURE_TEXT}, \ - {"no-impure-text", -MASK_IMPURE_TEXT}, \ - {"flat", MASK_FLAT}, \ - {"no-flat", -MASK_FLAT}, \ - {"app-regs", MASK_APP_REGS}, \ - {"no-app-regs", -MASK_APP_REGS}, \ - {"hard-quad-float", MASK_HARD_QUAD}, \ - {"soft-quad-float", -MASK_HARD_QUAD}, \ - {"v8plus", MASK_V8PLUS}, \ - {"no-v8plus", -MASK_V8PLUS}, \ - {"vis", MASK_VIS}, \ + { {"fpu", MASK_FPU | MASK_FPU_SET, "Use hardware fp" }, \ + {"no-fpu", -MASK_FPU, "Do not use hardware fp" }, \ + {"no-fpu", MASK_FPU_SET, "Do not use hardware fp" }, \ + {"hard-float", MASK_FPU | MASK_FPU_SET, "Use hardware fp" }, \ + {"soft-float", -MASK_FPU, "Do not use hardware fp" }, \ + {"soft-float", MASK_FPU_SET, "Do not use hardware fp" }, \ + {"epilogue", MASK_EPILOGUE, "Use FUNCTION_EPILOGUE" }, \ + {"no-epilogue", -MASK_EPILOGUE, "Do not use FUNCTION_EPILOGUE" }, \ + {"unaligned-doubles", MASK_UNALIGNED_DOUBLES, "Assume possible double misalignment" },\ + {"no-unaligned-doubles", -MASK_UNALIGNED_DOUBLES, "Assume all doubles are aligned" }, \ + {"impure-text", MASK_IMPURE_TEXT, "Pass -assert pure-text to linker" }, \ + {"no-impure-text", -MASK_IMPURE_TEXT, "Do not pass -assert pure-text to linker" }, \ + {"flat", MASK_FLAT, "Use flat register window model" }, \ + {"no-flat", -MASK_FLAT, "Do not use flat register window model" }, \ + {"app-regs", MASK_APP_REGS, "Use ABI reserved registers" }, \ + {"no-app-regs", -MASK_APP_REGS, "Do not use ABI reserved registers" }, \ + {"hard-quad-float", MASK_HARD_QUAD, "Use hardware quad fp instructions" }, \ + {"soft-quad-float", -MASK_HARD_QUAD, "Do not use hardware quad fp instructions" }, \ + {"v8plus", MASK_V8PLUS, "Compile for v8plus ABI" }, \ + {"no-v8plus", -MASK_V8PLUS, "Do not compile for v8plus ABI" }, \ + {"vis", MASK_VIS, "Utilize Visual Instruction Set" }, \ + {"no-vis", -MASK_VIS, "Do not utilize Visual Instruction Set" }, \ /* ??? These are deprecated, coerced to -mcpu=. Delete in 2.9. */ \ - {"cypress", 0}, \ - {"sparclite", 0}, \ - {"f930", 0}, \ - {"f934", 0}, \ - {"v8", 0}, \ - {"supersparc", 0}, \ + {"cypress", 0, "Optimize for Cypress processors" }, \ + {"sparclite", 0, "Optimize for SparcLite processors" }, \ + {"f930", 0, "Optimize for F930 processors" }, \ + {"f934", 0, "Optimize for F934 processors" }, \ + {"v8", 0, "Use V8 Sparc ISA" }, \ + {"supersparc", 0, "Optimize for SuperSparc processors" }, \ /* End of deprecated options. */ \ - /* -mptrNN exists for *experimental* purposes. */ \ -/* {"ptr64", MASK_PTR64}, */ \ -/* {"ptr32", -MASK_PTR64}, */ \ - {"32", -MASK_64BIT}, \ - {"64", MASK_64BIT}, \ - {"stack-bias", MASK_STACK_BIAS}, \ - {"no-stack-bias", -MASK_STACK_BIAS}, \ + {"ptr64", MASK_PTR64, "Pointers are 64-bit" }, \ + {"ptr32", -MASK_PTR64, "Pointers are 32-bit" }, \ + {"32", -MASK_64BIT, "Use 32-bit ABI" }, \ + {"64", MASK_64BIT, "Use 64-bit ABI" }, \ + {"stack-bias", MASK_STACK_BIAS, "Use stack bias" }, \ + {"no-stack-bias", -MASK_STACK_BIAS, "Do not use stack bias" }, \ SUBTARGET_SWITCHES \ - { "", TARGET_DEFAULT}} + { "", TARGET_DEFAULT, ""}} /* MASK_APP_REGS must always be the default because that's what FIXED_REGISTERS is set to and -ffixed- is processed before @@ -537,6 +626,8 @@ enum processor_type { PROCESSOR_SPARCLITE, PROCESSOR_F930, PROCESSOR_F934, + PROCESSOR_HYPERSPARC, + PROCESSOR_SPARCLITE86X, PROCESSOR_SPARCLET, PROCESSOR_TSC701, PROCESSOR_V9, @@ -569,12 +660,12 @@ extern enum processor_type sparc_cpu; #define TARGET_OPTIONS \ { \ - { "cpu=", &sparc_select[1].string }, \ - { "tune=", &sparc_select[2].string }, \ - { "cmodel=", &sparc_cmodel_string }, \ - { "align-loops=", &sparc_align_loops_string }, \ - { "align-jumps=", &sparc_align_jumps_string }, \ - { "align-functions=", &sparc_align_funcs_string }, \ + { "cpu=", &sparc_select[1].string, "Use features of and schedule code for given CPU" }, \ + { "tune=", &sparc_select[2].string, "Schedule code for given CPU" }, \ + { "cmodel=", &sparc_cmodel_string, "Use given Sparc code model" }, \ + { "align-loops=", &sparc_align_loops_string, "Loop code aligned to this power of 2" }, \ + { "align-jumps=", &sparc_align_jumps_string, "Jump targets are aligned to this power of 2" }, \ + { "align-functions=", &sparc_align_funcs_string, "Function starts are aligned to this power of 2" }, \ SUBTARGET_OPTIONS \ } @@ -584,8 +675,8 @@ extern enum processor_type sparc_cpu; /* sparc_select[0] is reserved for the default cpu. */ struct sparc_cpu_select { - char *string; - char *name; + const char *string; + const char *name; int set_tune_p; int set_arch_p; }; @@ -593,9 +684,9 @@ struct sparc_cpu_select extern struct sparc_cpu_select sparc_select[]; /* Variables to record values the user passes. */ -extern char *sparc_align_loops_string; -extern char *sparc_align_jumps_string; -extern char *sparc_align_funcs_string; +extern const char *sparc_align_loops_string; +extern const char *sparc_align_jumps_string; +extern const char *sparc_align_funcs_string; /* Parsed values as a power of two. */ extern int sparc_align_loops; extern int sparc_align_jumps; @@ -623,7 +714,7 @@ extern int sparc_align_funcs; /* Define this to set the endianness to use in libgcc2.c, which can not depend on target_flags. */ -#if defined (__LITTLE_ENDIAN__) +#if defined (__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN_DATA__) #define LIBGCC2_WORDS_BIG_ENDIAN 0 #else #define LIBGCC2_WORDS_BIG_ENDIAN 1 @@ -912,14 +1003,17 @@ if (TARGET_ARCH64 \ #define CONDITIONAL_REGISTER_USAGE \ do \ { \ - if (TARGET_ARCH32) \ + if (flag_pic) \ { \ - fixed_regs[5] = 1; \ + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ + call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ } \ - else \ + if (TARGET_ARCH32) \ { \ - fixed_regs[1] = 1; \ + fixed_regs[5] = 1; \ } \ + if (TARGET_LIVE_G0) \ + fixed_regs[0] = 0; \ if (! TARGET_V9) \ { \ int regno; \ @@ -959,11 +1053,6 @@ do \ fixed_regs[1] = 1; \ fixed_regs[2] = 1; \ } \ - if (flag_pic != 0) \ - { \ - fixed_regs[23] = 1; \ - call_used_regs[23] = 1; \ - } \ } \ while (0) @@ -987,9 +1076,18 @@ while (0) /* A subreg in 64 bit mode will have the wrong offset for a floating point register. The least significant part is at offset 1, compared to 0 for - integer registers. */ + integer registers. This only applies when FMODE is a larger mode. + We also need to handle a special case of TF-->DF conversions. */ #define ALTER_HARD_SUBREG(TMODE, WORD, FMODE, REGNO) \ - (TARGET_ARCH64 && (REGNO) >= 32 && (REGNO) < 96 && (TMODE) == SImode ? 1 : ((REGNO) + (WORD))) + (TARGET_ARCH64 \ + && (REGNO) >= SPARC_FIRST_FP_REG \ + && (REGNO) <= SPARC_LAST_V9_FP_REG \ + && (TMODE) == SImode \ + && !((FMODE) == QImode || (FMODE) == HImode) \ + ? ((REGNO) + 1) \ + : ((TMODE) == DFmode && (FMODE) == TFmode) \ + ? ((REGNO) + ((WORD) * 2)) \ + : ((REGNO) + (WORD))) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. See sparc.c for how we initialize this. */ @@ -1080,7 +1178,6 @@ extern int sparc_mode_class[]; #define PIC_OFFSET_TABLE_REGNUM 23 -#define INITIALIZE_PIC initialize_pic () #define FINALIZE_PIC finalize_pic () /* Pick a default value we can notice from override_options: @@ -1348,37 +1445,60 @@ extern char leaf_reg_remap[]; in class CLASS, return the class of reg to actually use. In general this is just CLASS; but on some machines in some cases it is preferable to use a more restrictive class. */ -/* We can't load constants into FP registers. We can't load any FP constant - if an 'E' constraint fails to match it. */ +/* - We can't load constants into FP registers. We can't load any FP + constant if an 'E' constraint fails to match it. + - Try and reload integer constants (symbolic or otherwise) back into + registers directly, rather than having them dumped to memory. */ + #define PREFERRED_RELOAD_CLASS(X,CLASS) \ (CONSTANT_P (X) \ - && (FP_REG_CLASS_P (CLASS) \ + ? ((FP_REG_CLASS_P (CLASS) \ || (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ && (HOST_FLOAT_FORMAT != IEEE_FLOAT_FORMAT \ || HOST_BITS_PER_INT != BITS_PER_WORD))) \ - ? NO_REGS : (CLASS)) + ? NO_REGS \ + : (!FP_REG_CLASS_P (CLASS) \ + && GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \ + ? GENERAL_REGS \ + : (CLASS)) \ + : (CLASS)) /* Return the register class of a scratch register needed to load IN into a register of class CLASS in MODE. - On the SPARC, when PIC, we need a temporary when loading some addresses - into a register. - - Also, we need a temporary when loading/storing a HImode/QImode value + We need a temporary when loading/storing a HImode/QImode value between memory and the FPU registers. This can happen when combine puts a paradoxical subreg in a float/fix conversion insn. */ #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \ + ((FP_REG_CLASS_P (CLASS) \ + && ((MODE) == HImode || (MODE) == QImode) \ && (GET_CODE (IN) == MEM \ - || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ - && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS) + || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ + && true_regnum (IN) == -1))) \ + ? GENERAL_REGS \ + : (((TARGET_CM_MEDANY \ + && symbolic_operand ((IN), (MODE))) \ + || (TARGET_CM_EMBMEDANY \ + && text_segment_operand ((IN), (MODE)))) \ + && !flag_pic) \ + ? GENERAL_REGS \ + : NO_REGS) #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, IN) \ - ((FP_REG_CLASS_P (CLASS) && ((MODE) == HImode || (MODE) == QImode) \ - && (GET_CODE (IN) == MEM \ - || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ - && true_regnum (IN) == -1))) ? GENERAL_REGS : NO_REGS) + ((FP_REG_CLASS_P (CLASS) \ + && ((MODE) == HImode || (MODE) == QImode) \ + && (GET_CODE (IN) == MEM \ + || ((GET_CODE (IN) == REG || GET_CODE (IN) == SUBREG) \ + && true_regnum (IN) == -1))) \ + ? GENERAL_REGS \ + : (((TARGET_CM_MEDANY \ + && symbolic_operand ((IN), (MODE))) \ + || (TARGET_CM_EMBMEDANY \ + && text_segment_operand ((IN), (MODE)))) \ + && !flag_pic) \ + ? GENERAL_REGS \ + : NO_REGS) /* On SPARC it is not possible to directly move data between GENERAL_REGS and FP_REGS. */ @@ -1459,6 +1579,10 @@ extern char leaf_reg_remap[]; (TARGET_ARCH64 ? (SPARC_STACK_BIAS + 16 * UNITS_PER_WORD) \ : (STRUCT_VALUE_OFFSET + UNITS_PER_WORD)) +/* Offset from the argument pointer register value to the CFA. */ + +#define ARG_POINTER_CFA_OFFSET SPARC_STACK_BIAS + /* When a parameter is passed in a register, stack space is still allocated for it. !v9: All 6 possible integer registers have backing store allocated. @@ -1714,246 +1838,38 @@ do { \ to do a "save" insn. The decision about whether or not to do this is made in regclass.c. */ -extern int leaf_function; #define FUNCTION_PROLOGUE(FILE, SIZE) \ (TARGET_FLAT ? sparc_flat_output_function_prologue (FILE, (int)SIZE) \ - : output_function_prologue (FILE, (int)SIZE, leaf_function)) + : output_function_prologue (FILE, (int)SIZE, \ + current_function_uses_only_leaf_regs)) /* Output assembler code to FILE to increment profiler label # LABELNO - for profiling a function entry. - - 32 bit sparc uses %g2 as the STATIC_CHAIN_REGNUM which gets clobbered - during profiling so we need to save/restore it around the call to mcount. - We're guaranteed that a save has just been done, and we use the space - allocated for intreg/fpreg value passing. */ - -#define FUNCTION_PROFILER(FILE, LABELNO) \ - do { \ - char buf[20]; \ - ASM_GENERATE_INTERNAL_LABEL (buf, "LP", (LABELNO)); \ - if (! TARGET_ARCH64) \ - fputs ("\tst %g2,[%fp-4]\n", FILE); \ - fputs ("\tsethi %hi(", FILE); \ - assemble_name (FILE, buf); \ - fputs ("),%o0\n", FILE); \ - fputs ("\tcall mcount\n\tadd %o0,%lo(", FILE); \ - assemble_name (FILE, buf); \ - fputs ("),%o0\n", FILE); \ - if (! TARGET_ARCH64) \ - fputs ("\tld [%fp-4],%g2\n", FILE); \ - } while (0) - -/* There are three profiling modes for basic blocks available. - The modes are selected at compile time by using the options - -a or -ax of the gnu compiler. - The variable `profile_block_flag' will be set according to the - selected option. + for profiling a function entry. */ - profile_block_flag == 0, no option used: +#define FUNCTION_PROFILER(FILE, LABELNO) \ + sparc_function_profiler(FILE, LABELNO) - No profiling done. +/* Set the name of the mcount function for the system. */ - profile_block_flag == 1, -a option used. - - Count frequency of execution of every basic block. - - profile_block_flag == 2, -ax option used. - - Generate code to allow several different profiling modes at run time. - Available modes are: - Produce a trace of all basic blocks. - Count frequency of jump instructions executed. - In every mode it is possible to start profiling upon entering - certain functions and to disable profiling of some other functions. - - The result of basic-block profiling will be written to a file `bb.out'. - If the -ax option is used parameters for the profiling will be read - from file `bb.in'. - -*/ +#define MCOUNT_FUNCTION "*mcount" /* The following macro shall output assembler code to FILE - to initialize basic-block profiling. - - If profile_block_flag == 2 - - Output code to call the subroutine `__bb_init_trace_func' - and pass two parameters to it. The first parameter is - the address of a block allocated in the object module. - The second parameter is the number of the first basic block - of the function. + to initialize basic-block profiling. */ - The name of the block is a local symbol made with this statement: - - ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); - - Of course, since you are writing the definition of - `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you - can take a short cut in the definition of this macro and use the - name that you know will result. - - The number of the first basic block of the function is - passed to the macro in BLOCK_OR_LABEL. - - If described in a virtual assembler language the code to be - output looks like: - - parameter1 <- LPBX0 - parameter2 <- BLOCK_OR_LABEL - call __bb_init_trace_func - - else if profile_block_flag != 0 - - Output code to call the subroutine `__bb_init_func' - and pass one single parameter to it, which is the same - as the first parameter to `__bb_init_trace_func'. - - The first word of this parameter is a flag which will be nonzero if - the object module has already been initialized. So test this word - first, and do not call `__bb_init_func' if the flag is nonzero. - Note: When profile_block_flag == 2 the test need not be done - but `__bb_init_trace_func' *must* be called. - - BLOCK_OR_LABEL may be used to generate a label number as a - branch destination in case `__bb_init_func' will not be called. - - If described in a virtual assembler language the code to be - output looks like: - - cmp (LPBX0),0 - jne local_label - parameter1 <- LPBX0 - call __bb_init_func -local_label: - -*/ - -#define FUNCTION_BLOCK_PROFILER(FILE, BLOCK_OR_LABEL) \ -do \ - { \ - int bol = (BLOCK_OR_LABEL); \ - switch (profile_block_flag) \ - { \ - case 2: \ - fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tor %%o0,%%lo(LPBX0),%%o0\n\tsethi %%hi(%d),%%o1\n\tcall ___bb_init_trace_func\n\tor %%o1,%%lo(%d),%%o1\n",\ - bol, bol); \ - break; \ - default: \ - fprintf (FILE, "\tsethi %%hi(LPBX0),%%o0\n\tld [%%lo(LPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(LPBX0),%%o0\n\tcall ___bb_init_func\n\tnop\nLPY%d:\n",\ - bol, bol); \ - break; \ - } \ - } \ -while (0) +#define FUNCTION_BLOCK_PROFILER(FILE, BLOCK_OR_LABEL) \ + sparc_function_block_profiler(FILE, BLOCK_OR_LABEL) /* The following macro shall output assembler code to FILE - to increment a counter associated with basic block number BLOCKNO. - - If profile_block_flag == 2 - - Output code to initialize the global structure `__bb' and - call the function `__bb_trace_func' which will increment the - counter. - - `__bb' consists of two words. In the first word the number - of the basic block has to be stored. In the second word - the address of a block allocated in the object module - has to be stored. + to increment a counter associated with basic block number BLOCKNO. */ - The basic block number is given by BLOCKNO. - - The address of the block is given by the label created with - - ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); - - by FUNCTION_BLOCK_PROFILER. - - Of course, since you are writing the definition of - `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you - can take a short cut in the definition of this macro and use the - name that you know will result. - - If described in a virtual assembler language the code to be - output looks like: - - move BLOCKNO -> (__bb) - move LPBX0 -> (__bb+4) - call __bb_trace_func - - Note that function `__bb_trace_func' must not change the - machine state, especially the flag register. To grant - this, you must output code to save and restore registers - either in this macro or in the macros MACHINE_STATE_SAVE - and MACHINE_STATE_RESTORE. The last two macros will be - used in the function `__bb_trace_func', so you must make - sure that the function prologue does not change any - register prior to saving it with MACHINE_STATE_SAVE. - - else if profile_block_flag != 0 - - Output code to increment the counter directly. - Basic blocks are numbered separately from zero within each - compiled object module. The count associated with block number - BLOCKNO is at index BLOCKNO in an array of words; the name of - this array is a local symbol made with this statement: - - ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); - - Of course, since you are writing the definition of - `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you - can take a short cut in the definition of this macro and use the - name that you know will result. - - If described in a virtual assembler language, the code to be - output looks like: - - inc (LPBX2+4*BLOCKNO) - -*/ - -#define BLOCK_PROFILER(FILE, BLOCKNO) \ -do \ - { \ - int blockn = (BLOCKNO); \ - switch (profile_block_flag) \ - { \ - case 2: \ - fprintf (FILE, "\tsethi %%hi(___bb),%%g1\n\tsethi %%hi(%d),%%g2\n\tor %%g2,%%lo(%d),%%g2\n\tst %%g2,[%%lo(___bb)+%%g1]\n\tsethi %%hi(LPBX0),%%g2\n\tor %%g2,%%lo(LPBX0),%%g2\n\tadd 4,%%g1,%%g1\n\tst %%g2,[%%lo(___bb)+%%g1]\n\tmov %%o7,%%g2\n\tcall ___bb_trace_func\n\tnop\n\tmov %%g2,%%o7\n",\ - blockn, blockn); \ - break; \ - default: \ - fprintf (FILE, "\tsethi %%hi(LPBX2+%d),%%g1\n\tld [%%lo(LPBX2+%d)+%%g1],%%g2\n\ -\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(LPBX2+%d)+%%g1]\n", \ - 4 * blockn, 4 * blockn, 4 * blockn); \ - break; \ - } \ - } \ -while(0) +#define BLOCK_PROFILER(FILE, BLOCKNO) \ + sparc_block_profiler (FILE, BLOCKNO) /* The following macro shall output assembler code to FILE - to indicate a return from function during basic-block profiling. - - If profiling_block_flag == 2: - - Output assembler code to call function `__bb_trace_ret'. - - Note that function `__bb_trace_ret' must not change the - machine state, especially the flag register. To grant - this, you must output code to save and restore registers - either in this macro or in the macros MACHINE_STATE_SAVE_RET - and MACHINE_STATE_RESTORE_RET. The last two macros will be - used in the function `__bb_trace_ret', so you must make - sure that the function prologue does not change any - register prior to saving it with MACHINE_STATE_SAVE_RET. - - else if profiling_block_flag != 0: - - The macro will not be used, so it need not distinguish - these cases. -*/ + to indicate a return from function during basic-block profiling. */ #define FUNCTION_BLOCK_PROFILER_EXIT(FILE) \ - fprintf (FILE, "\tcall ___bb_trace_ret\n\tnop\n" ); + sparc_function_block_profiler_exit(FILE) /* The function `__bb_trace_func' is called in every basic block and is not allowed to change the machine state. Saving (restoring) @@ -2092,7 +2008,8 @@ extern union tree_node *current_function_decl; #define FUNCTION_EPILOGUE(FILE, SIZE) \ (TARGET_FLAT ? sparc_flat_output_function_epilogue (FILE, (int)SIZE) \ - : output_function_epilogue (FILE, (int)SIZE, leaf_function)) + : output_function_epilogue (FILE, (int)SIZE, \ + current_function_uses_only_leaf_regs)) #define DELAY_SLOTS_FOR_EPILOGUE \ (TARGET_FLAT ? sparc_flat_epilogue_delay_slots () : 1) @@ -2190,11 +2107,11 @@ extern struct rtx_def *sparc_builtin_saveregs (); /* Addressing modes, and classification of registers for them. */ -/* #define HAVE_POST_INCREMENT */ -/* #define HAVE_POST_DECREMENT */ +/* #define HAVE_POST_INCREMENT 0 */ +/* #define HAVE_POST_DECREMENT 0 */ -/* #define HAVE_PRE_DECREMENT */ -/* #define HAVE_PRE_INCREMENT */ +/* #define HAVE_PRE_DECREMENT 0 */ +/* #define HAVE_PRE_INCREMENT 0 */ /* Macros to check register numbers against specific register classes. */ @@ -2250,10 +2167,13 @@ extern struct rtx_def *sparc_builtin_saveregs (); #define LEGITIMATE_PIC_OPERAND_P(X) (! pic_address_needs_scratch (X)) /* Nonzero if the constant value X is a legitimate general operand. - Anything can be made to work except floating point constants. */ + 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) +#define LEGITIMATE_CONSTANT_P(X) \ + (GET_CODE (X) != CONST_DOUBLE || GET_MODE (X) == VOIDmode || \ + (TARGET_VIS && (GET_MODE (X) == SFmode || GET_MODE (X) == DFmode) && \ + fp_zero_operand (X))) /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and check its validity for a certain class. @@ -2268,15 +2188,13 @@ extern struct rtx_def *sparc_builtin_saveregs (); After reload, it makes no difference, since pseudo regs have been eliminated by then. */ -/* Optional extra constraints for this machine. Borrowed from romp.h. +/* Optional extra constraints for this machine. - For the SPARC, `Q' means that this is a memory operand but not a - symbolic memory operand. Note that an unassigned pseudo register - is such a memory operand. Needed because reload will generate - these things in insns and then not re-recognize the insns, causing - constrain_operands to fail. + 'T' handles memory addresses where the alignment is known to + be at least 8 bytes. - `S' handles constraints for calls. ??? So where is it? */ + `U' handles all pseudo registers or a hard even numbered + integer register, needed for ldd/std instructions. */ #ifndef REG_OK_STRICT @@ -2292,17 +2210,11 @@ extern struct rtx_def *sparc_builtin_saveregs (); /* 'T', 'U' are for aligned memory loads which aren't needed for v9. */ #define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' \ - ? ((GET_CODE (OP) == MEM \ - && memory_address_p (GET_MODE (OP), XEXP (OP, 0)) \ - && ! symbolic_memory_operand (OP, VOIDmode)) \ - || (reload_in_progress && GET_CODE (OP) == REG \ - && REGNO (OP) >= FIRST_PSEUDO_REGISTER)) \ - : (! TARGET_ARCH64 && (C) == 'T') \ - ? (mem_aligned_8 (OP)) \ - : (! TARGET_ARCH64 && (C) == 'U') \ - ? (register_ok_for_ldd (OP)) \ - : 0) + ((! TARGET_ARCH64 && (C) == 'T') \ + ? (mem_min_alignment (OP, 8)) \ + : ((! TARGET_ARCH64 && (C) == 'U') \ + ? (register_ok_for_ldd (OP)) \ + : 0)) #else @@ -2312,19 +2224,14 @@ extern struct rtx_def *sparc_builtin_saveregs (); #define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) #define EXTRA_CONSTRAINT(OP, C) \ - ((C) == 'Q' \ - ? (GET_CODE (OP) == REG \ - ? (REGNO (OP) >= FIRST_PSEUDO_REGISTER \ - && reg_renumber[REGNO (OP)] < 0) \ - : GET_CODE (OP) == MEM) \ - : (! TARGET_ARCH64 && (C) == 'T') \ - ? mem_aligned_8 (OP) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \ - : (! TARGET_ARCH64 && (C) == 'U') \ - ? (GET_CODE (OP) == REG \ - && (REGNO (OP) < FIRST_PSEUDO_REGISTER \ - || reg_renumber[REGNO (OP)] >= 0) \ - && register_ok_for_ldd (OP)) \ - : 0) + ((! TARGET_ARCH64 && (C) == 'T') \ + ? mem_min_alignment (OP, 8) && strict_memory_address_p (Pmode, XEXP (OP, 0)) \ + : ((! TARGET_ARCH64 && (C) == 'U') \ + ? (GET_CODE (OP) == REG \ + && (REGNO (OP) < FIRST_PSEUDO_REGISTER \ + || reg_renumber[REGNO (OP)] >= 0) \ + && register_ok_for_ldd (OP)) \ + : 0)) #endif /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression @@ -2373,13 +2280,32 @@ extern struct rtx_def *sparc_builtin_saveregs (); } \ else if (RTX_OK_FOR_BASE_P (op0)) \ { \ - if (RTX_OK_FOR_INDEX_P (op1) \ + 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))) \ || RTX_OK_FOR_OFFSET_P (op1)) \ goto ADDR; \ } \ else if (RTX_OK_FOR_BASE_P (op1)) \ { \ - if (RTX_OK_FOR_INDEX_P (op0) \ + if ((RTX_OK_FOR_INDEX_P (op0) \ + /* See the previous comment. */ \ + && (MODE != TFmode \ + || (TARGET_FPU && TARGET_ARCH64 \ + && TARGET_V9 \ + && TARGET_HARD_QUAD))) \ || RTX_OK_FOR_OFFSET_P (op0)) \ goto ADDR; \ } \ @@ -2392,8 +2318,8 @@ extern struct rtx_def *sparc_builtin_saveregs (); && 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. */ \ - && MODE != TFmode) \ + 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)) \ @@ -2440,11 +2366,43 @@ extern struct rtx_def *legitimize_pic_address (); 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) = gen_rtx_LO_SUM (Pmode, \ - copy_to_mode_reg (Pmode, gen_rtx_HIGH (Pmode, X)), X); \ + (X) = copy_to_suggested_reg (X, NULL_RTX, Pmode); \ 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 + macro is used in only one place: `find_reloads_address' in reload.c. + + For Sparc 32, we wish to handle addresses by splitting them into + HIGH+LO_SUM pairs, retaining the LO_SUM in the memory reference. + This cuts the number of extra insns by one. + + Do nothing when generating PIC code and the address is a + symbolic operand or requires a scratch register. */ + +#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \ +do { \ + /* Decompose SImode constants into hi+lo_sum. We do have to \ + rerecognize what we produce, so be careful. */ \ + if (CONSTANT_P (X) \ + && (MODE != TFmode || TARGET_V9) \ + && GET_MODE (X) == SImode \ + && GET_CODE (X) != LO_SUM && GET_CODE (X) != HIGH \ + && ! (flag_pic \ + && (symbolic_operand (X, Pmode) \ + || pic_address_needs_scratch (X)))) \ + { \ + X = gen_rtx_LO_SUM (GET_MODE (X), \ + gen_rtx_HIGH (GET_MODE (X), X), X); \ + push_reload (XEXP (X, 0), NULL_RTX, &XEXP (X, 0), NULL_PTR, \ + BASE_REG_CLASS, GET_MODE (X), VOIDmode, 0, 0, \ + OPNUM, TYPE); \ + goto WIN; \ + } \ + /* ??? 64-bit reloads. */ \ +} 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 SPARC this is never true. */ @@ -2463,7 +2421,17 @@ extern struct rtx_def *legitimize_pic_address (); /* Specify the machine mode that this machine uses for the index in the tablejump instruction. */ -#define CASE_VECTOR_MODE Pmode +/* If we ever implement any of the full models (such as CM_FULLANY), + this has to be DImode in that case */ +#ifdef HAVE_GAS_SUBSECTION_ORDERING +#define CASE_VECTOR_MODE \ +(! TARGET_PTR64 ? SImode : flag_pic ? SImode : TARGET_CM_MEDLOW ? SImode : DImode) +#else +/* If assembler does not have working .subsection -1, we use DImode for pic, as otherwise + we have to sign extend which slows things down. */ +#define CASE_VECTOR_MODE \ +(! TARGET_PTR64 ? SImode : flag_pic ? DImode : TARGET_CM_MEDLOW ? SImode : DImode) +#endif /* Define as C expression which evaluates to nonzero if the tablejump instruction expects the table to contain offsets from the address of the @@ -2597,25 +2565,26 @@ extern struct rtx_def *legitimize_pic_address (); #define MULSI3_LIBCALL "*.umul" /* Define library calls for quad FP operations. These are all part of the - SPARC 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" + SPARC ABI. + ??? ARCH64 still does not work as the _Qp_* routines take pointers. */ +#define ADDTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_add" : "_Q_add") +#define SUBTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_sub" : "_Q_sub") +#define NEGTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_neg" : "_Q_neg") +#define MULTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_mul" : "_Q_mul") +#define DIVTF3_LIBCALL (TARGET_ARCH64 ? "_Qp_div" : "_Q_div") +#define FLOATSITF2_LIBCALL (TARGET_ARCH64 ? "_Qp_itoq" : "_Q_itoq") +#define FIX_TRUNCTFSI2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtoi" : "_Q_qtoi") +#define FIXUNS_TRUNCTFSI2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtoui" : "_Q_qtou") +#define EXTENDSFTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_stoq" : "_Q_stoq") +#define TRUNCTFSF2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtos" : "_Q_qtos") +#define EXTENDDFTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_dtoq" : "_Q_dtoq") +#define TRUNCTFDF2_LIBCALL (TARGET_ARCH64 ? "_Qp_qtod" : "_Q_qtod") +#define EQTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_feq" : "_Q_feq") +#define NETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fne" : "_Q_fne") +#define GTTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fgt" : "_Q_fgt") +#define GETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fge" : "_Q_fge") +#define LTTF2_LIBCALL (TARGET_ARCH64 ? "_Qp_flt" : "_Q_flt") +#define LETF2_LIBCALL (TARGET_ARCH64 ? "_Qp_fle" : "_Q_fle") /* 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, @@ -2681,9 +2650,6 @@ extern struct rtx_def *legitimize_pic_address (); return 0; \ return 8; -/* Compute the cost of an address. For the sparc, all valid addresses are - the same cost. */ - #define ADDRESS_COST(RTX) 1 /* Compute extra cost of moving data between one register class @@ -2704,11 +2670,17 @@ extern struct rtx_def *legitimize_pic_address (); #define RTX_COSTS(X,CODE,OUTER_CODE) \ case MULT: \ + if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + return (GET_MODE (X) == DImode ? \ + COSTS_N_INSNS (34) : COSTS_N_INSNS (19)); \ return TARGET_HARD_MUL ? COSTS_N_INSNS (5) : COSTS_N_INSNS (25); \ case DIV: \ case UDIV: \ case MOD: \ case UMOD: \ + if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + return (GET_MODE (X) == DImode ? \ + COSTS_N_INSNS (68) : COSTS_N_INSNS (37)); \ return COSTS_N_INSNS (25); \ /* Make FLOAT and FIX more expensive than CONST_DOUBLE,\ so that cse will favor the latter. */ \ @@ -2719,12 +2691,26 @@ extern struct rtx_def *legitimize_pic_address (); #define ISSUE_RATE sparc_issue_rate() /* Adjust the cost of dependencies. */ -#define ADJUST_COST(INSN,LINK,DEP,COST) \ - if (sparc_cpu == PROCESSOR_SUPERSPARC) \ - (COST) = supersparc_adjust_cost (INSN, LINK, DEP, COST); \ - else if (sparc_cpu == PROCESSOR_ULTRASPARC) \ - (COST) = ultrasparc_adjust_cost (INSN, LINK, DEP, COST); \ - else +#define ADJUST_COST(INSN,LINK,DEP,COST) \ + sparc_adjust_cost(INSN, LINK, DEP, COST) + +extern void ultrasparc_sched_reorder (); +extern void ultrasparc_sched_init (); +extern int ultrasparc_variable_issue (); + +#define MD_SCHED_INIT(DUMP, SCHED_VERBOSE) \ + if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + ultrasparc_sched_init (DUMP, SCHED_VERBOSE) + +#define MD_SCHED_REORDER(DUMP, SCHED_VERBOSE, READY, N_READY) \ + if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + ultrasparc_sched_reorder (DUMP, SCHED_VERBOSE, READY, N_READY) + +#define MD_SCHED_VARIABLE_ISSUE(DUMP, SCHED_VERBOSE, INSN, CAN_ISSUE_MORE) \ + if (sparc_cpu == PROCESSOR_ULTRASPARC) \ + (CAN_ISSUE_MORE) = ultrasparc_variable_issue (INSN); \ + else \ + (CAN_ISSUE_MORE)-- /* Conditional branches with empty delay slots have a length of two. */ #define ADJUST_INSN_LENGTH(INSN, LENGTH) \ @@ -2925,13 +2911,23 @@ extern struct rtx_def *legitimize_pic_address (); #define ASM_OUTPUT_BYTE(FILE,VALUE) \ fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE)) +/* This is how we hook in and defer the case-vector until the end of + the function. */ +extern void sparc_defer_case_vector (); + +#define ASM_OUTPUT_ADDR_VEC(LAB,VEC) \ + sparc_defer_case_vector ((LAB),(VEC), 0) + +#define ASM_OUTPUT_ADDR_DIFF_VEC(LAB,VEC) \ + sparc_defer_case_vector ((LAB),(VEC), 1) + /* This is how to output an element of a case-vector that is absolute. */ #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ do { \ char label[30]; \ ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \ - if (Pmode == SImode) \ + if (CASE_VECTOR_MODE == SImode) \ fprintf (FILE, "\t.word\t"); \ else \ fprintf (FILE, "\t.xword\t"); \ @@ -2945,8 +2941,8 @@ do { \ #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \ do { \ char label[30]; \ - ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \ - if (Pmode == SImode) \ + ASM_GENERATE_INTERNAL_LABEL (label, "L", (VALUE)); \ + if (CASE_VECTOR_MODE == SImode) \ fprintf (FILE, "\t.word\t"); \ else \ fprintf (FILE, "\t.xword\t"); \ @@ -2957,6 +2953,20 @@ do { \ fputc ('\n', FILE); \ } while (0) +/* This is what to output before and after case-vector (both + relative and absolute). If .subsection -1 works, we put case-vectors + at the beginning of the current section. */ + +#ifdef HAVE_GAS_SUBSECTION_ORDERING + +#define ASM_OUTPUT_ADDR_VEC_START(FILE) \ + fprintf(FILE, "\t.subsection\t-1\n") + +#define ASM_OUTPUT_ADDR_VEC_END(FILE) \ + fprintf(FILE, "\t.previous\n") + +#endif + /* This is how to output an assembler line that says to advance the location counter to a multiple of 2**LOG bytes. */ @@ -3105,7 +3115,6 @@ do { \ else if (GET_CODE (index) == REG) \ fprintf (FILE, "+%s", reg_names[REGNO (index)]); \ else if (GET_CODE (index) == SYMBOL_REF \ - || GET_CODE (index) == LABEL_REF \ || GET_CODE (index) == CONST) \ fputc ('+', FILE), output_addr_const (FILE, index); \ else abort (); \ @@ -3121,7 +3130,10 @@ do { \ else if (GET_CODE (addr) == LO_SUM) \ { \ output_operand (XEXP (addr, 0), 0); \ - fputs ("+%lo(", FILE); \ + if (TARGET_CM_MEDMID) \ + fputs ("+%l44(", FILE); \ + else \ + fputs ("+%lo(", FILE); \ output_address (XEXP (addr, 1)); \ fputc (')', FILE); \ } \ @@ -3148,46 +3160,49 @@ do { \ /* Define the codes that are matched by predicates in sparc.c. */ -#define PREDICATE_CODES \ -{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ -{"fp_zero_operand", {CONST_DOUBLE}}, \ -{"intreg_operand", {SUBREG, REG}}, \ -{"fcc_reg_operand", {REG}}, \ -{"icc_or_fcc_reg_operand", {REG}}, \ -{"restore_operand", {REG}}, \ -{"call_operand", {MEM}}, \ -{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, ADDRESSOF, \ - SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \ -{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \ -{"symbolic_memory_operand", {SUBREG, MEM}}, \ -{"label_ref_operand", {LABEL_REF}}, \ -{"sp64_medium_pic_operand", {CONST}}, \ -{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \ -{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \ -{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \ -{"sparc_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, MEM}}, \ -{"move_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE, MEM}}, \ -{"splittable_symbolic_memory_operand", {MEM}}, \ -{"splittable_immediate_memory_operand", {MEM}}, \ -{"eq_or_neq", {EQ, NE}}, \ -{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \ -{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \ -{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \ -{"v8plus_regcmp_op", {EQ, NE}}, \ -{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \ -{"cc_arithop", {AND, IOR, XOR}}, \ -{"cc_arithopn", {AND, IOR}}, \ -{"arith_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ -{"arith11_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ -{"arith10_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}}, \ -{"arith_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ -{"arith11_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ -{"arith10_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \ -{"small_int", {CONST_INT, CONSTANT_P_RTX}}, \ -{"uns_small_int", {CONST_INT, CONSTANT_P_RTX}}, \ -{"uns_arith_operand", {SUBREG, REG, CONST_INT, CONSTANT_P_RTX}}, \ -{"clobbered_register", {REG}}, - +#define PREDICATE_CODES \ +{"reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"fp_zero_operand", {CONST_DOUBLE}}, \ +{"intreg_operand", {SUBREG, REG}}, \ +{"fcc_reg_operand", {REG}}, \ +{"icc_or_fcc_reg_operand", {REG}}, \ +{"restore_operand", {REG}}, \ +{"call_operand", {MEM}}, \ +{"call_operand_address", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE, \ + ADDRESSOF, SUBREG, REG, PLUS, LO_SUM, CONST_INT}}, \ +{"symbolic_operand", {SYMBOL_REF, LABEL_REF, CONST, CONST_DOUBLE}}, \ +{"symbolic_memory_operand", {SUBREG, MEM}}, \ +{"label_ref_operand", {LABEL_REF}}, \ +{"sp64_medium_pic_operand", {CONST}}, \ +{"data_segment_operand", {SYMBOL_REF, PLUS, CONST}}, \ +{"text_segment_operand", {LABEL_REF, SYMBOL_REF, PLUS, CONST}}, \ +{"reg_or_nonsymb_mem_operand", {SUBREG, REG, MEM}}, \ +{"splittable_symbolic_memory_operand", {MEM}}, \ +{"splittable_immediate_memory_operand", {MEM}}, \ +{"eq_or_neq", {EQ, NE}}, \ +{"normal_comp_operator", {GE, GT, LE, LT, GTU, LEU}}, \ +{"noov_compare_op", {NE, EQ, GE, GT, LE, LT, GEU, GTU, LEU, LTU}}, \ +{"v9_regcmp_op", {EQ, NE, GE, LT, LE, GT}}, \ +{"extend_op", {SIGN_EXTEND, ZERO_EXTEND}}, \ +{"cc_arithop", {AND, IOR, XOR}}, \ +{"cc_arithopn", {AND, IOR}}, \ +{"arith_operand", {SUBREG, REG, CONST_INT}}, \ +{"arith_add_operand", {SUBREG, REG, CONST_INT}}, \ +{"arith11_operand", {SUBREG, REG, CONST_INT}}, \ +{"arith10_operand", {SUBREG, REG, CONST_INT}}, \ +{"arith_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"arith_double_add_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"arith11_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"arith10_double_operand", {SUBREG, REG, CONST_INT, CONST_DOUBLE}}, \ +{"small_int", {CONST_INT}}, \ +{"small_int_or_double", {CONST_INT, CONST_DOUBLE}}, \ +{"uns_small_int", {CONST_INT}}, \ +{"uns_arith_operand", {SUBREG, REG, CONST_INT}}, \ +{"clobbered_register", {REG}}, \ +{"input_operand", {SUBREG, REG, CONST_INT, MEM, CONST}}, \ +{"zero_operand", {CONST_INT}}, \ +{"const64_operand", {CONST_INT, CONST_DOUBLE}}, \ +{"const64_high_operand", {CONST_INT, CONST_DOUBLE}}, /* The number of Pmode words for the setjmp buffer. */ #define JMP_BUF_SIZE 12 @@ -3196,17 +3211,15 @@ do { \ /* Declare functions defined in sparc.c and used in templates. */ -extern char *doublemove_string (); -extern char *output_block_move (); +extern void sparc_emit_set_const32 (); +extern void sparc_emit_set_const64 (); +extern void sparc_emit_set_symbolic_const64 (); +extern int sparc_splitdi_legitimate (); +extern int sparc_absnegfloat_split_legitimate (); + extern char *output_cbranch (); -extern char *output_fp_move_double (); -extern char *output_fp_move_quad (); -extern char *output_move_double (); -extern char *output_move_quad (); -extern char *output_return (); -extern char *output_scc_insn (); +extern const char *output_return (); extern char *output_v9branch (); -extern char *singlemove_string (); extern void emit_v9_brxx_insn (); extern void finalize_pic (); @@ -3224,8 +3237,16 @@ extern int arith10_operand (); extern int arith11_double_operand (); extern int arith11_operand (); extern int arith_double_operand (); +extern int arith_double_4096_operand (); +extern int arith_double_add_operand (); extern int arith_operand (); +extern int arith_4096_operand (); +extern int arith_add_operand (); extern int call_operand_address (); +extern int input_operand (); +extern int zero_operand (); +extern int const64_operand (); +extern int const64_high_operand (); extern int cc_arithop (); extern int cc_arithopn (); extern int check_pic (); @@ -3239,8 +3260,7 @@ extern int fcc_reg_operand (); extern int fp_zero_operand (); extern int icc_or_fcc_reg_operand (); extern int label_ref_operand (); -extern int mem_aligned_8 (); -extern int move_operand (); +extern int mem_min_alignment (); extern int noov_compare_op (); extern int pic_address_needs_scratch (); extern int reg_or_0_operand (); @@ -3251,27 +3271,29 @@ extern int registers_ok_for_ldd_peep (); extern int restore_operand (); extern int short_branch (); extern int small_int (); +extern int small_int_or_double (); extern int sp64_medium_pic_operand (); extern int sparc_flat_eligible_for_epilogue_delay (); extern int sparc_flat_epilogue_delay_slots (); extern int sparc_issue_rate (); -extern int sparc_operand (); extern int splittable_immediate_memory_operand (); extern int splittable_symbolic_memory_operand (); -extern int supersparc_adjust_cost (); +extern int sparc_adjust_cost (); extern int symbolic_memory_operand (); extern int symbolic_operand (); extern int text_segment_operand (); -extern int ultrasparc_adjust_cost (); extern int uns_small_int (); -extern int v8plus_regcmp_op (); -extern int v8plus_regcmp_p (); extern int v9_regcmp_op (); extern int v9_regcmp_p (); extern unsigned long sparc_flat_compute_frame_size (); extern unsigned long sparc_type_code (); +extern void sparc_function_profiler (); +extern void sparc_function_block_profiler (); +extern void sparc_block_profiler (); +extern void sparc_function_block_profiler_exit (); + extern char *sparc_v8plus_shift (); #ifdef __STDC__ diff --git a/contrib/gcc/config/sparc/sparc.md b/contrib/gcc/config/sparc/sparc.md index ccfde05..02170b7 100644 --- a/contrib/gcc/config/sparc/sparc.md +++ b/contrib/gcc/config/sparc/sparc.md @@ -1,5 +1,5 @@ ;;- Machine description for SPARC chip for GNU C compiler -;; Copyright (C) 1987, 88, 89, 92-96, 1997 Free Software Foundation, Inc. +;; Copyright (C) 1987, 88, 89, 92-98, 1999 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. @@ -23,6 +23,37 @@ ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. +;; Uses of UNSPEC and UNSPEC_VOLATILE in this file: +;; +;; UNSPEC: 0 movsi_{lo_sum,high}_pic +;; pic_lo_sum_di +;; pic_sethi_di +;; 1 update_return +;; 2 get_pc +;; 5 movsi_{,lo_sum_,high_}pic_label_ref +;; 6 seth44 +;; 7 setm44 +;; 8 setl44 +;; 9 sethh +;; 10 setlm +;; 11 embmedany_sethi, embmedany_brsum +;; 12 movsf_const_high +;; 13 embmedany_textuhi +;; 14 embmedany_texthi +;; 15 embmedany_textulo +;; 16 embmedany_textlo +;; 17 movsf_const_lo +;; 18 sethm +;; 19 setlo +;; +;; UNSPEC_VOLATILE: 0 blockage +;; 1 flush_register_windows +;; 2 goto_handler_and_restore +;; 3 goto_handler_and_restore_v9* +;; 4 flush +;; 5 nonlocal_goto_receiver +;; + ;; The upper 32 fp regs on the v9 can't hold SFmode values. To deal with this ;; a second register class, EXTRA_FP_REGS, exists for the v9 chip. The name ;; is a bit of a misnomer as it covers all 64 fp regs. The corresponding @@ -34,7 +65,7 @@ ;; Attribute for cpu type. ;; These must match the values for enum processor_type in sparc.h. -(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,sparclet,tsc701,v9,ultrasparc" +(define_attr "cpu" "v7,cypress,v8,supersparc,sparclite,f930,f934,hypersparc,sparclite86x,sparclet,tsc701,v9,ultrasparc" (const (symbol_ref "sparc_cpu_attr"))) ;; Attribute for the instruction set. @@ -128,8 +159,7 @@ [(eq_attr "in_call_delay" "true") (nil) (nil)]) (define_attr "leaf_function" "false,true" - (const (symbol_ref "leaf_function"))) - + (const (symbol_ref "current_function_uses_only_leaf_regs"))) (define_attr "in_return_delay" "false,true" (if_then_else (and (and (and (eq_attr "type" "move,load,sload,store,binary,ialu") @@ -315,6 +345,53 @@ (eq_attr "type" "imul")) 4 4) +;; ----- hypersparc/sparclite86x scheduling +;; The Hypersparc can issue 1 - 2 insns per cycle. The dual issue cases are: +;; L-Ld/St I-Int F-Float B-Branch LI/LF/LB/II/IF/IB/FF/FB +;; II/FF case is only when loading a 32 bit hi/lo constant +;; Single issue insns include call, jmpl, u/smul, u/sdiv, lda, sta, fcmp +;; Memory delivers its result in one cycle to IU + +(define_function_unit "memory" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "load,sload,fpload")) + 1 1) + +(define_function_unit "memory" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "store,fpstore")) + 2 1) + +(define_function_unit "fp_alu" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fp,fpmove,fpcmp")) + 1 1) + +(define_function_unit "fp_mds" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpmul")) + 1 1) + +(define_function_unit "fp_mds" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpdivs")) + 8 6) + +(define_function_unit "fp_mds" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpdivd")) + 12 10) + +(define_function_unit "fp_mds" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "fpsqrt")) + 17 15) + +(define_function_unit "fp_mds" 1 0 + (and (ior (eq_attr "cpu" "hypersparc") (eq_attr "cpu" "sparclite86x")) + (eq_attr "type" "imul")) + 17 15) + ;; ----- sparclet tsc701 scheduling ;; The tsc701 issues 1 insn per cycle. ;; Results may be written back out of order. @@ -370,21 +447,31 @@ (eq_attr "type" "store,fpstore")) 1 1) -(define_function_unit "ieu" 1 0 +(define_function_unit "ieuN" 2 0 (and (eq_attr "cpu" "ultrasparc") - (eq_attr "type" "ialu,binary,shift,compare,cmove,call")) + (eq_attr "type" "ialu,binary,move,unary,shift,compare,call,call_no_delay_slot,uncond_branch")) 1 1) -(define_function_unit "ieu_shift" 1 0 +(define_function_unit "ieu0" 1 0 (and (eq_attr "cpu" "ultrasparc") (eq_attr "type" "shift")) 1 1) -(define_function_unit "ieu_shift" 1 0 +(define_function_unit "ieu0" 1 0 (and (eq_attr "cpu" "ultrasparc") (eq_attr "type" "cmove")) 2 1) +(define_function_unit "ieu1" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "compare,call,call_no_delay_slot,uncond_branch")) + 1 1) + +(define_function_unit "cti" 1 0 + (and (eq_attr "cpu" "ultrasparc") + (eq_attr "type" "branch")) + 1 1) + ;; Timings; throughput/latency ;; FMOV 1/1 fmov, fabs, fneg ;; FMOVcc 1/2 @@ -395,6 +482,11 @@ ;; FSQRTs 12/12 ;; FSQRTd 22/22 ;; FCMP takes 1 cycle to branch, 2 cycles to conditional move. +;; +;; ??? This is really bogus because the timings really depend upon +;; who uses the result. We should record who the user is with +;; more descriptive 'type' attribute names and account for these +;; issues in ultrasparc_adjust_cost. (define_function_unit "fadd" 1 0 (and (eq_attr "cpu" "ultrasparc") @@ -426,17 +518,17 @@ (eq_attr "type" "fpcmove")) 2 1) -(define_function_unit "fadd" 1 0 +(define_function_unit "fmul" 1 0 (and (eq_attr "cpu" "ultrasparc") (eq_attr "type" "fpdivs")) 12 12) -(define_function_unit "fadd" 1 0 +(define_function_unit "fmul" 1 0 (and (eq_attr "cpu" "ultrasparc") (eq_attr "type" "fpdivd")) 22 22) -(define_function_unit "fadd" 1 0 +(define_function_unit "fmul" 1 0 (and (eq_attr "cpu" "ultrasparc") (eq_attr "type" "fpsqrt")) 12 12) @@ -475,7 +567,7 @@ [(set (reg:CCX 100) (compare:CCX (match_operand:DI 0 "register_operand" "") (match_operand:DI 1 "arith_double_operand" "")))] - "TARGET_ARCH64 || TARGET_V8PLUS" + "TARGET_ARCH64" " { sparc_compare_op0 = operands[0]; @@ -529,7 +621,7 @@ (compare:CC (match_operand:SI 0 "register_operand" "r") (match_operand:SI 1 "arith_operand" "rI")))] "" - "cmp %0,%1" + "cmp\\t%0, %1" [(set_attr "type" "compare")]) (define_insn "*cmpdi_sp64" @@ -537,42 +629,9 @@ (compare:CCX (match_operand:DI 0 "register_operand" "r") (match_operand:DI 1 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "cmp %0,%1" + "cmp\\t%0, %1" [(set_attr "type" "compare")]) -(define_insn "cmpdi_v8plus" - [(set (reg:CCX 100) - (compare:CCX (match_operand:DI 0 "register_operand" "r,r,r") - (match_operand:DI 1 "arith_double_operand" "J,I,r"))) - (clobber (match_scratch:SI 2 "=&h,&h,&h")) - (clobber (match_scratch:SI 3 "=X,X,&h"))] - "TARGET_V8PLUS" - "* -{ - /* The srl can be omitted if the value in the %L0 or %L1 is already - zero extended. */ - - output_asm_insn (\"sllx %H0,32,%2\", operands); - - if (sparc_check_64 (operands[0], insn) <= 0) - output_asm_insn (\"srl %L0,0,%L0\", operands); - - switch (which_alternative) - { - case 0: - return \"orcc %L0,%2,%%g0\"; - case 1: - return \"or %L0,%2,%2\;cmp %2,%1\"; - case 2: - if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn (\"srl %L1,0,%L1\", operands); - return \"sllx %H1,32,%3\;or %L0,%2,%2\;or %L1,%3,%3\;cmp %2,%3\"; - default: - abort(); - } -}" - [(set_attr "length" "3,4,7")]) - (define_insn "*cmpsf_fpe" [(set (match_operand:CCFPE 0 "fcc_reg_operand" "=c") (compare:CCFPE (match_operand:SF 1 "register_operand" "f") @@ -581,8 +640,8 @@ "* { if (TARGET_V9) - return \"fcmpes %0,%1,%2\"; - return \"fcmpes %1,%2\"; + return \"fcmpes\\t%0, %1, %2\"; + return \"fcmpes\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -594,8 +653,8 @@ "* { if (TARGET_V9) - return \"fcmped %0,%1,%2\"; - return \"fcmped %1,%2\"; + return \"fcmped\\t%0, %1, %2\"; + return \"fcmped\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -607,8 +666,8 @@ "* { if (TARGET_V9) - return \"fcmpeq %0,%1,%2\"; - return \"fcmpeq %1,%2\"; + return \"fcmpeq\\t%0, %1, %2\"; + return \"fcmpeq\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -620,8 +679,8 @@ "* { if (TARGET_V9) - return \"fcmps %0,%1,%2\"; - return \"fcmps %1,%2\"; + return \"fcmps\\t%0, %1, %2\"; + return \"fcmps\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -633,8 +692,8 @@ "* { if (TARGET_V9) - return \"fcmpd %0,%1,%2\"; - return \"fcmpd %1,%2\"; + return \"fcmpd\\t%0, %1, %2\"; + return \"fcmpd\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -646,8 +705,8 @@ "* { if (TARGET_V9) - return \"fcmpq %0,%1,%2\"; - return \"fcmpq %1,%2\"; + return \"fcmpq\\t%0, %1, %2\"; + return \"fcmpq\\t%1, %2\"; }" [(set_attr "type" "fpcmp")]) @@ -704,7 +763,7 @@ (xor:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) (set (match_operand:SI 0 "register_operand" "") - (eq:DI (match_dup 3) (const_int 0)))] + (eq:SI (match_dup 3) (const_int 0)))] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -713,7 +772,7 @@ (xor:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) (set (match_operand:SI 0 "register_operand" "") - (ne:DI (match_dup 3) (const_int 0)))] + (ne:SI (match_dup 3) (const_int 0)))] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (DImode); }") @@ -722,7 +781,7 @@ (xor:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") - (eq:SI (match_dup 3) (const_int 0))) + (eq:DI (match_dup 3) (const_int 0))) (clobber (reg:CC 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (SImode); }") @@ -732,7 +791,7 @@ (xor:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" ""))) (parallel [(set (match_operand:DI 0 "register_operand" "") - (ne:SI (match_dup 3) (const_int 0))) + (ne:DI (match_dup 3) (const_int 0))) (clobber (reg:CC 100))])] "TARGET_ARCH64" "{ operands[3] = gen_reg_rtx (SImode); }") @@ -787,7 +846,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (EQ, sparc_compare_op0, sparc_compare_op1); + FAIL; }") ;; ??? v9: Operand 0 needs a mode, so SImode was chosen. @@ -840,7 +899,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (NE, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "sgt" @@ -861,7 +920,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (GT, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "slt" @@ -882,7 +941,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (LT, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "sge" @@ -903,7 +962,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (GE, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "sle" @@ -924,7 +983,7 @@ DONE; /* fall through */ } - operands[1] = gen_compare_reg (LE, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "sgtu" @@ -935,7 +994,7 @@ { if (! TARGET_V9) { - rtx tem; + rtx tem, pat; /* We can do ltu easily, so if both operands are registers, swap them and do a LTU. */ @@ -947,7 +1006,10 @@ tem = sparc_compare_op0; sparc_compare_op0 = sparc_compare_op1; sparc_compare_op1 = tem; - emit_insn (gen_sltu (operands[0])); + pat = gen_sltu (operands[0]); + if (pat == NULL_RTX) + FAIL; + emit_insn (pat); DONE; } } @@ -956,7 +1018,7 @@ if (gen_v9_scc (GTU, operands)) DONE; } - operands[1] = gen_compare_reg (GTU, sparc_compare_op0, sparc_compare_op1); + FAIL; }") (define_expand "sltu" @@ -995,7 +1057,7 @@ { if (! TARGET_V9) { - rtx tem; + rtx tem, pat; /* We can do geu easily, so if both operands are registers, swap them and do a GEU. */ @@ -1007,7 +1069,10 @@ tem = sparc_compare_op0; sparc_compare_op0 = sparc_compare_op1; sparc_compare_op1 = tem; - emit_insn (gen_sgeu (operands[0])); + pat = gen_sgeu (operands[0]); + if (pat == NULL_RTX) + FAIL; + emit_insn (pat); DONE; } } @@ -1016,13 +1081,15 @@ if (gen_v9_scc (LEU, operands)) DONE; } - operands[1] = gen_compare_reg (LEU, sparc_compare_op0, sparc_compare_op1); + FAIL; }") ;; Now the DEFINE_INSNs for the scc cases. ;; The SEQ and SNE patterns are special because they can be done -;; without any branching and do not involve a COMPARE. +;; without any branching and do not involve a COMPARE. We want +;; them to always use the splitz below so the results can be +;; scheduled. (define_insn "*snesi_zero" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1030,9 +1097,19 @@ (const_int 0))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + "#" + [(set_attr "length" "2")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (ne:SI (match_operand:SI 1 "register_operand" "") + (const_int 0))) + (clobber (reg:CC 100))] + "" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))] + "") (define_insn "*neg_snesi_zero" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1040,56 +1117,126 @@ (const_int 0)))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;subx %%g0,0,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + "#" + [(set_attr "length" "2")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)))) + (clobber (reg:CC 100))] + "" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] + "") (define_insn "*snesi_zero_extend" [(set (match_operand:DI 0 "register_operand" "=r") - (ne:SI (match_operand:SI 1 "register_operand" "r") + (ne:DI (match_operand:SI 1 "register_operand" "r") (const_int 0))) (clobber (reg:CC 100))] "TARGET_ARCH64" - "subcc %%g0,%1,%%g0\;addx %%g0,0,%0" + "#" [(set_attr "type" "unary") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (ne:DI (match_operand:SI 1 "register_operand" "") + (const_int 0))) + (clobber (reg:CC 100))] + "TARGET_ARCH64" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0) + (const_int 0)) + (ltu:SI (reg:CC_NOOV 100) + (const_int 0)))))] + "") + (define_insn "*snedi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64" - "mov 0,%0\;movrnz %1,1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (ne:DI (match_operand:DI 1 "register_operand" "") + (const_int 0)))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) + (const_int 0)) + (const_int 1) + (match_dup 0)))] + "") + (define_insn "*neg_snedi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))))] "TARGET_ARCH64" - "mov 0,%0\;movrnz %1,-1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (neg:DI (ne:DI (match_operand:DI 1 "register_operand" "") + (const_int 0))))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1) + (const_int 0)) + (const_int -1) + (match_dup 0)))] + "") + (define_insn "*snedi_zero_trunc" [(set (match_operand:SI 0 "register_operand" "=&r") - (ne:DI (match_operand:DI 1 "register_operand" "r") + (ne:SI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64" - "mov 0,%0\;movrnz %1,1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (ne:SI (match_operand:DI 1 "register_operand" "") + (const_int 0)))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1) + (const_int 0)) + (const_int 1) + (match_dup 0)))] + "") + (define_insn "*seqsi_zero" [(set (match_operand:SI 0 "register_operand" "=r") (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + "#" + [(set_attr "length" "2")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (eq:SI (match_operand:SI 1 "register_operand" "") + (const_int 0))) + (clobber (reg:CC 100))] + "" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))] + "") (define_insn "*neg_seqsi_zero" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1097,47 +1244,107 @@ (const_int 0)))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;addx %%g0,-1,%0" - [(set_attr "type" "unary") - (set_attr "length" "2")]) + "#" + [(set_attr "length" "2")]) + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)))) + (clobber (reg:CC 100))] + "" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] + "") (define_insn "*seqsi_zero_extend" [(set (match_operand:DI 0 "register_operand" "=r") - (eq:SI (match_operand:SI 1 "register_operand" "r") + (eq:DI (match_operand:SI 1 "register_operand" "r") (const_int 0))) (clobber (reg:CC 100))] "TARGET_ARCH64" - "subcc %%g0,%1,%%g0\;subx %%g0,-1,%0" + "#" [(set_attr "type" "unary") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (eq:DI (match_operand:SI 1 "register_operand" "") + (const_int 0))) + (clobber (reg:CC 100))] + "TARGET_ARCH64" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0) + (const_int -1)) + (ltu:SI (reg:CC_NOOV 100) + (const_int 0)))))] + "") + (define_insn "*seqdi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64" - "mov 0,%0\;movrz %1,1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (eq:DI (match_operand:DI 1 "register_operand" "") + (const_int 0)))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) + (const_int 0)) + (const_int 1) + (match_dup 0)))] + "") + (define_insn "*neg_seqdi_zero" [(set (match_operand:DI 0 "register_operand" "=&r") (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "r") (const_int 0))))] "TARGET_ARCH64" - "mov 0,%0\;movrz %1,-1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (neg:DI (eq:DI (match_operand:DI 1 "register_operand" "") + (const_int 0))))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1) + (const_int 0)) + (const_int -1) + (match_dup 0)))] + "") + (define_insn "*seqdi_zero_trunc" [(set (match_operand:SI 0 "register_operand" "=&r") - (eq:DI (match_operand:DI 1 "register_operand" "r") + (eq:SI (match_operand:DI 1 "register_operand" "r") (const_int 0)))] "TARGET_ARCH64" - "mov 0,%0\;movrz %1,1,%0" + "#" [(set_attr "type" "cmove") (set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (eq:SI (match_operand:DI 1 "register_operand" "") + (const_int 0)))] + "TARGET_ARCH64" + [(set (match_dup 0) (const_int 0)) + (set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1) + (const_int 0)) + (const_int 1) + (match_dup 0)))] + "") + ;; We can also do (x + (i == 0)) and related, so put them in. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode ;; versions for v9. @@ -1149,9 +1356,22 @@ (match_operand:SI 2 "register_operand" "r"))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;addx %2,0,%0" + "#" [(set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)) + (match_operand:SI 2 "register_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) + (match_dup 2)))] + "") + (define_insn "*x_minus_i_ne_0" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 2 "register_operand" "r") @@ -1159,9 +1379,22 @@ (const_int 0)))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;subx %2,0,%0" + "#" [(set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_operand:SI 2 "register_operand" "") + (ne:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)))) + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (minus:SI (match_dup 2) + (ltu:SI (reg:CC 100) (const_int 0))))] + "") + (define_insn "*x_plus_i_eq_0" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "r") @@ -1169,9 +1402,22 @@ (match_operand:SI 2 "register_operand" "r"))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;subx %2,-1,%0" + "#" [(set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)) + (match_operand:SI 2 "register_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0)) + (match_dup 2)))] + "") + (define_insn "*x_minus_i_eq_0" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 2 "register_operand" "r") @@ -1179,9 +1425,22 @@ (const_int 0)))) (clobber (reg:CC 100))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%%g0\;addx %2,-1,%0" + "#" [(set_attr "length" "2")]) +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_operand:SI 2 "register_operand" "") + (eq:SI (match_operand:SI 1 "register_operand" "") + (const_int 0)))) + (clobber (reg:CC 100))] + "! TARGET_LIVE_G0" + [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) + (set (match_dup 0) (minus:SI (match_dup 2) + (geu:SI (reg:CC 100) (const_int 0))))] + "") + ;; We can also do GEU and LTU directly, but these operate after a compare. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode ;; versions for v9. @@ -1190,15 +1449,17 @@ [(set (match_operand:SI 0 "register_operand" "=r") (ltu:SI (reg:CC 100) (const_int 0)))] "! TARGET_LIVE_G0" - "addx %%g0,0,%0" - [(set_attr "type" "misc")]) + "addx\\t%%g0, 0, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*neg_sltu_insn" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] "! TARGET_LIVE_G0" - "subx %%g0,0,%0" - [(set_attr "type" "misc")]) + "subx\\t%%g0, 0, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) ;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*neg_sltu_minus_x" @@ -1206,30 +1467,34 @@ (minus:SI (neg:SI (ltu:SI (reg:CC 100) (const_int 0))) (match_operand:SI 1 "arith_operand" "rI")))] "! TARGET_LIVE_G0" - "subx %%g0,%1,%0" - [(set_attr "type" "unary")]) + "subx\\t%%g0, %1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*neg_sltu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI"))))] "! TARGET_LIVE_G0" - "subx %%g0,%1,%0" - [(set_attr "type" "unary")]) + "subx\\t%%g0, %1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") (geu:SI (reg:CC 100) (const_int 0)))] "! TARGET_LIVE_G0" - "subx %%g0,-1,%0" - [(set_attr "type" "misc")]) + "subx\\t%%g0, -1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*neg_sgeu_insn" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] "! TARGET_LIVE_G0" - "addx %%g0,-1,%0" - [(set_attr "type" "misc")]) + "addx\\t%%g0, -1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) ;; We can also do (x + ((unsigned) i >= 0)) and related, so put them in. ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode @@ -1240,8 +1505,9 @@ (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "arith_operand" "rI")))] "! TARGET_LIVE_G0" - "addx %%g0,%1,%0" - [(set_attr "type" "unary")]) + "addx\\t%%g0, %1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*sltu_plus_x_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") @@ -1249,64 +1515,57 @@ (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI"))))] "" - "addx %1,%2,%0") + "addx\\t%1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*x_minus_sltu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (ltu:SI (reg:CC 100) (const_int 0))))] "" - "subx %1,0,%0" - [(set_attr "type" "unary")]) + "subx\\t%1, 0, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) ;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*x_minus_y_minus_sltu" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) (ltu:SI (reg:CC 100) (const_int 0))))] "" - "subx %1,%2,%0") + "subx\\t%r1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*x_minus_sltu_plus_y" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (match_operand:SI 1 "register_operand" "r") + (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 2 "arith_operand" "rI"))))] "" - "subx %1,%2,%0") + "subx\\t%r1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*sgeu_plus_x" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (geu:SI (reg:CC 100) (const_int 0)) (match_operand:SI 1 "register_operand" "r")))] "" - "subx %1,-1,%0" - [(set_attr "type" "unary")]) + "subx\\t%1, -1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "*x_minus_sgeu" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "r") (geu:SI (reg:CC 100) (const_int 0))))] "" - "addx %1,-1,%0" - [(set_attr "type" "unary")]) - -;; Now we have the generic scc insns. -;; !v9: These will be done using a jump. -;; v9: Use conditional moves which are defined elsewhere. -;; We have to exclude the cases above, since we will not want combine to -;; turn something that does not require a jump into something that does. - -(define_insn "*scc_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operator:SI 2 "noov_compare_op" - [(match_operand 1 "icc_or_fcc_reg_operand" "") - (const_int 0)]))] - "" - "* return output_scc_insn (operands, insn); " - [(set_attr "type" "multi") - (set_attr "length" "3")]) + "addx\\t%1, -1, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_split [(set (match_operand:SI 0 "register_operand" "=r") @@ -1324,15 +1583,6 @@ (match_dup 0)))] "") -(define_insn "*scc_di" - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operator:DI 2 "noov_compare_op" - [(match_operand 1 "icc_or_fcc_reg_operand" "") - (const_int 0)]))] - "TARGET_ARCH64" - "* return output_scc_insn (operands, insn); " - [(set_attr "type" "multi") - (set_attr "length" "3")]) ;; These control RTL generation for conditional jump insns @@ -1526,6 +1776,7 @@ ;; Now match both normal and inverted jump. +;; XXX fpcmp nop braindamage (define_insn "*normal_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_op" @@ -1541,6 +1792,7 @@ }" [(set_attr "type" "branch")]) +;; XXX fpcmp nop braindamage (define_insn "*inverted_branch" [(set (pc) (if_then_else (match_operator 0 "noov_compare_op" @@ -1556,6 +1808,7 @@ }" [(set_attr "type" "branch")]) +;; XXX fpcmp nop braindamage (define_insn "*normal_fp_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" @@ -1572,6 +1825,7 @@ }" [(set_attr "type" "branch")]) +;; XXX fpcmp nop braindamage (define_insn "*inverted_fp_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" @@ -1588,6 +1842,7 @@ }" [(set_attr "type" "branch")]) +;; XXX fpcmp nop braindamage (define_insn "*normal_fpe_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" @@ -1604,6 +1859,7 @@ }" [(set_attr "type" "branch")]) +;; XXX fpcmp nop braindamage (define_insn "*inverted_fpe_branch" [(set (pc) (if_then_else (match_operator 1 "comparison_operator" @@ -1625,6 +1881,7 @@ ;; There are no 32 bit brreg insns. +;; XXX (define_insn "*normal_int_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "v9_regcmp_op" @@ -1637,10 +1894,11 @@ { return output_v9branch (operands[0], 1, 2, 0, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) +;; XXX (define_insn "*inverted_int_branch_sp64" [(set (pc) (if_then_else (match_operator 0 "v9_regcmp_op" @@ -1653,673 +1911,972 @@ { return output_v9branch (operands[0], 1, 2, 1, final_sequence && INSN_ANNULLED_BRANCH_P (insn), - ! final_sequence); + ! final_sequence, insn); }" [(set_attr "type" "branch")]) -;; Esoteric move insns (lo_sum, high, pic). - -(define_insn "*lo_sum_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (match_operand:SI 2 "immediate_operand" "in")))] - "" - ;; V9 needs "add" because of the code models. We still use "or" for v8 - ;; so we can compare the old compiler with the new. - "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - -;; For PIC, symbol_refs are put inside unspec so that the optimizer will not -;; confuse them with real addresses. -(define_insn "pic_lo_sum_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "register_operand" "r") - (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] - "flag_pic" - ;; V9 needs "add" because of the code models. We still use "or" for v8 - ;; so we can compare the old compiler with the new. - "* return TARGET_ARCH64 ? \"add %1,%%lo(%a2),%0\" : \"or %1,%%lo(%a2),%0\";" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) - -;; The PIC version of sethi must appear before the non-pic case so that -;; the unspec will not be matched as part of the operand. -;; For PIC, symbol_refs are put inside unspec so that the optimizer will not -;; confuse them with real addresses. -(define_insn "pic_sethi_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] - "flag_pic && check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - -(define_insn "pic_lo_sum_di" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:SI (match_operand:DI 1 "register_operand" "r") - (unspec:SI [(match_operand:DI 2 "immediate_operand" "in")] 0)))] - "TARGET_ARCH64 && flag_pic" - "add %1,%%lo(%a2),%0" - [(set_attr "length" "1")]) - -(define_insn "pic_sethi_di" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] - "TARGET_ARCH64 && flag_pic && check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) +;; Load program counter insns. (define_insn "get_pc" [(clobber (reg:SI 15)) (set (match_operand 0 "register_operand" "=r") (unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))] "flag_pic && REGNO (operands[0]) == 23" - "sethi %%hi(%a1-4),%0\;call %a2\;add %0,%%lo(%a1+4),%0" + "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0" [(set_attr "length" "3")]) -(define_insn "get_pc_via_rdpc" - [(set (match_operand 0 "register_operand" "=r") (pc))] - "TARGET_V9" - "rd %%pc,%0" - [(set_attr "type" "move")]) +;; Currently unused... +;; (define_insn "get_pc_via_rdpc" +;; [(set (match_operand 0 "register_operand" "=r") (pc))] +;; "TARGET_V9" +;; "rd\\t%%pc, %0" +;; [(set_attr "type" "move")]) -(define_insn "*sethi_hi" - [(set (match_operand:HI 0 "register_operand" "=r") - (high:HI (match_operand 1 "" "")))] - "check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) - -;; This must appear after the PIC sethi so that the PIC unspec will not -;; be matched as part of the operand. -(define_insn "*sethi_si" - [(set (match_operand:SI 0 "register_operand" "=r") - (high:SI (match_operand 1 "" "")))] - "check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") - (set_attr "length" "1")]) + +;; Move instructions -(define_insn "*lo_sum_di_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "immediate_operand" "in")))] - "! TARGET_ARCH64" - "* +(define_expand "movqi" + [(set (match_operand:QI 0 "general_operand" "") + (match_operand:QI 1 "general_operand" ""))] + "" + " { - /* Don't output a 64 bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); - else if (GET_CODE (operands[2]) == CONST_INT - && HOST_BITS_PER_WIDE_INT > 32 - && INTVAL (operands[2]) > 0xffffffff) - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff); + /* Working with CONST_INTs is easier, so convert + a double if needed. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE) + { + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1]) & 0xff); + } + else if (GET_CODE (operands[1]) == CONST_INT) + { + /* And further, we know for all QI cases that only the + low byte is significant, which we can always process + in a single insn. So mask it now. */ + operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); + } - return \"or %L1,%%lo(%a2),%L0\"; -}" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) + /* Handle sets of MEM first. */ + if (GET_CODE (operands[0]) == MEM) + { + /* This checks TARGET_LIVE_G0 for us. */ + if (reg_or_0_operand (operands[1], QImode)) + goto movqi_is_ok; -;; ??? Optimizer does not handle "or %o1,%lo(0),%o1". How about add? + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (QImode, operands[1]); + } + } -(define_insn "*lo_sum_di_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (lo_sum:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "immediate_operand" "in")))] - "TARGET_ARCH64" - "* -{ - /* Don't output a 64 bit constant, since we can't trust the assembler to - handle it correctly. */ - if (GET_CODE (operands[2]) == CONST_DOUBLE) - operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2])); - else if (GET_CODE (operands[2]) == CONST_INT - && HOST_BITS_PER_WIDE_INT > 32 - && INTVAL (operands[2]) > 0xffffffff) - operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffffffff); - - /* Note that we use add here. This is important because Medium/Anywhere - code model support depends on it. */ - return \"add %1,%%lo(%a2),%0\"; -}" - ;; Need to set length for this arith insn because operand2 - ;; is not an "arith_operand". - [(set_attr "length" "1")]) + /* Fixup PIC cases. */ + if (flag_pic) + { + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], QImode, 0); -(define_insn "*sethi_di_sp32" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "" "")))] - "! TARGET_ARCH64 && check_pic (1)" - "* + if (symbolic_operand (operands[1], QImode)) + { + operands[1] = legitimize_pic_address (operands[1], + QImode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + goto movqi_is_ok; + } + } + + /* All QI constants require only one insn, so proceed. */ + + movqi_is_ok: + ; +}") + +(define_insn "*movqi_insn" + [(set (match_operand:QI 0 "general_operand" "=r,r,m") + (match_operand:QI 1 "input_operand" "rI,m,rJ"))] + "(register_operand (operands[0], QImode) + || reg_or_0_operand (operands[1], QImode))" + "@ + mov\\t%1, %0 + ldub\\t%1, %0 + stb\\t%r1, %0" + [(set_attr "type" "move,load,store") + (set_attr "length" "1")]) + +(define_expand "movhi" + [(set (match_operand:HI 0 "general_operand" "") + (match_operand:HI 1 "general_operand" ""))] + "" + " { - rtx op0 = operands[0]; - rtx op1 = operands[1]; + /* Working with CONST_INTs is easier, so convert + a double if needed. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE) + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - if (GET_CODE (op1) == CONST_INT) + /* Handle sets of MEM first. */ + if (GET_CODE (operands[0]) == MEM) { - operands[0] = operand_subword (op0, 1, 0, DImode); - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); + /* This checks TARGET_LIVE_G0 for us. */ + if (reg_or_0_operand (operands[1], HImode)) + goto movhi_is_ok; - operands[0] = operand_subword (op0, 0, 0, DImode); - if (INTVAL (op1) < 0) - return \"mov -1,%0\"; - else - return \"mov 0,%0\"; + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (HImode, operands[1]); + } } - else if (GET_CODE (op1) == CONST_DOUBLE) + + /* Fixup PIC cases. */ + if (flag_pic) { - operands[0] = operand_subword (op0, 1, 0, DImode); - operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1)); - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], HImode, 0); - operands[0] = operand_subword (op0, 0, 0, DImode); - operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1)); - return singlemove_string (operands); + if (symbolic_operand (operands[1], HImode)) + { + operands[1] = legitimize_pic_address (operands[1], + HImode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + goto movhi_is_ok; + } } - else - abort (); - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "2")]) -;;; ??? This pattern originally clobbered a scratch register. However, this -;;; is invalid, the movdi pattern may not use a temp register because it -;;; may be called from reload to reload a DImode value. In that case, we -;;; end up with a scratch register that never gets allocated. To avoid this, -;;; we use global register 1 which is never otherwise used by gcc as a temp. -;;; The correct solution here might be to force DImode constants to memory, -;;; e.g. by using a toc like the romp and rs6000 ports do for addresses, reg -;;; 1 will then no longer need to be considered a fixed reg. - -(define_expand "sethi_di_sp64" - [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (high:DI (match_operand 1 "general_operand" ""))) - (clobber (reg:DI 1))])] + /* This makes sure we will not get rematched due to splittage. */ + if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode)) + ; + else if (CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && GET_CODE (operands[1]) != LO_SUM) + { + sparc_emit_set_const32 (operands[0], operands[1]); + DONE; + } + movhi_is_ok: + ; +}") + +(define_insn "*movhi_const64_special" + [(set (match_operand:HI 0 "register_operand" "=r") + (match_operand:HI 1 "const64_high_operand" ""))] "TARGET_ARCH64" - "") + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) -(define_insn "*sethi_di_sp64_const" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "const_double_operand" ""))) - (clobber (reg:DI 1))] - "TARGET_ARCH64 && check_pic (1)" - "* +(define_insn "*movhi_insn" + [(set (match_operand:HI 0 "general_operand" "=r,r,r,m") + (match_operand:HI 1 "input_operand" "rI,K,m,rJ"))] + "(register_operand (operands[0], HImode) + || reg_or_0_operand (operands[1], HImode))" + "@ + mov\\t%1, %0 + sethi\\t%%hi(%a1), %0 + lduh\\t%1, %0 + sth\\t%r1, %0" + [(set_attr "type" "move,move,load,store") + (set_attr "length" "1")]) + +;; 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")))] + "" + "or\\t%1, %2, %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_expand "movsi" + [(set (match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "" + " { -#if HOST_BITS_PER_WIDE_INT == 32 - rtx high, low; - - split_double (operands[1], &high, &low); + /* Working with CONST_INTs is easier, so convert + a double if needed. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE) + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); - if (high == const0_rtx) + /* Handle sets of MEM first. */ + if (GET_CODE (operands[0]) == MEM) { - operands[1] = low; - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); - } - else - { - operands[1] = high; - output_asm_insn (singlemove_string (operands), operands); + /* This checks TARGET_LIVE_G0 for us. */ + if (reg_or_0_operand (operands[1], SImode)) + goto movsi_is_ok; - operands[1] = low; - output_asm_insn (\"sllx %0,32,%0\", operands); - if (low != const0_rtx) - output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands); + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (SImode, operands[1]); + } } -#else - rtx op = operands[1]; - if (! SPARC_SETHI_P (INTVAL(op))) + /* Fixup PIC cases. */ + if (flag_pic) { - operands[1] = GEN_INT (INTVAL (op) >> 32); - output_asm_insn (singlemove_string (operands), operands); + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], SImode, 0); + + if (GET_CODE (operands[1]) == LABEL_REF) + { + /* shit */ + emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1])); + DONE; + } - output_asm_insn (\"sllx %0,32,%0\", operands); - if (INTVAL (op) & 0xffffffff) + if (symbolic_operand (operands[1], SImode)) { - operands[1] = GEN_INT (INTVAL (op) & 0xffffffff); - output_asm_insn (\"sethi %%hi(%a1),%%g1; or %0,%%g1,%0\", operands); + operands[1] = legitimize_pic_address (operands[1], + SImode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + goto movsi_is_ok; } } - else + + /* If we are trying to toss an integer constant into the + FPU registers, force it into memory. */ + if (GET_CODE (operands[0]) == REG + && REGNO (operands[0]) >= SPARC_FIRST_FP_REG + && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG + && CONSTANT_P (operands[1])) + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), + operands[1])); + + /* This makes sure we will not get rematched due to splittage. */ + if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode)) + ; + else if (CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && GET_CODE (operands[1]) != LO_SUM) { - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); + sparc_emit_set_const32 (operands[0], operands[1]); + DONE; } -#endif + movsi_is_ok: + ; +}") - return \"\"; -}" - [(set_attr "type" "move") - (set_attr "length" "5")]) - -;; Most of the required support for the various code models is here. -;; We can do this because sparcs need the high insn to load the address. We -;; just need to get high to do the right thing for each code model. Then each -;; uses the same "%X+%lo(...)" in the load/store insn, though in the case of -;; the medium/middle code model "%lo" is written "%l44". - -;; When TARGET_CM_MEDLOW, assume that the upper 32 bits of symbol addresses are -;; always 0. -;; When TARGET_CM_MEDMID, 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. -;; ??? Not implemented yet. -;; When TARGET_CM_EMBMEDANY, the text and data segments have a maximum size of -;; 31 bits and may be located anywhere. EMBMEDANY_BASE_REG contains the start -;; address of the data segment, currently %g4. -;; When TARGET_CM_MEDANY, 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. +;; Special LIVE_G0 pattern to obtain zero in a register. +(define_insn "*movsi_zero_liveg0" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operand:SI 1 "zero_operand" "J"))] + "TARGET_LIVE_G0" + "and\\t%0, 0, %0" + [(set_attr "type" "binary") + (set_attr "length" "1")]) -(define_insn "*sethi_di_medlow" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "" ""))) - ;; The clobber is here because emit_move_sequence assumes the worst case. - (clobber (reg:DI 1))] - "TARGET_CM_MEDLOW && check_pic (1)" - "sethi %%hi(%a1),%0" +;; This is needed to show CSE exactly which bits are set +;; in a 64-bit register by sethi instructions. +(define_insn "*movsi_const64_special" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operand:SI 1 "const64_high_operand" ""))] + "TARGET_ARCH64" + "sethi\\t%%hi(%a1), %0" [(set_attr "type" "move") (set_attr "length" "1")]) -(define_insn "*sethi_di_medium_pic" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "sp64_medium_pic_operand" "")))] - "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" - "sethi %%hi(%a1),%0" - [(set_attr "type" "move") +(define_insn "*movsi_insn" + [(set (match_operand:SI 0 "general_operand" "=r,f,r,r,r,f,m,m,d") + (match_operand:SI 1 "input_operand" "rI,!f,K,J,m,!m,rJ,!f,J"))] + "(register_operand (operands[0], SImode) + || reg_or_0_operand (operands[1], SImode))" + "@ + mov\\t%1, %0 + fmovs\\t%1, %0 + sethi\\t%%hi(%a1), %0 + clr\\t%0 + ld\\t%1, %0 + ld\\t%1, %0 + st\\t%r1, %0 + st\\t%1, %0 + fzeros\\t%0" + [(set_attr "type" "move,fpmove,move,move,load,fpload,store,fpstore,fpmove") (set_attr "length" "1")]) -;; WARNING: %0 gets %hi(%1)+%g4. -;; You cannot OR in %lo(%1), it must be added in. +(define_insn "*movsi_lo_sum" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "immediate_operand" "in")))] + "" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) -(define_insn "*sethi_di_embmedany_data" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "data_segment_operand" ""))) - ;; The clobber is here because emit_move_sequence assumes the worst case. - (clobber (reg:DI 1))] - "TARGET_CM_EMBMEDANY && check_pic (1)" - "sethi %%hi(%a1),%0; add %0,%_,%0" +(define_insn "*movsi_high" + [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI (match_operand:SI 1 "immediate_operand" "in")))] + "" + "sethi\\t%%hi(%a1), %0" [(set_attr "type" "move") - (set_attr "length" "2")]) + (set_attr "length" "1")]) -(define_insn "*sethi_di_embmedany_text" - [(set (match_operand:DI 0 "register_operand" "=r") - (high:DI (match_operand 1 "text_segment_operand" ""))) - ;; The clobber is here because emit_move_sequence assumes the worst case. - (clobber (reg:DI 1))] - "TARGET_CM_EMBMEDANY && check_pic (1)" - "sethi %%uhi(%a1),%%g1; or %%g1,%%ulo(%a1),%%g1; sllx %%g1,32,%%g1; sethi %%hi(%a1),%0; or %0,%%g1,%0" +;; The next two patterns must wrap the SYMBOL_REF in an UNSPEC +;; so that CSE won't optimize the address computation away. +(define_insn "movsi_lo_sum_pic" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (unspec:SI [(match_operand:SI 2 "immediate_operand" "in")] 0)))] + "flag_pic" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "movsi_high_pic" + [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI (unspec:SI [(match_operand 1 "" "")] 0)))] + "flag_pic && check_pic (1)" + "sethi\\t%%hi(%a1), %0" [(set_attr "type" "move") - (set_attr "length" "5")]) - -;; Move instructions + (set_attr "length" "1")]) -(define_expand "movqi" - [(set (match_operand:QI 0 "general_operand" "") - (match_operand:QI 1 "general_operand" ""))] - "" +(define_expand "movsi_pic_label_ref" + [(set (match_dup 3) (high:SI + (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (match_dup 2)] 5))) + (set (match_dup 4) (lo_sum:SI (match_dup 3) + (unspec:SI [(match_dup 1) (match_dup 2)] 5))) + (set (match_operand:SI 0 "register_operand" "=r") + (minus:SI (match_dup 5) (match_dup 4)))] + "flag_pic" " { - if (emit_move_sequence (operands, QImode)) - DONE; + current_function_uses_pic_offset_table = 1; + operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\"); + operands[3] = gen_reg_rtx (SImode); + operands[4] = gen_reg_rtx (SImode); + operands[5] = pic_offset_table_rtx; }") -(define_insn "*movqi_insn" - [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") - (match_operand:QI 1 "move_operand" "rI,K,Q,rJ"))] - "! TARGET_LIVE_G0 - && (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode) - || operands[1] == const0_rtx)" - "@ - mov %1,%0 - sethi %%hi(%a1),%0 - ldub %1,%0 - stb %r1,%0" - [(set_attr "type" "move,move,load,store") +(define_insn "*movsi_high_pic_label_ref" + [(set (match_operand:SI 0 "register_operand" "=r") + (high:SI + (unspec:SI [(match_operand:SI 1 "label_ref_operand" "") + (match_operand:SI 2 "" "")] 5)))] + "flag_pic" + "sethi\\t%%hi(%a2-(%a1-.)), %0" + [(set_attr "type" "move") (set_attr "length" "1")]) -(define_insn "*movqi_insn_liveg0" - [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q") - (match_operand:QI 1 "move_operand" "r,J,I,K,Q,r"))] - "TARGET_LIVE_G0 - && (register_operand (operands[0], QImode) - || register_operand (operands[1], QImode))" - "@ - mov %1,%0 - and %0,0,%0 - and %0,0,%0\;or %0,%1,%0 - sethi %%hi(%a1),%0 - ldub %1,%0 - stb %1,%0" - [(set_attr "type" "move,move,move,move,load,store") - (set_attr "length" "1,1,2,1,1,1")]) - -(define_insn "*lo_sum_qi" - [(set (match_operand:QI 0 "register_operand" "=r") - (subreg:QI (lo_sum:SI (match_operand:QI 1 "register_operand" "r") - (match_operand 2 "immediate_operand" "in")) 0))] - "" - "or %1,%%lo(%a2),%0" - [(set_attr "length" "1")]) - -(define_insn "*store_qi" - [(set (mem:QI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:QI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "sethi %%hi(%a0),%2\;stb %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) +(define_insn "*movsi_lo_sum_pic_label_ref" + [(set (match_operand:SI 0 "register_operand" "=r") + (lo_sum:SI (match_operand:SI 1 "register_operand" "r") + (unspec:SI [(match_operand:SI 2 "label_ref_operand" "") + (match_operand:SI 3 "" "")] 5)))] + "flag_pic" + "or\\t%1, %%lo(%a3-(%a2-.)), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) -(define_expand "movhi" - [(set (match_operand:HI 0 "general_operand" "") - (match_operand:HI 1 "general_operand" ""))] +(define_expand "movdi" + [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") + (match_operand:DI 1 "general_operand" ""))] "" " { - if (emit_move_sequence (operands, HImode)) - DONE; + /* Where possible, convert CONST_DOUBLE into a CONST_INT. */ + if (GET_CODE (operands[1]) == CONST_DOUBLE +#if HOST_BITS_PER_WIDE_INT == 32 + && ((CONST_DOUBLE_HIGH (operands[1]) == 0 + && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0) + || (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff + && (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0)) +#endif + ) + operands[1] = GEN_INT (CONST_DOUBLE_LOW (operands[1])); + + /* Handle MEM cases first. */ + if (GET_CODE (operands[0]) == MEM) + { + /* If it's a REG, we can always do it. + The const zero case is more complex, on v9 + we can always perform it. */ + if (register_operand (operands[1], DImode) + || (TARGET_ARCH64 + && (operands[1] == const0_rtx))) + goto movdi_is_ok; + + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (DImode, operands[1]); + } + } + + if (flag_pic) + { + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], DImode, 0); + + if (GET_CODE (operands[1]) == LABEL_REF) + { + if (! TARGET_ARCH64) + abort (); + emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1])); + DONE; + } + + if (symbolic_operand (operands[1], DImode)) + { + operands[1] = legitimize_pic_address (operands[1], + DImode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + goto movdi_is_ok; + } + } + + /* If we are trying to toss an integer constant into the + FPU registers, force it into memory. */ + if (GET_CODE (operands[0]) == REG + && REGNO (operands[0]) >= SPARC_FIRST_FP_REG + && REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG + && CONSTANT_P (operands[1])) + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), + operands[1])); + + /* This makes sure we will not get rematched due to splittage. */ + if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode)) + ; + else if (TARGET_ARCH64 + && CONSTANT_P (operands[1]) + && GET_CODE (operands[1]) != HIGH + && GET_CODE (operands[1]) != LO_SUM) + { + sparc_emit_set_const64 (operands[0], operands[1]); + DONE; + } + + movdi_is_ok: + ; }") -(define_insn "*movhi_insn" - [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q") - (match_operand:HI 1 "move_operand" "rI,K,Q,rJ"))] - "! TARGET_LIVE_G0 - && (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode) - || operands[1] == const0_rtx)" +;; Be careful, fmovd does not exist when !arch64. +;; We match MEM moves directly when we have correct even +;; numbered registers, but fall into splits otherwise. +;; The constraint ordering here is really important to +;; avoid insane problems in reload, especially for patterns +;; of the form: +;; +;; (set (mem:DI (plus:SI (reg:SI 30 %fp) +;; (const_int -5016))) +;; (reg:DI 2 %g2)) +;; +(define_insn "*movdi_insn_sp32" + [(set (match_operand:DI 0 "general_operand" "=T,U,o,r,r,r,?T,?f,?f,?o,?f") + (match_operand:DI 1 "input_operand" "U,T,r,o,i,r,f,T,o,f,f"))] + "! TARGET_ARCH64 && + (register_operand (operands[0], DImode) + || register_operand (operands[1], DImode))" "@ - mov %1,%0 - sethi %%hi(%a1),%0 - lduh %1,%0 - sth %r1,%0" - [(set_attr "type" "move,move,load,store") + std\\t%1, %0 + ldd\\t%1, %0 + # + # + # + # + std\\t%1, %0 + ldd\\t%1, %0 + # + # + #" + [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,*,*,*") + (set_attr "length" "1,1,2,2,2,2,1,1,2,2,2")]) + +;; The following are generated by sparc_emit_set_const64 +(define_insn "*movdi_sp64_dbl" + [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "const64_operand" ""))] + "(TARGET_ARCH64 + && HOST_BITS_PER_WIDE_INT != 64)" + "mov\\t%1, %0" + [(set_attr "type" "move") (set_attr "length" "1")]) -(define_insn "*movhi_insn_liveg0" - [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q") - (match_operand:HI 1 "move_operand" "r,J,I,K,Q,r"))] - "TARGET_LIVE_G0 - && (register_operand (operands[0], HImode) - || register_operand (operands[1], HImode))" - "@ - mov %1,%0 - and %0,0,%0 - and %0,0,%0\;or %0,%1,%0 - sethi %%hi(%a1),%0 - lduh %1,%0 - sth %1,%0" - [(set_attr "type" "move,move,move,move,load,store") - (set_attr "length" "1,1,2,1,1,1")]) - -(define_insn "*lo_sum_hi" - [(set (match_operand:HI 0 "register_operand" "=r") - (lo_sum:HI (match_operand:HI 1 "register_operand" "r") - (match_operand 2 "immediate_operand" "in")))] - "" - "or %1,%%lo(%a2),%0" - [(set_attr "length" "1")]) +;; This is needed to show CSE exactly which bits are set +;; in a 64-bit register by sethi instructions. +(define_insn "*movdi_const64_special" + [(set (match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "const64_high_operand" ""))] + "TARGET_ARCH64" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) -(define_insn "*store_hi" - [(set (mem:HI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:HI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "sethi %%hi(%a0),%2\;sth %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) +(define_insn "*movdi_insn_sp64" + [(set (match_operand:DI 0 "general_operand" "=r,r,r,r,m,?e,?e,?m,b") + (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e,J"))] + "TARGET_ARCH64 && + (register_operand (operands[0], DImode) + || reg_or_0_operand (operands[1], DImode))" + "@ + mov\\t%1, %0 + sethi\\t%%hi(%a1), %0 + clr\\t%0 + ldx\\t%1, %0 + stx\\t%r1, %0 + fmovd\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + fzero\\t%0" + [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore,fpmove") + (set_attr "length" "1")]) -(define_expand "movsi" - [(set (match_operand:SI 0 "general_operand" "") - (match_operand:SI 1 "general_operand" ""))] - "" +(define_expand "movdi_pic_label_ref" + [(set (match_dup 3) (high:DI + (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (match_dup 2)] 5))) + (set (match_dup 4) (lo_sum:DI (match_dup 3) + (unspec:DI [(match_dup 1) (match_dup 2)] 5))) + (set (match_operand:DI 0 "register_operand" "=r") + (minus:DI (match_dup 5) (match_dup 4)))] + "TARGET_ARCH64 && flag_pic" " { - if (emit_move_sequence (operands, SImode)) - DONE; + current_function_uses_pic_offset_table = 1; + operands[2] = gen_rtx_SYMBOL_REF (Pmode, \"_GLOBAL_OFFSET_TABLE_\"); + operands[3] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (DImode); + operands[5] = pic_offset_table_rtx; }") -;; We must support both 'r' and 'f' registers here, because combine may -;; convert SFmode hard registers to SImode hard registers when simplifying -;; subreg sets. +(define_insn "*movdi_high_pic_label_ref" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI + (unspec:DI [(match_operand:DI 1 "label_ref_operand" "") + (match_operand:DI 2 "" "")] 5)))] + "TARGET_ARCH64 && flag_pic" + "sethi\\t%%hi(%a2-(%a1-.)), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "*movdi_lo_sum_pic_label_ref" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (unspec:DI [(match_operand:DI 2 "label_ref_operand" "") + (match_operand:DI 3 "" "")] 5)))] + "TARGET_ARCH64 && flag_pic" + "or\\t%1, %%lo(%a3-(%a2-.)), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) -;; We cannot combine the similar 'r' and 'f' constraints, because it causes -;; problems with register allocation. Reload might try to put an integer -;; in an fp register, or an fp number is an integer register. +;; Sparc-v9 code model support insns. See sparc_emit_set_symbolic_const64 +;; in sparc.c to see what is going on here... PIC stuff comes first. -(define_insn "*movsi_insn" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,f,r,r,f,Q,Q,d") - (match_operand:SI 1 "move_operand" "rI,!f,K,Q,!Q,rJ,!f,J"))] - "! TARGET_LIVE_G0 - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode) - || operands[1] == const0_rtx) - && (GET_CODE (operands[0]) != REG || ! CONSTANT_P (operands[1]) - || REGNO (operands[0]) < 32 - || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)" - "@ - mov %1,%0 - fmovs %1,%0 - sethi %%hi(%a1),%0 - ld %1,%0 - ld %1,%0 - st %r1,%0 - st %1,%0 - fzeros %0" - [(set_attr "type" "move,fpmove,move,load,fpload,store,fpstore,fpmove") - (set_attr "length" "1")]) - -(define_insn "*movsi_insn_liveg0" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,f,r,r,f,Q,Q") - (match_operand:SI 1 "move_operand" "r,J,I,!f,K,Q,!Q,r,!f"))] - "TARGET_LIVE_G0 - && (register_operand (operands[0], SImode) - || register_operand (operands[1], SImode))" - "@ - mov %1,%0 - and %0,0,%0 - and %0,0,%0\;or %0,%1,%0 - fmovs %1,%0 - sethi %%hi(%a1),%0 - ld %1,%0 - ld %1,%0 - st %1,%0 - st %1,%0" - [(set_attr "type" "move,move,move,fpmove,move,load,fpload,store,fpstore") - (set_attr "length" "1,1,2,1,1,1,1,1,1")]) - -(define_insn "*store_si" - [(set (mem:SI (match_operand:SI 0 "symbolic_operand" "")) - (match_operand:SI 1 "reg_or_0_operand" "rJ")) - (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) +(define_insn "movdi_lo_sum_pic" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (unspec:DI [(match_operand:DI 2 "immediate_operand" "in")] 0)))] + "TARGET_ARCH64 && flag_pic" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) -(define_expand "movdi" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "") - (match_operand:DI 1 "general_operand" ""))] - "" +(define_insn "movdi_high_pic" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand 1 "" "")] 0)))] + "TARGET_ARCH64 && flag_pic && check_pic (1)" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "*sethi_di_medlow_embmedany_pic" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (match_operand:DI 1 "sp64_medium_pic_operand" "")))] + "(TARGET_CM_MEDLOW || TARGET_CM_EMBMEDANY) && check_pic (1)" + "sethi\\t%%lo(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "*sethi_di_medlow" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (match_operand:DI 1 "symbolic_operand" "")))] + "TARGET_CM_MEDLOW && check_pic (1)" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "*losum_di_medlow" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "")))] + "TARGET_CM_MEDLOW" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "seth44" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 6)))] + "TARGET_CM_MEDMID" + "sethi\\t%%h44(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "setm44" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 7)))] + "TARGET_CM_MEDMID" + "or\\t%1, %%m44(%a2), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "setl44" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "")))] + "TARGET_CM_MEDMID" + "or\\t%1, %%l44(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "sethh" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 9)))] + "TARGET_CM_MEDANY" + "sethi\\t%%hh(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "setlm" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "symbolic_operand" "")] 10)))] + "TARGET_CM_MEDANY" + "sethi\\t%%lm(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "sethm" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (unspec:DI [(match_operand:DI 2 "symbolic_operand" "")] 18)))] + "TARGET_CM_MEDANY" + "or\\t%1, %%hm(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "setlo" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand" "")))] + "TARGET_CM_MEDANY" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "embmedany_sethi" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "data_segment_operand" "")] 11)))] + "TARGET_CM_EMBMEDANY && check_pic (1)" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "embmedany_losum" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "data_segment_operand" "")))] + "TARGET_CM_EMBMEDANY" + "add\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "embmedany_brsum" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r")] 11))] + "TARGET_CM_EMBMEDANY" + "add\\t%1, %_, %0" + [(set_attr "length" "1")]) + +(define_insn "embmedany_textuhi" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 13)))] + "TARGET_CM_EMBMEDANY && check_pic (1)" + "sethi\\t%%uhi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "embmedany_texthi" + [(set (match_operand:DI 0 "register_operand" "=r") + (high:DI (unspec:DI [(match_operand:DI 1 "text_segment_operand" "")] 14)))] + "TARGET_CM_EMBMEDANY && check_pic (1)" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "embmedany_textulo" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (unspec:DI [(match_operand:DI 2 "text_segment_operand" "")] 15)))] + "TARGET_CM_EMBMEDANY" + "or\\t%1, %%ulo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +(define_insn "embmedany_textlo" + [(set (match_operand:DI 0 "register_operand" "=r") + (lo_sum:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "text_segment_operand" "")))] + "TARGET_CM_EMBMEDANY" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) + +;; Now some patterns to help reload out a bit. +(define_expand "reload_indi" + [(parallel [(match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "immediate_operand" "") + (match_operand:TI 2 "register_operand" "=&r")])] + "(TARGET_CM_MEDANY + || TARGET_CM_EMBMEDANY) + && ! flag_pic" " { - if (emit_move_sequence (operands, DImode)) - DONE; + sparc_emit_set_symbolic_const64 (operands[0], operands[1], + gen_rtx_REG (DImode, REGNO (operands[2]))); + DONE; }") -;; 32 bit V9 movdi is like regular 32 bit except: a 64 bit zero can be stored -;; to aligned memory with a single instruction, the ldd/std instructions -;; are not used, and constants can not be moved to floating point registers. - -(define_insn "*movdi_sp32_v9" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,Q,r,r,?e,?e,?Q,?b") - (match_operand:DI 1 "general_operand" "r,J,r,Q,i,e,Q,e,J"))] - "TARGET_V9 && ! TARGET_ARCH64 - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx) - && (GET_CODE (operands[0]) != REG || ! CONSTANT_P (operands[1]) - || REGNO (operands[0]) < 32 - || REGNO (operands[0]) >= FIRST_PSEUDO_REGISTER)" - "* +(define_expand "reload_outdi" + [(parallel [(match_operand:DI 0 "register_operand" "=r") + (match_operand:DI 1 "immediate_operand" "") + (match_operand:TI 2 "register_operand" "=&r")])] + "(TARGET_CM_MEDANY + || TARGET_CM_EMBMEDANY) + && ! flag_pic" + " { - if (which_alternative == 1) - return \"stx %%g0,%0\"; - if (which_alternative == 8) - return \"fzero %0\"; - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -}" - [(set_attr "type" "move,store,store,load,multi,fp,fpload,fpstore,fpmove") - (set_attr "length" "2,1,3,3,3,2,3,3,1")]) + sparc_emit_set_symbolic_const64 (operands[0], operands[1], + gen_rtx_REG (DImode, REGNO (operands[2]))); + DONE; +}") -;; SPARC V9 deprecates std. Split it here. +;; Split up putting CONSTs and REGs into DI regs when !arch64 (define_split - [(set (match_operand:DI 0 "memory_operand" "=m") - (match_operand:DI 1 "register_operand" "r"))] - "TARGET_V9 && ! TARGET_ARCH64 && reload_completed - && REGNO (operands[1]) < 32 && ! MEM_VOLATILE_P (operands[0]) - && offsettable_memref_p (operands[0])" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] - "operands[3] = gen_highpart (SImode, operands[1]); - operands[5] = gen_lowpart (SImode, operands[1]); - operands[4] = adj_offsettable_operand (operands[0], 4); - PUT_MODE (operands[4], SImode); - operands[2] = copy_rtx (operands[0]); - PUT_MODE (operands[2], SImode);") - -;; Split register to register moves. + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "const_int_operand" ""))] + "! TARGET_ARCH64 && reload_completed" + [(clobber (const_int 0))] + " +{ + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), + (INTVAL (operands[1]) < 0) ? + constm1_rtx : + const0_rtx)); + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + operands[1])); + DONE; +}") + (define_split - [(set (match_operand:DI 0 "register_operand" "=r") - (match_operand:DI 1 "arith_double_operand" "rIN"))] - "! TARGET_ARCH64 - && REGNO (operands[0]) < 32 - && GET_CODE (operands[1]) == REG && REGNO (operands[1]) < 32 - && ! reg_overlap_mentioned_p (operands[0], operands[1])" - [(set (match_dup 2) (match_dup 4)) - (set (match_dup 3) (match_dup 5))] - "operands[2] = gen_highpart (SImode, operands[0]); - operands[3] = gen_lowpart (SImode, operands[0]); - operands[4] = gen_highpart (SImode, operands[1]); - operands[5] = gen_lowpart (SImode, operands[1]);") + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "const_double_operand" ""))] + "! TARGET_ARCH64 && reload_completed" + [(clobber (const_int 0))] + " +{ + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), + GEN_INT (CONST_DOUBLE_HIGH (operands[1])))); -(define_insn "*movdi_sp32" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,T,U,Q,r,r,?f,?f,?Q") - (match_operand:DI 1 "general_operand" "r,U,T,r,Q,i,f,Q,f"))] - "! TARGET_V9 - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx)" - "* + /* Slick... but this trick loses if this subreg constant part + can be done in one insn. */ + if (CONST_DOUBLE_LOW (operands[1]) == CONST_DOUBLE_HIGH (operands[1]) + && !(SPARC_SETHI_P (CONST_DOUBLE_HIGH (operands[1])) + || SPARC_SIMM13_P (CONST_DOUBLE_HIGH (operands[1])))) + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + gen_highpart (SImode, operands[0]))); + } + else + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + GEN_INT (CONST_DOUBLE_LOW (operands[1])))); + } + DONE; +}") + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" ""))] + "! TARGET_ARCH64 && reload_completed" + [(clobber (const_int 0))] + " { - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -}" - [(set_attr "type" "move,store,load,store,load,multi,fp,fpload,fpstore") - (set_attr "length" "2,1,1,3,3,3,2,3,3")]) - -;;; ??? The trick used below can be extended to load any negative 32 bit -;;; constant in two instructions. Currently the compiler will use HIGH/LO_SUM -;;; for anything not matching the HIK constraints, which results in 5 -;;; instructions. Positive 32 bit constants can be loaded in the obvious way -;;; with sethi/ori. To extend the trick, in the xor instruction, use -;;; xor %o0, ((op1 & 0x3ff) | -0x400), %o0 -;;; This needs the original value of operands[1], not the inverted value. - -(define_insn "*movdi_sp64_insn" - [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,Q,?e,?e,?Q") - (match_operand:DI 1 "move_operand" "rI,K,Q,rJ,e,Q,e"))] - "TARGET_ARCH64 - && (register_operand (operands[0], DImode) - || register_operand (operands[1], DImode) - || operands[1] == const0_rtx)" - "* + rtx set_dest = operands[0]; + rtx set_src = operands[1]; + rtx dest1, dest2; + rtx src1, src2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + if (GET_CODE (set_src) == SUBREG) + set_src = alter_subreg (set_src); + + dest1 = gen_highpart (SImode, set_dest); + dest2 = gen_lowpart (SImode, set_dest); + src1 = gen_highpart (SImode, set_src); + src2 = gen_lowpart (SImode, set_src); + + /* Now emit using the real source and destination we found, swapping + the order if we detect overlap. */ + if (reg_overlap_mentioned_p (dest1, src2)) + { + emit_insn (gen_movsi (dest2, src2)); + emit_insn (gen_movsi (dest1, src1)); + } + else + { + emit_insn (gen_movsi (dest1, src1)); + emit_insn (gen_movsi (dest2, src2)); + } + DONE; +}") + +;; Now handle the cases of memory moves from/to non-even +;; DI mode register pairs. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "memory_operand" ""))] + "(! TARGET_ARCH64 + && reload_completed + && sparc_splitdi_legitimate (operands[0], operands[1]))" + [(clobber (const_int 0))] + " { - switch (which_alternative) + rtx word0 = change_address (operands[1], SImode, NULL_RTX); + rtx word1 = change_address (operands[1], SImode, + plus_constant_for_output (XEXP (word0, 0), 4)); + rtx high_part = gen_highpart (SImode, operands[0]); + rtx low_part = gen_lowpart (SImode, operands[0]); + + if (reg_overlap_mentioned_p (high_part, word1)) { - case 0: - return \"mov %1,%0\"; - case 1: - /* 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 a 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. */ - - if ((INTVAL (operands[1]) & 0x80000000) == 0) - return \"sethi %%hi(%a1),%0\"; - else - { - operands[1] = GEN_INT (~INTVAL (operands[1])); - output_asm_insn (\"sethi %%hi(%a1),%0\", operands); - /* The low 10 bits are already zero, but invert the rest. - Assemblers don't accept 0x1c00, so use -0x400 instead. */ - return \"xor %0,-0x400,%0\"; - } - case 2: - return \"ldx %1,%0\"; - case 3: - return \"stx %r1,%0\"; - case 4: - return \"fmovd %1,%0\"; - case 5: - return \"ldd %1,%0\"; - case 6: - return \"std %1,%0\"; - default: - abort (); + emit_insn (gen_movsi (low_part, word1)); + emit_insn (gen_movsi (high_part, word0)); } -}" - [(set_attr "type" "move,move,load,store,fp,fpload,fpstore") - (set_attr "length" "1,2,1,1,1,1,1")]) + else + { + emit_insn (gen_movsi (high_part, word0)); + emit_insn (gen_movsi (low_part, word1)); + } + DONE; +}") + +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (match_operand:DI 1 "register_operand" ""))] + "(! TARGET_ARCH64 + && reload_completed + && sparc_splitdi_legitimate (operands[1], operands[0]))" + [(clobber (const_int 0))] + " +{ + rtx word0 = change_address (operands[0], SImode, NULL_RTX); + rtx word1 = change_address (operands[0], SImode, + plus_constant_for_output (XEXP (word0, 0), 4)); + rtx high_part = gen_highpart (SImode, operands[1]); + rtx low_part = gen_lowpart (SImode, operands[1]); + + emit_insn (gen_movsi (word0, high_part)); + emit_insn (gen_movsi (word1, low_part)); + DONE; +}") -;; ??? There's no symbolic (set (mem:DI ...) ...). -;; Experimentation with v9 suggested one isn't needed. ;; Floating point move insns -;; This pattern forces (set (reg:SF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movsf pattern. -(define_insn "*movsf_const_insn" - [(set (match_operand:SF 0 "general_operand" "=f,d,m,?r") - (match_operand:SF 1 "" "m,G,G,?F"))] +(define_insn "*clear_sf" + [(set (match_operand:SF 0 "general_operand" "=f") + (match_operand:SF 1 "" ""))] + "TARGET_VIS + && GET_CODE (operands[1]) == CONST_DOUBLE + && GET_CODE (operands[0]) == REG + && fp_zero_operand (operands[1])" + "fzeros\\t%0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) + +(define_insn "*movsf_const_intreg" + [(set (match_operand:SF 0 "general_operand" "=f,r") + (match_operand:SF 1 "" "m,F"))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE - && (GET_CODE (operands[0]) == REG - || fp_zero_operand (operands[1]))" + && GET_CODE (operands[0]) == REG" "* { - switch (which_alternative) + REAL_VALUE_TYPE r; + long i; + + if (which_alternative == 0) + return \"ld\\t%1, %0\"; + + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + REAL_VALUE_TO_TARGET_SINGLE (r, i); + if (SPARC_SIMM13_P (i) || SPARC_SETHI_P (i)) { - case 0: - return \"ld %1,%0\"; - case 1: - return \"fzeros %0\"; - case 2: - return \"st %%g0,%0\"; - case 3: - return singlemove_string (operands); - default: - abort (); + operands[1] = GEN_INT (i); + if (SPARC_SIMM13_P (INTVAL (operands[1]))) + return \"mov\\t%1, %0\"; + else if (SPARC_SETHI_P (INTVAL (operands[1]))) + return \"sethi\\t%%hi(%a1), %0\"; + else + abort (); } + else + return \"#\"; }" - [(set_attr "type" "fpload,fpmove,store,load") - (set_attr "length" "1,1,1,2")]) + [(set_attr "type" "move") + (set_attr "length" "1")]) + +;; There isn't much I can do about this, if I change the +;; mode then flow info gets really confused because the +;; destination no longer looks the same. Ho hum... +(define_insn "*movsf_const_high" + [(set (match_operand:SF 0 "register_operand" "=r") + (unspec:SF [(match_operand 1 "const_int_operand" "")] 12))] + "" + "sethi\\t%%hi(%a1), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_insn "*movsf_const_lo" + [(set (match_operand:SF 0 "register_operand" "=r") + (unspec:SF [(match_operand 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "")] 17))] + "" + "or\\t%1, %%lo(%a2), %0" + [(set_attr "type" "move") + (set_attr "length" "1")]) + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (match_operand:SF 1 "const_double_operand" ""))] + "TARGET_FPU + && (GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32)" + [(set (match_dup 0) (unspec:SF [(match_dup 1)] 12)) + (set (match_dup 0) (unspec:SF [(match_dup 0) (match_dup 1)] 17))] + " +{ + REAL_VALUE_TYPE r; + long i; + + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + REAL_VALUE_TO_TARGET_SINGLE (r, i); + operands[1] = GEN_INT (i); +}") (define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") @@ -2327,88 +2884,193 @@ "" " { - if (emit_move_sequence (operands, SFmode)) - DONE; + /* Force SFmode constants into memory. */ + if (GET_CODE (operands[0]) == REG + && CONSTANT_P (operands[1])) + { + if (TARGET_VIS + && GET_CODE (operands[1]) == CONST_DOUBLE + && fp_zero_operand (operands[1])) + goto movsf_is_ok; + + /* emit_group_store will send such bogosity to us when it is + not storing directly into memory. So fix this up to avoid + crashes in output_constant_pool. */ + if (operands [1] == const0_rtx) + operands[1] = CONST0_RTX (SFmode); + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), + operands[1])); + } + + /* Handle sets of MEM first. */ + if (GET_CODE (operands[0]) == MEM) + { + if (register_operand (operands[1], SFmode)) + goto movsf_is_ok; + + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (SFmode, operands[1]); + } + } + + /* Fixup PIC cases. */ + if (flag_pic) + { + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], SFmode, 0); + + if (symbolic_operand (operands[1], SFmode)) + { + operands[1] = legitimize_pic_address (operands[1], + SFmode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + } + } + + movsf_is_ok: + ; }") (define_insn "*movsf_insn" - [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,f,Q,r,r,Q") - (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,Q,f,r,Q,r"))] + [(set (match_operand:SF 0 "general_operand" "=f,f,m,r,r,m") + (match_operand:SF 1 "input_operand" "f,m,f,r,m,r"))] "TARGET_FPU && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "@ - fmovs %1,%0 - ld %1,%0 - st %1,%0 - mov %1,%0 - ld %1,%0 - st %1,%0" - [(set_attr "type" "fpmove,fpload,fpstore,move,load,store")]) + fmovs\\t%1, %0 + ld\\t%1, %0 + st\\t%1, %0 + mov\\t%1, %0 + ld\\t%1, %0 + st\\t%1, %0" + [(set_attr "type" "fpmove,fpload,fpstore,move,load,store") + (set_attr "length" "1")]) ;; 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 -mno-fpu. (define_insn "*movsf_no_f_insn" - [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q") - (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))] + [(set (match_operand:SF 0 "general_operand" "=r,r,m") + (match_operand:SF 1 "input_operand" "r,m,r"))] "! TARGET_FPU && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "@ - mov %1,%0 - ld %1,%0 - st %1,%0" - [(set_attr "type" "move,load,store")]) - -(define_insn "*store_sf" - [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i")) - (match_operand:SF 1 "reg_or_0_operand" "rfG")) - (clobber (match_scratch:SI 2 "=&r"))] - "(reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "sethi %%hi(%a0),%2\;st %r1,[%2+%%lo(%a0)]" - [(set_attr "type" "store") - (set_attr "length" "2")]) + mov\\t%1, %0 + ld\\t%1, %0 + st\\t%1, %0" + [(set_attr "type" "move,load,store") + (set_attr "length" "1")]) -;; This pattern forces (set (reg:DF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movdf pattern. +(define_insn "*clear_df" + [(set (match_operand:DF 0 "general_operand" "=e") + (match_operand:DF 1 "" ""))] + "TARGET_VIS + && GET_CODE (operands[1]) == CONST_DOUBLE + && GET_CODE (operands[0]) == REG + && fp_zero_operand (operands[1])" + "fzero\\t%0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) + +(define_insn "*movdf_const_intreg_sp32" + [(set (match_operand:DF 0 "general_operand" "=e,e,r") + (match_operand:DF 1 "" "T,o,F"))] + "TARGET_FPU && ! TARGET_ARCH64 + && GET_CODE (operands[1]) == CONST_DOUBLE + && GET_CODE (operands[0]) == REG" + "* +{ + if (which_alternative == 0) + return \"ldd\\t%1, %0\"; + else + return \"#\"; +}" + [(set_attr "type" "move") + (set_attr "length" "1,2,2")]) + +;; Now that we redo life analysis with a clean slate after +;; instruction splitting for sched2 this can work. +(define_insn "*movdf_const_intreg_sp64" + [(set (match_operand:DF 0 "general_operand" "=e,e,r") + (match_operand:DF 1 "" "m,o,F"))] + "TARGET_FPU + && TARGET_ARCH64 + && GET_CODE (operands[1]) == CONST_DOUBLE + && GET_CODE (operands[0]) == REG" + "* +{ + if (which_alternative == 0) + return \"ldd\\t%1, %0\"; + else + return \"#\"; +}" + [(set_attr "type" "move") + (set_attr "length" "1")]) -(define_insn "*movdf_const_insn" - [(set (match_operand:DF 0 "general_operand" "=?r,e,o,d") - (match_operand:DF 1 "" "?F,m,G,G"))] +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "const_double_operand" ""))] "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE && (GET_CODE (operands[0]) == REG - || fp_zero_operand (operands[1]))" - "* + && REGNO (operands[0]) < 32) + && reload_completed" + [(clobber (const_int 0))] + " { - switch (which_alternative) + REAL_VALUE_TYPE r; + long l[2]; + + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); + REAL_VALUE_TO_TARGET_DOUBLE (r, l); + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0])); + + if (TARGET_ARCH64) { - case 0: - return output_move_double (operands); - case 1: - return output_fp_move_double (operands); - case 2: - if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0]))) - { - return \"stx %%g0,%0\"; - } +#if HOST_BITS_PER_WIDE_INT == 64 + HOST_WIDE_INT val; + + val = ((HOST_WIDE_INT)l[1] | + ((HOST_WIDE_INT)l[0] << 32)); + emit_insn (gen_movdi (operands[0], GEN_INT (val))); +#else + emit_insn (gen_movdi (operands[0], + gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx, + l[1], l[0]))); +#endif + } + else + { + emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), + GEN_INT (l[0]))); + + /* Slick... but this trick loses if this subreg constant part + can be done in one insn. */ + if (l[1] == l[0] + && !(SPARC_SETHI_P (l[0]) + || SPARC_SIMM13_P (l[0]))) + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + gen_highpart (SImode, operands[0]))); + } else - { - operands[1] = adj_offsettable_operand (operands[0], 4); - return \"st %%g0,%0\;st %%g0,%1\"; - } - case 3: - return \"fzero %0\"; - default: - abort (); + { + emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), + GEN_INT (l[1]))); + } } -}" - [(set_attr "type" "load,fpload,store,fpmove") - (set_attr "length" "3,3,3,1")]) + DONE; +}") (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") @@ -2416,126 +3078,271 @@ "" " { - if (emit_move_sequence (operands, DFmode)) - DONE; + /* Force DFmode constants into memory. */ + if (GET_CODE (operands[0]) == REG + && CONSTANT_P (operands[1])) + { + if (TARGET_VIS + && GET_CODE (operands[1]) == CONST_DOUBLE + && fp_zero_operand (operands[1])) + goto movdf_is_ok; + + /* emit_group_store will send such bogosity to us when it is + not storing directly into memory. So fix this up to avoid + crashes in output_constant_pool. */ + if (operands [1] == const0_rtx) + operands[1] = CONST0_RTX (DFmode); + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), + operands[1])); + } + + /* Handle MEM cases first. */ + if (GET_CODE (operands[0]) == MEM) + { + if (register_operand (operands[1], DFmode)) + goto movdf_is_ok; + + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (DFmode, operands[1]); + } + } + + /* Fixup PIC cases. */ + if (flag_pic) + { + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], DFmode, 0); + + if (symbolic_operand (operands[1], DFmode)) + { + operands[1] = legitimize_pic_address (operands[1], + DFmode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + } + } + + movdf_is_ok: + ; }") -(define_insn "*movdf_insn" - [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=e,Q,e,T,U,r,Q,r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "e,e,Q,U,T,r,r,Q"))] +;; Be careful, fmovd does not exist when !v9. +(define_insn "*movdf_insn_sp32" + [(set (match_operand:DF 0 "general_operand" "=e,T,U,T,e,r,r,o,e,o") + (match_operand:DF 1 "input_operand" "T,e,T,U,e,r,o,r,o,e"))] "TARGET_FPU + && ! TARGET_V9 && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_double (operands); - return output_move_double (operands); -}" - [(set_attr "type" "fp,fpstore,fpload,fpstore,fpload,move,store,load") - (set_attr "length" "2,3,3,1,1,2,2,2")]) - -;; Exactly the same as above, except that all `e' cases are deleted. -;; This is necessary to prevent reload from ever trying to use a `e' reg -;; when -mno-fpu. - -(define_insn "*movdf_no_e_insn" - [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r") - (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))] + "@ + ldd\\t%1, %0 + std\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + # + # + # + # + # + #" + [(set_attr "type" "fpload,fpstore,load,store,*,*,*,*,*,*") + (set_attr "length" "1,1,1,1,2,2,2,2,2,2")]) + +(define_insn "*movdf_no_e_insn_sp32" + [(set (match_operand:DF 0 "general_operand" "=U,T,r,r,o") + (match_operand:DF 1 "input_operand" "T,U,r,o,r"))] "! TARGET_FPU + && ! TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + "@ + ldd\\t%1, %0 + std\\t%1, %0 + # + # + #" + [(set_attr "type" "load,store,*,*,*") + (set_attr "length" "1,1,2,2,2")]) + +;; We have available v9 double floats but not 64-bit +;; integer registers. +(define_insn "*movdf_insn_v9only" + [(set (match_operand:DF 0 "general_operand" "=e,e,m,U,T,r,r,o") + (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))] + "TARGET_FPU + && TARGET_V9 + && ! TARGET_ARCH64 && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" - "* return output_move_double (operands);" - [(set_attr "type" "store,load,move,store,load") - (set_attr "length" "1,1,2,3,3")]) + "@ + fmovd\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + # + # + #" + [(set_attr "type" "fpmove,load,store,load,store,*,*,*") + (set_attr "length" "1,1,1,1,1,2,2,2")]) + +;; We have available both v9 double floats and 64-bit +;; integer registers. +(define_insn "*movdf_insn_sp64" + [(set (match_operand:DF 0 "general_operand" "=e,e,m,r,r,m") + (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))] + "TARGET_FPU + && TARGET_V9 + && TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + "@ + fmovd\\t%1, %0 + ldd\\t%1, %0 + std\\t%1, %0 + mov\\t%1, %0 + ldx\\t%1, %0 + stx\\t%1, %0" + [(set_attr "type" "fpmove,load,store,move,load,store") + (set_attr "length" "1")]) -;; Must handle overlapping registers here, since parameters can be unaligned -;; in registers. +(define_insn "*movdf_no_e_insn_sp64" + [(set (match_operand:DF 0 "general_operand" "=r,r,m") + (match_operand:DF 1 "input_operand" "r,m,r"))] + "! TARGET_FPU + && TARGET_ARCH64 + && (register_operand (operands[0], DFmode) + || register_operand (operands[1], DFmode))" + "@ + mov\\t%1, %0 + ldx\\t%1, %0 + stx\\t%1, %0" + [(set_attr "type" "move,load,store") + (set_attr "length" "1")]) +;; Ok, now the splits to handle all the multi insn and +;; mis-aligned memory address cases. +;; In these splits please take note that we must be +;; careful when V9 but not ARCH64 because the integer +;; register DFmode cases must be handled. (define_split [(set (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "register_operand" ""))] - "! TARGET_ARCH64 && reload_completed - && REGNO (operands[0]) < SPARC_FIRST_V9_FP_REG - && REGNO (operands[1]) < SPARC_FIRST_V9_FP_REG" - [(set (match_dup 2) (match_dup 3)) - (set (match_dup 4) (match_dup 5))] + (match_operand:DF 1 "register_operand" ""))] + "(! TARGET_V9 + || (! TARGET_ARCH64 + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32)))) + && reload_completed" + [(clobber (const_int 0))] " { - rtx first_set = operand_subword (operands[0], 0, 0, DFmode); - rtx second_use = operand_subword (operands[1], 1, 0, DFmode); + rtx set_dest = operands[0]; + rtx set_src = operands[1]; + rtx dest1, dest2; + rtx src1, src2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + if (GET_CODE (set_src) == SUBREG) + set_src = alter_subreg (set_src); + + dest1 = gen_highpart (SFmode, set_dest); + dest2 = gen_lowpart (SFmode, set_dest); + src1 = gen_highpart (SFmode, set_src); + src2 = gen_lowpart (SFmode, set_src); - if (REGNO (first_set) == REGNO (second_use)) + /* Now emit using the real source and destination we found, swapping + the order if we detect overlap. */ + if (reg_overlap_mentioned_p (dest1, src2)) { - operands[2] = operand_subword (operands[0], 1, 0, DFmode); - operands[3] = second_use; - operands[4] = first_set; - operands[5] = operand_subword (operands[1], 0, 0, DFmode); + emit_insn (gen_movsf (dest2, src2)); + emit_insn (gen_movsf (dest1, src1)); } else { - operands[2] = first_set; - operands[3] = operand_subword (operands[1], 0, 0, DFmode); - operands[4] = operand_subword (operands[0], 1, 0, DFmode); - operands[5] = second_use; + emit_insn (gen_movsf (dest1, src1)); + emit_insn (gen_movsf (dest2, src2)); } + DONE; }") -(define_insn "*store_df" - [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i")) - (match_operand:DF 1 "reg_or_0_operand" "re,G")) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "(reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "* +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (match_operand:DF 1 "memory_operand" ""))] + "((! TARGET_V9 + || (! TARGET_ARCH64 + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32)))) + && (reload_completed + && (((REGNO (operands[0])) % 2) != 0 + || ! mem_min_alignment (operands[1], 8)) + && offsettable_memref_p (operands[1])))" + [(clobber (const_int 0))] + " { - output_asm_insn (\"sethi %%hi(%a0),%2\", operands); - if (which_alternative == 0) - return \"std %1,[%2+%%lo(%a0)]\"; + rtx word0 = change_address (operands[1], SFmode, NULL_RTX); + rtx word1 = change_address (operands[1], SFmode, + plus_constant_for_output (XEXP (word0, 0), 4)); + + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + + if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1)) + { + emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]), + word1)); + emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]), + word0)); + } else - return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\"; -}" - [(set_attr "type" "store") - (set_attr "length" "3")]) - -;; This pattern forces (set (reg:TF ...) (const_double ...)) -;; to be reloaded by putting the constant into memory. -;; It must come before the more general movtf pattern. -(define_insn "*movtf_const_insn" - [(set (match_operand:TF 0 "general_operand" "=?r,e,o") - (match_operand:TF 1 "" "?F,m,G"))] - "TARGET_FPU - && GET_CODE (operands[1]) == CONST_DOUBLE - && (GET_CODE (operands[0]) == REG - || fp_zero_operand (operands[1]))" - "* -{ - switch (which_alternative) { - case 0: - return output_move_quad (operands); - case 1: - return output_fp_move_quad (operands); - case 2: - if (TARGET_ARCH64 || (TARGET_V9 && mem_aligned_8 (operands[0]))) - { - operands[1] = adj_offsettable_operand (operands[0], 8); - return \"stx %%g0,%0\;stx %%g0,%1\"; - } - else - { - /* ??? Do we run off the end of the array here? */ - operands[1] = adj_offsettable_operand (operands[0], 4); - operands[2] = adj_offsettable_operand (operands[0], 8); - operands[3] = adj_offsettable_operand (operands[0], 12); - return \"st %%g0,%0\;st %%g0,%1\;st %%g0,%2\;st %%g0,%3\"; - } - default: - abort (); + emit_insn (gen_movsf (gen_highpart (SFmode, operands[0]), + word0)); + emit_insn (gen_movsf (gen_lowpart (SFmode, operands[0]), + word1)); } -}" - [(set_attr "type" "load,fpload,store") - (set_attr "length" "5,5,5")]) + DONE; +}") + +(define_split + [(set (match_operand:DF 0 "memory_operand" "") + (match_operand:DF 1 "register_operand" ""))] + "((! TARGET_V9 + || (! TARGET_ARCH64 + && ((GET_CODE (operands[1]) == REG + && REGNO (operands[1]) < 32) + || (GET_CODE (operands[1]) == SUBREG + && GET_CODE (SUBREG_REG (operands[1])) == REG + && REGNO (SUBREG_REG (operands[1])) < 32)))) + && (reload_completed + && (((REGNO (operands[1])) % 2) != 0 + || ! mem_min_alignment (operands[0], 8)) + && offsettable_memref_p (operands[0])))" + [(clobber (const_int 0))] + " +{ + rtx word0 = change_address (operands[0], SFmode, NULL_RTX); + rtx word1 = change_address (operands[0], SFmode, + plus_constant_for_output (XEXP (word0, 0), 4)); + + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + emit_insn (gen_movsf (word0, + gen_highpart (SFmode, operands[1]))); + emit_insn (gen_movsf (word1, + gen_lowpart (SFmode, operands[1]))); + DONE; +}") (define_expand "movtf" [(set (match_operand:TF 0 "general_operand" "") @@ -2543,63 +3350,219 @@ "" " { - if (emit_move_sequence (operands, TFmode)) - DONE; + /* Force TFmode constants into memory. */ + if (GET_CODE (operands[0]) == REG + && CONSTANT_P (operands[1])) + { + /* emit_group_store will send such bogosity to us when it is + not storing directly into memory. So fix this up to avoid + crashes in output_constant_pool. */ + if (operands [1] == const0_rtx) + operands[1] = CONST0_RTX (TFmode); + operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]), + operands[1])); + } + + /* Handle MEM cases first, note that only v9 guarentees + full 16-byte alignment for quads. */ + if (GET_CODE (operands[0]) == MEM) + { + if (register_operand (operands[1], TFmode)) + goto movtf_is_ok; + + if (! reload_in_progress) + { + operands[0] = validize_mem (operands[0]); + operands[1] = force_reg (TFmode, operands[1]); + } + } + + /* Fixup PIC cases. */ + if (flag_pic) + { + if (CONSTANT_P (operands[1]) + && pic_address_needs_scratch (operands[1])) + operands[1] = legitimize_pic_address (operands[1], TFmode, 0); + + if (symbolic_operand (operands[1], TFmode)) + { + operands[1] = legitimize_pic_address (operands[1], + TFmode, + (reload_in_progress ? + operands[0] : + NULL_RTX)); + } + } + + movtf_is_ok: + ; }") -(define_insn "*movtf_insn" - [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=e,Q,e,r,Q,r") - (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "e,e,Q,r,r,Q"))] +;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so +;; we must split them all. :-( +(define_insn "*movtf_insn_sp32" + [(set (match_operand:TF 0 "general_operand" "=e,o,U,o,e,r,r,o") + (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))] "TARGET_FPU + && ! TARGET_ARCH64 && (register_operand (operands[0], TFmode) || register_operand (operands[1], TFmode))" - "* -{ - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -}" - [(set_attr "type" "fp,fpstore,fpload,move,store,load") - (set_attr "length" "5,4,4,5,4,4")]) + "#" + [(set_attr "length" "4")]) ;; Exactly the same as above, except that all `e' cases are deleted. ;; This is necessary to prevent reload from ever trying to use a `e' reg ;; when -mno-fpu. -(define_insn "*movtf_no_e_insn" - [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r") - (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))] +(define_insn "*movtf_no_e_insn_sp32" + [(set (match_operand:TF 0 "general_operand" "=U,o,r,r,o") + (match_operand:TF 1 "input_operand" "o,U,r,o,r"))] "! TARGET_FPU + && ! TARGET_ARCH64 && (register_operand (operands[0], TFmode) || register_operand (operands[1], TFmode))" - "* + "#" + [(set_attr "length" "4")]) + +;; Now handle the float reg cases directly when arch64, +;; hard_quad, and proper reg number alignment are all true. +(define_insn "*movtf_insn_hq_sp64" + [(set (match_operand:TF 0 "general_operand" "=e,e,m,r,r,o") + (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))] + "TARGET_FPU + && TARGET_ARCH64 + && TARGET_V9 + && TARGET_HARD_QUAD + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode))" + "@ + fmovq\\t%1, %0 + ldq\\t%1, %0 + stq\\t%1, %0 + # + # + #" + [(set_attr "type" "fpmove,fpload,fpstore,*,*,*") + (set_attr "length" "1,1,1,2,2,2")]) + +;; Now we allow the integer register cases even when +;; only arch64 is true. +(define_insn "*movtf_insn_sp64" + [(set (match_operand:TF 0 "general_operand" "=e,o,r,o,e,r") + (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))] + "TARGET_FPU + && TARGET_ARCH64 + && ! TARGET_HARD_QUAD + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode))" + "#" + [(set_attr "length" "2")]) + +(define_insn "*movtf_no_e_insn_sp64" + [(set (match_operand:TF 0 "general_operand" "=r,o,r") + (match_operand:TF 1 "input_operand" "o,r,r"))] + "! TARGET_FPU + && TARGET_ARCH64 + && (register_operand (operands[0], TFmode) + || register_operand (operands[1], TFmode))" + "#" + [(set_attr "length" "2")]) + +;; Now all the splits to handle multi-insn TF mode moves. +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "register_operand" ""))] + "reload_completed + && (! TARGET_ARCH64 + || (TARGET_FPU + && ! TARGET_HARD_QUAD))" + [(clobber (const_int 0))] + " { - if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) - return output_fp_move_quad (operands); - return output_move_quad (operands); -}" - [(set_attr "type" "move,store,load") - (set_attr "length" "4,5,5")]) - -;; This is disabled because it does not work. Long doubles have only 8 -;; byte alignment. Adding an offset of 8 or 12 to an 8 byte aligned %lo may -;; cause it to overflow. See also GO_IF_LEGITIMATE_ADDRESS. -(define_insn "*store_tf" - [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i")) - (match_operand:TF 1 "reg_or_0_operand" "re,G")) - (clobber (match_scratch:SI 2 "=&r,&r"))] - "0 && (reload_completed || reload_in_progress) - && ! TARGET_PTR64" - "* + rtx set_dest = operands[0]; + rtx set_src = operands[1]; + rtx dest1, dest2; + rtx src1, src2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + if (GET_CODE (set_src) == SUBREG) + set_src = alter_subreg (set_src); + + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0); + dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0); + src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0); + src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0); + + /* Now emit using the real source and destination we found, swapping + the order if we detect overlap. */ + if (reg_overlap_mentioned_p (dest1, src2)) + { + emit_insn (gen_movdf (dest2, src2)); + emit_insn (gen_movdf (dest1, src1)); + } + else + { + emit_insn (gen_movdf (dest1, src1)); + emit_insn (gen_movdf (dest2, src2)); + } + DONE; +}") + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "memory_operand" ""))] + "(reload_completed + && offsettable_memref_p (operands[1]))" + [(clobber (const_int 0))] + " { - output_asm_insn (\"sethi %%hi(%a0),%2\", operands); - if (which_alternative == 0) - return \"std %1,[%2+%%lo(%a0)]\;std %S1,[%2+%%lo(%a0+8)]\"; + rtx word0 = change_address (operands[1], DFmode, NULL_RTX); + rtx word1 = change_address (operands[1], DFmode, + plus_constant_for_output (XEXP (word0, 0), 8)); + rtx dest1, dest2; + + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0); + dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0); + + /* Now output, ordering such that we don't clobber any registers + mentioned in the address. */ + if (reg_overlap_mentioned_p (dest1, word1)) + + { + emit_insn (gen_movdf (dest2, word1)); + emit_insn (gen_movdf (dest1, word0)); + } else - return \"st %%g0,[%2+%%lo(%a0)]\;st %%g0,[%2+%%lo(%a0+4)]\; st %%g0,[%2+%%lo(%a0+8)]\;st %%g0,[%2+%%lo(%a0+12)]\"; -}" - [(set_attr "type" "store") - (set_attr "length" "5")]) + { + emit_insn (gen_movdf (dest1, word0)); + emit_insn (gen_movdf (dest2, word1)); + } + DONE; +}") + +(define_split + [(set (match_operand:TF 0 "memory_operand" "") + (match_operand:TF 1 "register_operand" ""))] + "(reload_completed + && offsettable_memref_p (operands[0]))" + [(clobber (const_int 0))] + " +{ + rtx word0 = change_address (operands[0], DFmode, NULL_RTX); + rtx word1 = change_address (operands[0], DFmode, + plus_constant_for_output (XEXP (word0, 0), 8)); + rtx src1, src2; + + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0); + src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0); + emit_insn (gen_movdf (word0, src1)); + emit_insn (gen_movdf (word1, src2)); + DONE; +}") ;; Sparc V9 conditional move instructions. @@ -2682,8 +3645,7 @@ if (sparc_compare_op1 == const0_rtx && GET_CODE (sparc_compare_op0) == REG - && ((TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code)) - || (op0_mode == SImode && v8plus_regcmp_p (code)))) + && (TARGET_ARCH64 && op0_mode == DImode && v9_regcmp_p (code))) { operands[1] = gen_rtx_fmt_ee (code, op0_mode, sparc_compare_op0, sparc_compare_op1); @@ -2821,39 +3783,42 @@ (if_then_else:QI (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:QI 3 "arith11_operand" "rL,0") - (match_operand:QI 4 "arith11_operand" "0,rL")))] + (match_operand:QI 3 "arith11_operand" "rL,0") + (match_operand:QI 4 "arith11_operand" "0,rL")))] "TARGET_V9" "@ - mov%C1 %x2,%3,%0 - mov%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + mov%C1\\t%x2, %3, %0 + mov%c1\\t%x2, %4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movhi_cc_sp64" [(set (match_operand:HI 0 "register_operand" "=r,r") (if_then_else:HI (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:HI 3 "arith11_operand" "rL,0") - (match_operand:HI 4 "arith11_operand" "0,rL")))] + (match_operand:HI 3 "arith11_operand" "rL,0") + (match_operand:HI 4 "arith11_operand" "0,rL")))] "TARGET_V9" "@ - mov%C1 %x2,%3,%0 - mov%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + mov%C1\\t%x2, %3, %0 + mov%c1\\t%x2, %4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movsi_cc_sp64" [(set (match_operand:SI 0 "register_operand" "=r,r") (if_then_else:SI (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:SI 3 "arith11_operand" "rL,0") - (match_operand:SI 4 "arith11_operand" "0,rL")))] + (match_operand:SI 3 "arith11_operand" "rL,0") + (match_operand:SI 4 "arith11_operand" "0,rL")))] "TARGET_V9" "@ - mov%C1 %x2,%3,%0 - mov%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + mov%C1\\t%x2, %3, %0 + mov%c1\\t%x2, %4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) ;; ??? The constraints of operands 3,4 need work. (define_insn "*movdi_cc_sp64" @@ -2861,142 +3826,112 @@ (if_then_else:DI (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:DI 3 "arith11_double_operand" "rLH,0") - (match_operand:DI 4 "arith11_double_operand" "0,rLH")))] + (match_operand:DI 3 "arith11_double_operand" "rLH,0") + (match_operand:DI 4 "arith11_double_operand" "0,rLH")))] + "TARGET_ARCH64" + "@ + mov%C1\\t%x2, %3, %0 + mov%c1\\t%x2, %4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) + +(define_insn "*movdi_cc_sp64_trunc" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (if_then_else:SI (match_operator 1 "comparison_operator" + [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") + (const_int 0)]) + (match_operand:SI 3 "arith11_double_operand" "rLH,0") + (match_operand:SI 4 "arith11_double_operand" "0,rLH")))] "TARGET_ARCH64" "@ - mov%C1 %x2,%3,%0 - mov%c1 %x2,%4,%0" - [(set_attr "type" "cmove")]) + mov%C1\\t%x2, %3, %0 + mov%c1\\t%x2, %4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movsf_cc_sp64" [(set (match_operand:SF 0 "register_operand" "=f,f") (if_then_else:SF (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f,0") + (match_operand:SF 4 "register_operand" "0,f")))] "TARGET_V9 && TARGET_FPU" "@ - fmovs%C1 %x2,%3,%0 - fmovs%c1 %x2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovs%C1\\t%x2, %3, %0 + fmovs%c1\\t%x2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) (define_insn "*movdf_cc_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e,0") + (match_operand:DF 4 "register_operand" "0,e")))] "TARGET_V9 && TARGET_FPU" "@ - fmovd%C1 %x2,%3,%0 - fmovd%c1 %x2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovd%C1\\t%x2, %3, %0 + fmovd%c1\\t%x2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) (define_insn "*movtf_cc_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") (if_then_else:TF (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" "@ - fmovq%C1 %x2,%3,%0 - fmovq%c1 %x2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovq%C1\\t%x2, %3, %0 + fmovq%c1\\t%x2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) (define_insn "*movqi_cc_reg_sp64" [(set (match_operand:QI 0 "register_operand" "=r,r") (if_then_else:QI (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:QI 3 "arith10_operand" "rM,0") - (match_operand:QI 4 "arith10_operand" "0,rM")))] + (match_operand:QI 3 "arith10_operand" "rM,0") + (match_operand:QI 4 "arith10_operand" "0,rM")))] "TARGET_ARCH64" "@ - movr%D1 %2,%r3,%0 - movr%d1 %2,%r4,%0" - [(set_attr "type" "cmove")]) + movr%D1\\t%2, %r3, %0 + movr%d1\\t%2, %r4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movhi_cc_reg_sp64" [(set (match_operand:HI 0 "register_operand" "=r,r") (if_then_else:HI (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:HI 3 "arith10_operand" "rM,0") - (match_operand:HI 4 "arith10_operand" "0,rM")))] + (match_operand:HI 3 "arith10_operand" "rM,0") + (match_operand:HI 4 "arith10_operand" "0,rM")))] "TARGET_ARCH64" "@ - movr%D1 %2,%r3,%0 - movr%d1 %2,%r4,%0" - [(set_attr "type" "cmove")]) + movr%D1\\t%2, %r3, %0 + movr%d1\\t%2, %r4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movsi_cc_reg_sp64" [(set (match_operand:SI 0 "register_operand" "=r,r") (if_then_else:SI (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:SI 3 "arith10_operand" "rM,0") - (match_operand:SI 4 "arith10_operand" "0,rM")))] + (match_operand:SI 3 "arith10_operand" "rM,0") + (match_operand:SI 4 "arith10_operand" "0,rM")))] "TARGET_ARCH64" "@ - movr%D1 %2,%r3,%0 - movr%d1 %2,%r4,%0" - [(set_attr "type" "cmove")]) - -;; On UltraSPARC this is slightly worse than cmp/mov %icc if the register -;; needs to be zero extended but better on average. -(define_insn "*movsi_cc_reg_v8plus" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (if_then_else:SI (match_operator 1 "v8plus_regcmp_op" - [(match_operand:SI 2 "register_operand" "r,r") - (const_int 0)]) - (match_operand:SI 3 "arith10_operand" "rM,0") - (match_operand:SI 4 "arith10_operand" "0,rM")))] - "TARGET_V9" - "* -{ - if (! sparc_check_64 (operands[2], insn)) - output_asm_insn (\"srl %2,0,%2\", operands); - if (which_alternative == 0) - return \"movr%D1 %2,%r3,%0\"; - return \"movr%d1 %2,%r4,%0\"; -}" + movr%D1\\t%2, %r3, %0 + movr%d1\\t%2, %r4, %0" [(set_attr "type" "cmove") - (set_attr "length" "2")]) - -;; To work well this needs to know the current insn, but that is not an -;; argument to gen_split_*. - -(define_split - [(set (match_operand:SI 0 "register_operand" "=r,r") - (if_then_else:SI (match_operator 1 "v8plus_regcmp_op" - [(match_operand:SI 2 "register_operand" "r,r") - (const_int 0)]) - (match_operand:SI 3 "arith10_operand" "rM,0") - (match_operand:SI 4 "arith10_operand" "0,rM")))] - "reload_completed" - [(set (match_dup 0) - (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 4)] 9))] - "if (! sparc_check_64 (operands[2], NULL_RTX)) - emit_insn (gen_v8plus_clear_high (operands[2], operands[2]));") - -;; A conditional move with the condition argument known to be zero extended -(define_insn "" - [(set (match_operand:SI 0 "register_operand" "=r,r") - (unspec:SI [(match_operator 1 "v8plus_regcmp_op" - [(match_operand:SI 2 "register_operand" "r,r") - (const_int 0)]) - (match_operand:SI 3 "arith10_operand" "rM,0") - (match_operand:SI 4 "arith10_operand" "0,rM")] 9))] - "TARGET_V9" - "@ - movr%D1 %2,%r3,%0 - movr%d1 %2,%r4,%0" - [(set_attr "type" "cmove")]) + (set_attr "length" "1")]) ;; ??? The constraints of operands 3,4 need work. (define_insn "*movdi_cc_reg_sp64" @@ -3004,52 +3939,70 @@ (if_then_else:DI (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:DI 3 "arith10_double_operand" "rMH,0") - (match_operand:DI 4 "arith10_double_operand" "0,rMH")))] + (match_operand:DI 3 "arith10_double_operand" "rMH,0") + (match_operand:DI 4 "arith10_double_operand" "0,rMH")))] + "TARGET_ARCH64" + "@ + movr%D1\\t%2, %r3, %0 + movr%d1\\t%2, %r4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) + +(define_insn "*movdi_cc_reg_sp64_trunc" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (if_then_else:SI (match_operator 1 "v9_regcmp_op" + [(match_operand:DI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:SI 3 "arith10_double_operand" "rMH,0") + (match_operand:SI 4 "arith10_double_operand" "0,rMH")))] "TARGET_ARCH64" "@ - movr%D1 %2,%r3,%0 - movr%d1 %2,%r4,%0" - [(set_attr "type" "cmove")]) + movr%D1\\t%2, %r3, %0 + movr%d1\\t%2, %r4, %0" + [(set_attr "type" "cmove") + (set_attr "length" "1")]) (define_insn "*movsf_cc_reg_sp64" [(set (match_operand:SF 0 "register_operand" "=f,f") (if_then_else:SF (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "f,0") + (match_operand:SF 4 "register_operand" "0,f")))] "TARGET_ARCH64 && TARGET_FPU" "@ - fmovrs%D1 %2,%3,%0 - fmovrs%d1 %2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovrs%D1\\t%2, %3, %0 + fmovrs%d1\\t%2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) (define_insn "*movdf_cc_reg_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") (if_then_else:DF (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:DF 3 "register_operand" "e,0") - (match_operand:DF 4 "register_operand" "0,e")))] + (match_operand:DF 3 "register_operand" "e,0") + (match_operand:DF 4 "register_operand" "0,e")))] "TARGET_ARCH64 && TARGET_FPU" "@ - fmovrd%D1 %2,%3,%0 - fmovrd%d1 %2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovrd%D1\\t%2, %3, %0 + fmovrd%d1\\t%2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) (define_insn "*movtf_cc_reg_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") (if_then_else:TF (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) - (match_operand:TF 3 "register_operand" "e,0") - (match_operand:TF 4 "register_operand" "0,e")))] + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] "TARGET_ARCH64 && TARGET_FPU" "@ - fmovrq%D1 %2,%3,%0 - fmovrq%d1 %2,%4,%0" - [(set_attr "type" "fpcmove")]) + fmovrq%D1\\t%2, %3, %0 + fmovrq%d1\\t%2, %4, %0" + [(set_attr "type" "fpcmove") + (set_attr "length" "1")]) ;;- zero extension instructions @@ -3084,8 +4037,9 @@ [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "" - "lduh %1,%0" - [(set_attr "type" "load")]) + "lduh\\t%1, %0" + [(set_attr "type" "load") + (set_attr "length" "1")]) (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") @@ -3095,11 +4049,11 @@ (define_insn "*zero_extendqihi2_insn" [(set (match_operand:HI 0 "register_operand" "=r,r") - (zero_extend:HI (match_operand:QI 1 "sparc_operand" "r,Q")))] + (zero_extend:HI (match_operand:QI 1 "input_operand" "r,m")))] "GET_CODE (operands[1]) != CONST_INT" "@ - and %1,0xff,%0 - ldub %1,%0" + and\\t%1, 0xff, %0 + ldub\\t%1, %0" [(set_attr "type" "unary,load") (set_attr "length" "1")]) @@ -3111,11 +4065,11 @@ (define_insn "*zero_extendqisi2_insn" [(set (match_operand:SI 0 "register_operand" "=r,r") - (zero_extend:SI (match_operand:QI 1 "sparc_operand" "r,Q")))] + (zero_extend:SI (match_operand:QI 1 "input_operand" "r,m")))] "GET_CODE (operands[1]) != CONST_INT" "@ - and %1,0xff,%0 - ldub %1,%0" + and\\t%1, 0xff, %0 + ldub\\t%1, %0" [(set_attr "type" "unary,load") (set_attr "length" "1")]) @@ -3127,11 +4081,11 @@ (define_insn "*zero_extendqidi2_insn" [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (match_operand:QI 1 "sparc_operand" "r,Q")))] + (zero_extend:DI (match_operand:QI 1 "input_operand" "r,m")))] "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" "@ - and %1,0xff,%0 - ldub %1,%0" + and\\t%1, 0xff, %0 + ldub\\t%1, %0" [(set_attr "type" "unary,load") (set_attr "length" "1")]) @@ -3162,8 +4116,9 @@ [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_ARCH64" - "lduh %1,%0" - [(set_attr "type" "load")]) + "lduh\\t%1, %0" + [(set_attr "type" "load") + (set_attr "length" "1")]) ;; ??? Write truncdisi pattern using sra? @@ -3171,32 +4126,59 @@ (define_expand "zero_extendsidi2" [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] - "TARGET_ARCH64" + "" "") -(define_insn "*zero_extendsidi2_insn" +(define_insn "*zero_extendsidi2_insn_sp64" [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))] + (zero_extend:DI (match_operand:SI 1 "input_operand" "r,m")))] "TARGET_ARCH64 && GET_CODE (operands[1]) != CONST_INT" "@ - srl %1,0,%0 - lduw %1,%0" - [(set_attr "type" "unary,load") + srl\\t%1, 0, %0 + lduw\\t%1, %0" + [(set_attr "type" "shift,load") (set_attr "length" "1")]) -;; Zero extend a 32 bit value in a 64 bit register. -(define_insn "v8plus_clear_high" - [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand" "=r,Q") - (unspec:SI [(match_operand:SI 1 "register_operand" "r,r")] 10))] - "TARGET_V9" - "* -if (which_alternative == 1) - return \"st %1,%0\"; -if (sparc_check_64 (operands[1], insn) > 0) - return final_sequence ? \"nop\" : \"\"; -return \"srl %1,0,%0\"; -" - [(set_attr "type" "shift,store")]) +(define_insn "*zero_extendsidi2_insn_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (match_operand:SI 1 "register_operand" "r")))] + "! TARGET_ARCH64" + "#" + [(set_attr "type" "unary") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] + "! TARGET_ARCH64 && reload_completed" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 4) (match_dup 5))] + " +{ + rtx dest1, dest2; + + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + + dest1 = gen_highpart (SImode, operands[0]); + dest2 = gen_lowpart (SImode, operands[0]); + + /* Swap the order in case of overlap. */ + if (REGNO (dest1) == REGNO (operands[1])) + { + operands[2] = dest2; + operands[3] = operands[1]; + operands[4] = dest1; + operands[5] = const0_rtx; + } + else + { + operands[2] = dest1; + operands[3] = const0_rtx; + operands[4] = dest2; + operands[5] = operands[1]; + } +}") ;; Simplify comparisons of extended values. @@ -3204,9 +4186,10 @@ return \"srl %1,0,%0\"; [(set (reg:CC 100) (compare:CC (zero_extend:SI (match_operand:QI 0 "register_operand" "r")) (const_int 0)))] - "" - "andcc %0,0xff,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "andcc\\t%0, 0xff, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_zero_extendqisi2_set" [(set (reg:CC 100) @@ -3215,28 +4198,71 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_dup 1)))] "" - "andcc %1,0xff,%0" - [(set_attr "type" "unary")]) + "andcc\\t%1, 0xff, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) + +(define_insn "*cmp_zero_extendqidi2" + [(set (reg:CCX 100) + (compare:CCX (zero_extend:DI (match_operand:QI 0 "register_operand" "r")) + (const_int 0)))] + "TARGET_ARCH64" + "andcc\\t%0, 0xff, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) -;; Similarly, handle SI->QI mode truncation followed by a compare. +(define_insn "*cmp_zero_extendqidi2_set" + [(set (reg:CCX 100) + (compare:CCX (zero_extend:DI (match_operand:QI 1 "register_operand" "r")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (match_dup 1)))] + "TARGET_ARCH64" + "andcc\\t%1, 0xff, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) + +;; Similarly, handle {SI,DI}->QI mode truncation followed by a compare. (define_insn "*cmp_siqi_trunc" [(set (reg:CC 100) (compare:CC (subreg:QI (match_operand:SI 0 "register_operand" "r") 0) (const_int 0)))] - "" - "andcc %0,0xff,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "andcc\\t%0, 0xff, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_siqi_trunc_set" [(set (reg:CC 100) (compare:CC (subreg:QI (match_operand:SI 1 "register_operand" "r") 0) (const_int 0))) (set (match_operand:QI 0 "register_operand" "=r") - (match_dup 1))] + (subreg:QI (match_dup 1) 0))] "" - "andcc %1,0xff,%0" - [(set_attr "type" "unary")]) + "andcc\\t%1, 0xff, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) + +(define_insn "*cmp_diqi_trunc" + [(set (reg:CC 100) + (compare:CC (subreg:QI (match_operand:DI 0 "register_operand" "r") 0) + (const_int 0)))] + "TARGET_ARCH64" + "andcc\\t%0, 0xff, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) + +(define_insn "*cmp_diqi_trunc_set" + [(set (reg:CC 100) + (compare:CC (subreg:QI (match_operand:DI 1 "register_operand" "r") 0) + (const_int 0))) + (set (match_operand:QI 0 "register_operand" "=r") + (subreg:QI (match_dup 1) 0))] + "TARGET_ARCH64" + "andcc\\t%1, 0xff, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;;- sign extension instructions @@ -3271,8 +4297,9 @@ return \"srl %1,0,%0\"; [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "" - "ldsh %1,%0" - [(set_attr "type" "sload")]) + "ldsh\\t%1, %0" + [(set_attr "type" "sload") + (set_attr "length" "1")]) (define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") @@ -3308,8 +4335,9 @@ return \"srl %1,0,%0\"; [(set (match_operand:HI 0 "register_operand" "=r") (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "" - "ldsb %1,%0" - [(set_attr "type" "sload")]) + "ldsb\\t%1, %0" + [(set_attr "type" "sload") + (set_attr "length" "1")]) (define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") @@ -3338,8 +4366,9 @@ return \"srl %1,0,%0\"; [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] "" - "ldsb %1,%0" - [(set_attr "type" "sload")]) + "ldsb\\t%1, %0" + [(set_attr "type" "sload") + (set_attr "length" "1")]) (define_expand "extendqidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -3368,8 +4397,9 @@ return \"srl %1,0,%0\"; [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] "TARGET_ARCH64" - "ldsb %1,%0" - [(set_attr "type" "sload")]) + "ldsb\\t%1, %0" + [(set_attr "type" "sload") + (set_attr "length" "1")]) (define_expand "extendhidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -3398,8 +4428,9 @@ return \"srl %1,0,%0\"; [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] "TARGET_ARCH64" - "ldsh %1,%0" - [(set_attr "type" "load")]) + "ldsh\\t%1, %0" + [(set_attr "type" "sload") + (set_attr "length" "1")]) (define_expand "extendsidi2" [(set (match_operand:DI 0 "register_operand" "") @@ -3409,12 +4440,12 @@ return \"srl %1,0,%0\"; (define_insn "*sign_extendsidi2_insn" [(set (match_operand:DI 0 "register_operand" "=r,r") - (sign_extend:DI (match_operand:SI 1 "sparc_operand" "r,Q")))] + (sign_extend:DI (match_operand:SI 1 "input_operand" "r,m")))] "TARGET_ARCH64" "@ - sra %1,0,%0 - ldsw %1,%0" - [(set_attr "type" "unary,sload") + sra\\t%1, 0, %0 + ldsw\\t%1, %0" + [(set_attr "type" "shift,sload") (set_attr "length" "1")]) ;; Special pattern for optimizing bit-field compares. This is needed @@ -3424,37 +4455,59 @@ return \"srl %1,0,%0\"; [(set (reg:CC 100) (compare:CC (zero_extract:SI (match_operand:SI 0 "register_operand" "r") - (match_operand:SI 1 "small_int" "n") - (match_operand:SI 2 "small_int" "n")) + (match_operand:SI 1 "small_int_or_double" "n") + (match_operand:SI 2 "small_int_or_double" "n")) (const_int 0)))] - "INTVAL (operands[2]) > 19" + "! TARGET_LIVE_G0 + && ((GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) > 19) + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_LOW (operands[2]) > 19))" "* { - int len = INTVAL (operands[1]); - int pos = 32 - INTVAL (operands[2]) - len; - unsigned mask = ((1 << len) - 1) << pos; + int len = (GET_CODE (operands[1]) == CONST_INT + ? INTVAL (operands[1]) + : CONST_DOUBLE_LOW (operands[1])); + int pos = 32 - + (GET_CODE (operands[2]) == CONST_INT + ? INTVAL (operands[2]) + : CONST_DOUBLE_LOW (operands[2])) - len; + HOST_WIDE_INT mask = ((1 << len) - 1) << pos; operands[1] = GEN_INT (mask); - return \"andcc %0,%1,%%g0\"; -}") + return \"andcc\\t%0, %1, %%g0\"; +}" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_zero_extract_sp64" [(set (reg:CCX 100) (compare:CCX (zero_extract:DI (match_operand:DI 0 "register_operand" "r") - (match_operand:SI 1 "small_int" "n") - (match_operand:SI 2 "small_int" "n")) + (match_operand:SI 1 "small_int_or_double" "n") + (match_operand:SI 2 "small_int_or_double" "n")) (const_int 0)))] - "TARGET_ARCH64 && INTVAL (operands[2]) > 51" + "TARGET_ARCH64 + && ((GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) > 51) + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_LOW (operands[2]) > 51))" "* { - int len = INTVAL (operands[1]); - int pos = 64 - INTVAL (operands[2]) - len; - unsigned HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; + int len = (GET_CODE (operands[1]) == CONST_INT + ? INTVAL (operands[1]) + : CONST_DOUBLE_LOW (operands[1])); + int pos = 64 - + (GET_CODE (operands[2]) == CONST_INT + ? INTVAL (operands[2]) + : CONST_DOUBLE_LOW (operands[2])) - len; + HOST_WIDE_INT mask = (((unsigned HOST_WIDE_INT) 1 << len) - 1) << pos; operands[1] = GEN_INT (mask); - return \"andcc %0,%1,%%g0\"; -}") + return \"andcc\\t%0, %1, %%g0\"; +}" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;; Conversions between float, double and long double. @@ -3463,48 +4516,54 @@ return \"srl %1,0,%0\"; (float_extend:DF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" - "fstod %1,%0" - [(set_attr "type" "fp")]) + "fstod\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "extendsftf2" [(set (match_operand:TF 0 "register_operand" "=e") (float_extend:TF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fstoq %1,%0" - [(set_attr "type" "fp")]) + "fstoq\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "extenddftf2" [(set (match_operand:TF 0 "register_operand" "=e") (float_extend:TF (match_operand:DF 1 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fdtoq %1,%0" - [(set_attr "type" "fp")]) + "fdtoq\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=f") (float_truncate:SF (match_operand:DF 1 "register_operand" "e")))] "TARGET_FPU" - "fdtos %1,%0" - [(set_attr "type" "fp")]) + "fdtos\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "trunctfsf2" [(set (match_operand:SF 0 "register_operand" "=f") (float_truncate:SF (match_operand:TF 1 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fqtos %1,%0" - [(set_attr "type" "fp")]) + "fqtos\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "trunctfdf2" [(set (match_operand:DF 0 "register_operand" "=e") (float_truncate:DF (match_operand:TF 1 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fqtod %1,%0" - [(set_attr "type" "fp")]) + "fqtod\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) ;; Conversion between fixed point and floating point. @@ -3512,22 +4571,25 @@ return \"srl %1,0,%0\"; [(set (match_operand:SF 0 "register_operand" "=f") (float:SF (match_operand:SI 1 "register_operand" "f")))] "TARGET_FPU" - "fitos %1,%0" - [(set_attr "type" "fp")]) + "fitos\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "floatsidf2" [(set (match_operand:DF 0 "register_operand" "=e") (float:DF (match_operand:SI 1 "register_operand" "f")))] "TARGET_FPU" - "fitod %1,%0" - [(set_attr "type" "fp")]) + "fitod\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "floatsitf2" [(set (match_operand:TF 0 "register_operand" "=e") (float:TF (match_operand:SI 1 "register_operand" "f")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fitoq %1,%0" - [(set_attr "type" "fp")]) + "fitoq\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) ;; Now the same for 64 bit sources. @@ -3535,22 +4597,25 @@ return \"srl %1,0,%0\"; [(set (match_operand:SF 0 "register_operand" "=f") (float:SF (match_operand:DI 1 "register_operand" "e")))] "TARGET_V9 && TARGET_FPU" - "fxtos %1,%0" - [(set_attr "type" "fp")]) + "fxtos\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "floatdidf2" [(set (match_operand:DF 0 "register_operand" "=e") (float:DF (match_operand:DI 1 "register_operand" "e")))] "TARGET_V9 && TARGET_FPU" - "fxtod %1,%0" - [(set_attr "type" "fp")]) + "fxtod\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "floatditf2" [(set (match_operand:TF 0 "register_operand" "=e") (float:TF (match_operand:DI 1 "register_operand" "e")))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fxtoq %1,%0" - [(set_attr "type" "fp")]) + "fxtoq\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) ;; Convert a float to an actual integer. ;; Truncation is performed as part of the conversion. @@ -3559,22 +4624,25 @@ return \"srl %1,0,%0\"; [(set (match_operand:SI 0 "register_operand" "=f") (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] "TARGET_FPU" - "fstoi %1,%0" - [(set_attr "type" "fp")]) + "fstoi\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "register_operand" "=f") (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] "TARGET_FPU" - "fdtoi %1,%0" - [(set_attr "type" "fp")]) + "fdtoi\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "fix_trunctfsi2" [(set (match_operand:SI 0 "register_operand" "=f") (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] "TARGET_FPU && TARGET_HARD_QUAD" - "fqtoi %1,%0" - [(set_attr "type" "fp")]) + "fqtoi\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) ;; Now the same, for V9 targets @@ -3582,29 +4650,32 @@ return \"srl %1,0,%0\"; [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))] "TARGET_V9 && TARGET_FPU" - "fstox %1,%0" - [(set_attr "type" "fp")]) + "fstox\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "fix_truncdfdi2" [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "e"))))] "TARGET_V9 && TARGET_FPU" - "fdtox %1,%0" - [(set_attr "type" "fp")]) + "fdtox\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "fix_trunctfdi2" [(set (match_operand:DI 0 "register_operand" "=e") (fix:DI (fix:TF (match_operand:TF 1 "register_operand" "e"))))] "TARGET_V9 && TARGET_FPU && TARGET_HARD_QUAD" - "fqtox %1,%0" - [(set_attr "type" "fp")]) + "fqtox\\t%1, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) ;;- arithmetic instructions (define_expand "adddi3" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + (match_operand:DI 2 "arith_double_add_operand" "rHI")))] "" " { @@ -3618,41 +4689,24 @@ return \"srl %1,0,%0\"; gen_rtx_REG (CCmode, SPARC_ICC_REG))))); DONE; } + if (arith_double_4096_operand(operands[2], DImode)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_MINUS (DImode, operands[1], + GEN_INT(-4096)))); + DONE; + } }") -(define_insn "*adddi3_sp32" +(define_insn "adddi3_insn_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI"))) (clobber (reg:CC 100))] "! TARGET_ARCH64" - "* -{ - rtx op2 = operands[2]; - - if (GET_CODE (op2) == CONST_INT - || GET_CODE (op2) == CONST_DOUBLE) - { - rtx xoperands[4]; - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - if (WORDS_BIG_ENDIAN) - split_double (op2, &xoperands[2], &xoperands[3]); - else - split_double (op2, &xoperands[3], &xoperands[2]); - if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1]) - output_asm_insn (\"add %H1,%2,%H0\", xoperands); - else - output_asm_insn (\"addcc %L1,%3,%L0\;addx %H1,%2,%H0\", xoperands); - return \"\"; - } - return \"addcc %L1,%L2,%L0\;addx %H1,%H2,%H0\"; -}" + "#" [(set_attr "length" "2")]) - -;; Split DImode arithmetic - (define_split [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") @@ -3722,58 +4776,163 @@ return \"srl %1,0,%0\"; }") ;; LTU here means "carry set" -(define_insn "*addx" +(define_insn "addx" [(set (match_operand:SI 0 "register_operand" "=r") (plus:SI (plus:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")) (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] "" - "addx %1,%2,%0" - [(set_attr "type" "unary")]) + "addx\\t%1, %2, %0" + [(set_attr "type" "unary") + (set_attr "length" "1")]) + +(define_insn "*addx_extend_sp32" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "! TARGET_ARCH64" + "#" + [(set_attr "type" "unary") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "") + (match_operand:SI 2 "arith_operand" "")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "! TARGET_ARCH64 && reload_completed" + [(set (match_dup 3) (plus:SI (plus:SI (match_dup 1) (match_dup 2)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) + (set (match_dup 4) (const_int 0))] + "operands[3] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]);") + +(define_insn "*addx_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (plus:SI (plus:SI (match_operand:SI 1 "reg_or_0_operand" "%rJ") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "TARGET_ARCH64" + "addx\\t%r1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) -(define_insn "*subx" +(define_insn "subx" [(set (match_operand:SI 0 "register_operand" "=r") - (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r") + (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] "" - "subx %1,%2,%0" - [(set_attr "type" "unary")]) + "subx\\t%r1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) + +(define_insn "*subx_extend_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "TARGET_ARCH64" + "subx\\t%r1, %2, %0" + [(set_attr "type" "misc") + (set_attr "length" "1")]) + +(define_insn "*subx_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "! TARGET_ARCH64" + "#" + [(set_attr "type" "unary") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extend:DI (minus:SI (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") + (match_operand:SI 2 "arith_operand" "rI")) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))))] + "! TARGET_ARCH64 && reload_completed" + [(set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 2)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0)))) + (set (match_dup 4) (const_int 0))] + "operands[3] = gen_lowpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[0]);") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") - (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r"))) + (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) + (match_operand:DI 2 "register_operand" "r"))) (clobber (reg:CC 100))] "! TARGET_ARCH64" - "addcc %L2,%1,%L0\;addx %H2,0,%H0" - [(set_attr "type" "multi")]) + "#" + [(set_attr "type" "multi") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) + (match_operand:DI 2 "register_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 && reload_completed" + [(parallel [(set (reg:CC_NOOV 100) + (compare:CC_NOOV (plus:SI (match_dup 3) (match_dup 1)) + (const_int 0))) + (set (match_dup 5) (plus:SI (match_dup 3) (match_dup 1)))]) + (set (match_dup 6) + (plus:SI (plus:SI (match_dup 4) (const_int 0)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + "operands[3] = gen_lowpart (SImode, operands[2]); + operands[4] = gen_highpart (SImode, operands[2]); + operands[5] = gen_lowpart (SImode, operands[0]); + operands[6] = gen_highpart (SImode, operands[0]);") (define_insn "*adddi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "add %1,%2,%0") + "add\\t%1, %2, %0" + [(set_attr "type" "binary") + (set_attr "length" "1")]) + +(define_expand "addsi3" + [(set (match_operand:SI 0 "register_operand" "=r,d") + (plus:SI (match_operand:SI 1 "arith_operand" "%r,d") + (match_operand:SI 2 "arith_add_operand" "rI,d")))] + "" + " +{ + if (arith_4096_operand(operands[2], DImode)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_MINUS (SImode, operands[1], + GEN_INT(-4096)))); + DONE; + } +}") -(define_insn "addsi3" +(define_insn "*addsi3" [(set (match_operand:SI 0 "register_operand" "=r,d") (plus:SI (match_operand:SI 1 "arith_operand" "%r,d") (match_operand:SI 2 "arith_operand" "rI,d")))] "" "@ - add %1,%2,%0 - fpadd32s %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + add\\t%1, %2, %0 + fpadd32s\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1")]) (define_insn "*cmp_cc_plus" [(set (reg:CC_NOOV 100) (compare:CC_NOOV (plus:SI (match_operand:SI 0 "arith_operand" "%r") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] - "" - "addcc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "addcc\\t%0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_plus" [(set (reg:CCX_NOOV 100) @@ -3781,8 +4940,9 @@ return \"srl %1,0,%0\"; (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" - "addcc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "addcc\\t%0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_plus_set" [(set (reg:CC_NOOV 100) @@ -3792,7 +4952,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (plus:SI (match_dup 1) (match_dup 2)))] "" - "addcc %1,%2,%0") + "addcc\\t%1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_plus_set" [(set (reg:CCX_NOOV 100) @@ -3802,12 +4964,14 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_ARCH64" - "addcc %1,%2,%0") + "addcc\\t%1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_expand "subdi3" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + (match_operand:DI 2 "arith_double_add_operand" "rHI")))] "" " { @@ -3821,6 +4985,13 @@ return \"srl %1,0,%0\"; gen_rtx_REG (CCmode, SPARC_ICC_REG))))); DONE; } + if (arith_double_4096_operand(operands[2], DImode)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_PLUS (DImode, operands[1], + GEN_INT(-4096)))); + DONE; + } }") (define_insn "*subdi3_sp32" @@ -3829,29 +5000,64 @@ return \"srl %1,0,%0\"; (match_operand:DI 2 "arith_double_operand" "rHI"))) (clobber (reg:CC 100))] "! TARGET_ARCH64" - "* + "#" + [(set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "arith_double_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 + && reload_completed + && (GET_CODE (operands[2]) == CONST_INT + || GET_CODE (operands[2]) == CONST_DOUBLE)" + [(clobber (const_int 0))] + " { - rtx op2 = operands[2]; + rtx highp, lowp; - if (GET_CODE (op2) == CONST_INT - || GET_CODE (op2) == CONST_DOUBLE) + highp = gen_highpart (SImode, operands[2]); + lowp = gen_lowpart (SImode, operands[2]); + if ((lowp == const0_rtx) + && (operands[0] == operands[1])) { - rtx xoperands[4]; - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - if (WORDS_BIG_ENDIAN) - split_double (op2, &xoperands[2], &xoperands[3]); - else - split_double (op2, &xoperands[3], &xoperands[2]); - if (xoperands[3] == const0_rtx && xoperands[0] == xoperands[1]) - output_asm_insn (\"sub %H1,%2,%H0\", xoperands); - else - output_asm_insn (\"subcc %L1,%3,%L0\;subx %H1,%2,%H0\", xoperands); - return \"\"; + emit_insn (gen_rtx_SET (VOIDmode, + gen_highpart (SImode, operands[0]), + gen_rtx_MINUS (SImode, + gen_highpart (SImode, operands[1]), + highp))); } - return \"subcc %L1,%L2,%L0\;subx %H1,%H2,%H0\"; -}" - [(set_attr "length" "2")]) + else + { + emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]), + gen_lowpart (SImode, operands[1]), + lowp)); + emit_insn (gen_subx (gen_highpart (SImode, operands[0]), + gen_highpart (SImode, operands[1]), + highp)); + } + DONE; +}") + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 + && reload_completed" + [(clobber (const_int 0))] + " +{ + emit_insn (gen_cmp_minus_cc_set (gen_lowpart (SImode, operands[0]), + gen_lowpart (SImode, operands[1]), + gen_lowpart (SImode, operands[2]))); + emit_insn (gen_subx (gen_highpart (SImode, operands[0]), + gen_highpart (SImode, operands[1]), + gen_highpart (SImode, operands[2]))); + DONE; +}") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") @@ -3859,34 +5065,73 @@ return \"srl %1,0,%0\"; (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))) (clobber (reg:CC 100))] "! TARGET_ARCH64" - "subcc %L1,%2,%L0\;addx %H1,0,%H0" - [(set_attr "type" "multi")]) + "#" + [(set_attr "type" "multi") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "register_operand" "") + (zero_extend:DI (match_operand:SI 2 "register_operand" "")))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 && reload_completed" + [(parallel [(set (reg:CC_NOOV 100) + (compare:CC_NOOV (minus:SI (match_dup 3) (match_dup 2)) + (const_int 0))) + (set (match_dup 5) (minus:SI (match_dup 3) (match_dup 2)))]) + (set (match_dup 6) + (minus:SI (minus:SI (match_dup 4) (const_int 0)) + (ltu:SI (reg:CC_NOOV 100) (const_int 0))))] + "operands[3] = gen_lowpart (SImode, operands[1]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_lowpart (SImode, operands[0]); + operands[6] = gen_highpart (SImode, operands[0]);") (define_insn "*subdi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "sub %1,%2,%0") + "sub\\t%1, %2, %0" + [(set_attr "type" "binary") + (set_attr "length" "1")]) + +(define_expand "subsi3" + [(set (match_operand:SI 0 "register_operand" "=r,d") + (minus:SI (match_operand:SI 1 "register_operand" "r,d") + (match_operand:SI 2 "arith_add_operand" "rI,d")))] + "" + " +{ + if (arith_4096_operand(operands[2], DImode)) + { + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_PLUS (SImode, operands[1], + GEN_INT(-4096)))); + DONE; + } +}") -(define_insn "subsi3" +(define_insn "*subsi3" [(set (match_operand:SI 0 "register_operand" "=r,d") (minus:SI (match_operand:SI 1 "register_operand" "r,d") (match_operand:SI 2 "arith_operand" "rI,d")))] "" "@ - sub %1,%2,%0 - fpsub32s %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + sub\\t%1, %2, %0 + fpsub32s\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1")]) (define_insn "*cmp_minus_cc" [(set (reg:CC_NOOV 100) - (compare:CC_NOOV (minus:SI (match_operand:SI 0 "register_operand" "r") + (compare:CC_NOOV (minus:SI (match_operand:SI 0 "reg_or_0_operand" "rJ") (match_operand:SI 1 "arith_operand" "rI")) (const_int 0)))] - "" - "subcc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "subcc\\t%r0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_minus_ccx" [(set (reg:CCX_NOOV 100) @@ -3894,18 +5139,21 @@ return \"srl %1,0,%0\"; (match_operand:DI 1 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" - "subcc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "subcc\\t%0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) -(define_insn "*cmp_minus_cc_set" +(define_insn "cmp_minus_cc_set" [(set (reg:CC_NOOV 100) - (compare:CC_NOOV (minus:SI (match_operand:SI 1 "register_operand" "r") + (compare:CC_NOOV (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ") (match_operand:SI 2 "arith_operand" "rI")) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_dup 1) (match_dup 2)))] "" - "subcc %1,%2,%0") + "subcc\\t%r1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_minus_ccx_set" [(set (reg:CCX_NOOV 100) @@ -3915,7 +5163,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (minus:DI (match_dup 1) (match_dup 2)))] "TARGET_ARCH64" - "subcc %1,%2,%0") + "subcc\\t%1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;; Integer Multiply/Divide. @@ -3928,8 +5178,9 @@ return \"srl %1,0,%0\"; (mult:SI (match_operand:SI 1 "arith_operand" "%r") (match_operand:SI 2 "arith_operand" "rI")))] "TARGET_HARD_MUL" - "smul %1,%2,%0" - [(set_attr "type" "imul")]) + "smul\\t%1, %2, %0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) (define_expand "muldi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -3950,9 +5201,12 @@ return \"srl %1,0,%0\"; (mult:DI (match_operand:DI 1 "arith_double_operand" "%r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "mulx %1,%2,%0") + "mulx\\t%1, %2, %0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) ;; V8plus wide multiply. +;; XXX (define_insn "muldi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=r,h") (mult:DI (match_operand:DI 1 "arith_double_operand" "%r,0") @@ -3963,15 +5217,15 @@ return \"srl %1,0,%0\"; "* { if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn (\"srl %L1,0,%L1\", operands); + output_asm_insn (\"srl\\t%L1, 0, %L1\", operands); if (which_alternative == 1) - output_asm_insn (\"sllx %H1,32,%H1\", operands); + output_asm_insn (\"sllx\\t%H1, 32, %H1\", operands); if (sparc_check_64 (operands[2], insn) <= 0) - output_asm_insn (\"srl %L2,0,%L2\", operands); + output_asm_insn (\"srl\\t%L2, 0, %L2\", operands); if (which_alternative == 1) - return \"or %L1,%H1,%H1\;sllx %H2,32,%L1\;or %L2,%L1,%L1\;mulx %H1,%L1,%L0\;srlx %L0,32,%H0\"; + return \"or\\t%L1, %H1, %H1\\n\\tsllx\\t%H2, 32, %L1\\n\\tor\\t%L2, %L1, %L1\\n\\tmulx\\t%H1, %L1, %L0\;srlx\\t%L0, 32, %H0\"; else - return \"sllx %H1,32,%3\;sllx %H2,32,%4\;or %L1,%3,%3\;or %L2,%4,%4\;mulx %3,%4,%3\;srlx %3,32,%H0\;mov %3,%L0\"; + return \"sllx\\t%H1, 32, %3\\n\\tsllx\\t%H2, 32, %4\\n\\tor\\t%L1, %3, %3\\n\\tor\\t%L2, %4, %4\\n\\tmulx\\t%3, %4, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0\"; }" [(set_attr "length" "9,8")]) @@ -3985,8 +5239,9 @@ return \"srl %1,0,%0\"; (compare:CC_NOOV (mult:SI (match_dup 1) (match_dup 2)) (const_int 0)))] "TARGET_V8 || TARGET_SPARCLITE || TARGET_DEPRECATED_V8_INSNS" - "smulcc %1,%2,%0" - [(set_attr "type" "imul")]) + "smulcc\\t%1, %2, %0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) (define_expand "mulsidi3" [(set (match_operand:DI 0 "register_operand" "") @@ -4015,6 +5270,7 @@ return \"srl %1,0,%0\"; ;; V9 puts the 64 bit product in a 64 bit register. Only out or global ;; registers can hold 64 bit values in the V8plus environment. +;; XXX (define_insn "mulsidi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=h,r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) @@ -4022,10 +5278,11 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 3 "=X,&h"))] "TARGET_V8PLUS" "@ - smul %1,%2,%L0\;srlx %L0,32,%H0 - smul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 + smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" [(set_attr "length" "2,3")]) +;; XXX (define_insn "const_mulsidi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=h,r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r,r")) @@ -4033,10 +5290,11 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 3 "=X,&h"))] "TARGET_V8PLUS" "@ - smul %1,%2,%L0\;srlx %L0,32,%H0 - smul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + smul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 + smul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" [(set_attr "length" "2,3")]) +;; XXX (define_insn "*mulsidi3_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) @@ -4044,7 +5302,7 @@ return \"srl %1,0,%0\"; "TARGET_HARD_MUL32" "* { - return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\"; + return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "sparclet") @@ -4052,6 +5310,7 @@ return \"srl %1,0,%0\"; ;; Extra pattern, because sign_extend of a constant isn't valid. +;; XXX (define_insn "const_mulsidi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) @@ -4059,7 +5318,7 @@ return \"srl %1,0,%0\"; "TARGET_HARD_MUL" "* { - return TARGET_SPARCLET ? \"smuld %1,%2,%L0\" : \"smul %1,%2,%L0\;rd %%y,%H0\"; + return TARGET_SPARCLET ? \"smuld\\t%1, %2, %L0\" : \"smul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "sparclet") @@ -4095,6 +5354,7 @@ return \"srl %1,0,%0\"; } }") +;; XXX (define_insn "smulsi3_highpart_v8plus" [(set (match_operand:SI 0 "register_operand" "=h,r") (truncate:SI @@ -4109,6 +5369,7 @@ return \"srl %1,0,%0\"; [(set_attr "length" "2")]) ;; The combiner changes TRUNCATE in the previous pattern to SUBREG. +;; XXX (define_insn "" [(set (match_operand:SI 0 "register_operand" "=h,r") (subreg:SI @@ -4120,10 +5381,11 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 4 "=X,&h"))] "TARGET_V8PLUS" "@ - smul %1,%2,%0\;srlx %0,%3,%0 - smul %1,%2,%4\;srlx %4,%3,%0" + smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 + smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "const_smulsi3_highpart_v8plus" [(set (match_operand:SI 0 "register_operand" "=h,r") (truncate:SI @@ -4133,28 +5395,32 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 4 "=X,&h"))] "TARGET_V8PLUS" "@ - smul %1,%2,%0\;srlx %0,%3,%0 - smul %1,%2,%4\;srlx %4,%3,%0" + smul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 + smul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "*smulsi3_highpart_sp32" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_HARD_MUL32" - "smul %1,%2,%%g0\;rd %%y,%0" + "TARGET_HARD_MUL32 + && ! TARGET_LIVE_G0" + "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "const_smulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "register_operand" "r")) (const_int 32))))] - "TARGET_HARD_MUL32" - "smul %1,%2,%%g0\;rd %%y,%0" + "TARGET_HARD_MUL32 + && ! TARGET_LIVE_G0" + "smul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" [(set_attr "length" "2")]) (define_expand "umulsidi3" @@ -4182,6 +5448,7 @@ return \"srl %1,0,%0\"; } }") +;; XXX (define_insn "umulsidi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=h,r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) @@ -4189,10 +5456,11 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 3 "=X,&h"))] "TARGET_V8PLUS" "@ - umul %1,%2,%L0\;srlx %L0,32,%H0 - umul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 + umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" [(set_attr "length" "2,3")]) +;; XXX (define_insn "*umulsidi3_sp32" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) @@ -4200,7 +5468,7 @@ return \"srl %1,0,%0\"; "TARGET_HARD_MUL32" "* { - return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\"; + return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "sparclet") @@ -4208,6 +5476,7 @@ return \"srl %1,0,%0\"; ;; Extra pattern, because sign_extend of a constant isn't valid. +;; XXX (define_insn "const_umulsidi3" [(set (match_operand:DI 0 "register_operand" "=r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) @@ -4215,12 +5484,13 @@ return \"srl %1,0,%0\"; "TARGET_HARD_MUL32" "* { - return TARGET_SPARCLET ? \"umuld %1,%2,%L0\" : \"umul %1,%2,%L0\;rd %%y,%H0\"; + return TARGET_SPARCLET ? \"umuld\\t%1, %2, %L0\" : \"umul\\t%1, %2, %L0\\n\\trd\\t%%y, %H0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "sparclet") (const_int 1) (const_int 2)))]) +;; XXX (define_insn "const_umulsidi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=h,r") (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r,r")) @@ -4228,8 +5498,8 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 3 "=X,h"))] "TARGET_V8PLUS" "@ - umul %1,%2,%L0\;srlx %L0,32,%H0 - umul %1,%2,%3\;srlx %3,32,%H0\;mov %3,%L0" + umul\\t%1, %2, %L0\\n\\tsrlx\\t%L0, 32, %H0 + umul\\t%1, %2, %3\\n\\tsrlx\\t%3, 32, %H0\\n\\tmov\\t%3, %L0" [(set_attr "length" "2,3")]) (define_expand "umulsi3_highpart" @@ -4262,6 +5532,7 @@ return \"srl %1,0,%0\"; } }") +;; XXX (define_insn "umulsi3_highpart_v8plus" [(set (match_operand:SI 0 "register_operand" "=h,r") (truncate:SI @@ -4271,10 +5542,11 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 4 "=X,h"))] "TARGET_V8PLUS" "@ - umul %1,%2,%0\;srlx %0,%3,%0 - umul %1,%2,%4\;srlx %4,%3,%0" + umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 + umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "const_umulsi3_highpart_v8plus" [(set (match_operand:SI 0 "register_operand" "=h,r") (truncate:SI @@ -4284,51 +5556,58 @@ return \"srl %1,0,%0\"; (clobber (match_scratch:SI 4 "=X,h"))] "TARGET_V8PLUS" "@ - umul %1,%2,%0\;srlx %0,%3,%0 - umul %1,%2,%4\;srlx %4,%3,%0" + umul\\t%1, %2, %0\\n\\tsrlx\\t%0, %3, %0 + umul\\t%1, %2, %4\\n\\tsrlx\\t%4, %3, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "*umulsi3_highpart_sp32" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) (const_int 32))))] - "TARGET_HARD_MUL32" - "umul %1,%2,%%g0\;rd %%y,%0" + "TARGET_HARD_MUL32 + && ! TARGET_LIVE_G0" + "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" [(set_attr "length" "2")]) +;; XXX (define_insn "const_umulsi3_highpart" [(set (match_operand:SI 0 "register_operand" "=r") (truncate:SI (lshiftrt:DI (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) (match_operand:SI 2 "uns_small_int" "")) (const_int 32))))] - "TARGET_HARD_MUL32" - "umul %1,%2,%%g0\;rd %%y,%0" + "TARGET_HARD_MUL32 + && ! TARGET_LIVE_G0" + "umul\\t%1, %2, %%g0\\n\\trd\\t%%y, %0" [(set_attr "length" "2")]) ;; The v8 architecture specifies that there must be 3 instructions between ;; a y register write and a use of it for correct results. +;; XXX SHEESH (define_insn "divsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (div:SI (match_operand:SI 1 "register_operand" "r,r") - (match_operand:SI 2 "move_operand" "rI,m"))) + (match_operand:SI 2 "input_operand" "rI,m"))) (clobber (match_scratch:SI 3 "=&r,&r"))] - "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "(TARGET_V8 + || TARGET_DEPRECATED_V8_INSNS) + && ! TARGET_LIVE_G0" "* { if (which_alternative == 0) if (TARGET_V9) - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdiv %1,%2,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdiv\\t%1, %2, %0\"; else - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdiv %1,%2,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %2, %0\"; else if (TARGET_V9) - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;ld %2,%3\;sdiv %1,%3,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tsdiv\\t%1, %3, %0\"; else - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;ld %2,%3\;nop\;nop\;sdiv %1,%3,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tld\\t%2, %3\\n\\tnop\\n\\tnop\\n\\tsdiv\\t%1, %3, %0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "v9") @@ -4339,10 +5618,11 @@ return \"srl %1,0,%0\"; (div:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "sdivx %1,%2,%0") + "sdivx\\t%1, %2, %0") ;; It is not known whether this will match. +;; XXX I hope it doesn't fucking match... (define_insn "*cmp_sdiv_cc_set" [(set (match_operand:SI 0 "register_operand" "=r") (div:SI (match_operand:SI 1 "register_operand" "r") @@ -4351,36 +5631,41 @@ return \"srl %1,0,%0\"; (compare:CC (div:SI (match_dup 1) (match_dup 2)) (const_int 0))) (clobber (match_scratch:SI 3 "=&r"))] - "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "(TARGET_V8 + || TARGET_DEPRECATED_V8_INSNS) + && ! TARGET_LIVE_G0" "* { if (TARGET_V9) - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;sdivcc %1,%2,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tsdivcc\\t%1, %2, %0\"; else - return \"sra %1,31,%3\;wr %%g0,%3,%%y\;nop\;nop\;nop\;sdivcc %1,%2,%0\"; + return \"sra\\t%1, 31, %3\\n\\twr\\t%%g0, %3, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tsdivcc\\t%1, %2, %0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "v9") (const_int 3) (const_int 6)))]) +;; XXX (define_insn "udivsi3" [(set (match_operand:SI 0 "register_operand" "=r,&r,&r") (udiv:SI (match_operand:SI 1 "reg_or_nonsymb_mem_operand" "r,r,m") - (match_operand:SI 2 "move_operand" "rI,m,r")))] - "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + (match_operand:SI 2 "input_operand" "rI,m,r")))] + "(TARGET_V8 + || TARGET_DEPRECATED_V8_INSNS) + && ! TARGET_LIVE_G0" "* { - output_asm_insn (\"wr %%g0,%%g0,%%y\", operands); + output_asm_insn (\"wr\\t%%g0, %%g0, %%y\", operands); switch (which_alternative) { default: if (TARGET_V9) - return \"udiv %1,%2,%0\"; - return \"nop\;nop\;nop\;udiv %1,%2,%0\"; + return \"udiv\\t%1, %2, %0\"; + return \"nop\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %2, %0\"; case 1: - return \"ld %2,%0\;nop\;nop\;udiv %1,%0,%0\"; + return \"ld\\t%2, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%1, %0, %0\"; case 2: - return \"ld %1,%0\;nop\;nop\;udiv %0,%2,%0\"; + return \"ld\\t%1, %0\\n\\tnop\\n\\tnop\\n\\tudiv\\t%0, %2, %0\"; } }" [(set (attr "length") @@ -4393,10 +5678,11 @@ return \"srl %1,0,%0\"; (udiv:DI (match_operand:DI 1 "register_operand" "r") (match_operand:DI 2 "arith_double_operand" "rHI")))] "TARGET_ARCH64" - "udivx %1,%2,%0") + "udivx\\t%1, %2, %0") ;; It is not known whether this will match. +;; XXX I hope it doesn't fucking match... (define_insn "*cmp_udiv_cc_set" [(set (match_operand:SI 0 "register_operand" "=r") (udiv:SI (match_operand:SI 1 "register_operand" "r") @@ -4404,13 +5690,15 @@ return \"srl %1,0,%0\"; (set (reg:CC 100) (compare:CC (udiv:SI (match_dup 1) (match_dup 2)) (const_int 0)))] - "TARGET_V8 || TARGET_DEPRECATED_V8_INSNS" + "(TARGET_V8 + || TARGET_DEPRECATED_V8_INSNS) + && ! TARGET_LIVE_G0" "* { if (TARGET_V9) - return \"wr %%g0,%%g0,%%y\;udivcc %1,%2,%0\"; + return \"wr\\t%%g0, %%g0, %%y\\n\\tudivcc\\t%1, %2, %0\"; else - return \"wr %%g0,%%g0,%%y\;nop\;nop\;nop\;udivcc %1,%2,%0\"; + return \"wr\\t%%g0, %%g0, %%y\\n\\tnop\\n\\tnop\\n\\tnop\\n\\tudivcc\\t%1, %2, %0\"; }" [(set (attr "length") (if_then_else (eq_attr "isa" "v9") @@ -4424,8 +5712,9 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI")) (match_operand:SI 3 "register_operand" "0")))] "TARGET_SPARCLET" - "smac %1,%2,%0" - [(set_attr "type" "imul")]) + "smac\\t%1, %2, %0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) (define_insn "*smacdi" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4435,8 +5724,9 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "register_operand" "r"))) (match_operand:DI 3 "register_operand" "0")))] "TARGET_SPARCLET" - "smacd %1,%2,%L0" - [(set_attr "type" "imul")]) + "smacd\\t%1, %2, %L0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) (define_insn "*umacdi" [(set (match_operand:DI 0 "register_operand" "=r") @@ -4446,8 +5736,9 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "register_operand" "r"))) (match_operand:DI 3 "register_operand" "0")))] "TARGET_SPARCLET" - "umacd %1,%2,%L0" - [(set_attr "type" "imul")]) + "umacd\\t%1, %2, %L0" + [(set_attr "type" "imul") + (set_attr "length" "1")]) ;;- Boolean instructions ;; We define DImode `and' so with DImode `not' we can get @@ -4465,36 +5756,22 @@ return \"srl %1,0,%0\"; (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b") (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "! TARGET_ARCH64" - "* -{ - rtx op2 = operands[2]; - - if (which_alternative == 1) - return \"fand %1,%2,%0\"; - - if (GET_CODE (op2) == CONST_INT - || GET_CODE (op2) == CONST_DOUBLE) - { - rtx xoperands[4]; - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - if (WORDS_BIG_ENDIAN) - split_double (op2, &xoperands[2], &xoperands[3]); - else - split_double (op2, &xoperands[3], &xoperands[2]); - output_asm_insn (\"and %L1,%3,%L0\;and %H1,%2,%H0\", xoperands); - return \"\"; - } - return \"and %1,%2,%0\;and %R1,%R2,%R0\"; -}" - [(set_attr "length" "2,1")]) + "@ + # + fand\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "2,1")]) (define_insn "*anddi3_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (and:DI (match_operand:DI 1 "arith_double_operand" "%r,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "TARGET_ARCH64" - "and %1,%2,%0") + "@ + and\\t%1, %2, %0 + fand\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4502,9 +5779,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI,d")))] "" "@ - and %1,%2,%0 - fands %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + and\\t%1, %2, %0 + fands\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4527,12 +5805,19 @@ return \"srl %1,0,%0\"; (match_operator:DI 1 "cc_arithop" ; AND, IOR, XOR [(match_operand:DI 2 "register_operand" "") (match_operand:DI 3 "arith_double_operand" "")]))] - "! TARGET_ARCH64 && reload_completed - && GET_CODE (operands[0]) == REG && REGNO (operands[0]) < 32" + "! TARGET_ARCH64 + && reload_completed + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" [(set (match_dup 4) (match_op_dup:SI 1 [(match_dup 6) (match_dup 8)])) (set (match_dup 5) (match_op_dup:SI 1 [(match_dup 7) (match_dup 9)]))] " { + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); operands[4] = gen_highpart (SImode, operands[0]); operands[5] = gen_lowpart (SImode, operands[0]); operands[6] = gen_highpart (SImode, operands[2]); @@ -4555,16 +5840,43 @@ return \"srl %1,0,%0\"; (match_operand:DI 2 "register_operand" "r,b")))] "! TARGET_ARCH64" "@ - andn %2,%1,%0\;andn %R2,%R1,%R0 - fandnot1 %1,%2,%0" - [(set_attr "length" "2,1")]) + # + fandnot1\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "2,1")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (and:DI (not:DI (match_operand:DI 1 "register_operand" "")) + (match_operand:DI 2 "register_operand" "")))] + "! TARGET_ARCH64 + && reload_completed + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" + [(set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5))) + (set (match_dup 6) (and:SI (not:SI (match_dup 7)) (match_dup 8)))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[6] = gen_lowpart (SImode, operands[0]); + operands[7] = gen_lowpart (SImode, operands[1]); + operands[8] = gen_lowpart (SImode, operands[2]);") (define_insn "*and_not_di_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (and:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (and:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) + (match_operand:DI 2 "register_operand" "r,b")))] "TARGET_ARCH64" - "andn %2,%1,%0") + "@ + andn\\t%2, %1, %0 + fandnot1\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_insn "*and_not_si" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4572,9 +5884,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "register_operand" "r,d")))] "" "@ - andn %2,%1,%0 - fandnot1s %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + andn\\t%2, %1, %0 + fandnot1s\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_expand "iordi3" [(set (match_operand:DI 0 "register_operand" "") @@ -4587,37 +5900,23 @@ return \"srl %1,0,%0\"; [(set (match_operand:DI 0 "register_operand" "=r,b") (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b") (match_operand:DI 2 "arith_double_operand" "rHI,b")))] - "! TARGET_ARCH64" - "* -{ - rtx op2 = operands[2]; - - if (which_alternative == 1) - return \"for %1,%2,%0\"; - - if (GET_CODE (op2) == CONST_INT - || GET_CODE (op2) == CONST_DOUBLE) - { - rtx xoperands[4]; - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - if (WORDS_BIG_ENDIAN) - split_double (op2, &xoperands[2], &xoperands[3]); - else - split_double (op2, &xoperands[3], &xoperands[2]); - output_asm_insn (\"or %L1,%3,%L0\;or %H1,%2,%H0\", xoperands); - return \"\"; - } - return \"or %1,%2,%0\;or %R1,%R2,%R0\"; -}" - [(set_attr "length" "2,1")]) - -(define_insn "*iordi3_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (match_operand:DI 1 "arith_double_operand" "%r") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + "! TARGET_ARCH64" + "@ + # + for\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "2,1")]) + +(define_insn "*iordi3_sp64" + [(set (match_operand:DI 0 "register_operand" "=r,b") + (ior:DI (match_operand:DI 1 "arith_double_operand" "%r,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "TARGET_ARCH64" - "or %1,%2,%0") + "@ + or\\t%1, %2, %0 + for\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4625,9 +5924,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI,d")))] "" "@ - or %1,%2,%0 - fors %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + or\\t%1, %2, %0 + fors\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4650,16 +5950,43 @@ return \"srl %1,0,%0\"; (match_operand:DI 2 "register_operand" "r,b")))] "! TARGET_ARCH64" "@ - orn %2,%1,%0\;orn %R2,%R1,%R0 - fornot1 %1,%2,%0" - [(set_attr "length" "2,1")]) + # + fornot1\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "2,1")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (ior:DI (not:DI (match_operand:DI 1 "register_operand" "")) + (match_operand:DI 2 "register_operand" "")))] + "! TARGET_ARCH64 + && reload_completed + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" + [(set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5))) + (set (match_dup 6) (ior:SI (not:SI (match_dup 7)) (match_dup 8)))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[6] = gen_lowpart (SImode, operands[0]); + operands[7] = gen_lowpart (SImode, operands[1]); + operands[8] = gen_lowpart (SImode, operands[2]);") (define_insn "*or_not_di_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r")) - (match_operand:DI 2 "register_operand" "r")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (ior:DI (not:DI (match_operand:DI 1 "register_operand" "r,b")) + (match_operand:DI 2 "register_operand" "r,b")))] "TARGET_ARCH64" - "orn %2,%1,%0") + "@ + orn\\t%2, %1, %0 + fornot1\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_insn "*or_not_si" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4667,9 +5994,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "register_operand" "r,d")))] "" "@ - orn %2,%1,%0 - fornot1s %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + orn\\t%2, %1, %0 + fornot1s\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_expand "xordi3" [(set (match_operand:DI 0 "register_operand" "") @@ -4683,37 +6011,32 @@ return \"srl %1,0,%0\"; (xor:DI (match_operand:DI 1 "arith_double_operand" "%r,b") (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "! TARGET_ARCH64" - "* -{ - rtx op2 = operands[2]; - - if (which_alternative == 1) - return \"fxor %1,%2,%0\"; - - if (GET_CODE (op2) == CONST_INT - || GET_CODE (op2) == CONST_DOUBLE) - { - rtx xoperands[4]; - xoperands[0] = operands[0]; - xoperands[1] = operands[1]; - if (WORDS_BIG_ENDIAN) - split_double (op2, &xoperands[2], &xoperands[3]); - else - split_double (op2, &xoperands[3], &xoperands[2]); - output_asm_insn (\"xor %L1,%3,%L0\;xor %H1,%2,%H0\", xoperands); - return \"\"; - } - return \"xor %1,%2,%0\;xor %R1,%R2,%R0\"; -}" + "@ + # + fxor\\t%1, %2, %0" [(set_attr "length" "2,1") (set_attr "type" "ialu,fp")]) (define_insn "*xordi3_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ") - (match_operand:DI 2 "arith_double_operand" "rHI")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (xor:DI (match_operand:DI 1 "arith_double_operand" "%rJ,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b")))] "TARGET_ARCH64" - "xor %r1,%2,%0") + "@ + xor\\t%r1, %2, %0 + fxor\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) + +(define_insn "*xordi3_sp64_dbl" + [(set (match_operand:DI 0 "register_operand" "=r") + (xor:DI (match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "const64_operand" "")))] + "(TARGET_ARCH64 + && HOST_BITS_PER_WIDE_INT != 64)" + "xor\\t%1, %2, %0" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) (define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4721,9 +6044,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI,d")))] "" "@ - xor %r1,%2,%0 - fxors %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + xor\\t%r1, %2, %0 + fxors\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_split [(set (match_operand:SI 0 "register_operand" "") @@ -4763,18 +6087,43 @@ return \"srl %1,0,%0\"; (match_operand:DI 2 "register_operand" "r,b"))))] "! TARGET_ARCH64" "@ - xnor %1,%2,%0\;xnor %R1,%R2,%R0 - fxnor %1,%2,%0" + # + fxnor\\t%1, %2, %0" [(set_attr "length" "2,1") (set_attr "type" "ialu,fp")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (not:DI (xor:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "register_operand" ""))))] + "! TARGET_ARCH64 + && reload_completed + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" + [(set (match_dup 3) (not:SI (xor:SI (match_dup 4) (match_dup 5)))) + (set (match_dup 6) (not:SI (xor:SI (match_dup 7) (match_dup 8))))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[3] = gen_highpart (SImode, operands[0]); + operands[4] = gen_highpart (SImode, operands[1]); + operands[5] = gen_highpart (SImode, operands[2]); + operands[6] = gen_lowpart (SImode, operands[0]); + operands[7] = gen_lowpart (SImode, operands[1]); + operands[8] = gen_lowpart (SImode, operands[2]);") + (define_insn "*xor_not_di_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ") - (match_operand:DI 2 "arith_double_operand" "rHI"))))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (not:DI (xor:DI (match_operand:DI 1 "reg_or_0_operand" "rJ,b") + (match_operand:DI 2 "arith_double_operand" "rHI,b"))))] "TARGET_ARCH64" - "xnor %r1,%2,%0" - [(set_attr "type" "ialu")]) + "@ + xnor\\t%r1, %2, %0 + fxnor\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) (define_insn "*xor_not_si" [(set (match_operand:SI 0 "register_operand" "=r,d") @@ -4782,9 +6131,10 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI,d"))))] "" "@ - xnor %r1,%2,%0 - fxnors %1,%2,%0" - [(set_attr "type" "ialu,fp")]) + xnor\\t%r1, %2, %0 + fxnors\\t%1, %2, %0" + [(set_attr "type" "ialu,fp") + (set_attr "length" "1,1")]) ;; These correspond to the above in the case where we also (or only) ;; want to set the condition code. @@ -4796,9 +6146,10 @@ return \"srl %1,0,%0\"; [(match_operand:SI 0 "arith_operand" "%r") (match_operand:SI 1 "arith_operand" "rI")]) (const_int 0)))] - "" - "%A2cc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "%A2cc\\t%0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_arith_op" [(set (reg:CCX 100) @@ -4808,8 +6159,9 @@ return \"srl %1,0,%0\"; (match_operand:DI 1 "arith_double_operand" "rHI")]) (const_int 0)))] "TARGET_ARCH64" - "%A2cc %0,%1,%%g0" - [(set_attr "type" "compare")]) + "%A2cc\\t%0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_arith_op_set" [(set (reg:CC 100) @@ -4821,7 +6173,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (match_dup 3))] "" - "%A3cc %1,%2,%0") + "%A3cc\\t%1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_arith_op_set" [(set (reg:CCX 100) @@ -4833,7 +6187,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (match_dup 3))] "TARGET_ARCH64" - "%A3cc %1,%2,%0") + "%A3cc\\t%1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_xor_not" [(set (reg:CC 100) @@ -4841,9 +6197,10 @@ return \"srl %1,0,%0\"; (not:SI (xor:SI (match_operand:SI 0 "reg_or_0_operand" "%rJ") (match_operand:SI 1 "arith_operand" "rI"))) (const_int 0)))] - "" - "xnorcc %r0,%1,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "xnorcc\\t%r0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_xor_not" [(set (reg:CCX 100) @@ -4852,8 +6209,9 @@ return \"srl %1,0,%0\"; (match_operand:DI 1 "arith_double_operand" "rHI"))) (const_int 0)))] "TARGET_ARCH64" - "xnorcc %r0,%1,%%g0" - [(set_attr "type" "compare")]) + "xnorcc\\t%r0, %1, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_xor_not_set" [(set (reg:CC 100) @@ -4864,7 +6222,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (not:SI (xor:SI (match_dup 1) (match_dup 2))))] "" - "xnorcc %r1,%2,%0") + "xnorcc\\t%r1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_xor_not_set" [(set (reg:CCX 100) @@ -4875,7 +6235,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (not:DI (xor:DI (match_dup 1) (match_dup 2))))] "TARGET_ARCH64" - "xnorcc %r1,%2,%0") + "xnorcc\\t%r1, %2, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_arith_op_not" [(set (reg:CC 100) @@ -4884,9 +6246,10 @@ return \"srl %1,0,%0\"; [(not:SI (match_operand:SI 0 "arith_operand" "rI")) (match_operand:SI 1 "reg_or_0_operand" "rJ")]) (const_int 0)))] - "" - "%B2cc %r1,%0,%%g0" - [(set_attr "type" "compare")]) + "! TARGET_LIVE_G0" + "%B2cc\\t%r1, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_arith_op_not" [(set (reg:CCX 100) @@ -4896,8 +6259,9 @@ return \"srl %1,0,%0\"; (match_operand:DI 1 "reg_or_0_operand" "rJ")]) (const_int 0)))] "TARGET_ARCH64" - "%B2cc %r1,%0,%%g0" - [(set_attr "type" "compare")]) + "%B2cc\\t%r1, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_arith_op_not_set" [(set (reg:CC 100) @@ -4909,7 +6273,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (match_dup 3))] "" - "%B3cc %r2,%1,%0") + "%B3cc\\t%r2, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_arith_op_not_set" [(set (reg:CCX 100) @@ -4921,7 +6287,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (match_dup 3))] "TARGET_ARCH64" - "%B3cc %r2,%1,%0") + "%B3cc\\t%r2, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;; We cannot use the "neg" pseudo insn because the Sun assembler ;; does not know how to make it work for constants. @@ -4947,54 +6315,81 @@ return \"srl %1,0,%0\"; [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "register_operand" "r"))) (clobber (reg:CC 100))] - "! TARGET_ARCH64" - "* -{ - if (TARGET_LIVE_G0) - output_asm_insn (\"and %%g0,0,%%g0\", operands); - return \"subcc %%g0,%L1,%L0\;subx %%g0,%H1,%H0\"; -}" + "! TARGET_ARCH64 + && ! TARGET_LIVE_G0" + "#" [(set_attr "type" "unary") - ;; ??? This is wrong for TARGET_LIVE_G0 but it's not critical. (set_attr "length" "2")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (neg:DI (match_operand:DI 1 "register_operand" ""))) + (clobber (reg:CC 100))] + "! TARGET_ARCH64 + && ! TARGET_LIVE_G0 + && reload_completed" + [(parallel [(set (reg:CC_NOOV 100) + (compare:CC_NOOV (minus:SI (const_int 0) (match_dup 5)) + (const_int 0))) + (set (match_dup 4) (minus:SI (const_int 0) (match_dup 5)))]) + (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) + (ltu:SI (reg:CC 100) (const_int 0))))] + "operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); + operands[4] = gen_lowpart (SImode, operands[0]); + operands[5] = gen_lowpart (SImode, operands[1]);") + (define_insn "*negdi2_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_operand:DI 1 "register_operand" "r")))] "TARGET_ARCH64" - "sub %%g0,%1,%0" + "sub\\t%%g0, %1, %0" [(set_attr "type" "unary") (set_attr "length" "1")]) -(define_insn "negsi2" - [(set (match_operand:SI 0 "register_operand" "=r") - (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] +(define_expand "negsi2" + [(set (match_operand:SI 0 "register_operand" "") + (neg:SI (match_operand:SI 1 "arith_operand" "")))] "" - "* + " { if (TARGET_LIVE_G0) - return \"and %%g0,0,%%g0\;sub %%g0,%1,%0\"; - return \"sub %%g0,%1,%0\"; -}" + { + rtx zero_reg = gen_reg_rtx (SImode); + + emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx)); + emit_insn (gen_rtx_SET (VOIDmode, operands[0], + gen_rtx_MINUS (SImode, zero_reg, + operands[1]))); + DONE; + } +}") + +(define_insn "*negsi2_not_liveg0" + [(set (match_operand:SI 0 "register_operand" "=r") + (neg:SI (match_operand:SI 1 "arith_operand" "rI")))] + "! TARGET_LIVE_G0" + "sub\\t%%g0, %1, %0" [(set_attr "type" "unary") - (set (attr "length") - (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)))]) + (set_attr "length" "1")]) (define_insn "*cmp_cc_neg" [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] "! TARGET_LIVE_G0" - "subcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) + "subcc\\t%%g0, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_neg" [(set (reg:CCX_NOOV 100) (compare:CCX_NOOV (neg:DI (match_operand:DI 0 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" - "subcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) + "subcc\\t%%g0, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_set_neg" [(set (reg:CC_NOOV 100) @@ -5003,8 +6398,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_dup 1)))] "! TARGET_LIVE_G0" - "subcc %%g0,%1,%0" - [(set_attr "type" "unary")]) + "subcc\\t%%g0, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_set_neg" [(set (reg:CCX_NOOV 100) @@ -5013,8 +6409,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (neg:DI (match_dup 1)))] "TARGET_ARCH64" - "subcc %%g0,%1,%0" - [(set_attr "type" "unary")]) + "subcc\\t%%g0, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;; We cannot use the "not" pseudo insn because the Sun assembler ;; does not know how to make it work for constants. @@ -5029,53 +6426,99 @@ return \"srl %1,0,%0\"; (not:DI (match_operand:DI 1 "register_operand" "r,b")))] "! TARGET_ARCH64" "@ - xnor %1,0,%0\;xnor %R1,0,%R0 - fnot1 %1,%0" + # + fnot1\\t%1, %0" [(set_attr "type" "unary,fp") (set_attr "length" "2,1")]) +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (not:DI (match_operand:DI 1 "register_operand" "")))] + "! TARGET_ARCH64 + && reload_completed + && ((GET_CODE (operands[0]) == REG + && REGNO (operands[0]) < 32) + || (GET_CODE (operands[0]) == SUBREG + && GET_CODE (SUBREG_REG (operands[0])) == REG + && REGNO (SUBREG_REG (operands[0])) < 32))" + [(set (match_dup 2) (not:SI (xor:SI (match_dup 3) (const_int 0)))) + (set (match_dup 4) (not:SI (xor:SI (match_dup 5) (const_int 0))))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + operands[2] = gen_highpart (SImode, operands[0]); + operands[3] = gen_highpart (SImode, operands[1]); + operands[4] = gen_lowpart (SImode, operands[0]); + operands[5] = gen_lowpart (SImode, operands[1]);") + (define_insn "*one_cmpldi2_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (not:DI (match_operand:DI 1 "arith_double_operand" "rHI")))] + [(set (match_operand:DI 0 "register_operand" "=r,b") + (not:DI (match_operand:DI 1 "arith_double_operand" "rHI,b")))] "TARGET_ARCH64" - "xnor %1,0,%0" - [(set_attr "type" "unary")]) + "@ + xnor\\t%%g0, %1, %0 + fnot1\\t%1, %0" + [(set_attr "type" "unary,fp") + (set_attr "length" "1")]) -(define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "register_operand" "=r,r,d") - (not:SI (match_operand:SI 1 "arith_operand" "r,I,d")))] +(define_expand "one_cmplsi2" + [(set (match_operand:SI 0 "register_operand" "") + (not:SI (match_operand:SI 1 "arith_operand" "")))] "" - "* + " { - if (which_alternative == 0) - return \"xnor %1,0,%0\"; - if (which_alternative == 2) - return \"fnot1s %1,%0\"; - if (TARGET_LIVE_G0) - output_asm_insn (\"and %%g0,0,%%g0\", operands); - return \"xnor %%g0,%1,%0\"; -}" - [(set_attr "type" "unary,unary,fp") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "live_g0" "yes") (const_int 2) (const_int 1)) - (const_int 1)])]) + if (TARGET_LIVE_G0 + && GET_CODE (operands[1]) == CONST_INT) + { + rtx zero_reg = gen_reg_rtx (SImode); + + emit_insn (gen_rtx_SET (VOIDmode, zero_reg, const0_rtx)); + emit_insn (gen_rtx_SET (VOIDmode, + operands[0], + gen_rtx_NOT (SImode, + gen_rtx_XOR (SImode, + zero_reg, + operands[1])))); + DONE; + } +}") + +(define_insn "*one_cmplsi2_not_liveg0" + [(set (match_operand:SI 0 "register_operand" "=r,d") + (not:SI (match_operand:SI 1 "arith_operand" "rI,d")))] + "! TARGET_LIVE_G0" + "@ + xnor\\t%%g0, %1, %0 + fnot1s\\t%1, %0" + [(set_attr "type" "unary,fp") + (set_attr "length" "1,1")]) + +(define_insn "*one_cmplsi2_liveg0" + [(set (match_operand:SI 0 "register_operand" "=r,d") + (not:SI (match_operand:SI 1 "arith_operand" "r,d")))] + "TARGET_LIVE_G0" + "@ + xnor\\t%1, 0, %0 + fnot1s\\t%1, %0" + [(set_attr "type" "unary,fp") + (set_attr "length" "1,1")]) (define_insn "*cmp_cc_not" [(set (reg:CC 100) (compare:CC (not:SI (match_operand:SI 0 "arith_operand" "rI")) (const_int 0)))] "! TARGET_LIVE_G0" - "xnorcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) + "xnorcc\\t%%g0, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_not" [(set (reg:CCX 100) (compare:CCX (not:DI (match_operand:DI 0 "arith_double_operand" "rHI")) (const_int 0)))] "TARGET_ARCH64" - "xnorcc %%g0,%0,%%g0" - [(set_attr "type" "compare")]) + "xnorcc\\t%%g0, %0, %%g0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_cc_set_not" [(set (reg:CC 100) @@ -5084,8 +6527,9 @@ return \"srl %1,0,%0\"; (set (match_operand:SI 0 "register_operand" "=r") (not:SI (match_dup 1)))] "! TARGET_LIVE_G0" - "xnorcc %%g0,%1,%0" - [(set_attr "type" "unary")]) + "xnorcc\\t%%g0, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) (define_insn "*cmp_ccx_set_not" [(set (reg:CCX 100) @@ -5094,8 +6538,9 @@ return \"srl %1,0,%0\"; (set (match_operand:DI 0 "register_operand" "=r") (not:DI (match_dup 1)))] "TARGET_ARCH64" - "xnorcc %%g0,%1,%0" - [(set_attr "type" "unary")]) + "xnorcc\\t%%g0, %1, %0" + [(set_attr "type" "compare") + (set_attr "length" "1")]) ;; Floating point arithmetic instructions. @@ -5104,88 +6549,99 @@ return \"srl %1,0,%0\"; (plus:TF (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "faddq %1,%2,%0" - [(set_attr "type" "fp")]) + "faddq\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "adddf3" [(set (match_operand:DF 0 "register_operand" "=e") (plus:DF (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] "TARGET_FPU" - "faddd %1,%2,%0" - [(set_attr "type" "fp")]) + "faddd\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=f") (plus:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_FPU" - "fadds %1,%2,%0" - [(set_attr "type" "fp")]) + "fadds\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "subtf3" [(set (match_operand:TF 0 "register_operand" "=e") (minus:TF (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fsubq %1,%2,%0" - [(set_attr "type" "fp")]) + "fsubq\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=e") (minus:DF (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] "TARGET_FPU" - "fsubd %1,%2,%0" - [(set_attr "type" "fp")]) + "fsubd\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f") (minus:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_FPU" - "fsubs %1,%2,%0" - [(set_attr "type" "fp")]) + "fsubs\\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "length" "1")]) (define_insn "multf3" [(set (match_operand:TF 0 "register_operand" "=e") (mult:TF (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fmulq %1,%2,%0" - [(set_attr "type" "fpmul")]) + "fmulq\\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "length" "1")]) (define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=e") (mult:DF (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] "TARGET_FPU" - "fmuld %1,%2,%0" - [(set_attr "type" "fpmul")]) + "fmuld\\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "length" "1")]) (define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_FPU" - "fmuls %1,%2,%0" - [(set_attr "type" "fpmul")]) + "fmuls\\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "length" "1")]) (define_insn "*muldf3_extend" [(set (match_operand:DF 0 "register_operand" "=e") (mult:DF (float_extend:DF (match_operand:SF 1 "register_operand" "f")) (float_extend:DF (match_operand:SF 2 "register_operand" "f"))))] "(TARGET_V8 || TARGET_V9) && TARGET_FPU" - "fsmuld %1,%2,%0" - [(set_attr "type" "fpmul")]) + "fsmuld\\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "length" "1")]) (define_insn "*multf3_extend" [(set (match_operand:TF 0 "register_operand" "=e") (mult:TF (float_extend:TF (match_operand:DF 1 "register_operand" "e")) (float_extend:TF (match_operand:DF 2 "register_operand" "e"))))] "(TARGET_V8 || TARGET_V9) && TARGET_FPU && TARGET_HARD_QUAD" - "fdmulq %1,%2,%0" - [(set_attr "type" "fpmul")]) + "fdmulq\\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "length" "1")]) ;; don't have timing for quad-prec. divide. (define_insn "divtf3" @@ -5193,133 +6649,295 @@ return \"srl %1,0,%0\"; (div:TF (match_operand:TF 1 "register_operand" "e") (match_operand:TF 2 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fdivq %1,%2,%0" - [(set_attr "type" "fpdivd")]) + "fdivq\\t%1, %2, %0" + [(set_attr "type" "fpdivd") + (set_attr "length" "1")]) (define_insn "divdf3" [(set (match_operand:DF 0 "register_operand" "=e") (div:DF (match_operand:DF 1 "register_operand" "e") (match_operand:DF 2 "register_operand" "e")))] "TARGET_FPU" - "fdivd %1,%2,%0" - [(set_attr "type" "fpdivd")]) + "fdivd\\t%1, %2, %0" + [(set_attr "type" "fpdivd") + (set_attr "length" "1")]) (define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=f") (div:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "register_operand" "f")))] "TARGET_FPU" - "fdivs %1,%2,%0" - [(set_attr "type" "fpdivs")]) + "fdivs\\t%1, %2, %0" + [(set_attr "type" "fpdivs") + (set_attr "length" "1")]) -(define_insn "negtf2" +(define_expand "negtf2" [(set (match_operand:TF 0 "register_operand" "=e,e") (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] - ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. "TARGET_FPU" - "* -{ - /* v9: can't use fnegs, won't work with upper regs. */ - if (which_alternative == 0) - return TARGET_V9 ? \"fnegd %0,%0\" : \"fnegs %0,%0\"; - else - return TARGET_V9 ? \"fnegd %1,%0\;fmovd %S1,%S0\" - : \"fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; -}" + "") + +(define_insn "*negtf2_notv9" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] + ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. + "TARGET_FPU + && ! TARGET_V9" + "@ + fnegs\\t%0, %0 + #" [(set_attr "type" "fpmove") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])]) + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (neg:TF (match_operand:TF 1 "register_operand" "")))] + "TARGET_FPU + && ! TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (neg:SF (match_dup 3))) + (set (match_dup 4) (match_dup 5)) + (set (match_dup 6) (match_dup 7))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); + operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); + operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); + operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") + +(define_insn "*negtf2_v9" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (neg:TF (match_operand:TF 1 "register_operand" "0,e")))] + ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. + "TARGET_FPU && TARGET_V9" + "@ + fnegd\\t%0, %0 + #" + [(set_attr "type" "fpmove") + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (neg:TF (match_operand:TF 1 "register_operand" "")))] + "TARGET_FPU + && TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (neg:DF (match_dup 3))) + (set (match_dup 4) (match_dup 5))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); + operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") + +(define_expand "negdf2" + [(set (match_operand:DF 0 "register_operand" "") + (neg:DF (match_operand:DF 1 "register_operand" "")))] + "TARGET_FPU" + "") -(define_insn "negdf2" +(define_insn "*negdf2_notv9" [(set (match_operand:DF 0 "register_operand" "=e,e") (neg:DF (match_operand:DF 1 "register_operand" "0,e")))] - "TARGET_FPU" - "* -{ - if (TARGET_V9) - return \"fnegd %1,%0\"; - else if (which_alternative == 0) - return \"fnegs %0,%0\"; - else - return \"fnegs %1,%0\;fmovs %R1,%R0\"; -}" + "TARGET_FPU && ! TARGET_V9" + "@ + fnegs\\t%0, %0 + #" [(set_attr "type" "fpmove") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])]) + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (neg:DF (match_operand:DF 1 "register_operand" "")))] + "TARGET_FPU + && ! TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (neg:SF (match_dup 3))) + (set (match_dup 4) (match_dup 5))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); + operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);") + +(define_insn "*negdf2_v9" + [(set (match_operand:DF 0 "register_operand" "=e") + (neg:DF (match_operand:DF 1 "register_operand" "e")))] + "TARGET_FPU && TARGET_V9" + "fnegd\\t%1, %0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) (define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" - "fnegs %1,%0" - [(set_attr "type" "fpmove")]) + "fnegs\\t%1, %0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) + +(define_expand "abstf2" + [(set (match_operand:TF 0 "register_operand" "") + (abs:TF (match_operand:TF 1 "register_operand" "")))] + "TARGET_FPU" + "") -(define_insn "abstf2" +(define_insn "*abstf2_notv9" [(set (match_operand:TF 0 "register_operand" "=e,e") (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] ; We don't use quad float insns here so we don't need TARGET_HARD_QUAD. - "TARGET_FPU" - "* -{ - /* v9: can't use fabss, won't work with upper regs. */ - if (which_alternative == 0) - return TARGET_V9 ? \"fabsd %0,%0\" : \"fabss %0,%0\"; - else - return TARGET_V9 ? \"fabsd %1,%0\;fmovd %S1,%S0\" - : \"fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0\"; -}" + "TARGET_FPU && ! TARGET_V9" + "@ + fabss\\t%0, %0 + #" + [(set_attr "type" "fpmove") + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "=e,e") + (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] + "TARGET_FPU + && ! TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (abs:SF (match_dup 3))) + (set (match_dup 4) (match_dup 5)) + (set (match_dup 6) (match_dup 7))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); + operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1); + operands[6] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); + operands[7] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") + +(define_insn "*abstf2_hq_v9" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] + "TARGET_FPU && TARGET_V9 && TARGET_HARD_QUAD" + "@ + fabsd\\t%0, %0 + fabsq\\t%1, %0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) + +(define_insn "*abstf2_v9" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] + "TARGET_FPU && TARGET_V9 && !TARGET_HARD_QUAD" + "@ + fabsd\\t%0, %0 + #" [(set_attr "type" "fpmove") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "isa" "v9") (const_int 2) (const_int 4))])]) + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "=e,e") + (abs:TF (match_operand:TF 1 "register_operand" "0,e")))] + "TARGET_FPU + && TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (abs:DF (match_dup 3))) + (set (match_dup 4) (match_dup 5))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (DFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (DFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (DFmode, REGNO (operands[0]) + 2); + operands[5] = gen_rtx_raw_REG (DFmode, REGNO (operands[1]) + 2);") + +(define_expand "absdf2" + [(set (match_operand:DF 0 "register_operand" "") + (abs:DF (match_operand:DF 1 "register_operand" "")))] + "TARGET_FPU" + "") -(define_insn "absdf2" +(define_insn "*absdf2_notv9" [(set (match_operand:DF 0 "register_operand" "=e,e") (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] - "TARGET_FPU" - "* -{ - if (TARGET_V9) - return \"fabsd %1,%0\"; - else if (which_alternative == 0) - return \"fabss %0,%0\"; - else - return \"fabss %1,%0\;fmovs %R1,%R0\"; -}" + "TARGET_FPU && ! TARGET_V9" + "@ + fabss\\t%0, %0 + #" + [(set_attr "type" "fpmove") + (set_attr "length" "1,2")]) + +(define_split + [(set (match_operand:DF 0 "register_operand" "=e,e") + (abs:DF (match_operand:DF 1 "register_operand" "0,e")))] + "TARGET_FPU + && ! TARGET_V9 + && reload_completed + && sparc_absnegfloat_split_legitimate (operands[0], operands[1])" + [(set (match_dup 2) (abs:SF (match_dup 3))) + (set (match_dup 4) (match_dup 5))] + "if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); + operands[2] = gen_rtx_raw_REG (SFmode, REGNO (operands[0])); + operands[3] = gen_rtx_raw_REG (SFmode, REGNO (operands[1])); + operands[4] = gen_rtx_raw_REG (SFmode, REGNO (operands[0]) + 1); + operands[5] = gen_rtx_raw_REG (SFmode, REGNO (operands[1]) + 1);") + +(define_insn "*absdf2_v9" + [(set (match_operand:DF 0 "register_operand" "=e") + (abs:DF (match_operand:DF 1 "register_operand" "e")))] + "TARGET_FPU && TARGET_V9" + "fabsd\\t%1, %0" [(set_attr "type" "fpmove") - (set_attr_alternative "length" - [(const_int 1) - (if_then_else (eq_attr "isa" "v9") (const_int 1) (const_int 2))])]) + (set_attr "length" "1")]) (define_insn "abssf2" [(set (match_operand:SF 0 "register_operand" "=f") (abs:SF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" - "fabss %1,%0" - [(set_attr "type" "fpmove")]) + "fabss\\t%1, %0" + [(set_attr "type" "fpmove") + (set_attr "length" "1")]) (define_insn "sqrttf2" [(set (match_operand:TF 0 "register_operand" "=e") (sqrt:TF (match_operand:TF 1 "register_operand" "e")))] "TARGET_FPU && TARGET_HARD_QUAD" - "fsqrtq %1,%0" - [(set_attr "type" "fpsqrt")]) + "fsqrtq\\t%1, %0" + [(set_attr "type" "fpsqrt") + (set_attr "length" "1")]) (define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=e") (sqrt:DF (match_operand:DF 1 "register_operand" "e")))] "TARGET_FPU" - "fsqrtd %1,%0" - [(set_attr "type" "fpsqrt")]) + "fsqrtd\\t%1, %0" + [(set_attr "type" "fpsqrt") + (set_attr "length" "1")]) (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] "TARGET_FPU" - "fsqrts %1,%0" - [(set_attr "type" "fpsqrt")]) + "fsqrts\\t%1, %0" + [(set_attr "type" "fpsqrt") + (set_attr "length" "1")]) ;;- arithmetic shift instructions @@ -5334,9 +6952,21 @@ return \"srl %1,0,%0\"; && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); - return \"sll %1,%2,%0\"; + return \"sll\\t%1, %2, %0\"; }" - [(set_attr "type" "shift")]) + [(set_attr "type" "shift") + (set_attr "length" "1")]) + +;; We special case multiplication by two, as add can be done +;; in both ALUs, while shift only in IEU0 on UltraSPARC. +(define_insn "*ashlsi3_const1" + [(set (match_operand:SI 0 "register_operand" "=r") + (ashift:SI (match_operand:SI 1 "register_operand" "r") + (const_int 1)))] + "" + "add\\t%1, %1, %0" + [(set_attr "type" "binary") + (set_attr "length" "1")]) (define_expand "ashldi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5354,7 +6984,18 @@ return \"srl %1,0,%0\"; } }") -(define_insn "" +;; We special case multiplication by two, as add can be done +;; in both ALUs, while shift only in IEU0 on UltraSPARC. +(define_insn "*ashldi3_const1" + [(set (match_operand:DI 0 "register_operand" "=r") + (ashift:DI (match_operand:DI 1 "register_operand" "r") + (const_int 1)))] + "TARGET_ARCH64" + "add\\t%1, %1, %0" + [(set_attr "type" "binary") + (set_attr "length" "1")]) + +(define_insn "*ashldi3_sp64" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (match_operand:DI 1 "register_operand" "r") (match_operand:SI 2 "arith_operand" "rI")))] @@ -5362,12 +7003,15 @@ return \"srl %1,0,%0\"; "* { if (GET_CODE (operands[2]) == CONST_INT - && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) + && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); - return \"sllx %1,%2,%0\"; -}") + return \"sllx\\t%1, %2, %0\"; +}" + [(set_attr "type" "shift") + (set_attr "length" "1")]) +;; XXX UGH! (define_insn "ashldi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") (ashift:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") @@ -5378,12 +7022,14 @@ return \"srl %1,0,%0\"; [(set_attr "length" "5,5,6")]) ;; Optimize (1LL< 31) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); - return \"sra %1,%2,%0\"; + return \"sra\\t%1, %2, %0\"; }" - [(set_attr "type" "shift")]) + [(set_attr "type" "shift") + (set_attr "length" "1")]) + +(define_insn "*ashrsi3_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (sign_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "r"))))] + "TARGET_ARCH64" + "sra\\t%1, %2, %0" + [(set_attr "type" "shift") + (set_attr "length" "1")]) + +;; This handles the case as above, but with constant shift instead of +;; register. Combiner "simplifies" it for us a little bit though. +(define_insn "*ashrsi3_extend2" + [(set (match_operand:DI 0 "register_operand" "=r") + (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) + (const_int 32)) + (match_operand:SI 2 "small_int_or_double" "n")))] + "TARGET_ARCH64 + && ((GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) >= 32 && INTVAL (operands[2]) < 64) + || (GET_CODE (operands[2]) == CONST_DOUBLE + && !CONST_DOUBLE_HIGH (operands[2]) + && CONST_DOUBLE_LOW (operands[2]) >= 32 + && CONST_DOUBLE_LOW (operands[2]) < 64))" + "* +{ + operands[2] = GEN_INT (INTVAL (operands[2]) - 32); + + return \"sra\\t%1, %2, %0\"; +}" + [(set_attr "type" "shift") + (set_attr "length" "1")]) (define_expand "ashrdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5432,13 +7114,15 @@ return \"srl %1,0,%0\"; (match_operand:SI 2 "arith_operand" "rI")))] "TARGET_ARCH64 || TARGET_V8PLUS" " -if (! TARGET_ARCH64) - { - if (GET_CODE (operands[2]) == CONST_INT) - FAIL; /* prefer generic code in this case */ - emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); - DONE; - }") +{ + if (! TARGET_ARCH64) + { + if (GET_CODE (operands[2]) == CONST_INT) + FAIL; /* prefer generic code in this case */ + emit_insn (gen_ashrdi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5451,9 +7135,12 @@ if (! TARGET_ARCH64) && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); - return \"srax %1,%2,%0\"; -}") + return \"srax\\t%1, %2, %0\"; +}" + [(set_attr "type" "shift") + (set_attr "length" "1")]) +;; XXX (define_insn "ashrdi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") (ashiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") @@ -5474,9 +7161,54 @@ if (! TARGET_ARCH64) && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 31) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); - return \"srl %1,%2,%0\"; + return \"srl\\t%1, %2, %0\"; +}" + [(set_attr "type" "shift") + (set_attr "length" "1")]) + +;; This handles the case where +;; (zero_extend:DI (lshiftrt:SI (match_operand:SI) (match_operand:SI))), +;; but combiner "simplifies" it for us. +(define_insn "*lshrsi3_extend" + [(set (match_operand:DI 0 "register_operand" "=r") + (and:DI (subreg:DI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (match_operand:SI 2 "arith_operand" "r")) 0) + (match_operand 3 "" "")))] + "TARGET_ARCH64 + && ((GET_CODE (operands[3]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[3]) == 0 + && CONST_DOUBLE_LOW (operands[3]) == 0xffffffff) +#if HOST_BITS_PER_WIDE_INT >= 64 + || (GET_CODE (operands[3]) == CONST_INT + && (unsigned HOST_WIDE_INT) INTVAL (operands[3]) == 0xffffffff) +#endif + )" + "srl\\t%1, %2, %0" + [(set_attr "type" "shift") + (set_attr "length" "1")]) + +;; This handles the case where +;; (lshiftrt:DI (zero_extend:DI (match_operand:SI)) (const_int >=0 < 32)) +;; but combiner "simplifies" it for us. +(define_insn "*lshrsi3_extend2" + [(set (match_operand:DI 0 "register_operand" "=r") + (zero_extract:DI (subreg:DI (match_operand:SI 1 "register_operand" "r") 0) + (match_operand 2 "small_int_or_double" "n") + (const_int 32)))] + "TARGET_ARCH64 + && ((GET_CODE (operands[2]) == CONST_INT + && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) < 32) + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[2]) == 0 + && (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (operands[2]) < 32))" + "* +{ + operands[2] = GEN_INT (32 - INTVAL (operands[2])); + + return \"srl\\t%1, %2, %0\"; }" - [(set_attr "type" "shift")]) + [(set_attr "type" "shift") + (set_attr "length" "1")]) (define_expand "lshrdi3" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5484,13 +7216,15 @@ if (! TARGET_ARCH64) (match_operand:SI 2 "arith_operand" "rI")))] "TARGET_ARCH64 || TARGET_V8PLUS" " -if (! TARGET_ARCH64) - { - if (GET_CODE (operands[2]) == CONST_INT) - FAIL; - emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); - DONE; - }") +{ + if (! TARGET_ARCH64) + { + if (GET_CODE (operands[2]) == CONST_INT) + FAIL; + emit_insn (gen_lshrdi3_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}") (define_insn "" [(set (match_operand:DI 0 "register_operand" "=r") @@ -5503,9 +7237,12 @@ if (! TARGET_ARCH64) && (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 63) operands[2] = GEN_INT (INTVAL (operands[2]) & 0x3f); - return \"srlx %1,%2,%0\"; -}") + return \"srlx\\t%1, %2, %0\"; +}" + [(set_attr "type" "shift") + (set_attr "length" "1")]) +;; XXX (define_insn "lshrdi3_v8plus" [(set (match_operand:DI 0 "register_operand" "=&h,&h,r") (lshiftrt:DI (match_operand:DI 1 "arith_operand" "rI,0,rI") @@ -5524,19 +7261,19 @@ if (! TARGET_ARCH64) "" "* { - /* Some implementations (e.g. TurboSparc) are reported to have problems + /* 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 (flag_delayed_branch + if (! TARGET_V9 && flag_delayed_branch && (insn_addresses[INSN_UID (operands[0])] == insn_addresses[INSN_UID (insn)])) - return \"b %l0%#\"; + return \"b\\t%l0%#\"; else - return \"b%* %l0%(\"; + return TARGET_V9 ? \"ba,pt%*\\t%%xcc, %l0%(\" : \"b%*\\t%l0%(\"; }" [(set_attr "type" "uncond_branch")]) @@ -5546,7 +7283,7 @@ if (! TARGET_ARCH64) "" " { - if (GET_MODE (operands[0]) != Pmode) + if (GET_MODE (operands[0]) != CASE_VECTOR_MODE) abort (); /* In pic mode, our address differences are against the base of the @@ -5557,6 +7294,8 @@ if (! TARGET_ARCH64) rtx tmp, tmp2; tmp = gen_rtx_LABEL_REF (Pmode, operands[1]); tmp2 = operands[0]; + if (CASE_VECTOR_MODE != Pmode) + tmp2 = gen_rtx_SIGN_EXTEND (Pmode, tmp2); tmp = gen_rtx_PLUS (Pmode, tmp2, tmp); operands[0] = memory_address (Pmode, tmp); } @@ -5566,14 +7305,14 @@ if (! TARGET_ARCH64) [(set (pc) (match_operand:SI 0 "address_operand" "p")) (use (label_ref (match_operand 1 "" "")))] "! TARGET_PTR64" - "jmp %a0%#" + "jmp\\t%a0%#" [(set_attr "type" "uncond_branch")]) (define_insn "*tablejump_sp64" [(set (pc) (match_operand:DI 0 "address_operand" "p")) (use (label_ref (match_operand 1 "" "")))] "TARGET_PTR64" - "jmp %a0%#" + "jmp\\t%a0%#" [(set_attr "type" "uncond_branch")]) ;; This pattern recognizes the "instruction" that appears in @@ -5582,7 +7321,7 @@ if (! TARGET_ARCH64) ;(define_insn "*unimp_insn" ; [(match_operand:SI 0 "immediate_operand" "")] ; "GET_CODE (operands[0]) == CONST_INT && INTVAL (operands[0]) > 0" -; "unimp %0" +; "unimp\\t%0" ; [(set_attr "type" "marker")]) ;;- jump to subroutine @@ -5681,7 +7420,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_PTR64" - "call %a0,%1%#" + "call\\t%a0, %1%#" [(set_attr "type" "call")]) (define_insn "*call_symbolic_sp32" @@ -5690,7 +7429,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_PTR64" - "call %a0,%1%#" + "call\\t%a0, %1%#" [(set_attr "type" "call")]) (define_insn "*call_address_sp64" @@ -5699,7 +7438,7 @@ if (! TARGET_ARCH64) (clobber (reg:DI 15))] ;;- Do not use operand 1 for most machines. "TARGET_PTR64" - "call %a0,%1%#" + "call\\t%a0, %1%#" [(set_attr "type" "call")]) (define_insn "*call_symbolic_sp64" @@ -5708,7 +7447,7 @@ if (! TARGET_ARCH64) (clobber (reg:DI 15))] ;;- Do not use operand 1 for most machines. "TARGET_PTR64" - "call %a0,%1%#" + "call\\t%a0, %1%#" [(set_attr "type" "call")]) ;; This is a call that wants a structure value. @@ -5720,7 +7459,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" - "call %a0,%1\;nop\;unimp %2" + "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2" [(set_attr "type" "call_no_delay_slot")]) ;; This is a call that wants a structure value. @@ -5732,7 +7471,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0" - "call %a0,%1\;nop\;unimp %2" + "call\\t%a0, %1\\n\\tnop\\n\\tunimp\\t%2" [(set_attr "type" "call_no_delay_slot")]) ;; This is a call that may want a structure value. This is used for @@ -5744,7 +7483,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" - "call %a0,%1\;nop\;nop" + "call\\t%a0, %1\\n\\tnop\\n\\tnop" [(set_attr "type" "call_no_delay_slot")]) ;; This is a call that wants a structure value. @@ -5755,7 +7494,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 1 for most machines. "! TARGET_ARCH64 && GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0" - "call %a0,%1\;nop\;nop" + "call\\t%a0, %1\\n\\tnop\\n\\tnop" [(set_attr "type" "call_no_delay_slot")]) (define_expand "call_value" @@ -5803,7 +7542,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 2 for most machines. "! TARGET_PTR64" - "call %a1,%2%#" + "call\\t%a1, %2%#" [(set_attr "type" "call")]) (define_insn "*call_value_symbolic_sp32" @@ -5813,7 +7552,7 @@ if (! TARGET_ARCH64) (clobber (reg:SI 15))] ;;- Do not use operand 2 for most machines. "! TARGET_PTR64" - "call %a1,%2%#" + "call\\t%a1, %2%#" [(set_attr "type" "call")]) (define_insn "*call_value_address_sp64" @@ -5823,7 +7562,7 @@ if (! TARGET_ARCH64) (clobber (reg:DI 15))] ;;- Do not use operand 2 for most machines. "TARGET_PTR64" - "call %a1,%2%#" + "call\\t%a1, %2%#" [(set_attr "type" "call")]) (define_insn "*call_value_symbolic_sp64" @@ -5833,7 +7572,7 @@ if (! TARGET_ARCH64) (clobber (reg:DI 15))] ;;- Do not use operand 2 for most machines. "TARGET_PTR64" - "call %a1,%2%#" + "call\\t%a1, %2%#" [(set_attr "type" "call")]) (define_expand "untyped_call" @@ -5871,7 +7610,8 @@ if (! TARGET_ARCH64) (define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" - "") + "" + [(set_attr "length" "0")]) ;; Prepare to return any type including a structure value. @@ -5887,7 +7627,8 @@ if (! TARGET_ARCH64) if (! TARGET_ARCH64) { - rtx rtnreg = gen_rtx_REG (SImode, (leaf_function ? 15 : 31)); + rtx rtnreg = gen_rtx_REG (SImode, (current_function_uses_only_leaf_regs + ? 15 : 31)); rtx value = gen_reg_rtx (SImode); /* Fetch the instruction where we will return to and see if it's an unimp @@ -5938,12 +7679,14 @@ if (! TARGET_ARCH64) (parallel [(return) (use (reg:SI 31))])] "sparc_return_peephole_ok (operands[0], operands[1])" - "return %%i7+8\;mov %Y1,%Y0") + "return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0") (define_insn "nop" [(const_int 0)] "" - "nop") + "nop" + [(set_attr "type" "ialu") + (set_attr "length" "1")]) (define_expand "indirect_jump" [(set (pc) (match_operand 0 "address_operand" "p"))] @@ -5953,13 +7696,13 @@ if (! TARGET_ARCH64) (define_insn "*branch_sp32" [(set (pc) (match_operand:SI 0 "address_operand" "p"))] "! TARGET_PTR64" - "jmp %a0%#" + "jmp\\t%a0%#" [(set_attr "type" "uncond_branch")]) (define_insn "*branch_sp64" [(set (pc) (match_operand:DI 0 "address_operand" "p"))] "TARGET_PTR64" - "jmp %a0%#" + "jmp\\t%a0%#" [(set_attr "type" "uncond_branch")]) ;; ??? Doesn't work with -mflat. @@ -5971,7 +7714,9 @@ if (! TARGET_ARCH64) "" " { +#if 0 rtx chain = operands[0]; +#endif rtx fp = operands[1]; rtx stack = operands[2]; rtx lab = operands[3]; @@ -6001,6 +7746,8 @@ if (! TARGET_ARCH64) really needed. */ /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx)); + +#if 0 /* Return, restoring reg window and jumping to goto handler. */ if (TARGET_V9 && GET_CODE (chain) == CONST_INT && ! (INTVAL (chain) & ~(HOST_WIDE_INT)0xffffffff)) @@ -6012,6 +7759,8 @@ if (! TARGET_ARCH64) } /* Put in the static chain register the nonlocal label address. */ emit_move_insn (static_chain_rtx, chain); +#endif + emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx)); emit_insn (gen_goto_handler_and_restore (labreg)); emit_barrier (); @@ -6022,37 +7771,38 @@ if (! TARGET_ARCH64) (define_insn "flush_register_windows" [(unspec_volatile [(const_int 0)] 1)] "" - "* return TARGET_V9 ? \"flushw\" : \"ta 3\";" - [(set_attr "type" "misc")]) + "* return TARGET_V9 ? \"flushw\" : \"ta\\t3\";" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "goto_handler_and_restore" - [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r")] 2)] + [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)] "" - "jmp %0+0\;restore" + "jmp\\t%0+0\\n\\trestore" [(set_attr "type" "misc") (set_attr "length" "2")]) -(define_insn "goto_handler_and_restore_v9" - [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r") - (match_operand:SI 1 "register_operand" "=r,r") - (match_operand:SI 2 "const_int_operand" "I,n")] 3)] - "TARGET_V9 && ! TARGET_ARCH64" - "@ - return %0+0\;mov %2,%Y1 - sethi %%hi(%2),%1\;return %0+0\;or %Y1,%%lo(%2),%Y1" - [(set_attr "type" "misc") - (set_attr "length" "2,3")]) - -(define_insn "*goto_handler_and_restore_v9_sp64" - [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r") - (match_operand:DI 1 "register_operand" "=r,r") - (match_operand:SI 2 "const_int_operand" "I,n")] 3)] - "TARGET_V9 && TARGET_ARCH64" - "@ - return %0+0\;mov %2,%Y1 - sethi %%hi(%2),%1\;return %0+0\;or %Y1,%%lo(%2),%Y1" - [(set_attr "type" "misc") - (set_attr "length" "2,3")]) +;;(define_insn "goto_handler_and_restore_v9" +;; [(unspec_volatile [(match_operand:SI 0 "register_operand" "=r,r") +;; (match_operand:SI 1 "register_operand" "=r,r") +;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)] +;; "TARGET_V9 && ! TARGET_ARCH64" +;; "@ +;; return\\t%0+0\\n\\tmov\\t%2, %Y1 +;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1" +;; [(set_attr "type" "misc") +;; (set_attr "length" "2,3")]) +;; +;;(define_insn "*goto_handler_and_restore_v9_sp64" +;; [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r") +;; (match_operand:DI 1 "register_operand" "=r,r") +;; (match_operand:SI 2 "const_int_operand" "I,n")] 3)] +;; "TARGET_V9 && TARGET_ARCH64" +;; "@ +;; return\\t%0+0\\n\\tmov\\t%2, %Y1 +;; sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1" +;; [(set_attr "type" "misc") +;; (set_attr "length" "2,3")]) ;; Pattern for use after a setjmp to store FP and the return register ;; into the stack area. @@ -6086,10 +7836,11 @@ if (! TARGET_ARCH64) ;; Special pattern for the FLUSH instruction. (define_insn "flush" - [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 3)] + [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 4)] "" - "* return TARGET_V9 ? \"flush %f0\" : \"iflush %f0\";" - [(set_attr "type" "misc")]) + "* return TARGET_V9 ? \"flush\\t%f0\" : \"iflush\\t%f0\";" + [(set_attr "type" "misc") + (set_attr "length" "1")]) ;; find first set. @@ -6098,6 +7849,7 @@ if (! TARGET_ARCH64) ;; zero also differ. It takes at least 7 instructions to get the proper ;; result. Here is an obvious 8 instruction sequence. +;; XXX (define_insn "ffssi2" [(set (match_operand:SI 0 "register_operand" "=&r") (ffs:SI (match_operand:SI 1 "register_operand" "r"))) @@ -6126,205 +7878,7 @@ if (! TARGET_ARCH64) ; "neg %1,%2\;xnor %1,%2,%2\;popc %2,%0\;movzr %1,0,%0" ; [(set_attr "type" "multi") ; (set_attr "length" "4")]) - -;; Split up troublesome insns for better scheduling. */ - -;; The following patterns are straightforward. They can be applied -;; either before or after register allocation. - -(define_split - [(set (match_operand 0 "splittable_symbolic_memory_operand" "") - (match_operand 1 "reg_or_0_operand" "")) - (clobber (match_operand:SI 2 "register_operand" ""))] - "! flag_pic" - [(set (match_dup 2) (high:SI (match_dup 3))) - (set (match_dup 4) (match_dup 1))] - " -{ - operands[3] = XEXP (operands[0], 0); - operands[4] = gen_rtx_MEM (GET_MODE (operands[0]), - gen_rtx_LO_SUM (SImode, operands[2], operands[3])); - MEM_IN_STRUCT_P (operands[4]) = MEM_IN_STRUCT_P (operands[0]); - MEM_VOLATILE_P (operands[4]) = MEM_VOLATILE_P (operands[0]); - RTX_UNCHANGING_P (operands[4]) = RTX_UNCHANGING_P (operands[0]); -}") - -(define_split - [(set (match_operand 0 "splittable_immediate_memory_operand" "") - (match_operand 1 "general_operand" "")) - (clobber (match_operand:SI 2 "register_operand" ""))] - "flag_pic" - [(set (match_dup 3) (match_dup 1))] - " -{ - rtx addr = legitimize_pic_address (XEXP (operands[0], 0), - GET_MODE (operands[0]), - operands[2]); - operands[3] = gen_rtx_MEM (GET_MODE (operands[0]), addr); - MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[0]); - MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[0]); - RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[0]); -}") - -(define_split - [(set (match_operand 0 "register_operand" "") - (match_operand 1 "splittable_immediate_memory_operand" ""))] - "flag_pic" - [(set (match_dup 0) (match_dup 2))] - " -{ - rtx addr = legitimize_pic_address (XEXP (operands[1], 0), - GET_MODE (operands[1]), - operands[0]); - operands[2] = gen_rtx_MEM (GET_MODE (operands[1]), addr); - MEM_IN_STRUCT_P (operands[2]) = MEM_IN_STRUCT_P (operands[1]); - MEM_VOLATILE_P (operands[2]) = MEM_VOLATILE_P (operands[1]); - RTX_UNCHANGING_P (operands[2]) = RTX_UNCHANGING_P (operands[1]); -}") - -;; Sign- and Zero-extend operations can have symbolic memory operands. - -(define_split - [(set (match_operand 0 "register_operand" "") - (match_operator 1 "extend_op" [(match_operand 2 "splittable_immediate_memory_operand" "")]))] - "flag_pic" - [(set (match_dup 0) (match_op_dup 1 [(match_dup 3)]))] - " -{ - rtx addr = legitimize_pic_address (XEXP (operands[2], 0), - GET_MODE (operands[2]), - operands[0]); - operands[3] = gen_rtx_MEM (GET_MODE (operands[2]), addr); - MEM_IN_STRUCT_P (operands[3]) = MEM_IN_STRUCT_P (operands[2]); - MEM_VOLATILE_P (operands[3]) = MEM_VOLATILE_P (operands[2]); - RTX_UNCHANGING_P (operands[3]) = RTX_UNCHANGING_P (operands[2]); -}") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "immediate_operand" ""))] - "! flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST - || GET_CODE (operands[1]) == LABEL_REF)" - [(set (match_dup 0) (high:SI (match_dup 1))) - (set (match_dup 0) - (lo_sum:SI (match_dup 0) (match_dup 1)))] - "") - -;; LABEL_REFs are not modified by `legitimize_pic_address' -;; so do not recurse infinitely in the PIC case. -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "immediate_operand" ""))] - "flag_pic && (GET_CODE (operands[1]) == SYMBOL_REF - || GET_CODE (operands[1]) == CONST)" - [(set (match_dup 0) (match_dup 1))] - " -{ - operands[1] = legitimize_pic_address (operands[1], Pmode, operands[0]); -}") - -;; These split sne/seq insns. The forms of the resulting insns are -;; somewhat bogus, but they avoid extra patterns and show data dependency. -;; Nothing will look at these in detail after splitting has occurred. - -;; ??? v9 DImode versions are missing because addc and subc use %icc. - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (ltu:SI (reg:CC 100) (const_int 0)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (ltu:SI (reg:CC 100) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (geu:SI (reg:CC 100) (const_int 0)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (neg:SI (geu:SI (reg:CC 100) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (ltu:SI (reg:CC 100) (const_int 0)) - (match_dup 2)))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 2 "register_operand" "") - (ne:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (minus:SI (match_dup 2) - (ltu:SI (reg:CC 100) (const_int 0))))] - "") - -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (plus:SI (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)) - (match_operand:SI 2 "register_operand" ""))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (plus:SI (geu:SI (reg:CC 100) (const_int 0)) - (match_dup 2)))] - "") -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_operand:SI 2 "register_operand" "") - (eq:SI (match_operand:SI 1 "register_operand" "") - (const_int 0)))) - (clobber (reg:CC 100))] - "" - [(set (reg:CC_NOOV 100) (compare:CC_NOOV (neg:SI (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (minus:SI (match_dup 2) - (geu:SI (reg:CC 100) (const_int 0))))] - "") ;; Peepholes go at the end. @@ -6338,9 +7892,10 @@ if (! TARGET_ARCH64) (set (match_operand:SI 1 "memory_operand" "") (const_int 0))] "TARGET_V9 - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[1]) + && ! MEM_VOLATILE_P (operands[0]) + && ! MEM_VOLATILE_P (operands[1]) && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[1], 0))" - "stx %%g0,%0") + "stx\\t%%g0, %0") (define_peephole [(set (match_operand:SI 0 "memory_operand" "") @@ -6348,89 +7903,98 @@ if (! TARGET_ARCH64) (set (match_operand:SI 1 "memory_operand" "") (const_int 0))] "TARGET_V9 - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[1]) + && ! MEM_VOLATILE_P (operands[0]) + && ! MEM_VOLATILE_P (operands[1]) && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[0], 0))" - "stx %%g0,%1") + "stx\\t%%g0, %1") (define_peephole [(set (match_operand:SI 0 "register_operand" "=rf") (match_operand:SI 1 "memory_operand" "")) (set (match_operand:SI 2 "register_operand" "=rf") (match_operand:SI 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) + "registers_ok_for_ldd_peep (operands[0], operands[2]) + && ! MEM_VOLATILE_P (operands[1]) + && ! MEM_VOLATILE_P (operands[3]) && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "ldd %1,%0") + "ldd\\t%1, %0") (define_peephole [(set (match_operand:SI 0 "memory_operand" "") (match_operand:SI 1 "register_operand" "rf")) (set (match_operand:SI 2 "memory_operand" "") (match_operand:SI 3 "register_operand" "rf"))] - "registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) + "registers_ok_for_ldd_peep (operands[1], operands[3]) + && ! MEM_VOLATILE_P (operands[0]) + && ! MEM_VOLATILE_P (operands[2]) && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "std %1,%0") + "std\\t%1, %0") (define_peephole [(set (match_operand:SF 0 "register_operand" "=fr") (match_operand:SF 1 "memory_operand" "")) (set (match_operand:SF 2 "register_operand" "=fr") (match_operand:SF 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[0], operands[2]) - && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3]) + "registers_ok_for_ldd_peep (operands[0], operands[2]) + && ! MEM_VOLATILE_P (operands[1]) + && ! MEM_VOLATILE_P (operands[3]) && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" - "ldd %1,%0") + "ldd\\t%1, %0") (define_peephole [(set (match_operand:SF 0 "memory_operand" "") (match_operand:SF 1 "register_operand" "fr")) (set (match_operand:SF 2 "memory_operand" "") (match_operand:SF 3 "register_operand" "fr"))] - "registers_ok_for_ldd_peep (operands[1], operands[3]) - && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2]) - && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" - "std %1,%0") + "registers_ok_for_ldd_peep (operands[1], operands[3]) + && ! MEM_VOLATILE_P (operands[0]) + && ! MEM_VOLATILE_P (operands[2]) + && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))" + "std\\t%1, %0") (define_peephole [(set (match_operand:SI 0 "register_operand" "=rf") (match_operand:SI 1 "memory_operand" "")) (set (match_operand:SI 2 "register_operand" "=rf") (match_operand:SI 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" - "ldd %3,%2") + "registers_ok_for_ldd_peep (operands[2], operands[0]) + && ! MEM_VOLATILE_P (operands[3]) + && ! MEM_VOLATILE_P (operands[1]) + && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" + "ldd\\t%3, %2") (define_peephole [(set (match_operand:SI 0 "memory_operand" "") (match_operand:SI 1 "register_operand" "rf")) (set (match_operand:SI 2 "memory_operand" "") (match_operand:SI 3 "register_operand" "rf"))] - "registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" - "std %3,%2") + "registers_ok_for_ldd_peep (operands[3], operands[1]) + && ! MEM_VOLATILE_P (operands[2]) + && ! MEM_VOLATILE_P (operands[0]) + && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" + "std\\t%3, %2") (define_peephole [(set (match_operand:SF 0 "register_operand" "=fr") (match_operand:SF 1 "memory_operand" "")) (set (match_operand:SF 2 "register_operand" "=fr") (match_operand:SF 3 "memory_operand" ""))] - "registers_ok_for_ldd_peep (operands[2], operands[0]) - && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1]) - && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" - "ldd %3,%2") + "registers_ok_for_ldd_peep (operands[2], operands[0]) + && ! MEM_VOLATILE_P (operands[3]) + && ! MEM_VOLATILE_P (operands[1]) + && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))" + "ldd\\t%3, %2") (define_peephole [(set (match_operand:SF 0 "memory_operand" "") (match_operand:SF 1 "register_operand" "fr")) (set (match_operand:SF 2 "memory_operand" "") (match_operand:SF 3 "register_operand" "fr"))] - "registers_ok_for_ldd_peep (operands[3], operands[1]) - && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0]) - && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" - "std %3,%2") + "registers_ok_for_ldd_peep (operands[3], operands[1]) + && ! MEM_VOLATILE_P (operands[2]) + && ! MEM_VOLATILE_P (operands[0]) + && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" + "std\\t%3, %2") ;; Optimize the case of following a reg-reg move with a test ;; of reg just moved. Don't allow floating point regs for operand 0 or 1. @@ -6444,8 +8008,9 @@ if (! TARGET_ARCH64) (const_int 0)))] "(rtx_equal_p (operands[2], operands[0]) || rtx_equal_p (operands[2], operands[1])) - && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "orcc %1,0,%0") + && ! FP_REG_P (operands[0]) + && ! FP_REG_P (operands[1])" + "orcc\\t%1, 0, %0") (define_peephole [(set (match_operand:DI 0 "register_operand" "=r") @@ -6456,37 +8021,9 @@ if (! TARGET_ARCH64) "TARGET_ARCH64 && (rtx_equal_p (operands[2], operands[0]) || rtx_equal_p (operands[2], operands[1])) - && ! FP_REG_P (operands[0]) && ! FP_REG_P (operands[1])" - "orcc %1,0,%0") - -;; Floating-point move peepholes -;; ??? v9: Do we want similar ones? - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_dup 0) - (match_operand:SI 1 "immediate_operand" "i"))) - (set (match_operand:DF 2 "register_operand" "=er") - (mem:DF (match_dup 0)))] - "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" - "* -{ - /* Go by way of output_move_double in case the register in operand 2 - is not properly aligned for ldd. */ - operands[1] = gen_rtx_MEM (DFmode, - gen_rtx_LO_SUM (SImode, operands[0], operands[1])); - operands[0] = operands[2]; - return output_move_double (operands); -}") - -(define_peephole - [(set (match_operand:SI 0 "register_operand" "=r") - (lo_sum:SI (match_dup 0) - (match_operand:SI 1 "immediate_operand" "i"))) - (set (match_operand:SF 2 "register_operand" "=fr") - (mem:SF (match_dup 0)))] - "RTX_UNCHANGING_P (operands[1]) && reg_unused_after (operands[0], insn)" - "ld [%0+%%lo(%a1)],%2") + && ! FP_REG_P (operands[0]) + && ! FP_REG_P (operands[1])" + "orcc\\t%1, 0, %0") ;; Return peepholes. First the "normal" ones. ;; These are necessary to catch insns ending up in the epilogue delay list. @@ -6499,12 +8036,12 @@ if (! TARGET_ARCH64) "* { if (! TARGET_ARCH64 && current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; + return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) - return \"return %%i7+8\;mov %Y1,%Y0\"; + return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; else - return \"ret\;restore %%g0,%1,%Y0\"; + return \"ret\\n\\trestore %%g0, %1, %Y0\"; }" [(set_attr "type" "multi")]) @@ -6516,12 +8053,12 @@ if (! TARGET_ARCH64) "* { if (! TARGET_ARCH64 && current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; + return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) - return \"return %%i7+8\;mov %Y1,%Y0\"; + return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; else - return \"ret\;restore %%g0,%1,%Y0\"; + return \"ret\;restore %%g0, %1, %Y0\"; }" [(set_attr "type" "multi")]) @@ -6533,31 +8070,32 @@ if (! TARGET_ARCH64) "* { if (! TARGET_ARCH64 && current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; + return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; else if (TARGET_V9 && (GET_CODE (operands[1]) == CONST_INT || IN_OR_GLOBAL_P (operands[1]))) - return \"return %%i7+8\;mov %Y1,%Y0\"; + return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; else - return \"ret\;restore %%g0,%1,%Y0\"; + return \"ret\;restore %%g0, %1, %Y0\"; }" [(set_attr "type" "multi")]) ;; The following pattern is only generated by delayed-branch scheduling, -;; when the insn winds up in the epilogue. This can only happen when -;; ! TARGET_FPU because otherwise fp return values are in %f0. +;; when the insn winds up in the epilogue. This can happen not only when +;; ! TARGET_FPU because we move complex types around by parts using +;; SF mode SUBREGs. (define_insn "*return_sf_no_fpu" [(set (match_operand:SF 0 "restore_operand" "r") (match_operand:SF 1 "register_operand" "r")) (return)] - "! TARGET_FPU && ! TARGET_EPILOGUE && ! TARGET_LIVE_G0" + "! TARGET_EPILOGUE && ! TARGET_LIVE_G0" "* { if (! TARGET_ARCH64 && current_function_returns_struct) - return \"jmp %%i7+12\;restore %%g0,%1,%Y0\"; + return \"jmp\\t%%i7+12\\n\\trestore %%g0, %1, %Y0\"; else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1])) - return \"return %%i7+8\;mov %Y1,%Y0\"; + return \"return\\t%%i7+8\\n\\tmov\\t%Y1, %Y0\"; else - return \"ret\;restore %%g0,%1,%Y0\"; + return \"ret\;restore %%g0, %1, %Y0\"; }" [(set_attr "type" "multi")]) @@ -6570,14 +8108,14 @@ if (! TARGET_ARCH64) "* { if (! TARGET_ARCH64 && current_function_returns_struct) - return \"jmp %%i7+12\;restore %r1,%2,%Y0\"; + return \"jmp\\t%%i7+12\\n\\trestore %r1, %2, %Y0\"; /* If operands are global or in registers, can use return */ else if (TARGET_V9 && IN_OR_GLOBAL_P (operands[1]) && (GET_CODE (operands[2]) == CONST_INT || IN_OR_GLOBAL_P (operands[2]))) - return \"return %%i7+8\;add %Y1,%Y2,%Y0\"; + return \"return\\t%%i7+8\\n\\tadd\\t%Y1, %Y2, %Y0\"; else - return \"ret\;restore %r1,%2,%Y0\"; + return \"ret\;restore %r1, %2, %Y0\"; }" [(set_attr "type" "multi")]) @@ -6586,7 +8124,7 @@ if (! TARGET_ARCH64) (match_operand:DI 1 "arith_double_operand" "rHI")) (return)] "TARGET_ARCH64 && ! TARGET_EPILOGUE" - "ret\;restore %%g0,%1,%Y0" + "ret\;restore %%g0, %1, %Y0" [(set_attr "type" "multi")]) (define_insn "*return_adddi" @@ -6595,7 +8133,7 @@ if (! TARGET_ARCH64) (match_operand:DI 2 "arith_double_operand" "rHI"))) (return)] "TARGET_ARCH64 && ! TARGET_EPILOGUE" - "ret\;restore %r1,%2,%Y0" + "ret\;restore %r1, %2, %Y0" [(set_attr "type" "multi")]) ;; The following pattern is only generated by delayed-branch scheduling, @@ -6605,7 +8143,7 @@ if (! TARGET_ARCH64) (match_operand:SF 0 "register_operand" "f")) (return)] "! TARGET_EPILOGUE" - "ret\;fmovs %0,%%f0" + "ret\;fmovs\\t%0, %%f0" [(set_attr "type" "multi")]) ;; Now peepholes to do a call followed by a jump. @@ -6616,16 +8154,20 @@ if (! TARGET_ARCH64) (match_operand 2 "" ""))) (clobber (reg:SI 15))]) (set (pc) (label_ref (match_operand 3 "" "")))] - "short_branch (INSN_UID (insn), INSN_UID (operands[3])) && in_same_eh_region (insn, operands[3]) && in_same_eh_region (insn, ins1)" - "call %a1,%2\;add %%o7,(%l3-.-4),%%o7") + "short_branch (INSN_UID (insn), INSN_UID (operands[3])) + && in_same_eh_region (insn, operands[3]) + && in_same_eh_region (insn, ins1)" + "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])) && in_same_eh_region (insn, operands[2]) && in_same_eh_region (insn, ins1)" - "call %a0,%1\;add %%o7,(%l2-.-4),%%o7") + "short_branch (INSN_UID (insn), INSN_UID (operands[2])) + && in_same_eh_region (insn, operands[2]) + && in_same_eh_region (insn, ins1)" + "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7") (define_peephole [(parallel [(set (match_operand 0 "" "") @@ -6633,31 +8175,40 @@ if (! TARGET_ARCH64) (match_operand 2 "" ""))) (clobber (reg:DI 15))]) (set (pc) (label_ref (match_operand 3 "" "")))] - "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[3])) && in_same_eh_region (insn, operands[3]) && in_same_eh_region (insn, ins1)" - "call %a1,%2\;add %%o7,(%l3-.-4),%%o7") + "TARGET_ARCH64 + && short_branch (INSN_UID (insn), INSN_UID (operands[3])) + && in_same_eh_region (insn, operands[3]) + && in_same_eh_region (insn, ins1)" + "call\\t%a1, %2\\n\\tadd\\t%%o7, (%l3-.-4), %%o7") (define_peephole [(parallel [(call (mem:SI (match_operand:DI 0 "call_operand_address" "ps")) (match_operand 1 "" "")) (clobber (reg:DI 15))]) (set (pc) (label_ref (match_operand 2 "" "")))] - "TARGET_ARCH64 && short_branch (INSN_UID (insn), INSN_UID (operands[2])) && in_same_eh_region (insn, operands[2]) && in_same_eh_region (insn, ins1)" - "call %a0,%1\;add %%o7,(%l2-.-4),%%o7") + "TARGET_ARCH64 + && short_branch (INSN_UID (insn), INSN_UID (operands[2])) + && in_same_eh_region (insn, operands[2]) + && in_same_eh_region (insn, ins1)" + "call\\t%a0, %1\\n\\tadd\\t%%o7, (%l2-.-4), %%o7") ;; After a nonlocal goto, we need to restore the PIC register, but only ;; if we need it. So do nothing much here, but we'll check for this in ;; finalize_pic. +;; Make sure this unspec_volatile number agrees with finalize_pic. (define_insn "nonlocal_goto_receiver" - [(unspec_volatile [(const_int 0)] 4)] + [(unspec_volatile [(const_int 0)] 5)] "flag_pic" - "") + "" + [(set_attr "length" "0")]) (define_insn "trap" [(trap_if (const_int 1) (const_int 5))] "" - "ta 5" - [(set_attr "type" "misc")]) + "ta\\t5" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_expand "conditional_trap" [(trap_if (match_operator 0 "noov_compare_op" @@ -6672,13 +8223,14 @@ if (! TARGET_ARCH64) [(trap_if (match_operator 0 "noov_compare_op" [(reg:CC 100) (const_int 0)]) (match_operand:SI 1 "arith_operand" "rM"))] "" - "t%C0 %1" - [(set_attr "type" "misc")]) + "t%C0\\t%1" + [(set_attr "type" "misc") + (set_attr "length" "1")]) (define_insn "" [(trap_if (match_operator 0 "noov_compare_op" [(reg:CCX 100) (const_int 0)]) (match_operand:SI 1 "arith_operand" "rM"))] "TARGET_V9" - "t%C0 %%xcc,%1" - [(set_attr "type" "misc")]) - + "t%C0\\t%%xcc, %1" + [(set_attr "type" "misc") + (set_attr "length" "1")]) diff --git a/contrib/gcc/config/sparc/splet.h b/contrib/gcc/config/sparc/splet.h index 23c6414..d924e70 100644 --- a/contrib/gcc/config/sparc/splet.h +++ b/contrib/gcc/config/sparc/splet.h @@ -29,12 +29,12 @@ Boston, MA 02111-1307, USA. */ /* -mlive-g0 is only supported on the sparclet. */ #undef SUBTARGET_SWITCHES #define SUBTARGET_SWITCHES \ -{"big-endian", -MASK_LITTLE_ENDIAN}, \ -{"little-endian", MASK_LITTLE_ENDIAN}, \ -{"live-g0", MASK_LIVE_G0}, \ -{"no-live-g0", -MASK_LIVE_G0}, \ -{"broken-saverestore", MASK_BROKEN_SAVERESTORE}, \ -{"no-broken-saverestore", -MASK_BROKEN_SAVERESTORE}, +{"big-endian", -MASK_LITTLE_ENDIAN, "Generate code for big endian" }, \ +{"little-endian", MASK_LITTLE_ENDIAN, "Generate code for little endian" }, \ +{"live-g0", MASK_LIVE_G0, "Use g0 as a normal register" }, \ +{"no-live-g0", -MASK_LIVE_G0, "Register g0 is fixed with a zero value" }, \ +{"broken-saverestore", MASK_BROKEN_SAVERESTORE, "Enable save/restore bug workarounds" }, \ +{"no-broken-saverestore", -MASK_BROKEN_SAVERESTORE, "Disable save/restore bug workarouns" }, #undef ASM_SPEC #define ASM_SPEC "%{mlittle-endian:-EL} %(asm_cpu)" @@ -51,3 +51,19 @@ Boston, MA 02111-1307, USA. */ #define BYTES_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) #undef WORDS_BIG_ENDIAN #define WORDS_BIG_ENDIAN (! TARGET_LITTLE_ENDIAN) + +#undef SUBTARGET_OVERRIDE_OPTIONS +#define SUBTARGET_OVERRIDE_OPTIONS \ + do { \ + if (TARGET_LIVE_G0) \ + { \ + warning ("Option '-mlive-g0' deprecated."); \ + target_flags &= ~MASK_LIVE_G0; \ + } \ + else if (TARGET_BROKEN_SAVERESTORE) \ + { \ + warning ("Option '-mbroken-saverestore' deprecated."); \ + target_flags &= ~MASK_BROKEN_SAVERESTORE; \ + } \ + } while (0) + diff --git a/contrib/gcc/config/sparc/sun4o3.h b/contrib/gcc/config/sparc/sun4o3.h index 10c7391..d2a53c1 100644 --- a/contrib/gcc/config/sparc/sun4o3.h +++ b/contrib/gcc/config/sparc/sun4o3.h @@ -1,9 +1,9 @@ #include "sparc/sparc.h" -#undef FUNCTION_PROFILER -#define FUNCTION_PROFILER(FILE, LABELNO) \ - fprintf (FILE, "\tsethi %%hi(LP%d),%%o0\n\tcall .mcount\n\tor %%lo(LP%d),%%o0,%%o0\n", \ - (LABELNO), (LABELNO)) +/* Override the name of the mcount profiling function. */ + +#undef MCOUNT_FUNCTION +#define MCOUNT_FUNCTION "*.mcount" /* LINK_SPEC is needed only for SunOS 4. */ diff --git a/contrib/gcc/config/sparc/sysv4.h b/contrib/gcc/config/sparc/sysv4.h index 7e90bdd..5f9bba9 100644 --- a/contrib/gcc/config/sparc/sysv4.h +++ b/contrib/gcc/config/sparc/sysv4.h @@ -66,7 +66,9 @@ Boston, MA 02111-1307, USA. */ /* 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. */ -#define JUMP_TABLES_IN_TEXT_SECTION 1 +/* But we now defer the tables to the end of the function, so we make + this 0 to not confuse the branch shortening code. */ +#define JUMP_TABLES_IN_TEXT_SECTION 0 /* Pass -K to the assembler when PIC. */ #undef ASM_SPEC @@ -191,35 +193,13 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \ #define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \ do { \ if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL) \ - fprintf (FILE, ".section\t\"%s%s\",#alloc,#execinstr\n", \ - flag_function_sections ? ".text%" : "", (NAME)); \ + fprintf (FILE, ".section\t\"%s\",#alloc,#execinstr\n", \ + (NAME)); \ else if ((DECL) && DECL_READONLY_SECTION (DECL, RELOC)) \ fprintf (FILE, ".section\t\"%s\",#alloc\n", (NAME)); \ else \ fprintf (FILE, ".section\t\"%s\",#alloc,#write\n", (NAME)); \ } while (0) - -/* Output assembler code to FILE to initialize this source file's - basic block profiling info, if that has not already been done. */ - -#undef FUNCTION_BLOCK_PROFILER -#define FUNCTION_BLOCK_PROFILER(FILE, LABELNO) \ - do { \ - fprintf (FILE, "\tsethi %%hi(.LLPBX0),%%o0\n\tld [%%lo(.LLPBX0)+%%o0],%%o1\n\ttst %%o1\n\tbne LPY%d\n\tadd %%o0,%%lo(.LLPBX0),%%o0\n\tcall __bb_init_func\n\tnop\nLPY%d:\n", \ - (LABELNO), (LABELNO)); \ - } while (0) - -/* Output assembler code to FILE to increment the entry-count for - the BLOCKNO'th basic block in this source file. */ - -#undef BLOCK_PROFILER -#define BLOCK_PROFILER(FILE, BLOCKNO) \ -{ \ - int blockn = (BLOCKNO); \ - fprintf (FILE, "\tsethi %%hi(.LLPBX2+%d),%%g1\n\tld [%%lo(.LLPBX2+%d)+%%g1],%%g2\n\ -\tadd %%g2,1,%%g2\n\tst %%g2,[%%lo(.LLPBX2+%d)+%%g1]\n", \ - 4 * blockn, 4 * blockn, 4 * blockn); \ -} /* A C statement (sans semicolon) to output to the stdio stream FILE the assembler definition of uninitialized global DECL named @@ -229,3 +209,8 @@ do { \ #undef ASM_OUTPUT_ALIGNED_BSS #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN) + +/* Override the name of the mcount profiling function. */ + +#undef MCOUNT_FUNCTION +#define MCOUNT_FUNCTION "*_mcount" diff --git a/contrib/gcc/config/sparc/t-halos b/contrib/gcc/config/sparc/t-halos new file mode 100644 index 0000000..0bd5496 --- /dev/null +++ b/contrib/gcc/config/sparc/t-halos @@ -0,0 +1,2 @@ +# For a native HALOS compile, we need to set -e1 for the assembler +AS=as -e1 diff --git a/contrib/gcc/config/sparc/t-linux64 b/contrib/gcc/config/sparc/t-linux64 new file mode 100644 index 0000000..077cf69 --- /dev/null +++ b/contrib/gcc/config/sparc/t-linux64 @@ -0,0 +1,21 @@ +MULTILIB_OPTIONS = m64/m32 +MULTILIB_DIRNAMES = 64 32 +MULTILIB_MATCHES = + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o + +tcrtbeginS.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \ + defaults.h frame.h gbl-ctors.h + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ + -finhibit-size-directive -fno-inline-functions -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) \ + -c $(srcdir)/crtstuff.c -DCRT_BEGIN -o tcrtbeginS$(objext) + +tcrtendS.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \ + defaults.h frame.h gbl-ctors.h + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ + -finhibit-size-directive -fno-inline-functions -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) \ + -c $(srcdir)/crtstuff.c -DCRT_END -o tcrtendS$(objext) + diff --git a/contrib/gcc/config/sparc/t-sol2 b/contrib/gcc/config/sparc/t-sol2 index d41254a..a9b6ee1 100644 --- a/contrib/gcc/config/sparc/t-sol2 +++ b/contrib/gcc/config/sparc/t-sol2 @@ -6,19 +6,19 @@ CROSS_LIBGCC1 = LIBGCC1_TEST = # gmon build rule: -gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) stmp-int-hdrs - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) \ - -c $(srcdir)/config/sparc/gmon-sol2.c -o gmon.o +$(T)gmon.o: $(srcdir)/config/sparc/gmon-sol2.c $(GCC_PASSES) $(CONFIG_H) stmp-int-hdrs + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \ + -c $(srcdir)/config/sparc/gmon-sol2.c -o $(T)gmon.o # Assemble startup files. -crt1.o: $(srcdir)/config/sparc/sol2-c1.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o crt1.o -x assembler $(srcdir)/config/sparc/sol2-c1.asm -crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o crti.o -x assembler $(srcdir)/config/sparc/sol2-ci.asm -crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o crtn.o -x assembler $(srcdir)/config/sparc/sol2-cn.asm -gcrt1.o: $(srcdir)/config/sparc/sol2-g1.asm $(GCC_PASSES) - $(GCC_FOR_TARGET) -c -o gcrt1.o -x assembler $(srcdir)/config/sparc/sol2-g1.asm +$(T)crt1.o: $(srcdir)/config/sparc/sol2-c1.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crt1.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-c1.asm +$(T)crti.o: $(srcdir)/config/sparc/sol2-ci.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-ci.asm +$(T)crtn.o: $(srcdir)/config/sparc/sol2-cn.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-cn.asm +$(T)gcrt1.o: $(srcdir)/config/sparc/sol2-c1.asm $(GCC_PASSES) + $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -DGCRT1 -o $(T)gcrt1.o -x assembler-with-cpp $(srcdir)/config/sparc/sol2-c1.asm # We need to use -fPIC when we are using gcc to compile the routines in # crtstuff.c. This is only really needed when we are going to use gcc/g++ diff --git a/contrib/gcc/config/sparc/t-sol2-64 b/contrib/gcc/config/sparc/t-sol2-64 new file mode 100644 index 0000000..8d42c44 --- /dev/null +++ b/contrib/gcc/config/sparc/t-sol2-64 @@ -0,0 +1,8 @@ +MULTILIB_OPTIONS = m32/m64 +MULTILIB_DIRNAMES = sparcv7 sparcv9 +MULTILIB_MATCHES = + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o gmon.o crt1.o crti.o crtn.o gcrt1.o diff --git a/contrib/gcc/config/sparc/t-splet b/contrib/gcc/config/sparc/t-splet index 3409f5d..3329e0b 100644 --- a/contrib/gcc/config/sparc/t-splet +++ b/contrib/gcc/config/sparc/t-splet @@ -16,8 +16,7 @@ fp-bit.c: $(srcdir)/config/fp-bit.c echo '#define FLOAT' > fp-bit.c cat $(srcdir)/config/fp-bit.c >> fp-bit.c -MULTILIB_OPTIONS = mlittle-endian mlive-g0 mbroken-saverestore -MULTILIB_DIRNAMES = little live-g0 brknsave - +MULTILIB_OPTIONS = mlittle-endian mflat +MULTILIB_DIRNAMES = little flat LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib diff --git a/contrib/gcc/config/sparc/xm-sp64.h b/contrib/gcc/config/sparc/xm-sp64.h index 5954aff..b673161 100644 --- a/contrib/gcc/config/sparc/xm-sp64.h +++ b/contrib/gcc/config/sparc/xm-sp64.h @@ -21,5 +21,7 @@ Boston, MA 02111-1307, USA. */ #include /* This describes the machine the compiler is hosted on. */ +#if defined(__arch64__) || defined(__sparc_v9__) || defined(__sparcv9) #undef HOST_BITS_PER_LONG #define HOST_BITS_PER_LONG 64 +#endif diff --git a/contrib/gcc/config/sparc/xm-sysv4-64.h b/contrib/gcc/config/sparc/xm-sysv4-64.h new file mode 100644 index 0000000..c506d22 --- /dev/null +++ b/contrib/gcc/config/sparc/xm-sysv4-64.h @@ -0,0 +1,27 @@ +/* Configuration for GCC for Sparc v9 running 64-bit native. + Copyright (C) 1998 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. */ + +#include + +/* This describes the machine the compiler is hosted on. */ +#if defined(__arch64__) || defined(__sparc_v9__) || defined(__sparcv9) +#undef HOST_BITS_PER_LONG +#define HOST_BITS_PER_LONG 64 +#endif diff --git a/contrib/gcc/config/svr4.h b/contrib/gcc/config/svr4.h index 4737697..7fa30e8 100644 --- a/contrib/gcc/config/svr4.h +++ b/contrib/gcc/config/svr4.h @@ -1,6 +1,6 @@ /* Operating system specific defines to be used when targeting GCC for some generic System V Release 4 system. - Copyright (C) 1991, 94-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1991, 94-98, 1999 Free Software Foundation, Inc. Contributed by Ron Guilmette (rfg@monkeys.com). This file is part of GNU CC. @@ -212,8 +212,9 @@ Boston, MA 02111-1307, USA. #define ASM_FILE_END(FILE) \ do { \ - fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ - IDENT_ASM_OP, version_string); \ + if (!flag_no_ident) \ + fprintf ((FILE), "\t%s\t\"GCC: (GNU) %s\"\n", \ + IDENT_ASM_OP, version_string); \ } while (0) /* Allow #sccs in preprocessor. */ @@ -246,8 +247,9 @@ do { \ #define DWARF_DEBUGGING_INFO /* All ELF targets can support DWARF-2. */ - +#ifndef DWARF2_DEBUGGING_INFO #define DWARF2_DEBUGGING_INFO +#endif /* The numbers used to denote specific machine registers in the System V Release 4 DWARF debugging information are quite likely to be totally @@ -260,83 +262,14 @@ do { \ #undef DBX_REGISTER_NUMBER -/* gas on SVR4 supports the use of .stabs. Permit -gstabs to be used - in general, although it will only work when using gas. */ - -#define DBX_DEBUGGING_INFO - -/* When generating stabs debugging, use N_BINCL entries. */ - -#define DBX_USE_BINCL - /* Use DWARF debugging info by default. */ #ifndef PREFERRED_DEBUGGING_TYPE #define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG #endif -/* Make LBRAC and RBRAC addresses relative to the start of the - function. The native Solaris stabs debugging format works this - way, gdb expects it, and it reduces the number of relocation - entries. */ - -#define DBX_BLOCKS_FUNCTION_RELATIVE 1 - -/* When using stabs, gcc2_compiled must be a stabs entry, not an - ordinary symbol, or gdb won't see it. Furthermore, since gdb reads - the input piecemeal, starting with each N_SO, it's a lot easier if - the gcc2 flag symbol is *after* the N_SO rather than before it. So - we emit an N_OPT stab there. */ - -#define ASM_IDENTIFY_GCC(FILE) \ -do \ - { \ - if (write_symbols != DBX_DEBUG) \ - fputs ("gcc2_compiled.:\n", FILE); \ - } \ -while (0) - -#define ASM_IDENTIFY_GCC_AFTER_SOURCE(FILE) \ -do \ - { \ - if (write_symbols == DBX_DEBUG) \ - fputs ("\t.stabs\t\"gcc2_compiled.\", 0x3c, 0, 0, 0\n", FILE); \ - } \ -while (0) - -/* Like block addresses, stabs line numbers are relative to the - current function. */ - -#define ASM_OUTPUT_SOURCE_LINE(file, line) \ -do \ - { \ - static int sym_lineno = 1; \ - fprintf (file, ".stabn 68,0,%d,.LM%d-", \ - line, sym_lineno); \ - assemble_name (file, \ - XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));\ - fprintf (file, "\n.LM%d:\n", sym_lineno); \ - sym_lineno += 1; \ - } \ -while (0) - -/* In order for relative line numbers to work, we must output the - stabs entry for the function name first. */ - -#define DBX_FUNCTION_FIRST - -/* Generate a blank trailing N_SO to mark the end of the .o file, since - we can't depend upon the linker to mark .o file boundaries with - embedded stabs. */ - -#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \ -do \ - { \ - text_section (); \ - fprintf (FILE, \ - "\t.stabs \"\",%d,0,0,.Letext\n.Letext:\n", N_SO); \ - } \ -while (0) +/* But allow STABS to be supoorted as well. */ +#include "dbxelf.h" /* Define the actual types of some ANSI-mandated types. (These definitions should work for most SVR4 systems). */ @@ -655,7 +588,15 @@ do { \ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (DECL)); \ \ if (! DECL_ONE_ONLY (DECL)) \ - prefix = "."; \ + { \ + prefix = "."; \ + if (TREE_CODE (DECL) == FUNCTION_DECL) \ + prefix = ".text."; \ + else if (DECL_READONLY_SECTION (DECL, RELOC)) \ + prefix = ".rodata."; \ + else \ + prefix = ".data."; \ + } \ else if (TREE_CODE (DECL) == FUNCTION_DECL) \ prefix = ".gnu.linkonce.t."; \ else if (DECL_READONLY_SECTION (DECL, RELOC)) \ @@ -669,7 +610,6 @@ do { \ \ DECL_SECTION_NAME (DECL) = build_string (len, string); \ } while (0) - /* A C statement (sans semicolon) to output an element in the table of global constructors. */ #define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \ @@ -943,7 +883,7 @@ do { \ } \ for (p = _ascii_bytes; p < limit && *p != '\0'; p++) \ continue; \ - if (p < limit && (p - _ascii_bytes) <= STRING_LIMIT) \ + if (p < limit && (p - _ascii_bytes) <= (long)STRING_LIMIT) \ { \ if (bytes_in_chunk > 0) \ { \ diff --git a/contrib/gcc/config/t-freebsd b/contrib/gcc/config/t-freebsd index 5164669..9981686 100644 --- a/contrib/gcc/config/t-freebsd +++ b/contrib/gcc/config/t-freebsd @@ -2,4 +2,3 @@ STMP_FIXPROTO = # Use only native include files USER_H = $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS) - diff --git a/contrib/gcc/config/t-gnu b/contrib/gcc/config/t-gnu index 58969f2..575f729 100644 --- a/contrib/gcc/config/t-gnu +++ b/contrib/gcc/config/t-gnu @@ -1,5 +1,8 @@ -LIBGCC1=libgcc1.null -CROSS_LIBGCC1=libgcc1.null +# In GNU, "/usr" is a four-letter word. +SYSTEM_HEADER_DIR = /include + +LIBGCC1 = libgcc1.null +CROSS_LIBGCC1 = libgcc1.null # The pushl in CTOR initialization interferes with frame pointer elimination. diff --git a/contrib/gcc/config/t-openbsd b/contrib/gcc/config/t-openbsd index 6bd8123..14bebc1 100644 --- a/contrib/gcc/config/t-openbsd +++ b/contrib/gcc/config/t-openbsd @@ -5,5 +5,3 @@ STMP_FIXPROTO = USER_H = ${LANG_EXTRA_HEADERS} INSTALL_ASSERT_H = -# We don't want collisions with our mkstemps -T_CFLAGS=-Dmkstemps=my_mkstemps diff --git a/contrib/gcc/config/t-rtems b/contrib/gcc/config/t-rtems index aa0ca66..5d7d569 100644 --- a/contrib/gcc/config/t-rtems +++ b/contrib/gcc/config/t-rtems @@ -4,3 +4,10 @@ STMP_FIXPROTO = # Don't install "assert.h" in gcc. RTEMS uses the one in newlib. INSTALL_ASSERT_H = +# RTEMS always has limits.h. +LIMITS_H_TEST = true + +# If we are building next to newlib, this will let us find the RTEMS +# limits.h when building libgcc2. Otherwise, newlib must be installed +# first. +LIBGCC2_INCLUDES = -I$(srcdir)/../newlib/libc/sys/rtems/include diff --git a/contrib/gcc/config/tm-dwarf2.h b/contrib/gcc/config/tm-dwarf2.h new file mode 100644 index 0000000..a580964 --- /dev/null +++ b/contrib/gcc/config/tm-dwarf2.h @@ -0,0 +1,4 @@ +/* Enable Dwarf2 debugging and make it the default */ +#define DWARF2_DEBUGGING_INFO 1 +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG + diff --git a/contrib/gcc/config/x-interix b/contrib/gcc/config/x-interix new file mode 100644 index 0000000..afdfe76 --- /dev/null +++ b/contrib/gcc/config/x-interix @@ -0,0 +1,24 @@ +# These are host overrides +# From config dir + +# Interix doesn't yet have alloca; it's better to use the portable C version for +# bootstrapping. Do this by defining ALLOCA. + +ALLOCA = alloca.o + +# See all the declarations. +FIXPROTO_DEFINES = -D_XOPEN_SOURCE + +# Don't run fixproto +STMP_FIXPROTO = +RANLIB = : +RANLIB_TEST = false +SHELL = sh + +# Existing CC/GCC may not define -D__INTERIX, so need this here. +# Since we want to configure with _ALL_SOURCE, we need to build that way too +X_CFLAGS= -D__INTERIX -D_ALL_SOURCE + +LIBGCC2_INCLUDES = -idirafter $${INTERIX_ROOT}/usr/include +# Headers come from a funny place +SYSTEM_HEADER_DIR=$${INTERIX_ROOT}/usr/include diff --git a/contrib/gcc/config/xm-interix.h b/contrib/gcc/config/xm-interix.h new file mode 100644 index 0000000..756fb5d --- /dev/null +++ b/contrib/gcc/config/xm-interix.h @@ -0,0 +1,77 @@ +/* Configuration for GNU compiler for processor running Interix + Copyright (C) 1993, 1995, 1999 Free Software Foundation, Inc. + Donn Terry, Softway Systems, Inc, + from code + Contributed by Douglas B. Rupp (drupp@cs.washington.edu) + +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 USG +#define USG 1 +#endif + +#ifndef ONLY_INT_FIELDS +#ifndef __GNUC__ +#define ONLY_INT_FIELDS 1 +#endif +#endif + +#ifndef USE_PROTOTYPES +#define USE_PROTOTYPES 1 +#endif + +/* If not compiled with GNU C, use the portable alloca. */ +#ifndef __GNUC__ +#define USE_C_ALLOCA 1 +#endif + +#define NO_SYS_SIGLIST 1 + +/* Our strategy for finding global constructors is a bit different, although + not a lot. */ +#define DO_GLOBAL_CTORS_BODY \ +do { \ + int i; \ + unsigned long nptrs; \ + func_ptr *p; \ + asm( \ + " .section .ctor_head, \"rw\"\n" \ + "1:\n" \ + " .text \n" \ + ASM_LOAD_ADDR(1b,%0) \ + : "=r" (p) : : "cc"); \ + for (nptrs = 0; p[nptrs] != 0; nptrs++); \ + for (i = nptrs-1; i >= 0; i--) \ + p[i] (); \ +} while (0) + +#define DO_GLOBAL_DTORS_BODY \ +do { \ + func_ptr *p; \ + asm( \ + " .section .dtor_head, \"rw\"\n" \ + "1:\n" \ + " .text \n" \ + ASM_LOAD_ADDR(1b,%0) \ + : "=r" (p) : : "cc"); \ + while (*p) \ + { \ + p++; \ + (*(p-1)) (); \ + } \ +} while (0) diff --git a/contrib/gcc/configure b/contrib/gcc/configure index d341217..5eeba77 100755 --- a/contrib/gcc/configure +++ b/contrib/gcc/configure @@ -14,8 +14,12 @@ ac_default_prefix=/usr/local 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." @@ -27,16 +31,44 @@ ac_help="$ac_help ac_help="$ac_help --enable-checking enable expensive run-time checks." ac_help="$ac_help - --enable-c-cpplib Use cpplib for C." + --disable-cpp don't provide a user-visible C preprocessor." ac_help="$ac_help - --enable-haifa Use the experimental scheduler. - --disable-haifa Don't use the experimental scheduler for the - targets which normally enable it." + --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-cpplib use cpplib for the C preprocessor." ac_help="$ac_help - --with-fast-fixincludes Use a faster fixinclude program. Experimental" + --enable-c-cpplib link cpplib directly into C and C++ compilers + (EXPERIMENTAL) (implies --enable-cpplib)." +ac_help="$ac_help + --enable-c-mbchar enable multibyte characters for C and C++." +ac_help="$ac_help + --disable-fast-fixincludes + Disable the new fast fixincludes. + Run the old fixincludes script unconditionally" +ac_help="$ac_help + --enable-haifa use the experimental scheduler. + --disable-haifa don't use the experimental scheduler for the + targets which normally enable it." 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 + --enable-java-gc=TYPE choose garbage collector [boehm]" +ac_help="$ac_help + --enable-dwarf2 enable DWARF2 debugging as default." +ac_help="$ac_help + --enable-nls use Native Language Support (disabled by default)" +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 + --with-catgets use catgets functions if available" # Initialize some variables set by options. # The variables have the same names as the options, with @@ -554,6 +586,57 @@ 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 +# 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 +echo $ac_n "checking LIBRARY_PATH variable""... $ac_c" 1>&6 +echo "configure:599: checking LIBRARY_PATH variable" >&5 +case ${LIBRARY_PATH} in + [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* ) + library_path_setting="contains current directory" + ;; + *) + library_path_setting="ok" + ;; +esac +echo "$ac_t""$library_path_setting" 1>&6 +if test "$library_path_setting" != "ok"; then +{ echo "configure: 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; } +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 +echo $ac_n "checking GCC_EXEC_PREFIX variable""... $ac_c" 1>&6 +echo "configure:624: checking GCC_EXEC_PREFIX variable" >&5 +case ${GCC_EXEC_PREFIX} in + [:\;]* | *[:\;] | *[:\;][:\;]* | *[:\;]. | .[:\;]*| . | *[:\;].[:\;]* ) + gcc_exec_prefix_setting="contains current directory" + ;; + *) + gcc_exec_prefix_setting="ok" + ;; +esac +echo "$ac_t""$gcc_exec_prefix_setting" 1>&6 +if test "$gcc_exec_prefix_setting" != "ok"; then +{ echo "configure: 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; } +fi + # Check for additional parameters # With GNU ld @@ -566,6 +649,25 @@ else 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 + +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 + elif $DEFAULT_LINKER -v < /dev/null 2>&1 | grep GNU > /dev/null; then + gnu_ld_flag=yes + fi + cat >> confdefs.h <&2 + elif $DEFAULT_ASSEMBLER -v < /dev/null 2>&1 | grep GNU > /dev/null; then + gas_flag=yes + fi + cat >> confdefs.h <&2; exit 1; } ;; no) ;; -*) gxx_include_dir=$with_gxx_include_dir ;; +*) gcc_gxx_include_dir=$with_gxx_include_dir ;; esac fi -if test x${gxx_include_dir} = x; then +if test x${gcc_gxx_include_dir} = x; then if test x${enable_version_specific_runtime_libs} = xyes; then - gxx_include_dir='${libsubdir}/include/g++' + gcc_gxx_include_dir='${libsubdir}/include/g++' else - gxx_include_dir='${prefix}/include/g++' + topsrcdir=${srcdir}/.. . ${srcdir}/../config.if + gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/g++"-${libstdcxx_interface} fi fi @@ -650,21 +774,70 @@ esac fi -# Enable use of cpplib for C. +# Check whether --enable-cpp or --disable-cpp was given. +if test "${enable_cpp+set}" = set; then + enableval="$enable_cpp" + : +else + enable_cpp=yes +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 "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 + + +# Use cpplib+cppmain for the preprocessor, but don't link it with the compiler. cpp_main=cccp +# Check whether --enable-cpplib or --disable-cpplib was given. +if test "${enable_cpplib+set}" = set; then + enableval="$enable_cpplib" + if test x$enable_cpplib != xno; then + cpp_main=cppmain +fi +fi + + +# Link cpplib into the compiler proper, for C/C++/ObjC. # Check whether --enable-c-cpplib or --disable-c-cpplib was given. if test "${enable_c_cpplib+set}" = set; then enableval="$enable_c_cpplib" - if [ x$enable_c_cpplib != xno ]; then - extra_c_objs="${extra_c_objs} cpplib.o cppexp.o cpphash.o cpperror.o" - extra_c_objs="${extra_c_objs} prefix.o" - extra_cxx_objs="${extra_cxx_objs} ../cpplib.o ../cppexp.o ../cpphash.o ../cpperror.o ../prefix.o" - extra_c_flags=-DUSE_CPPLIB=1 + if test x$enable_c_cpplib != xno; then + extra_c_objs="${extra_c_objs} libcpp.a" + extra_cxx_objs="${extra_cxx_objs} ../libcpp.a" + extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1" cpp_main=cppmain fi 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 + extra_c_flags=-DMULTIBYTE_CHARS=1 +fi +fi + + +# Disable fast fixincludes +# Check whether --enable-fast-fixincludes or --disable-fast-fixincludes was given. +if test "${enable_fast_fixincludes+set}" = set; then + enableval="$enable_fast_fixincludes" + if test x$enable_fast_fixincludes = xno ; then + cp $srcdir/fixincludes ./fixinc.sh +fi +fi + + # Enable Haifa scheduler. # Check whether --enable-haifa or --disable-haifa was given. if test "${enable_haifa+set}" = set; then @@ -672,17 +845,6 @@ if test "${enable_haifa+set}" = set; then : fi -# Fast fixincludes -# -# This is a work in progress... -# Check whether --with-fast-fixincludes or --without-fast-fixincludes was given. -if test "${with_fast_fixincludes+set}" = set; then - withval="$with_fast_fixincludes" - fast_fixinc="$with_fast_fixincludes" -else - fast_fixinc=no -fi - # Enable threads # Pass with no value to take the default @@ -690,7 +852,7 @@ fi # Check whether --enable-threads or --disable-threads was given. if test "${enable_threads+set}" = set; then enableval="$enable_threads" - if [ x$enable_threads = xno ]; then + if test x$enable_threads = xno; then enable_threads='' fi else @@ -719,6 +881,38 @@ case x${enable_threads_flag} in ;; esac +# Check whether --enable-objc-gc or --disable-objc-gc was given. +if test "${enable_objc_gc+set}" = set; then + enableval="$enable_objc_gc" + if [ x$enable_objc_gc = xno ]; then + objc_boehm_gc='' +else + objc_boehm_gc=1 +fi +else + objc_boehm_gc='' +fi + + +# Check whether --enable-java-gc or --disable-java-gc was given. +if test "${enable_java_gc+set}" = set; then + enableval="$enable_java_gc" + + JAVAGC=$enableval +else + JAVAGC=boehm +fi + + +# Check whether --with-dwarf2 or --without-dwarf2 was given. +if test "${with_dwarf2+set}" = set; then + withval="$with_dwarf2" + dwarf2="$with_dwarf2" +else + dwarf2=no +fi + + # Determine the host, build, and target systems ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do @@ -767,7 +961,7 @@ 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:771: checking host system type" >&5 +echo "configure:965: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -788,7 +982,7 @@ 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:792: checking target system type" >&5 +echo "configure:986: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -806,7 +1000,7 @@ 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:810: checking build system type" >&5 +echo "configure:1004: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -833,7 +1027,7 @@ test "$host_alias" != "$target_alias" && # 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:837: checking for $ac_word" >&5 +echo "configure:1031: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -863,7 +1057,7 @@ 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:867: checking for $ac_word" >&5 +echo "configure:1061: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -914,7 +1108,7 @@ fi # 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:918: checking for $ac_word" >&5 +echo "configure:1112: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -946,7 +1140,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:950: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1144: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -957,12 +1151,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 961 "configure" +#line 1155 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:966: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1160: \"$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 @@ -988,12 +1182,12 @@ 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:992: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1186: 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:997: checking whether we are using GNU C" >&5 +echo "configure:1191: 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 @@ -1002,7 +1196,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1006: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1021,7 +1215,7 @@ 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:1025: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:1219: 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 else @@ -1052,8 +1246,19 @@ else fi fi + +# 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'. +if test "x$GCC" = "xyes"; then + stage1_warn_cflags='$(WARN_CFLAGS)' +else + stage1_warn_cflags="" +fi + + echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:1057: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:1262: 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 @@ -1080,13 +1285,37 @@ else fi +echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6 +echo "configure:1290: 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:1302: 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 + # 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. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1090: checking for $ac_word" >&5 +echo "configure:1319: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1118,7 +1347,7 @@ done # 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:1122: checking for $ac_word" >&5 +echo "configure:1351: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1152,7 +1381,7 @@ then *) ac_lib=l ;; esac echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6 -echo "configure:1156: checking for yywrap in -l$ac_lib" >&5 +echo "configure:1385: checking for yywrap in -l$ac_lib" >&5 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1160,7 +1389,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$ac_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1404: \"$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 @@ -1194,7 +1423,7 @@ fi fi echo $ac_n "checking whether ln works""... $ac_c" 1>&6 -echo "configure:1198: checking whether ln works" >&5 +echo "configure:1427: checking whether ln works" >&5 if eval "test \"`echo '$''{'gcc_cv_prog_LN'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1226,7 +1455,7 @@ else fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1230: checking whether ln -s works" >&5 +echo "configure:1459: 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 else @@ -1258,19 +1487,19 @@ else fi echo $ac_n "checking for volatile""... $ac_c" 1>&6 -echo "configure:1262: checking for volatile" >&5 +echo "configure:1491: 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 <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1503: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gcc_cv_c_volatile=yes else @@ -1293,7 +1522,7 @@ 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:1297: checking for $ac_word" >&5 +echo "configure:1526: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1325,7 +1554,7 @@ 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:1329: checking for $ac_word" >&5 +echo "configure:1558: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1366,7 +1595,7 @@ test -n "$YACC" || YACC="yacc" # 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:1370: checking for a BSD compatible install" >&5 +echo "configure:1599: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1417,7 +1646,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1421: checking how to run the C preprocessor" >&5 +echo "configure:1650: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1432,13 +1661,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < 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; } +{ (eval echo configure:1671: \"$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 : @@ -1449,13 +1678,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1459: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1688: \"$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 : @@ -1466,13 +1695,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1476: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1705: \"$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 : @@ -1497,12 +1726,12 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1501: checking for ANSI C header files" >&5 +echo "configure:1730: 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 else cat > conftest.$ac_ext < #include @@ -1510,7 +1739,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1514: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1743: \"$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* @@ -1527,7 +1756,7 @@ rm -f conftest* 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 @@ -1545,7 +1774,7 @@ 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 @@ -1566,7 +1795,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1577,7 +1806,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1601,12 +1830,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:1605: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:1834: 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 else cat > conftest.$ac_ext < #include @@ -1615,7 +1844,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:1619: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1848: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -1635,21 +1864,97 @@ EOF fi -for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h wait.h sys/wait.h +echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6 +echo "configure:1869: 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 +else + cat > conftest.$ac_ext < +#include +int main() { + +; return 0; } +EOF +if { (eval echo configure:1882: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + 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 +fi +rm -f conftest* +fi + +echo "$ac_t""$gcc_cv_header_string" 1>&6 +if test $gcc_cv_header_string = yes; then + cat >> confdefs.h <<\EOF +#define STRING_WITH_STRINGS 1 +EOF + +fi + +echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 +echo "configure:1903: 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 +else + cat > conftest.$ac_ext < +#include +#ifndef WEXITSTATUS +#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +#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:1924: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + 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 +fi +rm -f conftest* +fi + +echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 +if test $ac_cv_header_sys_wait_h = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_SYS_WAIT_H 1 +EOF + +fi + +for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h sys/stat.h direct.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1643: checking for $ac_hdr" >&5 +echo "configure:1948: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1653: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1958: \"$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* @@ -1679,17 +1984,17 @@ 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:1683: checking for thread.h" >&5 +echo "configure:1988: 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 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1693: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1998: \"$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* @@ -1713,17 +2018,17 @@ fi ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for pthread.h""... $ac_c" 1>&6 -echo "configure:1717: checking for pthread.h" >&5 +echo "configure:2022: 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 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2032: \"$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* @@ -1746,15 +2051,47 @@ have_pthread_h= fi +# See if GNAT has been installed +# 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:2059: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnat'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$gnat"; then + ac_cv_prog_gnat="$gnat" # 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_gnat="yes" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_gnat" && ac_cv_prog_gnat="no" +fi +fi +gnat="$ac_cv_prog_gnat" +if test -n "$gnat"; then + echo "$ac_t""$gnat" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + # See if the system preprocessor understands the ANSI C preprocessor # stringification operator. echo $ac_n "checking whether cpp understands the stringify operator""... $ac_c" 1>&6 -echo "configure:1753: checking whether cpp understands the stringify operator" >&5 +echo "configure:2090: checking whether cpp understands the stringify operator" >&5 if eval "test \"`echo '$''{'gcc_cv_c_have_stringify'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2103: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gcc_cv_c_have_stringify=yes else @@ -1785,12 +2122,12 @@ fi # Use only if it exists, # doesn't clash with , and declares intmax_t. echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6 -echo "configure:1789: checking for inttypes.h" >&5 +echo "configure:2126: 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 < #include @@ -1798,7 +2135,7 @@ int main() { intmax_t i = -1; ; return 0; } EOF -if { (eval echo configure:1802: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2139: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* gcc_cv_header_inttypes_h=yes else @@ -1820,15 +2157,16 @@ fi for ac_func in strtoul bsearch strerror putenv popen bcopy bzero bcmp \ index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \ - sysconf isascii gettimeofday + sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \ + fputs_unlocked do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1827: checking for $ac_func" >&5 +echo "configure:2165: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2193: \"$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 @@ -1876,13 +2214,16 @@ fi done +# Make sure wchar_t is available +#AC_CHECK_TYPE(wchar_t, unsigned int) + echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:1881: checking for vprintf" >&5 +echo "configure:2222: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -1929,12 +2270,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:1933: checking for _doprnt" >&5 +echo "configure:2274: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2302: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -1993,7 +2334,7 @@ fi echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6 -echo "configure:1997: checking whether the printf functions support %p" >&5 +echo "configure:2338: 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 else @@ -2001,7 +2342,7 @@ else gcc_cv_func_printf_ptr=no else cat > conftest.$ac_ext < @@ -2014,7 +2355,7 @@ main() exit (p != q); } EOF -if { (eval echo configure:2018: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then gcc_cv_func_printf_ptr=yes else @@ -2038,122 +2379,385 @@ EOF fi -for ac_func in malloc realloc calloc free bcopy bzero bcmp \ - index rindex getenv atol sbrk abort atof strerror getcwd getwd -do -echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 -echo "configure:2046: checking whether $ac_func must be declared" >&5 -if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then +case "${host}" in +*-*-uwin*) + # Under some versions of uwin, vfork is notoriously buggy and the test + # can hang configure; on other versions, vfork exists just as a stub. + # FIXME: This should be removed once vfork in uwin's runtime is fixed. + ac_cv_func_vfork_works=no + ;; +esac +echo $ac_n "checking for pid_t""... $ac_c" 1>&6 +echo "configure:2392: 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 < -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#ifdef HAVE_STDLIB_H +#include +#if STDC_HEADERS #include +#include #endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifndef HAVE_RINDEX -#define rindex strrchr -#endif -#ifndef HAVE_INDEX -#define index strchr -#endif - -int main() { -char *(*pfn) = (char *(*)) $ac_func -; return 0; } EOF -if { (eval echo configure:2079: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +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* - eval "gcc_cv_decl_needed_$ac_func=no" + ac_cv_type_pid_t=yes else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 rm -rf conftest* - eval "gcc_cv_decl_needed_$ac_func=yes" + ac_cv_type_pid_t=no fi rm -f conftest* -fi -if eval "test \"`echo '$gcc_cv_decl_needed_'$ac_func`\" = yes"; then - echo "$ac_t""yes" 1>&6 - gcc_tr_decl=NEED_DECLARATION_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` - cat >> confdefs.h <&6 +if test $ac_cv_type_pid_t = no; then + cat >> confdefs.h <<\EOF +#define pid_t int EOF -else - echo "$ac_t""no" 1>&6 fi -done - - -for ac_func in getrlimit setrlimit -do -echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 -echo "configure:2108: checking whether $ac_func must be declared" >&5 -if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then +ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for vfork.h""... $ac_c" 1>&6 +echo "configure:2426: 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 else cat > conftest.$ac_ext < -#ifdef HAVE_STRING_H -#include -#else -#ifdef HAVE_STRINGS_H -#include -#endif -#endif -#ifdef HAVE_STDLIB_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#ifndef HAVE_RINDEX -#define rindex strrchr -#endif -#ifndef HAVE_INDEX -#define index strchr -#endif -#include -#ifdef HAVE_SYS_RESOURCE_H -#include -#endif - -int main() { -char *(*pfn) = (char *(*)) $ac_func -; return 0; } +#include EOF -if { (eval echo configure:2145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:2436: \"$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 "gcc_cv_decl_needed_$ac_func=no" + 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 "gcc_cv_decl_needed_$ac_func=yes" + eval "ac_cv_header_$ac_safe=no" fi rm -f conftest* fi - -if eval "test \"`echo '$gcc_cv_decl_needed_'$ac_func`\" = yes"; then +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 + +else + echo "$ac_t""no" 1>&6 +fi + +echo $ac_n "checking for working vfork""... $ac_c" 1>&6 +echo "configure:2461: 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:2467: 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 < +/* 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 vfork(); + +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_vfork) || defined (__stub___vfork) +choke me +#else +vfork(); +#endif + +; return 0; } +EOF +if { (eval echo configure:2495: \"$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* +fi + +if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then + echo "$ac_t""yes" 1>&6 + : +else + echo "$ac_t""no" 1>&6 +fi + +ac_cv_func_vfork_works=$ac_cv_func_vfork +else + cat > conftest.$ac_ext < +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_VFORK_H +#include +#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 , + but some compilers (e.g. gcc -O) don't grok . + Test for this by using a static variable whose address + is put into a register that is clobbered by the vfork. */ +static +#ifdef __cplusplus +sparc_address_test (int arg) +#else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} +main() { + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (); + + 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. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || 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. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + exit( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +EOF +if { (eval echo configure:2612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +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 +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_vfork_works" 1>&6 +if test $ac_cv_func_vfork_works = no; then + cat >> confdefs.h <<\EOF +#define vfork fork +EOF + +fi + + +for ac_func in malloc realloc calloc free bcopy bzero bcmp \ + index rindex getenv atol sbrk abort atof strerror getcwd getwd \ + strsignal putc_unlocked fputs_unlocked strstr +do +echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 +echo "configure:2640: checking whether $ac_func must be declared" >&5 +if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#ifdef STRING_WITH_STRINGS +# include +# include +#else +# ifdef HAVE_STRING_H +# include +# else +# ifdef HAVE_STRINGS_H +# include +# endif +# endif +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifndef HAVE_RINDEX +#define rindex strrchr +#endif +#ifndef HAVE_INDEX +#define index strchr +#endif + +int main() { +char *(*pfn) = (char *(*)) $ac_func +; return 0; } +EOF +if { (eval echo configure:2678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "gcc_cv_decl_needed_$ac_func=no" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "gcc_cv_decl_needed_$ac_func=yes" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$gcc_cv_decl_needed_'$ac_func`\" = yes"; then + echo "$ac_t""yes" 1>&6 + gcc_tr_decl=NEED_DECLARATION_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` + cat >> confdefs.h <&6 +fi + +done + + +for ac_func in getrlimit setrlimit +do +echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6 +echo "configure:2707: checking whether $ac_func must be declared" >&5 +if eval "test \"`echo '$''{'gcc_cv_decl_needed_$ac_func'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#ifdef STRING_WITH_STRINGS +# include +# include +#else +# ifdef HAVE_STRING_H +# include +# else +# ifdef HAVE_STRINGS_H +# include +# endif +# endif +#endif +#ifdef HAVE_STDLIB_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif +#ifndef HAVE_RINDEX +#define rindex strrchr +#endif +#ifndef HAVE_INDEX +#define index strchr +#endif +#include +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif + +int main() { +char *(*pfn) = (char *(*)) $ac_func +; return 0; } +EOF +if { (eval echo configure:2749: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + eval "gcc_cv_decl_needed_$ac_func=no" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "gcc_cv_decl_needed_$ac_func=yes" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$gcc_cv_decl_needed_'$ac_func`\" = yes"; then echo "$ac_t""yes" 1>&6 gcc_tr_decl=NEED_DECLARATION_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'` cat >> confdefs.h <&6 -echo "configure:2172: checking for sys_siglist declaration in signal.h or unistd.h" >&5 +echo "configure:2776: checking for sys_siglist declaration in signal.h or unistd.h" >&5 if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2185,7 +2789,7 @@ int main() { char *msg = *(sys_siglist + 1); ; return 0; } EOF -if { (eval echo configure:2189: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2793: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_decl_sys_siglist=yes else @@ -2206,6 +2810,51 @@ EOF fi +# mkdir takes a single argument on some systems. +echo $ac_n "checking if mkdir takes one argument""... $ac_c" 1>&6 +echo "configure:2816: 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 +else + cat > conftest.$ac_ext < +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_DIRECT_H +# include +#endif +int main() { +mkdir ("foo", 0); +; return 0; } +EOF +if { (eval echo configure:2838: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + 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 +fi +rm -f conftest* +fi + +echo "$ac_t""$gcc_cv_mkdir_takes_one_arg" 1>&6 +if test $gcc_cv_mkdir_takes_one_arg = yes ; then + cat >> confdefs.h <<\EOF +#define MKDIR_TAKES_ONE_ARG 1 +EOF + +fi + + # File extensions manext='.1' objext='.o' @@ -2221,7 +2870,6 @@ host_xm_defines= host_xmake_file= host_truncate_target= host_exeext= -cpp_install_dir= # Decode the host machine, then the target machine. # For the host machine, we save the xm_file variable as host_xm_file; @@ -2245,10 +2893,6 @@ for machine in $build $host $target; do use_collect2= # Set this to override the default target model. target_cpu_default= - # Set this to control which fixincludes program to use. - if [ x$fast_fixinc != xyes ] ; then - fixincludes=fixincludes - else fixincludes=fixinc.sh ; fi # Set this to control how the header file directory is installed. install_headers_dir=install-headers-tar # Set this to a non-empty list of args to pass to cpp if the target @@ -2315,11 +2959,11 @@ for machine in $build $host $target; do ;; *-*-openbsd*) tm_file=${cpu_type}/openbsd.h - # On OpenBSD systems, the headers are okay - fixincludes=Makefile.in tmake_file="t-libc-ok t-openbsd" # avoid surprises, always provide an xm-openbsd file xm_file=${cpu_type}/xm-openbsd.h + # don't depend on processor x-fragments as well + xmake_file=none if test x$enable_threads = xyes; then thread_file='posix' tmake_file="${tmake_file} t-openbsd-thread" @@ -2334,11 +2978,11 @@ for machine in $build $host $target; do rest=`echo $machine | sed -e "s/$cpu_type-//"` xm_file=${cpu_type}/xm-$rest.h tm_file=${cpu_type}/$rest.h - if [ -f $srcdir/config/${cpu_type}/x-$rest ] ; \ + if test -f $srcdir/config/${cpu_type}/x-$rest; \ then xmake_file=${cpu_type}/x-$rest; \ else true; \ fi - if [ -f $srcdir/config/${cpu_type}/t-$rest ] ; \ + if test -f $srcdir/config/${cpu_type}/t-$rest; \ then tmake_file=${cpu_type}/t-$rest; \ else true; \ fi @@ -2364,9 +3008,31 @@ for machine in $build $host $target; do a29k-*-*) # Default a29k environment. use_collect2=yes ;; + 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_file="alpha/xm-alpha-interix.h xm-interix.h" + xmake_file="x-interix alpha/t-pe" + tmake_file="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-gnuecoff*) tm_file="${tm_file} alpha/linux-ecoff.h alpha/linux.h" target_cpu_default="MASK_GAS" + tmake_file="alpha/t-ieee" gas=no xmake_file=none gas=yes gnu_ld=yes @@ -2374,54 +3040,51 @@ for machine in $build $host $target; do alpha*-*-linux-gnulibc1*) tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" target_cpu_default="MASK_GAS" - tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe" + tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.wrap xmake_file=none gas=yes gnu_ld=yes - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; alpha*-*-linux-gnu*) tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" target_cpu_default="MASK_GAS" - tmake_file="t-linux alpha/t-linux alpha/t-crtbe" + tmake_file="t-linux alpha/t-linux alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" xmake_file=none - fixincludes=Makefile.in gas=yes gnu_ld=yes - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; alpha*-*-netbsd*) - tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsdl-elf.h" - xm_file="xm-netbsd.h ${xm_file}" + tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h" target_cpu_default="MASK_GAS" - tmake_file="alpha/t-crtbe" + tmake_file="alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" xmake_file=none - fixincludes=fixinc.wrap gas=yes gnu_ld=yes ;; alpha*-*-openbsd*) # default x-alpha is only appropriate for dec-osf. target_cpu_default="MASK_GAS" - xmake_file=none + tmake_file="alpha/t-ieee" ;; alpha*-dec-osf*) - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi - if [ x$gas != xyes ] + if test x$gas != xyes then extra_passes="mips-tfile mips-tdump" fi use_collect2=yes + tmake_file="alpha/t-ieee" case $machine in *-*-osf1*) tm_file="${tm_file} alpha/osf.h alpha/osf12.h alpha/osf2or3.h" @@ -2444,33 +3107,33 @@ for machine in $build $host $target; do ;; alpha*-*-vxworks*) tm_file="${tm_file} dbx.h alpha/vxworks.h" + tmake_file="alpha/t-ieee" if x$gas != xyes then extra_passes="mips-tfile mips-tdump" fi use_collect2=yes + thread_file='vxworks' ;; alpha*-*-winnt*) - tm_file="${tm_file} alpha/win-nt.h" + tm_file="${tm_file} alpha/alpha32.h alpha/win-nt.h winnt/win-nt.h" xm_file="${xm_file} config/winnt/xm-winnt.h alpha/xm-winnt.h" - tmake_file=t-libc-ok + tmake_file="t-libc-ok alpha/t-ieee" xmake_file=winnt/x-winnt extra_host_objs=oldnames.o extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then extra_programs=ld.exe fi - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='win32' fi ;; alpha*-dec-vms*) tm_file=alpha/vms.h xm_file="${xm_file} alpha/xm-vms.h" - tmake_file=alpha/t-vms - fixincludes=Makefile.in + tmake_file="alpha/t-vms alpha/t-ieee" ;; arc-*-elf*) extra_parts="crtinit.o crtfini.o" @@ -2479,12 +3142,17 @@ for machine in $build $host $target; do tm_file=arm/coff.h tmake_file=arm/t-bare ;; + arm-*-vxworks*) + tm_file=arm/vxarm.h + tmake_file=arm/t-bare + thread_file='vxworks' + ;; arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) tm_file=arm/riscix1-1.h use_collect2=yes ;; arm-*-riscix*) # Acorn RISC machine - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=arm/rix-gas.h else @@ -2497,57 +3165,84 @@ for machine in $build $host $target; do arm-semi-aout | armel-semi-aout) tm_file=arm/semi.h tmake_file=arm/t-semi - fixincludes=Makefile.in # There is nothing to fix ;; arm-semi-aof | armel-semi-aof) tm_file=arm/semiaof.h tmake_file=arm/t-semiaof - fixincludes=Makefile.in # There is nothing to fix ;; arm*-*-netbsd*) tm_file=arm/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" + xm_file="arm/xm-netbsd.h ${xm_file}" tmake_file="t-netbsd arm/t-netbsd" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap + use_collect2=yes ;; - arm-*-linux-gnuaout*) # ARM GNU/Linux + arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out cpu_type=arm xmake_file=x-linux - tm_file=arm/linux-gas.h + tm_file=arm/linux-aout.h tmake_file=arm/t-linux - fixincludes=Makefile.in gnu_ld=yes ;; - arm-*-aout) + arm*-*-linux-gnu*) # ARM GNU/Linux with ELF + xm_file=arm/xm-linux.h + xmake_file=x-linux + case $machine in + armv2*-*-*) + tm_file=arm/linux-elf26.h + ;; + *) + tm_file=arm/linux-elf.h + ;; + esac + tmake_file="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*-*-aout) tm_file=arm/aout.h tmake_file=arm/t-bare ;; + arm*-*-ecos-elf) + tm_file=arm/ecos-elf.h + tmake_file=arm/t-elf + ;; + arm*-*-elf) + tm_file=arm/unknown-elf.h + tmake_file=arm/t-arm-elf + ;; + arm*-*-oabi) + tm_file=arm/unknown-elf-oabi.h + tmake_file=arm/t-arm-elf + ;; c1-convex-*) # Convex C1 target_cpu_default=1 use_collect2=yes - fixincludes=Makefile.in ;; c2-convex-*) # Convex C2 target_cpu_default=2 use_collect2=yes - fixincludes=Makefile.in ;; c32-convex-*) target_cpu_default=4 use_collect2=yes - fixincludes=Makefile.in ;; c34-convex-*) target_cpu_default=8 use_collect2=yes - fixincludes=Makefile.in ;; c38-convex-*) target_cpu_default=16 use_collect2=yes - fixincludes=Makefile.in ;; + c4x-*) + cpu_type=c4x + tmake_file=c4x/t-c4x + ;; clipper-intergraph-clix*) tm_file="${tm_file} svr3.h clipper/clix.h" xm_file=clipper/xm-clix.h @@ -2568,8 +3263,8 @@ for machine in $build $host $target; do float_format=i32 ;; hppa*-*-openbsd*) - target_cpu_default="MASK_SNAKE" - tmake_file=pa/t-openbsd + target_cpu_default="MASK_PA_11" + tmake_file=pa/t-openbsd ;; hppa1.1-*-pro*) tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h" @@ -2577,10 +3272,9 @@ for machine in $build $host $target; do tmake_file=pa/t-pro ;; hppa1.1-*-osf*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-osf.h" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.1-*-rtems*) tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h" @@ -2590,22 +3284,19 @@ for machine in $build $host $target; do hppa1.0-*-osf*) tm_file="${tm_file} pa/pa-osf.h" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.1-*-bsd*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.0-*-bsd*) use_collect2=yes - fixincludes=Makefile.in ;; hppa1.0-*-hpux7*) tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/gas.h" fi @@ -2616,7 +3307,7 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" else @@ -2626,11 +3317,11 @@ for machine in $build $host $target; do use_collect2=yes ;; hppa1.1-*-hpux8.0[0-2]*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" else @@ -2640,11 +3331,11 @@ for machine in $build $host $target; do use_collect2=yes ;; hppa1.1-*-hpux8*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -2655,27 +3346,27 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hpux10*) - target_cpu_default=1 + hppa1.1-*-hpux10* | hppa2*-*-hpux10*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux tmake_file=pa/t-pa - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi - if [ x$enable_threads = x ]; then + if test x$enable_threads = x; then enable_threads=$have_pthread_h fi - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='dce' tmake_file="${tmake_file} pa/t-dce-thr" fi @@ -2687,26 +3378,26 @@ for machine in $build $host $target; do xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux tmake_file=pa/t-pa - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi - if [ x$enable_threads = x ]; then + if test x$enable_threads = x; then enable_threads=$have_pthread_h fi - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='dce' tmake_file="${tmake_file} pa/t-dce-thr" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hpux*) - target_cpu_default=1 + hppa1.1-*-hpux* | hppa2*-*-hpux*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -2717,19 +3408,19 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hiux*) - target_cpu_default=1 + hppa1.1-*-hiux* | hppa2*-*-hiux*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -2740,7 +3431,7 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -2748,14 +3439,13 @@ for machine in $build $host $target; do use_collect2=yes ;; hppa*-*-lites*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" use_collect2=yes - fixincludes=Makefile.in ;; i370-*-mvs*) ;; i[34567]86-ibm-aix*) # IBM PS/2 running AIX - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=i386/aix386.h extra_parts="crtbegin.o crtend.o" @@ -2768,11 +3458,11 @@ for machine in $build $host $target; do xm_defines=USG xmake_file=i386/x-aix ;; - i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 + i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" xmake_file=i386/x-ncr3000 - if [ x$stabs = xyes -a x$gas = xyes ] + if test x$stabs = xyes -a x$gas = xyes then tm_file=i386/sysv4gdb.h else @@ -2787,13 +3477,14 @@ for machine in $build $host $target; do tmake_file=i386/t-next xmake_file=i386/x-next extra_objs=nextstep.o - if [ x$enable_threads = xyes ]; then + extra_parts="crtbegin.o crtend.o" + if test x$enable_threads = xyes; then thread_file='mach' fi ;; i[34567]86-sequent-bsd*) # 80386 from Sequent use_collect2=yes - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=i386/seq-gas.h else @@ -2805,7 +3496,6 @@ for machine in $build $host $target; do xmake_file=i386/x-sysv3 tm_file=i386/seq-sysv3.h tmake_file=i386/t-crtstuff - fixincludes=fixinc.ptx extra_parts="crtbegin.o crtend.o" install_headers_dir=install-headers-cpio ;; @@ -2815,7 +3505,6 @@ for machine in $build $host $target; do tm_file=i386/seq2-sysv3.h tmake_file=i386/t-crtstuff extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx install_headers_dir=install-headers-cpio ;; i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) @@ -2825,7 +3514,6 @@ for machine in $build $host $target; do tm_file=i386/ptx4-i.h tmake_file=t-svr4 extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx install_headers_dir=install-headers-cpio ;; i386-sun-sunos*) # Sun i386 roadrunner @@ -2836,6 +3524,7 @@ for machine in $build $host $target; do i[34567]86-wrs-vxworks*) tm_file=i386/vxi386.h tmake_file=i386/t-i386bare + thread_file='vxworks' ;; i[34567]86-*-aout*) tm_file=i386/i386-aout.h @@ -2852,34 +3541,26 @@ for machine in $build $host $target; do # use_collect2=yes ;; i[34567]86-*-freebsdelf*) - tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h" - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap + tm_file="i386/i386.h i386/att.h svr4.h i386/freebsd-elf.h i386/perform.h" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - tmake_file=i386/t-freebsd + tmake_file=t-freebsd gas=yes gnu_ld=yes stabs=yes ;; i[34567]86-*-freebsd*) tm_file=i386/freebsd.h - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - tmake_file=i386/t-freebsd + tmake_file=t-freebsd ;; i[34567]86-*-netbsd*) tm_file=i386/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes + ;; + i[34567]86-*-openbsd*) + # we need collect2 until our bug is fixed... + use_collect2=yes ;; - i[34567]86-*-openbsd*) - # Remove when the math emulator is fixed - target_cpu_default="MASK_NO_FANCY_MATH_387" - # we need collect2 until our bug is fixed... - use_collect2=yes - ;; i[34567]86-*-coff*) tm_file=i386/i386-coff.h tmake_file=i386/t-i386bare @@ -2895,7 +3576,7 @@ for machine in $build $host $target; do xmake_file=i386/x-isc ;; esac - if [ x$gas = xyes -a x$stabs = xyes ] + if test x$gas = xyes -a x$stabs = xyes then tm_file=i386/iscdbx.h tmake_file=i386/t-svr3dbx @@ -2908,49 +3589,41 @@ for machine in $build $host $target; do install_headers_dir=install-headers-cpio ;; i[34567]86-*-linux-gnuoldld*) # Intel 80386's running GNU/Linux - # with a.out format using # pre BFD linkers xmake_file=x-linux-aout tmake_file="t-linux-aout i386/t-crtstuff" tm_file=i386/linux-oldld.h - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 ;; i[34567]86-*-linux-gnuaout*) # Intel 80386's running GNU/Linux - # with a.out format xmake_file=x-linux-aout tmake_file="t-linux-aout i386/t-crtstuff" tm_file=i386/linux-aout.h - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 ;; i[34567]86-*-linux-gnulibc1) # Intel 80386's running GNU/Linux - # with ELF format using the # GNU/Linux C library 5 xmake_file=x-linux tm_file=i386/linux.h tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='single' fi ;; i[34567]86-*-linux-gnu*) # Intel 80386's running GNU/Linux - # with ELF format using glibc 2 # aka GNU/Linux C library 6 xmake_file=x-linux tm_file=i386/linux.h tmake_file="t-linux i386/t-crtstuff" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -2958,26 +3631,30 @@ for machine in $build $host $target; do float_format=i386 ;; i[34567]86-go32-msdos | i[34567]86-*-go32*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 + echo "GO32/DJGPP V1.X is no longer supported. Use *-pc-msdosdjgpp for DJGPP V2.X instead." + exit 1 ;; i[34567]86-pc-msdosdjgpp*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 + xm_file=i386/xm-djgpp.h + tm_file=i386/djgpp.h + tmake_file=i386/t-djgpp + xmake_file=i386/x-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=i386/moss.h tmake_file=t-libc-ok - fixincludes=Makefile.in gnu_ld=yes gas=yes ;; i[34567]86-*-lynxos*) - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=i386/lynx.h else @@ -2993,7 +3670,7 @@ for machine in $build $host $target; do use_collect2=yes ;; i[34567]86-*-osfrose*) # 386 using OSF/rose - if [ x$elf = xyes ] + if test x$elf = xyes then tm_file=i386/osfelf.h use_collect2= @@ -3026,10 +3703,9 @@ for machine in $build $host $target; do xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h" xm_defines="USG SVR3" xmake_file=i386/x-sco5 - fixincludes=fixinc.sco install_headers_dir=install-headers-cpio tm_file=i386/sco5.h - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="i386/sco5gas.h ${tm_file}" tmake_file=i386/t-sco5gas @@ -3042,9 +3718,8 @@ for machine in $build $host $target; do xm_file="${xm_file} i386/xm-sco.h" xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST" xmake_file=i386/x-sco4 - fixincludes=fixinc.sco install_headers_dir=install-headers-cpio - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=i386/sco4dbx.h tmake_file=i386/t-svr3dbx @@ -3060,7 +3735,7 @@ for machine in $build $host $target; do xm_file=i386/xm-sco.h xmake_file=i386/x-sco install_headers_dir=install-headers-cpio - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=i386/scodbx.h tmake_file=i386/t-svr3dbx @@ -3075,7 +3750,7 @@ for machine in $build $host $target; do i[34567]86-*-solaris2*) xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=i386/sol2dbg.h else @@ -3084,34 +3759,30 @@ for machine in $build $host $target; do tmake_file=i386/t-sol2 extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" xmake_file=x-svr4 - case $machine in - *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='solaris' fi ;; i[34567]86-*-sysv5*) # Intel x86 on System V Release 5 xm_file="xm-alloca.h xm-siglist.h ${xm_file}" xm_defines="USG POSIX" - tm_file=i386/sysv4.h - if [ x$stabs = xyes ] + tm_file=i386/sysv5.h + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi tmake_file=i386/t-crtpic xmake_file=x-svr4 extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.svr4 + if test x$enable_threads = xyes; then + thread_file='posix' + fi ;; i[34567]86-*-sysv4*) # Intel 80386's running system V.4 xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" tm_file=i386/sysv4.h - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -3119,12 +3790,20 @@ for machine in $build $host $target; do xmake_file=x-svr4 extra_parts="crtbegin.o crtend.o" ;; + i[34567]86-*-udk*) # Intel x86 on SCO UW/OSR5 Dev Kit + xm_file="xm-alloca.h xm-siglist.h ${xm_file}" + xm_defines="USG POSIX" + tm_file=i386/udk.h + tmake_file="i386/t-crtpic i386/t-udk" + xmake_file=x-svr4 + extra_parts="crtbegin.o crtend.o" + install_headers_dir=install-headers-cpio + ;; i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+ cpu_type=i386 xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h" xm_defines="USE_C_ALLOCA SMALL_ARG_MAX" - fixincludes=Makefile.in #Don't do it on OSF/1 - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=i386/osf1elfgdb.h else @@ -3137,9 +3816,9 @@ for machine in $build $host $target; do i[34567]86-*-sysv*) # Intel 80386's running system V xm_defines="USG SVR3" xmake_file=i386/x-sysv3 - if [ x$gas = xyes ] + if test x$gas = xyes then - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=i386/svr3dbx.h tmake_file=i386/t-svr3dbx @@ -3161,14 +3840,24 @@ for machine in $build $host $target; do tmake_file=i386/t-vsta xmake_file=i386/x-vsta ;; - i[34567]86-*-pe | i[34567]86-*-cygwin32) - xm_file="${xm_file} i386/xm-cygwin32.h" - tmake_file=i386/t-cygwin32 - tm_file=i386/cygwin32.h - xmake_file=i386/x-cygwin32 + i[34567]86-*-win32) + xm_file="${xm_file} i386/xm-cygwin.h" + tmake_file=i386/t-cygwin + tm_file=i386/win32.h + xmake_file=i386/x-cygwin + extra_objs=winnt.o + if test x$enable_threads = xyes; then + thread_file='win32' + fi + exeext=.exe + ;; + i[34567]86-*-pe | i[34567]86-*-cygwin*) + xm_file="${xm_file} i386/xm-cygwin.h" + tmake_file=i386/t-cygwin + tm_file=i386/cygwin.h + xmake_file=i386/x-cygwin extra_objs=winnt.o - fixincludes=Makefile.in - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe @@ -3176,22 +3865,47 @@ for machine in $build $host $target; do i[34567]86-*-mingw32*) tm_file=i386/mingw32.h xm_file="${xm_file} i386/xm-mingw32.h" - tmake_file="i386/t-cygwin32 i386/t-mingw32" + tmake_file="i386/t-cygwin i386/t-mingw32" extra_objs=winnt.o - xmake_file=i386/x-cygwin32 - fixincludes=Makefile.in - if [ x$enable_threads = xyes ]; then + xmake_file=i386/x-cygwin + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe case $machine in *mingw32msv*) ;; - *mingw32crt* | *mingw32*) + *minwg32crt* | *mingw32*) tm_file="${tm_file} i386/crtdll.h" ;; esac ;; + i[34567]86-*-uwin*) + tm_file=i386/uwin.h + xm_file="${xm_file} i386/xm-uwin.h" + xm_defines="USG NO_STAB_H NO_SYS_SIGLIST" + tmake_file="i386/t-cygwin i386/t-uwin" + extra_objs=winnt.o + xmake_file=i386/x-cygwin + if test x$enable_threads = xyes; then + thread_file='win32' + fi + exeext=.exe + ;; + i[34567]86-*-interix*) + tm_file="i386/i386-interix.h interix.h" + xm_file="i386/xm-i386-interix.h xm-interix.h" + xm_defines="USG NO_SYS_SIGLIST" + tmake_file="i386/t-interix" + extra_objs=interix.o + xmake_file=x-interix + if test x$enable_threads = xyes ; then + thread_file='posix' + fi + if test x$stabs = xyes ; then + tm_file="${tm_file} dbxcoff.h" + fi + ;; i[34567]86-*-winnt3*) tm_file=i386/win-nt.h out_file=i386/i386.c @@ -3200,12 +3914,11 @@ for machine in $build $host $target; do tmake_file=i386/t-winnt extra_host_objs="winnt.o oldnames.o" extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then extra_programs=ld.exe fi - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='win32' fi ;; @@ -3216,7 +3929,6 @@ for machine in $build $host $target; do tm_file=i386/dgux.h tmake_file=i386/t-dgux xmake_file=i386/x-dgux - fixincludes=fixinc.dgux install_headers_dir=install-headers-cpio ;; i860-alliant-*) # Alliant FX/2800 @@ -3228,7 +3940,7 @@ for machine in $build $host $target; do ;; i860-*-bsd*) tm_file="${tm_file} i860/bsd.h" - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="${tm_file} i860/bsd-gas.h" fi @@ -3306,7 +4018,7 @@ for machine in $build $host $target; do m68000-hp-hpux*) # HP 9000 series 300 xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [ x$gas = xyes ] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp310g.h @@ -3331,7 +4043,7 @@ for machine in $build $host $target; do m68000-att-sysv*) xm_file="m68k/xm-3b1.h ${xm_file}" xm_defines=USG - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=m68k/3b1g.h else @@ -3347,13 +4059,13 @@ for machine in $build $host $target; do extra_headers=math-68881.h extra_parts="crt1.o mcrt1.o maccrt1.o crt2.o crtn.o" tm_file= - if [ "$gnu_ld" = yes ] + if test "$gnu_ld" = yes then tm_file="${tm_file} m68k/auxgld.h" else tm_file="${tm_file} m68k/auxld.h" fi - if [ "$gas" = yes ] + if test "$gas" = yes then tm_file="${tm_file} m68k/auxgas.h" else @@ -3370,7 +4082,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-altos-sysv*) # Altos 3068 - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=m68k/altos3068.h xm_defines=USG @@ -3381,9 +4093,9 @@ for machine in $build $host $target; do extra_headers=math-68881.h ;; m68k-bull-sysv*) # Bull DPX/2 - if [ x$gas = xyes ] + if test x$gas = xyes then - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=m68k/dpx2cdbx.h else @@ -3411,10 +4123,10 @@ for machine in $build $host $target; do tm_file=m68k/mot3300.h xm_file="xm-alloca.h m68k/xm-mot3300.h ${xm_file}" xm_defines=NO_SYS_SIGLIST - if [ x$gas = xyes ] + if test x$gas = xyes then xmake_file=m68k/x-mot3300-gas - if [ x$gnu_ld = xyes ] + if test x$gnu_ld = xyes then tmake_file=m68k/t-mot3300-gald else @@ -3423,7 +4135,7 @@ for machine in $build $host $target; do fi else xmake_file=m68k/x-mot3300 - if [ x$gnu_ld = xyes ] + if test x$gnu_ld = xyes then tmake_file=m68k/t-mot3300-gld else @@ -3483,7 +4195,6 @@ for machine in $build $host $target; do ;; m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd tm_file=m68k/hp3bsd44.h - xmake_file=m68k/x-hp3bsd44 use_collect2=yes extra_headers=math-68881.h float_format=m68k @@ -3495,7 +4206,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-isi-bsd*) - if [ x$with_fp = xno ] + if test x$with_fp = xno then tm_file=m68k/isi-nfp.h else @@ -3508,7 +4219,7 @@ for machine in $build $host $target; do m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7. xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [ x$gas = xyes ] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp320g.h @@ -3524,7 +4235,7 @@ for machine in $build $host $target; do m68k-hp-hpux*) # HP 9000 series 300 xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [ x$gas = xyes ] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp320g.h @@ -3544,7 +4255,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-sony-newsos3*) - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=m68k/news3gas.h else @@ -3555,7 +4266,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-sony-bsd* | m68k-sony-newsos*) - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=m68k/newsgas.h else @@ -3581,14 +4292,15 @@ for machine in $build $host $target; do tmake_file=m68k/t-next xmake_file=m68k/x-next extra_objs=nextstep.o + extra_parts="crtbegin.o crtend.o" extra_headers=math-68881.h float_format=m68k - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='mach' fi ;; m68k-sun-sunos3*) - if [ x$with_fp = xno ] + if test x$with_fp = xno then tm_file=m68k/sun3n3.h else @@ -3599,7 +4311,7 @@ for machine in $build $host $target; do extra_headers=math-68881.h ;; m68k-sun-sunos*) # For SunOS 4 (the default). - if [ x$with_fp = xno ] + if test x$with_fp = xno then tm_file=m68k/sun3n.h else @@ -3628,8 +4340,14 @@ for machine in $build $host $target; do extra_headers=math-68881.h float_format=m68k ;; + m68020-*-elf* | m68k-*-elf*) + tm_file="m68k/m68020-elf.h libgloss.h" + xm_file=m68k/xm-m68kv.h + tmake_file=m68k/t-m68kelf + header_files=math-68881.h + ;; m68k-*-lynxos*) - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=m68k/lynx.h else @@ -3643,11 +4361,9 @@ for machine in $build $host $target; do ;; m68k*-*-netbsd*) tm_file=m68k/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd float_format=m68k + use_collect2=yes ;; m68k*-*-openbsd*) float_format=m68k @@ -3676,7 +4392,6 @@ for machine in $build $host $target; do xmake_file=x-linux tm_file=m68k/linux-aout.h tmake_file="t-linux-aout m68k/t-linux-aout" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes @@ -3688,7 +4403,6 @@ for machine in $build $host $target; do tm_file=m68k/linux.h tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes @@ -3700,11 +4414,10 @@ for machine in $build $host $target; do tm_file=m68k/linux.h tmake_file="t-linux m68k/t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -3734,18 +4447,17 @@ for machine in $build $host $target; do esac extra_parts="crtbegin.o bcscrtbegin.o crtend.o m88kdgux.ld" xmake_file=m88k/x-dgux - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=m88k/t-dgux-gas fi - fixincludes=fixinc.dgux ;; m88k-dolphin-sysv3*) tm_file=m88k/dolph.h extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-dolph - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -3755,7 +4467,7 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-tekXD88 - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -3770,7 +4482,7 @@ for machine in $build $host $target; do m88k-*-luna*) tm_file=m88k/luna.h extra_parts="crtbegin.o crtend.o" - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=m88k/t-luna-gas else @@ -3785,7 +4497,7 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-sysv3 - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -3799,38 +4511,36 @@ for machine in $build $host $target; do mips-sgi-irix6*) # SGI System V.4., IRIX 6 tm_file=mips/iris6.h xm_file=mips/xm-iris6.h - fixincludes=fixinc.irix xmake_file=mips/x-iris6 tmake_file=mips/t-iris6 - if [ x$enable_threads = xyes ]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-wrs-vxworks) - tm_file="mips/elf.h libgloss.h" + tm_file="mips/elf.h libgloss.h mips/vxworks.h" tmake_file=mips/t-ecoff gas=yes gnu_ld=yes extra_parts="crtbegin.o crtend.o" -# thread_file='vxworks' + thread_file='vxworks' ;; mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 tm_file="mips/iris6.h mips/cross64.h" xm_defines=USG xm_file="mips/xm-iris5.h" - fixincludes=Makefile.in xmake_file=mips/x-iris tmake_file=mips/t-cross64 # See comment in mips/iris[56].h files. use_collect2=yes - if [ x$enable_threads = xyes ]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sni-sysv4) - if [ x$gas = xyes ] + if test x$gas = xyes then - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file=mips/iris5gdb.h else @@ -3842,16 +4552,16 @@ for machine in $build $host $target; do xm_defines=USG xmake_file=mips/x-sni-svr4 tmake_file=mips/t-mips-gas - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-sgi-irix5*) # SGI System V.4., IRIX 5 - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file="mips/iris5.h mips/iris5gas.h" - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -3860,72 +4570,71 @@ for machine in $build $host $target; do fi xm_defines=USG xm_file="mips/xm-iris5.h" - fixincludes=fixinc.irix xmake_file=mips/x-iris # mips-tfile doesn't work yet tmake_file=mips/t-mips-gas # See comment in mips/iris5.h file. use_collect2=yes - if [ x$enable_threads = xyes ]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-irix4loser*) # Mostly like a MIPS. tm_file="mips/iris4loser.h mips/iris3.h ${tm_file} mips/iris4.h" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi - if [ x$enable_threads = xyes ]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-irix4*) # Mostly like a MIPS. tm_file="mips/iris3.h ${tm_file} mips/iris4.h" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi - if [ x$enable_threads = xyes ]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-*) # Mostly like a MIPS. tm_file="mips/iris3.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris3 - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -3939,66 +4648,72 @@ for machine in $build $host $target; do ;; mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL tm_file=mips/dec-osf1.h - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xmake_file=mips/x-dec-osf1 - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-dec-bsd*) # Decstation running 4.4 BSD tm_file=mips/dec-bsd.h - fixincludes= - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD tm_file=mips/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd ;; + mips*-*-linux*) # Linux MIPS, either endian. + xmake_file=x-linux + xm_file="xm-siglist.h ${xm_file}" + case $machine in + mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;; + *) tm_file="mips/elf.h mips/linux.h" ;; + esac + extra_parts="crtbegin.o crtend.o" + gnu_ld=yes + gas=yes + ;; mips*el-*-openbsd*) # mips little endian target_cpu_default="MASK_GAS|MASK_ABICALLS" tm_file=mips/openbsd.h - xmake_file=none ;; mips*-*-openbsd*) # mips big endian target_cpu_default="MASK_GAS|MASK_ABICALLS" tm_file=mips/openbsd-be.h - xmake_file=none ;; mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. tm_file="mips/news4.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -4008,31 +4723,31 @@ for machine in $build $host $target; do # That is based on svr4. # t-svr4 is not right because this system doesn't use ELF. tm_file="mips/news5.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xm_defines=USG - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-tandem-sysv4*) # Tandem S2 running NonStop UX tm_file="mips/svr4-5.h mips/svr4-t.h" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xm_defines=USG xmake_file=mips/x-sysv - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas extra_parts="crtbegin.o crtend.o" @@ -4040,151 +4755,151 @@ for machine in $build $host $target; do tmake_file=mips/t-mips extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-ultrix* | mips-dec-mach3) # Decstation. tm_file="mips/ultrix.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xmake_file=mips/x-ultrix - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-riscos[56789]bsd*) tm_file=mips/bsd-5.h # MIPS BSD 4.3, RISC-OS 5.0 - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-bsd-gas else tmake_file=mips/t-bsd extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd*) tm_file="mips/bsd-4.h ${tm_file}" # MIPS BSD 4.3, RISC-OS 4.0 - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-bsd-gas else tmake_file=mips/t-bsd extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-riscos[56789]sysv4*) tm_file=mips/svr4-5.h # MIPS System V.4., RISC-OS 5.0 - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xmake_file=mips/x-sysv - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-svr4-gas else tmake_file=mips/t-svr4 extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4*) tm_file="mips/svr4-4.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-svr4-gas else tmake_file=mips/t-svr4 extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-riscos[56789]sysv*) tm_file=mips/svr3-5.h # MIPS System V.3, RISC-OS 5.0 - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-svr3-gas else tmake_file=mips/t-svr3 extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-sysv* | mips-*-riscos*sysv*) tm_file="mips/svr3-4.h ${tm_file}" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-svr3-gas else tmake_file=mips/t-svr3 extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-riscos[56789]*) # Default MIPS RISC-OS 5.0. tm_file=mips/mips-5.h - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -4193,65 +4908,65 @@ for machine in $build $host $target; do ;; mipsel-*-ecoff*) tm_file=mips/ecoffl.h - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi tmake_file=mips/t-ecoff ;; mips-*-ecoff*) tm_file="gofast.h mips/ecoff.h" - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi tmake_file=mips/t-ecoff ;; mipsel-*-elf*) tm_file="mips/elfl.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips-*-elf*) - tm_file="mips/elf.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elf.h" + tmake_file=mips/t-elf ;; mips64el-*-elf*) - tm_file="mips/elfl64.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elfl64.h" + tmake_file=mips/t-elf ;; mips64orionel-*-elf*) tm_file="mips/elforion.h mips/elfl64.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips64-*-elf*) - tm_file="mips/elf64.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elf64.h" + tmake_file=mips/t-elf ;; mips64orion-*-elf*) tm_file="mips/elforion.h mips/elf64.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips64orion-*-rtems*) tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h" tmake_file="mips/t-ecoff t-rtems" ;; mipstx39el-*-elf*) - tm_file="mips/r3900.h mips/elfl.h mips/abi64.h libgloss.h" + tm_file="mips/r3900.h mips/elfl.h mips/abi64.h" tmake_file=mips/t-r3900 ;; mipstx39-*-elf*) - tm_file="mips/r3900.h mips/elf.h mips/abi64.h libgloss.h" + tm_file="mips/r3900.h mips/elf.h mips/abi64.h" tmake_file=mips/t-r3900 ;; mips-*-*) # Default MIPS RISC-OS 4.0. - if [ x$stabs = xyes ]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [ x$gnu_ld != xyes ] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -4259,7 +4974,7 @@ for machine in $build $host $target; do mn10200-*-*) cpu_type=mn10200 tm_file="mn10200/mn10200.h" - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -4268,7 +4983,7 @@ for machine in $build $host $target; do mn10300-*-*) cpu_type=mn10300 tm_file="mn10300/mn10300.h" - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -4313,10 +5028,10 @@ for machine in $build $host $target; do ;; ns32k-*-netbsd*) tm_file=ns32k/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" + xm_file="ns32k/xm-netbsd.h ${xm_file}" # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes ;; pdp11-*-bsd) tm_file="${tm_file} pdp11/2bsd.h" @@ -4343,7 +5058,6 @@ for machine in $build $host $target; do ;; powerpc-*-openbsd*) tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd" - xmake_file=none ;; powerpc-*-beos*) cpu_type=rs6000 @@ -4357,7 +5071,7 @@ for machine in $build $host $target; do xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" extra_headers=ppc-asm.h - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else @@ -4368,52 +5082,47 @@ for machine in $build $host $target; do powerpc-*-eabiaix*) tm_file=rs6000/eabiaix.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-eabisim*) tm_file=rs6000/eabisim.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-eabi*) tm_file=rs6000/eabi.h - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-rtems*) tm_file=rs6000/rtems.h - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-linux-gnulibc1) tm_file=rs6000/linux.h xm_file=rs6000/xm-sysv4.h out_file=rs6000/rs6000.c - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm" fi xmake_file=x-linux - fixincludes=Makefile.in extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" extra_headers=ppc-asm.h - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -4422,17 +5131,16 @@ for machine in $build $host $target; do xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG ${xm_defines}" out_file=rs6000/rs6000.c - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm" fi xmake_file=x-linux - fixincludes=Makefile.in extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" extra_headers=ppc-asm.h - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -4449,7 +5157,7 @@ for machine in $build $host $target; do tm_file=rs6000/sysv4le.h xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else @@ -4461,38 +5169,34 @@ for machine in $build $host $target; do powerpcle-*-eabisim*) tm_file=rs6000/eabilesim.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpcle-*-eabi*) tm_file=rs6000/eabile.h - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpcle-*-winnt* ) tm_file=rs6000/win-nt.h tmake_file=rs6000/t-winnt # extra_objs=pe.o - fixincludes=Makefile.in - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='win32' fi extra_headers=ppc-asm.h ;; - powerpcle-*-pe | powerpcle-*-cygwin32) - tm_file=rs6000/cygwin32.h - xm_file="rs6000/xm-cygwin32.h ${xm_file}" + powerpcle-*-pe | powerpcle-*-cygwin*) + tm_file=rs6000/cygwin.h + xm_file="rs6000/xm-cygwin.h ${xm_file}" tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin32 + xmake_file=rs6000/x-cygwin # extra_objs=pe.o - fixincludes=Makefile.in - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe @@ -4502,73 +5206,79 @@ for machine in $build $host $target; do tm_file=rs6000/sol2.h xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" - if [ x$gas = xyes ] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi xmake_file=rs6000/x-sysv4 - case $machine in - *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac extra_headers=ppc-asm.h ;; rs6000-ibm-aix3.[01]*) tm_file=rs6000/aix31.h xmake_file=rs6000/x-aix31 + float_format=none use_collect2=yes ;; rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*) tm_file=rs6000/aix3newas.h - if [ x$host != x$target ] + if test x$host != x$target then tmake_file=rs6000/t-xnewas else tmake_file=rs6000/t-newas fi + float_format=none use_collect2=yes ;; rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*) tm_file=rs6000/aix41.h - if [ x$host != x$target ] + if test x$host != x$target then tmake_file=rs6000/t-xnewas else tmake_file=rs6000/t-newas fi - xmake_file=rs6000/x-aix41 + if test "$gnu_ld" = yes + then + xmake_file=rs6000/x-aix41-gld + else + xmake_file=rs6000/x-aix41 + fi + float_format=none use_collect2=yes ;; - rs6000-ibm-aix4.[3456789].* | powerpc-ibm-aix4.[3456789].*) + rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*) tm_file=rs6000/aix43.h - if [ x$host != x$target ] + if test x$host != x$target then tmake_file=rs6000/t-xaix43 else tmake_file=rs6000/t-aix43 fi xmake_file=rs6000/x-aix43 + float_format=none use_collect2=yes ;; rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) tm_file=rs6000/aix43.h - if [ x$host != x$target ] + if test x$host != x$target then tmake_file=rs6000/t-xaix43 else tmake_file=rs6000/t-aix43 fi xmake_file=rs6000/x-aix43 + float_format=none use_collect2=yes ;; rs6000-ibm-aix*) + float_format=none use_collect2=yes ;; rs6000-bull-bosx) + float_format=none use_collect2=yes ;; rs6000-*-mach*) @@ -4618,10 +5328,8 @@ for machine in $build $host $target; do ;; sparc-*-netbsd*) tm_file=sparc/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes ;; sparc-*-openbsd*) # we need collect2 until our bug is fixed... @@ -4641,7 +5349,6 @@ for machine in $build $host $target; do xm_file="${xm_file} sparc/xm-linux.h" tm_file=sparc/linux-aout.h xmake_file=x-linux - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes ;; sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5 @@ -4650,7 +5357,6 @@ for machine in $build $host $target; do tm_file=sparc/linux.h tmake_file="t-linux t-linux-gnulibc1" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes ;; sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6 @@ -4659,14 +5365,13 @@ for machine in $build $host $target; do tm_file=sparc/linux.h tmake_file="t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes - if [ x$enable_threads = xyes ]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; sparc-*-lynxos*) - if [ x$gas = xyes ] + if test x$gas = xyes then tm_file=sparc/lynx.h else @@ -4680,8 +5385,38 @@ for machine in $build $host $target; do tmake_file="sparc/t-sparcbare t-rtems" tm_file=sparc/rtems.h ;; + sparcv9-*-solaris2*) + tm_file=sparc/sol2-sld-64.h + xm_file="sparc/xm-sysv4-64.h sparc/xm-sol2.h" + xm_defines="USG POSIX" + tmake_file="sparc/t-sol2 sparc/t-sol2-64" + xmake_file=sparc/x-sysv4 + extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o" + float_format=none + if test x${enable_threads} = x ; then + enable_threads=$have_pthread_h + if test x${enable_threads} = x ; then + enable_threads=$have_thread_h + fi + fi + if test x${enable_threads} = xyes ; then + if test x${have_pthread_h} = xyes ; then + thread_file='posix' + else + thread_file='solaris' + fi + fi + ;; + sparc-hal-solaris2*) + xm_file=sparc/xm-sol2.h + tm_file="sparc/sol2.h sparc/hal.h" + tmake_file="sparc/t-halos sparc/t-sol2" + xmake_file=sparc/x-sysv4 + extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o" + broken_install=yes + ;; sparc-*-solaris2*) - if [ x$gnu_ld = xyes ] + if test x$gnu_ld = xyes then tm_file=sparc/sol2.h else @@ -4694,19 +5429,20 @@ for machine in $build $host $target; do extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" case $machine in *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4;; + float_format=i128 + ;; *) - fixincludes=fixinc.wrap;; + float_format=none + ;; esac - float_format=i128 - if [ x${enable_threads} = x ]; then + if test x${enable_threads} = x; then enable_threads=$have_pthread_h - if [ x${enable_threads} = x ]; then + if test x${enable_threads} = x; then enable_threads=$have_thread_h fi fi - if [ x${enable_threads} = xyes ]; then - if [ x${have_pthread_h} = xyes ]; then + if test x${enable_threads} = xyes; then + if test x${have_pthread_h} = xyes; then thread_file='posix' else thread_file='solaris' @@ -4722,7 +5458,7 @@ for machine in $build $host $target; do tm_file=sparc/sunos4.h tmake_file=sparc/t-sunos41 use_collect2=yes - if [ x$gas = xyes ]; then + if test x$gas = xyes; then tm_file="${tm_file} sparc/sun4gas.h" fi ;; @@ -4767,11 +5503,11 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" ;; sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux - tmake_file=sparc/t-sp64 + tmake_file="t-linux sparc/t-linux64" xm_file="sparc/xm-sp64.h sparc/xm-linux.h" tm_file=sparc/linux64.h xmake_file=x-linux - fixincludes=Makefile.in # The headers are ok already. + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" gnu_ld=yes ;; # This hasn't been upgraded to GCC 2. @@ -4786,7 +5522,14 @@ for machine in $build $host $target; do xm_file=arm/xm-thumb.h md_file=arm/thumb.md tmake_file=arm/t-thumb - fixincludes=Makefile.in # There is nothing to fix + ;; + thumb-wrs-vxworks) + tm_file=arm/tcoff.h + out_file=arm/thumb.c + xm_file=arm/xm-thumb.h + md_file=arm/thumb.md + tmake_file=arm/t-thumb + thread_file='vxworks' ;; # This hasn't been upgraded to GCC 2. # tron-*-*) @@ -4798,7 +5541,7 @@ for machine in $build $host $target; do tm_file="v850/v850.h" xm_file="v850/xm-v850.h" tmake_file=v850/t-v850 - if [ x$stabs = xyes ] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -4815,14 +5558,12 @@ for machine in $build $host $target; do ;; vax-*-netbsd*) tm_file="${tm_file} netbsd.h vax/netbsd.h" - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd float_format=vax + use_collect2=yes ;; vax-*-openbsd*) - tmake_file="${tm_file} vax/t-openbsd" + tmake_file="${tmake_file} vax/t-openbsd" ;; vax-*-ultrix*) # vaxen running ultrix tm_file="${tm_file} vax/ultrix.h" @@ -4862,13 +5603,10 @@ for machine in $build $host $target; do # GNU tools are the only tools. gnu_ld=yes gas=yes - # On GNU, the headers are already okay. - fixincludes=Makefile.in xmake_file=x-linux # These details are the same as Linux. tmake_file=t-gnu # These are not. ;; *-*-sysv4*) - fixincludes=fixinc.svr4 xmake_try_sysv=x-sysv install_headers_dir=install-headers-cpio ;; @@ -4886,7 +5624,14 @@ for machine in $build $host $target; do target_cpu_default2=1 ;; i586-*-*) - target_cpu_default2=2 + case $target_alias in + k6-*) + target_cpu_default2=4 + ;; + *) + target_cpu_default2=2 + ;; + esac ;; i686-*-* | i786-*-*) target_cpu_default2=3 @@ -4894,7 +5639,7 @@ for machine in $build $host $target; do alpha*-*-*) case $machine in alphaev6*) - target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_CIX|MASK_MAX" + target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX" ;; alphapca56*) target_cpu_default2="MASK_CPU_EV5|MASK_BWX|MASK_MAX" @@ -4907,9 +5652,9 @@ for machine in $build $host $target; do ;; esac - if [ x$gas = xyes ] + if test x$gas = xyes then - if [ "$target_cpu_default2" = "" ] + if test "$target_cpu_default2" = "" then target_cpu_default2="MASK_GAS" else @@ -4929,7 +5674,7 @@ for machine in $build $host $target; do xarm23678 | xarm250 | xarm67010 \ | xarm7m | xarm7dm | xarm7dmi | xarm7tdmi \ | xarm7100 | xarm7500 | xarm7500fe | xarm810 \ - | xstrongarm | xstrongarm110) + | xstrongarm | xstrongarm110 | xstrongarm1100) target_cpu_default2="TARGET_CPU_$with_cpu" ;; @@ -4939,7 +5684,7 @@ for machine in $build $host $target; do ;; *) - if [ x$pass2done = xyes ] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -4949,9 +5694,9 @@ for machine in $build $host $target; do ;; mips*-*-ecoff* | mips*-*-elf*) - if [ x$gas = xyes ] + if test x$gas = xyes then - if [ x$gnu_ld = xyes ] + if test x$gnu_ld = xyes then target_cpu_default2=20 else @@ -4960,7 +5705,7 @@ for machine in $build $host $target; do fi ;; mips*-*-*) - if [ x$gas = xyes ] + if test x$gas = xyes then target_cpu_default2=16 fi @@ -4973,6 +5718,7 @@ for machine in $build $host $target; do xcommon | xpower | xpower2 | xpowerpc | xrios \ | xrios1 | xrios2 | xrsc | xrsc1 \ | x601 | x602 | x603 | x603e | x604 | x604e | x620 \ + | xec603e | x740 | x750 | x401 \ | x403 | x505 | x801 | x821 | x823 | x860) target_cpu_default2="\"$with_cpu\"" ;; @@ -4983,7 +5729,7 @@ for machine in $build $host $target; do ;; *) - if [ x$pass2done = xyes ] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -4996,11 +5742,11 @@ for machine in $build $host $target; do .) target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`" ;; - .supersparc | .ultrasparc | .v7 | .v8 | .v9) + .supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9) target_cpu_default2="TARGET_CPU_$with_cpu" ;; *) - if [ x$pass2done = xyes ] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -5010,9 +5756,9 @@ for machine in $build $host $target; do ;; esac - if [ "$target_cpu_default2" != "" ] + if test "$target_cpu_default2" != "" then - if [ "$target_cpu_default" != "" ] + if test "$target_cpu_default" != "" then target_cpu_default="(${target_cpu_default}|${target_cpu_default2})" else @@ -5031,9 +5777,9 @@ for machine in $build $host $target; do # 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 [ x$pass1done = x ] + if test x$pass1done = x then - if [ x"$xm_file" = x ] + if test x"$xm_file" = x then build_xm_file=$cpu_type/xm-$cpu_type.h else build_xm_file=$xm_file fi @@ -5042,14 +5788,14 @@ for machine in $build $host $target; do build_exeext=$exeext pass1done=yes else - if [ x$pass2done = x ] + if test x$pass2done = x then - if [ x"$xm_file" = x ] + if test x"$xm_file" = x then host_xm_file=$cpu_type/xm-$cpu_type.h else host_xm_file=$xm_file fi host_xm_defines=$xm_defines - if [ x"$xmake_file" = x ] + if test x"$xmake_file" = x then xmake_file=$cpu_type/x-$cpu_type fi host_xmake_file="$xmake_file" @@ -5065,48 +5811,50 @@ done extra_objs="${host_extra_objs} ${extra_objs}" # Default the target-machine variables that were not explicitly set. -if [ x"$tm_file" = x ] +if test x"$tm_file" = x then tm_file=$cpu_type/$cpu_type.h; fi -if [ x$extra_headers = x ] +if test x$extra_headers = x then extra_headers=; fi -if [ x"$xm_file" = x ] +if test x"$xm_file" = x then xm_file=$cpu_type/xm-$cpu_type.h; fi -if [ x$md_file = x ] +if test x$md_file = x then md_file=$cpu_type/$cpu_type.md; fi -if [ x$out_file = x ] +if test x$out_file = x then out_file=$cpu_type/$cpu_type.c; fi -if [ x"$tmake_file" = x ] +if test x"$tmake_file" = x then tmake_file=$cpu_type/t-$cpu_type fi -if [ x$float_format = x ] +if test x"$dwarf2" = xyes +then tm_file="tm-dwarf2.h $tm_file" +fi + +if test x$float_format = x then float_format=i64 fi -if [ x$enable_haifa = x ] +if test $float_format = none +then float_h_file=Makefile.in +else float_h_file=float-$float_format.h +fi + +if test x$enable_haifa = x then case $target in - alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*) + alpha*-* | hppa*-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*) enable_haifa=yes;; esac fi # Handle cpp installation. -if [ x$enable_cpp != x ] +if test x$enable_cpp != xno then tmake_file="$tmake_file t-install-cpp" - case x$enable_cpp in - xyes | xno) ;; - x/*) cpp_install_dir=$enable_cpp ;; - x.*) echo "alternate cpp script installation directory must be an absolute path" 1>&2 - exit 1 - ;; - esac fi # Say what files are being used for the output code and MD file. @@ -5117,7 +5865,7 @@ count=a for f in $tm_file; do count=${count}x done -if [ $count = ax ]; then +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:" @@ -5130,7 +5878,7 @@ count=a for f in $host_xm_file; do count=${count}x done -if [ $count = ax ]; then +if 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:" @@ -5139,113 +5887,1997 @@ else done fi -if [ "$host_xm_file" != "$build_xm_file" ]; then - count=a - for f in $build_xm_file; do - count=${count}x - done - if [ $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 +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 = 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 + +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 +fi + +# Set up the header files. +# $links is the list of header files to create. +# $vars is the list of shell variables with file names to include. +# auto-host.h is the file containing items generated by autoconf and is +# the first file included by config.h. +null_defines= +host_xm_file="auto-host.h gansidecl.h ${host_xm_file} hwint.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 +# work to find out the build config parameters. +if test x$host = x$build +then + build_xm_file="auto-host.h gansidecl.h ${build_xm_file} hwint.h" +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 + /*) realsrcdir=${srcdir};; + *) realsrcdir=../${srcdir};; + esac + CC=${CC_FOR_BUILD} ${realsrcdir}/configure \ + --target=$target --host=$build --build=$build + + # 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_xm_file="auto-build.h gansidecl.h ${build_xm_file} hwint.h" +fi + +xm_file="gansidecl.h ${xm_file}" +tm_file="gansidecl.h ${tm_file}" + +vars="host_xm_file tm_file xm_file build_xm_file" +links="config.h tm.h tconfig.h hconfig.h" +defines="host_xm_defines null_defines xm_defines build_xm_defines" + +rm -f config.bak +if test -f config.status; then mv -f config.status config.bak; fi + +# Make the links. +while test -n "$vars" +do + set $vars; var=$1; shift; vars=$* + set $links; link=$1; shift; links=$* + set $defines; define=$1; shift; defines=$* + + rm -f $link + + # Define TARGET_CPU_DEFAULT if the system wants one. + # This substitutes for lots of *.h files. + if test "$target_cpu_default" != "" -a $link = tm.h + then + echo "#define TARGET_CPU_DEFAULT ($target_cpu_default)" >>$link + fi + + for file in `eval echo '$'$var`; do + case $file in + auto-config.h) + ;; + *) + echo '#ifdef IN_GCC' >>$link + ;; + esac + echo "#include \"$file\"" >>$link + case $file in + auto-config.h) + ;; + *) + echo '#endif' >>$link + ;; + esac + done + + for def in `eval echo '$'$define`; do + echo "#ifndef $def" >>$link + echo "#define $def" >>$link + echo "#endif" >>$link + done +done + +# Truncate the target if necessary +if test x$host_truncate_target != x; then + target=`echo $target | sed -e 's/\(..............\).*/\1/'` +fi + +# 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 +gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}` + +# Internationalization +PACKAGE=gcc +VERSION="$gcc_version" +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:6044: checking for strerror in -lcposix" >&5 +ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lcposix $LIBS" +cat > conftest.$ac_ext <&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 + LIBS="$LIBS -lcposix" +else + echo "$ac_t""no" 1>&6 +fi + + + +echo $ac_n "checking for working const""... $ac_c" 1>&6 +echo "configure:6086: 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 <j = 5; +} +{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; +} + +; return 0; } +EOF +if { (eval echo configure:6140: \"$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 inline""... $ac_c" 1>&6 +echo "configure:6161: checking for inline" >&5 +if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_inline=$ac_kw; break +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +done + +fi + +echo "$ac_t""$ac_cv_c_inline" 1>&6 +case "$ac_cv_c_inline" in + inline | yes) ;; + no) cat >> confdefs.h <<\EOF +#define inline +EOF + ;; + *) cat >> confdefs.h <&6 +echo "configure:6201: 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 < +#if STDC_HEADERS +#include +#include +#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:6234: 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 < +#if STDC_HEADERS +#include +#include +#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:6269: 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 < +int main() { +char *p = alloca(2 * sizeof(int)); +; return 0; } +EOF +if { (eval echo configure:6281: \"$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:6302: 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 < +# define alloca _alloca +# else +# if HAVE_ALLOCA_H +# include +# 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:6335: \"$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:6367: 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 <&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:6397: 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 < +/* 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:6425: \"$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 <&6 +fi + +done +fi + +echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 +echo "configure:6452: 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 < addr) ? 1 : -1; +} +main () +{ + exit (find_stack_direction() < 0); +} +EOF +if { (eval echo configure:6479: \"$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 <&6 +echo "configure:6504: 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 +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6514: \"$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 <&6 +fi +done + +for ac_func in getpagesize +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:6543: 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 < +/* 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:6571: \"$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 <&6 +fi +done + +echo $ac_n "checking for working mmap""... $ac_c" 1>&6 +echo "configure:6596: checking for working mmap" >&5 +if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_mmap_fixed_mapped=no +else + cat > conftest.$ac_ext < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# endif + +/* Assume that all systems that can run configure have sys/param.h. */ +# ifndef HAVE_SYS_PARAM_H +# define HAVE_SYS_PARAM_H 1 +# endif + +# ifdef _SC_PAGESIZE +# define getpagesize() sysconf(_SC_PAGESIZE) +# else /* no _SC_PAGESIZE */ +# ifdef HAVE_SYS_PARAM_H +# include +# ifdef EXEC_PAGESIZE +# define getpagesize() EXEC_PAGESIZE +# else /* no EXEC_PAGESIZE */ +# ifdef NBPG +# define getpagesize() NBPG * CLSIZE +# ifndef CLSIZE +# define CLSIZE 1 +# endif /* no CLSIZE */ +# else /* no NBPG */ +# ifdef NBPC +# define getpagesize() NBPC +# else /* no NBPC */ +# ifdef PAGESIZE +# define getpagesize() PAGESIZE +# endif /* PAGESIZE */ +# endif /* no NBPC */ +# endif /* no NBPG */ +# endif /* no EXEC_PAGESIZE */ +# else /* no HAVE_SYS_PARAM_H */ +# define getpagesize() 8192 /* punt totally */ +# endif /* no HAVE_SYS_PARAM_H */ +# endif /* no _SC_PAGESIZE */ + +#endif /* no HAVE_GETPAGESIZE */ + +#ifdef __cplusplus +extern "C" { void *malloc(unsigned); } +#else +char *malloc(); +#endif + +int +main() +{ + char *data, *data2, *data3; + int i, pagesize; + int fd; + + pagesize = getpagesize(); + + /* + * First, make a file with some known garbage in it. + */ + data = malloc(pagesize); + if (!data) + exit(1); + for (i = 0; i < pagesize; ++i) + *(data + i) = rand(); + umask(0); + fd = creat("conftestmmap", 0600); + if (fd < 0) + exit(1); + if (write(fd, data, pagesize) != pagesize) + exit(1); + close(fd); + + /* + * Next, try to mmap the file at a fixed address which + * already has something else allocated at it. If we can, + * also make sure that we see the same garbage. + */ + fd = open("conftestmmap", O_RDWR); + if (fd < 0) + exit(1); + data2 = malloc(2 * pagesize); + if (!data2) + exit(1); + data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); + if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED, fd, 0L)) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data2 + i)) + exit(1); + + /* + * Finally, make sure that changes to the mapped area + * do not percolate back to the file as seen by read(). + * (This is a bug on some variants of i386 svr4.0.) + */ + for (i = 0; i < pagesize; ++i) + *(data2 + i) = *(data2 + i) + 1; + data3 = malloc(pagesize); + if (!data3) + exit(1); + if (read(fd, data3, pagesize) != pagesize) + exit(1); + for (i = 0; i < pagesize; ++i) + if (*(data + i) != *(data3 + i)) + exit(1); + close(fd); + unlink("conftestmmap"); + exit(0); +} + +EOF +if { (eval echo configure:6744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_func_mmap_fixed_mapped=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_mmap_fixed_mapped=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 +if test $ac_cv_func_mmap_fixed_mapped = yes; then + cat >> confdefs.h <<\EOF +#define HAVE_MMAP 1 +EOF + +fi + + + for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.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:6772: 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 +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:6782: \"$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 <&6 +fi +done + + for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ +strdup __argz_count __argz_stringify __argz_next +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:6812: 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 < +/* 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:6840: \"$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 <&6 +fi +done + + + if test "${ac_cv_func_stpcpy+set}" != "set"; then + for ac_func in stpcpy +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:6869: 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 < +/* 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:6897: \"$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 <&6 +fi +done + + fi + if test "${ac_cv_func_stpcpy}" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_STPCPY 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:6931: 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 < +int main() { +return LC_MESSAGES +; return 0; } +EOF +if { (eval echo configure:6943: \"$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:6964: 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 + + + USE_INCLUDED_LIBINTL=no + + if test "$USE_NLS" = "yes"; then + cat >> confdefs.h <<\EOF +#define ENABLE_NLS 1 +EOF + + echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6 +echo "configure:6984: 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 + nls_cv_header_intl= + nls_cv_header_libgt= + CATOBJEXT=NONE + + ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 +echo "configure:7003: 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 +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7013: \"$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 + echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 +echo "configure:7030: checking for gettext in libc" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int main() { +return (int) gettext ("") +; return 0; } +EOF +if { (eval echo configure:7042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + gt_cv_func_gettext_libc=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + gt_cv_func_gettext_libc=no +fi +rm -f conftest* +fi + +echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 + + if test "$gt_cv_func_gettext_libc" != "yes"; then + echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 +echo "configure:7058: checking for bindtextdomain in -lintl" >&5 +ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&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 + echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 +echo "configure:7093: checking for gettext in libintl" >&5 +if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 +echo "configure:7098: checking for gettext in -lintl" >&5 +ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lintl $LIBS" +cat > conftest.$ac_ext <&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 + gt_cv_func_gettext_libintl=yes +else + echo "$ac_t""no" 1>&6 +gt_cv_func_gettext_libintl=no +fi + +fi + +echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + fi + + if test "$gt_cv_func_gettext_libc" = "yes" \ + || test "$gt_cv_func_gettext_libintl" = "yes"; then + cat >> confdefs.h <<\EOF +#define HAVE_GETTEXT 1 +EOF + + # 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:7156: 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; 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="no" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$MSGFMT"; then + echo "$ac_t""$MSGFMT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$MSGFMT" != "no"; then + for ac_func in dcgettext +do +echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 +echo "configure:7190: 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 < +/* 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:7218: \"$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 <&6 +fi +done + + # 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:7245: 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:7281: 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; 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 -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + CATOBJEXT=.gmo + DATADIRNAME=share +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CATOBJEXT=.mo + DATADIRNAME=lib +fi +rm -f conftest* + INSTOBJEXT=.mo + fi + fi + +else + echo "$ac_t""no" 1>&6 +fi + + + if test "$CATOBJEXT" = "NONE"; then + echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 +echo "configure:7344: checking whether catgets can be used" >&5 + # Check whether --with-catgets or --without-catgets was given. +if test "${with_catgets+set}" = set; then + withval="$with_catgets" + nls_cv_use_catgets=$withval +else + nls_cv_use_catgets=no +fi + + echo "$ac_t""$nls_cv_use_catgets" 1>&6 + + if test "$nls_cv_use_catgets" = "yes"; then + echo $ac_n "checking for main in -li""... $ac_c" 1>&6 +echo "configure:7357: checking for main in -li" >&5 +ac_lib_var=`echo i'_'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 +else + ac_save_LIBS="$LIBS" +LIBS="-li $LIBS" +cat > conftest.$ac_ext <&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 + ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \ + -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` + cat >> confdefs.h <&6 +fi + + echo $ac_n "checking for catgets""... $ac_c" 1>&6 +echo "configure:7400: checking for catgets" >&5 +if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* 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 catgets(); + +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_catgets) || defined (__stub___catgets) +choke me +#else +catgets(); +#endif + +; return 0; } +EOF +if { (eval echo configure:7428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_catgets=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_catgets=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_CATGETS 1 +EOF + + INTLOBJS="\$(CATOBJS)" + # Extract the first word of "gencat", so it can be a program name with args. +set dummy gencat; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:7450: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$GENCAT" in + /*) + ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_GENCAT="$GENCAT" # 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_GENCAT="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no" + ;; +esac +fi +GENCAT="$ac_cv_path_GENCAT" +if test -n "$GENCAT"; then + echo "$ac_t""$GENCAT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + if test "$GENCAT" != "no"; then + # 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:7486: 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="no" + ;; +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 + + if test "$GMSGFMT" = "no"; then + # 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:7523: 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. + ;; + *) + 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then + ac_cv_path_GMSGFMT="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" + ;; +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 + + 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:7558: 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; 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 -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.cat + INSTOBJEXT=.cat + DATADIRNAME=lib + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi +else + echo "$ac_t""no" 1>&6 +fi + + fi + 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:7616: 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; 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="msgfmt" + ;; +esac +fi +MSGFMT="$ac_cv_path_MSGFMT" +if test -n "$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:7650: 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:7686: 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 test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; 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 -n "$XGETTEXT"; then + echo "$ac_t""$XGETTEXT" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + + USE_INCLUDED_LIBINTL=yes + CATOBJEXT=.gmo + INSTOBJEXT=.mo + DATADIRNAME=share + INTLDEPS='$(top_builddir)/intl/libintl.a' + INTLLIBS=$INTLDEPS + LIBS=`echo $LIBS | sed -e 's/-lintl//'` + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi -if [ x$thread_file = x ]; then - if [ x$target_thread_file != x ]; then - thread_file=$target_thread_file + if test "$XGETTEXT" != ":"; then + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; else - thread_file='single' + echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" 1>&6 + XGETTEXT=":" fi -fi - -# Set up the header files. -# $links is the list of header files to create. -# $vars is the list of shell variables with file names to include. -# auto-host.h is the file containing items generated by autoconf and is -# the first file included by config.h. -null_defines= -host_xm_file="auto-host.h ${host_xm_file}" - -# 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 -# work to find out the build config parameters. -if [ x$host = x$build ] -then - build_xm_file="auto-host.h ${build_xm_file}" -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 - /*) realsrcdir=${srcdir};; - *) realsrcdir=../${srcdir};; - esac - CC=${CC_FOR_BUILD} ${realsrcdir}/configure \ - --target=$target --host=$build --build=$build - - # 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_xm_file="auto-build.h ${build_xm_file}" -fi + fi -vars="host_xm_file tm_file xm_file build_xm_file" -links="config.h tm.h tconfig.h hconfig.h" -defines="host_xm_defines null_defines xm_defines build_xm_defines" + # We need to process the po/ directory. + POSUB=po + else + DATADIRNAME=share + nls_cv_header_intl=intl/libintl.h + nls_cv_header_libgt=intl/libgettext.h + fi + + -rm -f config.bak -if [ -f config.status ]; then mv -f config.status config.bak; fi -# Make the links. -while [ -n "$vars" ] -do - set $vars; var=$1; shift; vars=$* - set $links; link=$1; shift; links=$* - set $defines; define=$1; shift; defines=$* + # If this is used in GNU gettext we have to set USE_NLS to `yes' + # because some of the sources are only built for this goal. + if test "$PACKAGE" = gettext; then + USE_NLS=yes + USE_INCLUDED_LIBINTL=yes + fi - rm -f $link + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done - # Define TARGET_CPU_DEFAULT if the system wants one. - # This substitutes for lots of *.h files. - if [ "$target_cpu_default" != "" -a $link = tm.h ] - then - echo "#define TARGET_CPU_DEFAULT ($target_cpu_default)" >>$link - fi + + + + + + + + + + + + - for file in `eval echo '$'$var`; do - echo "#include \"$file\"" >>$link - done + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 +echo "configure:7779: checking for catalogs to be installed" >&5 + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + echo "$ac_t""$LINGUAS" 1>&6 + fi + + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi - for def in `eval echo '$'$define`; do - echo "#ifndef $def" >>$link - echo "#define $def" >>$link - echo "#endif" >>$link - done -done + if test $ac_cv_header_locale_h = yes; then + INCLUDE_LOCALE_H="#include " + else + INCLUDE_LOCALE_H="\ +/* The system does not provide the header . Take care yourself. */" + fi + -# Truncate the target if necessary -if [ x$host_truncate_target != x ]; then - target=`echo $target | sed -e 's/\(..............\).*/\1/'` + test -d intl || mkdir intl + if test "$CATOBJEXT" = ".cat"; then + ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 +echo "configure:7807: checking for linux/version.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 +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:7817: \"$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 - -# Get the version trigger filename from the toplevel -if [ "${with_gcc_version_trigger+set}" = set ]; then - gcc_version_trigger=$with_gcc_version_trigger +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 + msgformat=linux else - gcc_version_trigger=${srcdir}/version.c + echo "$ac_t""no" 1>&6 +msgformat=xopen fi -gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}` + + + sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed + fi + sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ + $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed + + if test "$PACKAGE" = "gettext"; then + GT_NO="#NO#" + GT_YES= + else + GT_NO= + GT_YES="#YES#" + 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 + + + l= + + + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + +XGETTEXT="AWK='$AWK' \$(SHELL) \$(top_srcdir)/exgettext $XGETTEXT" # Get an absolute path to the GCC top-level source directory holddir=`pwd` @@ -5260,7 +7892,7 @@ host_overrides=Make-host dep_host_xmake_file= for f in .. ${host_xmake_file} do - if [ -f ${srcdir}/config/$f ] + if test -f ${srcdir}/config/$f then dep_host_xmake_file="${dep_host_xmake_file} ${srcdir}/config/$f" fi @@ -5273,7 +7905,7 @@ target_overrides=Make-target dep_tmake_file= for f in .. ${tmake_file} do - if [ -f ${srcdir}/config/$f ] + if test -f ${srcdir}/config/$f then dep_tmake_file="${dep_tmake_file} ${srcdir}/config/$f" fi @@ -5286,6 +7918,7 @@ 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)" else rm -f symtest.tem @@ -5296,6 +7929,7 @@ 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\`" fi rm -f symtest.tem @@ -5304,29 +7938,29 @@ out_object_file=`basename $out_file .c`.o tm_file_list= for f in $tm_file; do - tm_file_list="${tm_file_list} \$(srcdir)/config/$f" + case $f in + gansidecl.h ) + tm_file_list="${tm_file_list} $f" ;; + *) tm_file_list="${tm_file_list} \$(srcdir)/config/$f" ;; + esac done host_xm_file_list= for f in $host_xm_file; do - if test $f != "auto-host.h"; then - host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" - else - host_xm_file_list="${host_xm_file_list} auto-host.h" - fi + case $f in + auto-host.h | gansidecl.h | hwint.h ) + host_xm_file_list="${host_xm_file_list} $f" ;; + *) host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" ;; + esac done build_xm_file_list= for f in $build_xm_file; do - if test $f != "auto-build.h"; then - if test $f != "auto-host.h"; then - build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" - else - build_xm_file_list="${build_xm_file_list} auto-host.h" - fi - else - build_xm_file_list="${build_xm_file_list} auto-build.h" - fi + case $f in + auto-build.h | auto-host.h | gansidecl.h | hwint.h ) + build_xm_file_list="${build_xm_file_list} $f" ;; + *) build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" ;; + esac done # Define macro CROSS_COMPILE in compilation @@ -5334,7 +7968,7 @@ done # Also use all.cross instead of all.internal # and add cross-make to Makefile. cross_overrides="/dev/null" -if [ x$host != x$target ] +if test x$host != x$target then cross_defines="CROSS=-DCROSS_COMPILE" cross_overrides="${topdir}/cross-make" @@ -5344,7 +7978,7 @@ fi # This must come after cross-make as we want all.build to override # all.cross. build_overrides="/dev/null" -if [ x$build != x$host ] +if test x$build != x$host then build_overrides="${topdir}/build-make" fi @@ -5352,7 +7986,7 @@ fi # Expand extra_headers to include complete path. # This substitutes for lots of t-* files. extra_headers_list= -if [ "x$extra_headers" = x ] +if test "x$extra_headers" = x then true else # Prepend ${srcdir}/ginclude/ to every entry in extra_headers. @@ -5362,10 +7996,14 @@ else done fi +if test x$use_collect2 = xno; then + use_collect2= +fi + # Add a definition of USE_COLLECT2 if system wants one. # Also tell toplev.c what to do. # This substitutes for lots of t-* files. -if [ x$use_collect2 = x ] +if test x$use_collect2 = x then will_use_collect2= maybe_use_collect2= @@ -5381,7 +8019,7 @@ fi # building gcc with a cross compiler, use the cross compiler just # built. Otherwise, we can use the cpp just built. md_file_sub= -if [ "x$md_cppflags" = x ] +if test "x$md_cppflags" = x then md_file_sub=$srcdir/config/$md_file else @@ -5389,18 +8027,18 @@ else fi # If we have gas in the build tree, make a link to it. -if [ -f ../gas/Makefile ]; then +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 in the build tree, make a link to it. -if [ -f ../binutils/Makefile ]; then +if test -f ../binutils/Makefile; then rm -f nm; $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null fi # If we have ld in the build tree, make a link to it. -if [ -f ../ld/Makefile ]; then -# if [[ x$use_collect2 = x ]]; then +if test -f ../ld/Makefile; then +# if test x$use_collect2 = x; then # rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null # else rm -f collect-ld; $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext 2>/dev/null @@ -5409,28 +8047,32 @@ fi # Figure out what assembler alignment features are present. echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6 -echo "configure:5413: checking assembler alignment features" >&5 +echo "configure:8051: checking assembler alignment features" >&5 gcc_cv_as= gcc_cv_as_alignment_features= -gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,gcc$,gas,'` -if [ -x as$host_exeext ]; then +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 [ -f $gcc_cv_as_gas_srcdir/configure.in ]; then +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_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 [ x$gcc_cv_gas_version != x ]; then + 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]*\)"` - if [ x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x ]; then + 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 [ "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 6 -o "$gcc_cv_gas_major_version" -gt 2 ]; then + 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 #define HAVE_GAS_BALIGN_AND_P2ALIGN 1 @@ -5439,7 +8081,7 @@ EOF fi # Gas version 2.8 and later support specifying the maximum # bytes to skip when using .p2align. - if [ "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 8 -o "$gcc_cv_gas_major_version" -gt 2 ]; then + 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 @@ -5447,11 +8089,59 @@ EOF fi fi -elif [ x$host = x$target ]; then +elif test x$host = x$target; then # Native build. - gcc_cv_as=as$host_exeext + # 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. + as=as$host_exeext + + test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \ + $test_prefix/lib/gcc-lib/$target \ + /usr/lib/gcc/$target/$gcc_version \ + /usr/lib/gcc/$target \ + $test_prefix/$target/bin/$target/$gcc_version \ + $test_prefix/$target/bin \ + /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" + + for dir in $test_dirs; do + if test -f $dir/as$host_exeext; then + gcc_cv_as=$dir/as$host_exeext + break; + fi + done fi -if [ x$gcc_cv_as != x ]; then +if test x$gcc_cv_as != x; then # Check if we have .balign and .p2align echo ".balign 4" > conftest.s echo ".p2align 2" >> conftest.s @@ -5477,7 +8167,78 @@ EOF fi echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6 +echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6 +echo "configure:8172: checking assembler subsection support" >&5 +gcc_cv_as_subsections= +if 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 nm$host_exeext; then + gcc_cv_nm=./nm$host_exeext + elif test x$host = x$target; then + # Native build. + gcc_cv_nm=nm$host_exeext + fi + if test x$gcc_cv_nm != x; then + cat > 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" + cat >> confdefs.h <<\EOF +#define HAVE_GAS_SUBSECTION_ORDERING 1 +EOF + + fi + fi + fi + fi + rm -f conftest.s conftest.o conftest.nm1 conftest.nm2 +fi +echo "$ac_t""$gcc_cv_as_subsections" 1>&6 + +echo $ac_n "checking assembler instructions""... $ac_c" 1>&6 +echo "configure:8212: checking assembler instructions" >&5 +gcc_cv_as_instructions= +if 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" " + cat >> confdefs.h <&6 + # 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. +if test x"${enable_languages+set}" != xset; then + if test x"${LANGUAGES+set}" = xset; then + enable_languages="`echo ${LANGUAGES} | tr ' ' ','`" + else + enable_languages=all + fi +fi subdirs= for lang in ${srcdir}/*/config-lang.in .. do @@ -5486,13 +8247,44 @@ do # The odd quoting in the next line works around # an apparent bug in bash 1.12 on linux. ${srcdir}/[*]/config-lang.in) ;; - *) subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([^/]*\)/config-lang.in$,\1,'`" ;; + *) + lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang` + if test "x$lang_alias" = x + then + echo "$lang doesn't set \$language." 1>&2 + exit 1 + fi + if test x"${enable_languages}" = xall; then + add_this_lang=yes + else + case "${enable_languages}" in + ${lang_alias} | "${lang_alias},"* | *",${lang_alias},"* | *",${lang_alias}" ) + add_this_lang=yes + ;; + * ) + add_this_lang=no + ;; + esac + fi + if test x"${add_this_lang}" = xyes; then + case $lang in + ${srcdir}/ada/config-lang.in) + if test x$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 + ;; esac done # Make gthr-default.h if we have a thread file. gthread_flags= -if [ $thread_file != single ]; then +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 @@ -5504,18 +8296,23 @@ fi lang_specs_files= lang_options_files= -rm -f specs.h options.h -touch specs.h options.h +lang_tree_files= +rm -f specs.h options.h gencheck.h +touch specs.h options.h gencheck.h for subdir in . $subdirs do - if [ -f $srcdir/$subdir/lang-specs.h ]; then + if test -f $srcdir/$subdir/lang-specs.h; then echo "#include \"$subdir/lang-specs.h\"" >>specs.h lang_specs_files="$lang_specs_files $srcdir/$subdir/lang-specs.h" fi - if [ -f $srcdir/$subdir/lang-options.h ]; then + if test -f $srcdir/$subdir/lang-options.h; then echo "#include \"$subdir/lang-options.h\"" >>options.h lang_options_files="$lang_options_files $srcdir/$subdir/lang-options.h" fi + if test -f $srcdir/$subdir/$subdir-tree.def; then + echo "#include \"$subdir/$subdir-tree.def\"" >>gencheck.h + lang_tree_files="$lang_tree_files $srcdir/$subdir/$subdir-tree.def" + fi done # These (without "all_") are set in each config-lang.in. @@ -5525,7 +8322,7 @@ all_boot_languages= all_compilers= all_stagestuff= all_diff_excludes= -all_outputs=Makefile +all_outputs='Makefile intl/Makefile po/Makefile.in fixinc/Makefile' # List of language makefile fragments. all_lang_makefiles= all_headers= @@ -5544,7 +8341,7 @@ oldstyle_subdirs= for s in .. $subdirs do - if [ $s != ".." ] + if test $s != ".." then language= boot_language= @@ -5555,14 +8352,14 @@ do outputs= lib2funcs= . ${srcdir}/$s/config-lang.in - if [ "x$language" = x ] + if test "x$language" = x then 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 ${srcdir}/$s/Makefile.in" all_languages="$all_languages $language" - if [ "x$boot_language" = xyes ] + if test "x$boot_language" = xyes then all_boot_languages="$all_boot_languages $language" fi @@ -5571,7 +8368,7 @@ do all_diff_excludes="$all_diff_excludes $diff_excludes" all_headers="$all_headers $headers" all_outputs="$all_outputs $outputs" - if [ x$outputs = x ] + if test x$outputs = x then oldstyle_subdirs="$oldstyle_subdirs $s" fi @@ -5593,10 +8390,10 @@ target_list="all.build all.cross start.encap rest.encap \ for t in $target_list do x= - for l in .. $all_languages + for lang in .. $all_languages do - if [ $l != ".." ]; then - x="$x $l.$t" + if test $lang != ".."; then + x="$x $lang.$t" fi done echo "lang.$t: $x" >> Make-hooks @@ -5604,14 +8401,14 @@ done # If we're not building in srcdir, create .gdbinit. -if [ ! -f Makefile.in ]; then +if test ! -f Makefile.in; then echo "dir ." > .gdbinit echo "dir ${srcdir}" >> .gdbinit - if [ x$gdb_needs_out_file_path = xyes ] + if test x$gdb_needs_out_file_path = xyes then echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit fi - if [ "x$subdirs" != x ]; then + if test "x$subdirs" != x; then for s in $subdirs do echo "dir ${srcdir}/$s" >> .gdbinit @@ -5625,7 +8422,7 @@ fi build_canonical=${build} host_canonical=${host} target_subdir= -if [ "${host}" != "${target}" ] ; then +if test "${host}" != "${target}" ; then target_subdir=${target}/ fi @@ -5637,7 +8434,7 @@ fi # libgcc.a, but that's OK because newib should have its own version of # assert.h. inhibit_libc= -if [ x$with_newlib = xyes ]; then +if test x$with_newlib = xyes; then inhibit_libc=-Dinhibit_libc fi @@ -5645,23 +8442,60 @@ fi # Override SCHED_OBJ and SCHED_CFLAGS to enable the Haifa scheduler. sched_prefix= sched_cflags= -if [ x$enable_haifa = xyes ]; then +if test x$enable_haifa = xyes; then echo "Using the Haifa scheduler." sched_prefix=haifa- sched_cflags=-DHAIFA fi -if [ x$enable_haifa != x ]; then +if test x$enable_haifa != x; then # Explicitly remove files that need to be recompiled for the Haifa scheduler. - for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do - if [ -f $x ]; then + for x in genattrtab.o toplev.o *sched.o; do + if test -f $x; then echo "Removing $x" rm -f $x fi done 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 +# $(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_alias)' +else +# 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 occurance of / 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_alias)" +fi + + + # Nothing to do for FLOAT_H, float_format already handled. objdir=`pwd` @@ -5726,8 +8560,13 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma + + + + + # Echo that links are built -if [ x$host = x$target ] +if test x$host = x$target then str1="native " else @@ -5735,25 +8574,25 @@ else str2=" from $host" fi -if [ x$host != x$build ] +if test x$host != x$build then str3=" on a $build system" fi -if [ "x$str2" != x ] || [ "x$str3" != x ] +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 [ "x$str2" != x ] || [ "x$str3" != x ] +if test "x$str2" != x || test "x$str3" != x then echo " ${str2}${str3}." 1>&2 fi # Truncate the target if necessary -if [ x$host_truncate_target != x ]; then +if test x$host_truncate_target != x; then target=`echo $target | sed -e 's/\(..............\).*/\1/'` fi @@ -5910,6 +8749,7 @@ s%@build_cpu@%$build_cpu%g s%@build_vendor@%$build_vendor%g s%@build_os@%$build_os%g s%@CC@%$CC%g +s%@stage1_warn_cflags@%$stage1_warn_cflags%g s%@SET_MAKE@%$SET_MAKE%g s%@AWK@%$AWK%g s%@LEX@%$LEX%g @@ -5922,10 +8762,35 @@ s%@INSTALL@%$INSTALL%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CPP@%$CPP%g +s%@gnat@%$gnat%g s%@vfprintf@%$vfprintf%g s%@doprint@%$doprint%g s%@manext@%$manext%g s%@objext@%$objext%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ALLOCA@%$ALLOCA%g +s%@USE_NLS@%$USE_NLS%g +s%@MSGFMT@%$MSGFMT%g +s%@GMSGFMT@%$GMSGFMT%g +s%@XGETTEXT@%$XGETTEXT%g +s%@GENCAT@%$GENCAT%g +s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g +s%@CATALOGS@%$CATALOGS%g +s%@CATOBJEXT@%$CATOBJEXT%g +s%@DATADIRNAME@%$DATADIRNAME%g +s%@GMOFILES@%$GMOFILES%g +s%@INSTOBJEXT@%$INSTOBJEXT%g +s%@INTLDEPS@%$INTLDEPS%g +s%@INTLLIBS@%$INTLLIBS%g +s%@INTLOBJS@%$INTLOBJS%g +s%@POFILES@%$POFILES%g +s%@POSUB@%$POSUB%g +s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g +s%@GT_NO@%$GT_NO%g +s%@GT_YES@%$GT_YES%g +s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g +s%@l@%$l%g s%@gthread_flags@%$gthread_flags%g s%@build_canonical@%$build_canonical%g s%@host_canonical@%$host_canonical%g @@ -5933,53 +8798,60 @@ s%@target_subdir@%$target_subdir%g s%@inhibit_libc@%$inhibit_libc%g s%@sched_prefix@%$sched_prefix%g s%@sched_cflags@%$sched_cflags%g +s%@gcc_tooldir@%$gcc_tooldir%g +s%@dollar@%$dollar%g s%@objdir@%$objdir%g s%@subdirs@%$subdirs%g -s%@all_languages@%$all_languages%g s%@all_boot_languages@%$all_boot_languages%g s%@all_compilers@%$all_compilers%g -s%@all_lang_makefiles@%$all_lang_makefiles%g -s%@all_stagestuff@%$all_stagestuff%g s%@all_diff_excludes@%$all_diff_excludes%g -s%@all_lib2funcs@%$all_lib2funcs%g s%@all_headers@%$all_headers%g +s%@all_lang_makefiles@%$all_lang_makefiles%g +s%@all_languages@%$all_languages%g +s%@all_lib2funcs@%$all_lib2funcs%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%@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%@cpp_main@%$cpp_main%g -s%@extra_passes@%$extra_passes%g -s%@extra_programs@%$extra_programs%g -s%@extra_parts@%$extra_parts%g +s%@dep_host_xmake_file@%$dep_host_xmake_file%g +s%@dep_tmake_file@%$dep_tmake_file%g +s%@extra_c_flags@%$extra_c_flags%g s%@extra_c_objs@%$extra_c_objs%g +s%@extra_cpp_objs@%$extra_cpp_objs%g s%@extra_cxx_objs@%$extra_cxx_objs%g -s%@extra_c_flags@%$extra_c_flags%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%@fixinc_defs@%$fixinc_defs%g +s%@float_h_file@%$float_h_file%g +s%@gcc_gxx_include_dir@%$gcc_gxx_include_dir%g +s%@gcc_version@%$gcc_version%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%@extra_headers_list@%$extra_headers_list%g -s%@dep_host_xmake_file@%$dep_host_xmake_file%g -s%@dep_tmake_file@%$dep_tmake_file%g -s%@out_file@%$out_file%g -s%@out_object_file@%$out_object_file%g -s%@md_file@%$md_file%g -s%@tm_file_list@%$tm_file_list%g -s%@build_xm_file_list@%$build_xm_file_list%g s%@host_xm_file_list@%$host_xm_file_list%g -s%@lang_specs_files@%$lang_specs_files%g +s%@install@%$install%g +s%@JAVAGC@%$JAVAGC%g s%@lang_options_files@%$lang_options_files%g -s%@thread_file@%$thread_file%g -s%@gcc_version@%$gcc_version%g -s%@gcc_version_trigger@%$gcc_version_trigger%g +s%@lang_specs_files@%$lang_specs_files%g +s%@lang_tree_files@%$lang_tree_files%g s%@local_prefix@%$local_prefix%g -s%@gxx_include_dir@%$gxx_include_dir%g -s%@fixincludes@%$fixincludes%g -s%@build_install_headers_dir@%$build_install_headers_dir%g -s%@build_exeext@%$build_exeext%g -s%@host_exeext@%$host_exeext%g -s%@float_format@%$float_format%g -s%@will_use_collect2@%$will_use_collect2%g s%@maybe_use_collect2@%$maybe_use_collect2%g -s%@cc_set_by_configure@%$cc_set_by_configure%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%@install@%$install%g s%@symbolic_link@%$symbolic_link%g -s%@cpp_install_dir@%$cpp_install_dir%g +s%@thread_file@%$thread_file%g +s%@tm_file_list@%$tm_file_list%g +s%@will_use_collect2@%$will_use_collect2%g /@target_overrides@/r $target_overrides s%@target_overrides@%%g /@host_overrides@/r $host_overrides @@ -6196,8 +9068,54 @@ cat >> $CONFIG_STATUS <<\EOF fi; done EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +srcdir=$ac_given_srcdir +while test -n "$ac_sources"; do + set $ac_dests; ac_dest=$1; shift; ac_dests=$* + set $ac_sources; ac_source=$1; shift; ac_sources=$* + + echo "linking $srcdir/$ac_source to $ac_dest" + + if test ! -r $srcdir/$ac_source; then + { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1; } + fi + rm -f $ac_dest + + # Make relative symlinks. + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` + if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then + # The dest file is in a subdirectory. + test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" + ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dest_dir_suffix. + ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dest_dir_suffix= ac_dots= + fi + + case "$srcdir" in + [/$]*) ac_rel_source="$srcdir/$ac_source" ;; + *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; + esac + + # Make a symlink if possible; otherwise try a hard link. + if ln -s $ac_rel_source $ac_dest 2>/dev/null || + ln $srcdir/$ac_source $ac_dest; then : + else + { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&2; exit 1; } + fi +done +EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac . $srcdir/configure.lang case x$CONFIG_HEADERS in @@ -6244,9 +9165,9 @@ esac # 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 [ "$symbolic_link" = "ln -s" ]; then +if test "$symbolic_link" = "ln -s"; then for d in .. ${subdirs} ; do - if [ $d != .. ]; then + if test $d != ..; then STARTDIR=`pwd` cd $d for t in stage1 stage2 stage3 stage4 include @@ -6258,6 +9179,11 @@ if [ "$symbolic_link" = "ln -s" ]; then 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 exit 0 EOF diff --git a/contrib/gcc/configure.in b/contrib/gcc/configure.in index a943830..448e0f8 100644 --- a/contrib/gcc/configure.in +++ b/contrib/gcc/configure.in @@ -1,7 +1,7 @@ # configure.in for GNU CC # Process this file with autoconf to generate a configuration script. -# Copyright (C) 1997, 1998 Free Software Foundation, Inc. +# Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. #This file is part of GNU CC. @@ -21,6 +21,7 @@ #Boston, MA 02111-1307, USA. # Initialization and defaults +AC_PREREQ(2.12.1) AC_INIT(tree.c) AC_CONFIG_HEADER(auto-host.h:config.in) @@ -29,6 +30,59 @@ 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 +# 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 + # Check for additional parameters # With GNU ld @@ -37,12 +91,37 @@ AC_ARG_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") +fi + # 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") +fi + # With stabs AC_ARG_WITH(stabs, [ --with-stabs arrange to use stabs instead of host debug format.], @@ -66,11 +145,14 @@ no) ;; esac]) # Default local prefix if it is empty -if [[ x$local_prefix = x ]]; then +if test x$local_prefix = x; then local_prefix=/usr/local fi -gxx_include_dir= +# 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 @@ -78,14 +160,17 @@ AC_ARG_WITH(gxx-include-dir, [case "${withval}" in yes) AC_MSG_ERROR(bad value ${withval} given for g++ include directory) ;; no) ;; -*) gxx_include_dir=$with_gxx_include_dir ;; +*) gcc_gxx_include_dir=$with_gxx_include_dir ;; esac]) -if test x${gxx_include_dir} = x; then +if test x${gcc_gxx_include_dir} = x; then if test x${enable_version_specific_runtime_libs} = xyes; then - gxx_include_dir='${libsubdir}/include/g++' + gcc_gxx_include_dir='${libsubdir}/include/g++' else - gxx_include_dir='${prefix}/include/g++' + topsrcdir=${srcdir}/.. . ${srcdir}/../config.if +changequote(<<, >>)dnl + gcc_gxx_include_dir="\$(libsubdir)/\$(unlibsubdir)/..\`echo \$(exec_prefix) | sed -e 's|^\$(prefix)||' -e 's|/[^/]*|/..|g'\`/include/g++"-${libstdcxx_interface} +changequote([, ])dnl fi fi @@ -98,30 +183,60 @@ no) ;; *) AC_MSG_ERROR(bad value ${enableval} given for checking option) ;; esac]) -# Enable use of cpplib for C. +AC_ARG_ENABLE(cpp, +[ --disable-cpp don't provide a user-visible C preprocessor.], +[], [enable_cpp=yes]) + +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]) + +# Use cpplib+cppmain for the preprocessor, but don't link it with the compiler. cpp_main=cccp +AC_ARG_ENABLE(cpplib, +[ --enable-cpplib use cpplib for the C preprocessor.], +if test x$enable_cpplib != xno; then + cpp_main=cppmain +fi) + +# Link cpplib into the compiler proper, for C/C++/ObjC. AC_ARG_ENABLE(c-cpplib, -[ --enable-c-cpplib Use cpplib for C.], -if [[[ x$enable_c_cpplib != xno ]]]; then - extra_c_objs="${extra_c_objs} cpplib.o cppexp.o cpphash.o cpperror.o" - extra_c_objs="${extra_c_objs} prefix.o" - extra_cxx_objs="${extra_cxx_objs} ../cpplib.o ../cppexp.o ../cpphash.o ../cpperror.o ../prefix.o" - extra_c_flags=-DUSE_CPPLIB=1 +[ --enable-c-cpplib link cpplib directly into C and C++ compilers + (EXPERIMENTAL) (implies --enable-cpplib).], +if test x$enable_c_cpplib != xno; then + extra_c_objs="${extra_c_objs} libcpp.a" + extra_cxx_objs="${extra_cxx_objs} ../libcpp.a" + extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1" cpp_main=cppmain fi) - + +# Enable Multibyte Characters for C/C++ +AC_ARG_ENABLE(c-mbchar, +[ --enable-c-mbchar enable multibyte characters for C and C++.], +if test x$enable_c_mbchar != xno; then + extra_c_flags=-DMULTIBYTE_CHARS=1 +fi) + +# Disable fast fixincludes +AC_ARG_ENABLE(fast-fixincludes, +[ --disable-fast-fixincludes + Disable the new fast fixincludes. + Run the old fixincludes script unconditionally], +if test x$enable_fast_fixincludes = xno ; then + cp $srcdir/fixincludes ./fixinc.sh +fi) + # Enable Haifa scheduler. AC_ARG_ENABLE(haifa, -[ --enable-haifa Use the experimental scheduler. - --disable-haifa Don't use the experimental scheduler for the +[ --enable-haifa use the experimental scheduler. + --disable-haifa don't use the experimental scheduler for the targets which normally enable it.]) -# Fast fixincludes -# -# This is a work in progress... -AC_ARG_WITH(fast-fixincludes, -[ --with-fast-fixincludes Use a faster fixinclude program. Experimental], -fast_fixinc="$with_fast_fixincludes", -fast_fixinc=no) # Enable threads # Pass with no value to take the default @@ -129,7 +244,7 @@ fast_fixinc=no) AC_ARG_ENABLE(threads, [ --enable-threads enable thread usage for target GCC. --enable-threads=LIB use LIB thread package for target GCC.], -if [[[ x$enable_threads = xno ]]]; then +if test x$enable_threads = xno; then enable_threads='' fi, enable_threads='') @@ -155,13 +270,68 @@ case x${enable_threads_flag} in ;; esac +AC_ARG_ENABLE(objc-gc, +[ --enable-objc-gc enable the use of Boehm's garbage collector with + the GNU Objective-C runtime.], +if [[[ x$enable_objc_gc = xno ]]]; then + objc_boehm_gc='' +else + objc_boehm_gc=1 +fi, +objc_boehm_gc='') + +AC_ARG_ENABLE(java-gc, +changequote(<<,>>)dnl +<< --enable-java-gc=TYPE choose garbage collector [boehm]>>, +changequote([,]) + JAVAGC=$enableval, + JAVAGC=boehm) + +AC_ARG_WITH(dwarf2, +[ --enable-dwarf2 enable DWARF2 debugging as default.], +dwarf2="$with_dwarf2", +dwarf2=no) + # Determine the host, build, and target systems AC_CANONICAL_SYSTEM # Find the native compiler AC_PROG_CC + +# 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'. +if test "x$GCC" = "xyes"; then + stage1_warn_cflags='$(WARN_CFLAGS)' +else + stage1_warn_cflags="" +fi +AC_SUBST(stage1_warn_cflags) + AC_PROG_MAKE_SET +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 + +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 some useful tools AC_PROG_AWK AC_PROG_LEX @@ -174,12 +344,17 @@ EGCS_PROG_INSTALL AC_HEADER_STDC AC_HEADER_TIME -AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h fcntl.h unistd.h stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h wait.h sys/wait.h) +GCC_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 stab.h sys/file.h sys/time.h sys/resource.h sys/param.h sys/times.h sys/stat.h direct.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=]) +# See if GNAT has been installed +AC_CHECK_PROG(gnat, gnatbind, yes, no) + # See if the system preprocessor understands the ANSI C preprocessor # stringification operator. AC_MSG_CHECKING(whether cpp understands the stringify operator) @@ -210,13 +385,28 @@ fi AC_CHECK_FUNCS(strtoul bsearch strerror putenv popen bcopy bzero bcmp \ index rindex strchr strrchr kill getrlimit setrlimit atoll atoq \ - sysconf isascii gettimeofday) + sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \ + fputs_unlocked) + +# Make sure wchar_t is available +#AC_CHECK_TYPE(wchar_t, unsigned int) GCC_FUNC_VFPRINTF_DOPRNT GCC_FUNC_PRINTF_PTR +case "${host}" in +*-*-uwin*) + # Under some versions of uwin, vfork is notoriously buggy and the test + # can hang configure; on other versions, vfork exists just as a stub. + # FIXME: This should be removed once vfork in uwin's runtime is fixed. + ac_cv_func_vfork_works=no + ;; +esac +AC_FUNC_VFORK + GCC_NEED_DECLARATIONS(malloc realloc calloc free bcopy bzero bcmp \ - index rindex getenv atol sbrk abort atof strerror getcwd getwd) + index rindex getenv atol sbrk abort atof strerror getcwd getwd \ + strsignal putc_unlocked fputs_unlocked strstr) GCC_NEED_DECLARATIONS(getrlimit setrlimit, [ #include @@ -227,6 +417,9 @@ GCC_NEED_DECLARATIONS(getrlimit setrlimit, [ AC_DECL_SYS_SIGLIST +# mkdir takes a single argument on some systems. +GCC_FUNC_MKDIR_TAKES_ONE_ARG + # File extensions manext='.1' objext='.o' @@ -242,7 +435,6 @@ host_xm_defines= host_xmake_file= host_truncate_target= host_exeext= -cpp_install_dir= # Decode the host machine, then the target machine. # For the host machine, we save the xm_file variable as host_xm_file; @@ -266,10 +458,6 @@ for machine in $build $host $target; do use_collect2= # Set this to override the default target model. target_cpu_default= - # Set this to control which fixincludes program to use. - if [[ x$fast_fixinc != xyes ]] ; then - fixincludes=fixincludes - else fixincludes=fixinc.sh ; fi # Set this to control how the header file directory is installed. install_headers_dir=install-headers-tar # Set this to a non-empty list of args to pass to cpp if the target @@ -303,7 +491,9 @@ for machine in $build $host $target; do c*-convex-*) cpu_type=convex ;; - i[[34567]]86-*-*) +changequote(,)dnl + i[34567]86-*-*) +changequote([,])dnl cpu_type=i386 ;; hppa*-*-*) @@ -336,11 +526,11 @@ for machine in $build $host $target; do ;; *-*-openbsd*) tm_file=${cpu_type}/openbsd.h - # On OpenBSD systems, the headers are okay - fixincludes=Makefile.in tmake_file="t-libc-ok t-openbsd" # avoid surprises, always provide an xm-openbsd file xm_file=${cpu_type}/xm-openbsd.h + # don't depend on processor x-fragments as well + xmake_file=none if test x$enable_threads = xyes; then thread_file='posix' tmake_file="${tmake_file} t-openbsd-thread" @@ -355,11 +545,11 @@ for machine in $build $host $target; do rest=`echo $machine | sed -e "s/$cpu_type-//"` xm_file=${cpu_type}/xm-$rest.h tm_file=${cpu_type}/$rest.h - if [[ -f $srcdir/config/${cpu_type}/x-$rest ]] ; \ + if test -f $srcdir/config/${cpu_type}/x-$rest; \ then xmake_file=${cpu_type}/x-$rest; \ else true; \ fi - if [[ -f $srcdir/config/${cpu_type}/t-$rest ]] ; \ + if test -f $srcdir/config/${cpu_type}/t-$rest; \ then tmake_file=${cpu_type}/t-$rest; \ else true; \ fi @@ -385,9 +575,31 @@ for machine in $build $host $target; do a29k-*-*) # Default a29k environment. use_collect2=yes ;; + 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_file="alpha/xm-alpha-interix.h xm-interix.h" + xmake_file="x-interix alpha/t-pe" + tmake_file="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-gnuecoff*) tm_file="${tm_file} alpha/linux-ecoff.h alpha/linux.h" target_cpu_default="MASK_GAS" + tmake_file="alpha/t-ieee" gas=no xmake_file=none gas=yes gnu_ld=yes @@ -395,59 +607,58 @@ for machine in $build $host $target; do alpha*-*-linux-gnulibc1*) tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" target_cpu_default="MASK_GAS" - tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe" + tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.wrap xmake_file=none gas=yes gnu_ld=yes - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; alpha*-*-linux-gnu*) tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" target_cpu_default="MASK_GAS" - tmake_file="t-linux alpha/t-linux alpha/t-crtbe" + tmake_file="t-linux alpha/t-linux alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" xmake_file=none - fixincludes=Makefile.in gas=yes gnu_ld=yes - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; alpha*-*-netbsd*) - tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsdl-elf.h" - xm_file="xm-netbsd.h ${xm_file}" + tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h" target_cpu_default="MASK_GAS" - tmake_file="alpha/t-crtbe" + tmake_file="alpha/t-crtbe alpha/t-ieee" extra_parts="crtbegin.o crtend.o" xmake_file=none - fixincludes=fixinc.wrap gas=yes gnu_ld=yes ;; alpha*-*-openbsd*) # default x-alpha is only appropriate for dec-osf. target_cpu_default="MASK_GAS" - xmake_file=none + tmake_file="alpha/t-ieee" ;; alpha*-dec-osf*) - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi - if [[ x$gas != xyes ]] + if test x$gas != xyes then extra_passes="mips-tfile mips-tdump" fi use_collect2=yes + tmake_file="alpha/t-ieee" case $machine in *-*-osf1*) tm_file="${tm_file} alpha/osf.h alpha/osf12.h alpha/osf2or3.h" ;; - *-*-osf[[23]]*) +changequote(,)dnl + *-*-osf[23]*) +changequote([,])dnl tm_file="${tm_file} alpha/osf.h alpha/osf2or3.h" ;; *-*-osf4*) @@ -458,40 +669,42 @@ for machine in $build $host $target; do ;; esac case $machine in - *-*-osf4.0[[b-z]] | *-*-osf4.[[1-9]]*) +changequote(,)dnl + *-*-osf4.0[b-z] | *-*-osf4.[1-9]*) +changequote([,])dnl target_cpu_default=MASK_SUPPORT_ARCH ;; esac ;; alpha*-*-vxworks*) tm_file="${tm_file} dbx.h alpha/vxworks.h" + tmake_file="alpha/t-ieee" if [ x$gas != xyes ] then extra_passes="mips-tfile mips-tdump" fi use_collect2=yes + thread_file='vxworks' ;; alpha*-*-winnt*) - tm_file="${tm_file} alpha/win-nt.h" + tm_file="${tm_file} alpha/alpha32.h alpha/win-nt.h winnt/win-nt.h" xm_file="${xm_file} config/winnt/xm-winnt.h alpha/xm-winnt.h" - tmake_file=t-libc-ok + tmake_file="t-libc-ok alpha/t-ieee" xmake_file=winnt/x-winnt extra_host_objs=oldnames.o extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then extra_programs=ld.exe fi - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='win32' fi ;; alpha*-dec-vms*) tm_file=alpha/vms.h xm_file="${xm_file} alpha/xm-vms.h" - tmake_file=alpha/t-vms - fixincludes=Makefile.in + tmake_file="alpha/t-vms alpha/t-ieee" ;; arc-*-elf*) extra_parts="crtinit.o crtfini.o" @@ -500,12 +713,19 @@ for machine in $build $host $target; do tm_file=arm/coff.h tmake_file=arm/t-bare ;; - arm-*-riscix1.[[01]]*) # Acorn RISC machine (early versions) + arm-*-vxworks*) + tm_file=arm/vxarm.h + tmake_file=arm/t-bare + thread_file='vxworks' + ;; +changequote(,)dnl + arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) +changequote([,])dnl tm_file=arm/riscix1-1.h use_collect2=yes ;; arm-*-riscix*) # Acorn RISC machine - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=arm/rix-gas.h else @@ -518,57 +738,84 @@ for machine in $build $host $target; do arm-semi-aout | armel-semi-aout) tm_file=arm/semi.h tmake_file=arm/t-semi - fixincludes=Makefile.in # There is nothing to fix ;; arm-semi-aof | armel-semi-aof) tm_file=arm/semiaof.h tmake_file=arm/t-semiaof - fixincludes=Makefile.in # There is nothing to fix ;; arm*-*-netbsd*) tm_file=arm/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" + xm_file="arm/xm-netbsd.h ${xm_file}" tmake_file="t-netbsd arm/t-netbsd" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap + use_collect2=yes ;; - arm-*-linux-gnuaout*) # ARM GNU/Linux + arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out cpu_type=arm xmake_file=x-linux - tm_file=arm/linux-gas.h + tm_file=arm/linux-aout.h tmake_file=arm/t-linux - fixincludes=Makefile.in gnu_ld=yes ;; - arm-*-aout) + arm*-*-linux-gnu*) # ARM GNU/Linux with ELF + xm_file=arm/xm-linux.h + xmake_file=x-linux + case $machine in + armv2*-*-*) + tm_file=arm/linux-elf26.h + ;; + *) + tm_file=arm/linux-elf.h + ;; + esac + tmake_file="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*-*-aout) tm_file=arm/aout.h tmake_file=arm/t-bare ;; + arm*-*-ecos-elf) + tm_file=arm/ecos-elf.h + tmake_file=arm/t-elf + ;; + arm*-*-elf) + tm_file=arm/unknown-elf.h + tmake_file=arm/t-arm-elf + ;; + arm*-*-oabi) + tm_file=arm/unknown-elf-oabi.h + tmake_file=arm/t-arm-elf + ;; c1-convex-*) # Convex C1 target_cpu_default=1 use_collect2=yes - fixincludes=Makefile.in ;; c2-convex-*) # Convex C2 target_cpu_default=2 use_collect2=yes - fixincludes=Makefile.in ;; c32-convex-*) target_cpu_default=4 use_collect2=yes - fixincludes=Makefile.in ;; c34-convex-*) target_cpu_default=8 use_collect2=yes - fixincludes=Makefile.in ;; c38-convex-*) target_cpu_default=16 use_collect2=yes - fixincludes=Makefile.in ;; + c4x-*) + cpu_type=c4x + tmake_file=c4x/t-c4x + ;; clipper-intergraph-clix*) tm_file="${tm_file} svr3.h clipper/clix.h" xm_file=clipper/xm-clix.h @@ -589,8 +836,8 @@ for machine in $build $host $target; do float_format=i32 ;; hppa*-*-openbsd*) - target_cpu_default="MASK_SNAKE" - tmake_file=pa/t-openbsd + target_cpu_default="MASK_PA_11" + tmake_file=pa/t-openbsd ;; hppa1.1-*-pro*) tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h" @@ -598,10 +845,9 @@ for machine in $build $host $target; do tmake_file=pa/t-pro ;; hppa1.1-*-osf*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-osf.h" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.1-*-rtems*) tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h" @@ -611,33 +857,32 @@ for machine in $build $host $target; do hppa1.0-*-osf*) tm_file="${tm_file} pa/pa-osf.h" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.1-*-bsd*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" use_collect2=yes - fixincludes=Makefile.in ;; hppa1.0-*-bsd*) use_collect2=yes - fixincludes=Makefile.in ;; hppa1.0-*-hpux7*) tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/gas.h" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.0-*-hpux8.0[[0-2]]*) +changequote(,)dnl + hppa1.0-*-hpux8.0[0-2]*) +changequote([,])dnl tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" else @@ -646,12 +891,14 @@ for machine in $build $host $target; do install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hpux8.0[[0-2]]*) - target_cpu_default=1 +changequote(,)dnl + hppa1.1-*-hpux8.0[0-2]*) +changequote([,])dnl + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" else @@ -661,11 +908,11 @@ for machine in $build $host $target; do use_collect2=yes ;; hppa1.1-*-hpux8*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -676,27 +923,27 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hpux10*) - target_cpu_default=1 + hppa1.1-*-hpux10* | hppa2*-*-hpux10*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux tmake_file=pa/t-pa - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi - if [[ x$enable_threads = x ]]; then + if test x$enable_threads = x; then enable_threads=$have_pthread_h fi - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='dce' tmake_file="${tmake_file} pa/t-dce-thr" fi @@ -708,26 +955,26 @@ for machine in $build $host $target; do xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux tmake_file=pa/t-pa - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi - if [[ x$enable_threads = x ]]; then + if test x$enable_threads = x; then enable_threads=$have_pthread_h fi - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='dce' tmake_file="${tmake_file} pa/t-dce-thr" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hpux*) - target_cpu_default=1 + hppa1.1-*-hpux* | hppa2*-*-hpux*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -738,19 +985,19 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi install_headers_dir=install-headers-cpio use_collect2=yes ;; - hppa1.1-*-hiux*) - target_cpu_default=1 + hppa1.1-*-hiux* | hppa2*-*-hiux*) + target_cpu_default="MASK_PA_11" tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -761,7 +1008,7 @@ for machine in $build $host $target; do tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" xm_file=pa/xm-pahpux.h xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} pa/pa-gas.h" fi @@ -769,14 +1016,15 @@ for machine in $build $host $target; do use_collect2=yes ;; hppa*-*-lites*) - target_cpu_default=1 + target_cpu_default="MASK_PA_11" use_collect2=yes - fixincludes=Makefile.in ;; i370-*-mvs*) ;; - i[[34567]]86-ibm-aix*) # IBM PS/2 running AIX - if [[ x$gas = xyes ]] +changequote(,)dnl + i[34567]86-ibm-aix*) # IBM PS/2 running AIX +changequote([,])dnl + if test x$gas = xyes then tm_file=i386/aix386.h extra_parts="crtbegin.o crtend.o" @@ -789,11 +1037,13 @@ for machine in $build $host $target; do xm_defines=USG xmake_file=i386/x-aix ;; - i[[34567]]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 +changequote(,)dnl + i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 +changequote([,])dnl xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" xmake_file=i386/x-ncr3000 - if [[ x$stabs = xyes -a x$gas = xyes ]] + if test x$stabs = xyes -a x$gas = xyes then tm_file=i386/sysv4gdb.h else @@ -802,51 +1052,59 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" tmake_file=i386/t-crtpic ;; - i[[34567]]86-next-*) +changequote(,)dnl + i[34567]86-next-*) +changequote([,])dnl tm_file=i386/next.h xm_file=i386/xm-next.h tmake_file=i386/t-next xmake_file=i386/x-next extra_objs=nextstep.o - if [[ x$enable_threads = xyes ]]; then + extra_parts="crtbegin.o crtend.o" + if test x$enable_threads = xyes; then thread_file='mach' fi ;; - i[[34567]]86-sequent-bsd*) # 80386 from Sequent +changequote(,)dnl + i[34567]86-sequent-bsd*) # 80386 from Sequent +changequote([,])dnl use_collect2=yes - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=i386/seq-gas.h else tm_file=i386/sequent.h fi ;; - i[[34567]]86-sequent-ptx1*) +changequote(,)dnl + i[34567]86-sequent-ptx1*) +changequote([,])dnl xm_defines="USG SVR3" xmake_file=i386/x-sysv3 tm_file=i386/seq-sysv3.h tmake_file=i386/t-crtstuff - fixincludes=fixinc.ptx extra_parts="crtbegin.o crtend.o" install_headers_dir=install-headers-cpio ;; - i[[34567]]86-sequent-ptx2* | i[[34567]]86-sequent-sysv3*) +changequote(,)dnl + i[34567]86-sequent-ptx2* | i[34567]86-sequent-sysv3*) +changequote([,])dnl xm_defines="USG SVR3" xmake_file=i386/x-sysv3 tm_file=i386/seq2-sysv3.h tmake_file=i386/t-crtstuff extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx install_headers_dir=install-headers-cpio ;; - i[[34567]]86-sequent-ptx4* | i[[34567]]86-sequent-sysv4*) +changequote(,)dnl + i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) +changequote([,])dnl xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" xmake_file=x-svr4 tm_file=i386/ptx4-i.h tmake_file=t-svr4 extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx install_headers_dir=install-headers-cpio ;; i386-sun-sunos*) # Sun i386 roadrunner @@ -854,69 +1112,84 @@ for machine in $build $host $target; do tm_file=i386/sun.h use_collect2=yes ;; - i[[34567]]86-wrs-vxworks*) +changequote(,)dnl + i[34567]86-wrs-vxworks*) +changequote([,])dnl tm_file=i386/vxi386.h tmake_file=i386/t-i386bare + thread_file='vxworks' ;; - i[[34567]]86-*-aout*) +changequote(,)dnl + i[34567]86-*-aout*) +changequote([,])dnl tm_file=i386/i386-aout.h tmake_file=i386/t-i386bare ;; - i[[34567]]86-*-bsdi* | i[[34567]]86-*-bsd386*) +changequote(,)dnl + i[34567]86-*-bsdi* | i[34567]86-*-bsd386*) +changequote([,])dnl tm_file=i386/bsd386.h # tmake_file=t-libc-ok ;; - i[[34567]]86-*-bsd*) +changequote(,)dnl + i[34567]86-*-bsd*) +changequote([,])dnl tm_file=i386/386bsd.h # tmake_file=t-libc-ok # Next line turned off because both 386BSD and BSD/386 use GNU ld. # use_collect2=yes ;; - i[[34567]]86-*-freebsdelf*) - tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h" - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap +changequote(,)dnl + i[34567]86-*-freebsdelf*) +changequote([,])dnl + tm_file="i386/i386.h i386/att.h svr4.h i386/freebsd-elf.h i386/perform.h" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - tmake_file=i386/t-freebsd + tmake_file=t-freebsd gas=yes gnu_ld=yes stabs=yes ;; - i[[34567]]86-*-freebsd*) +changequote(,)dnl + i[34567]86-*-freebsd*) +changequote([,])dnl tm_file=i386/freebsd.h - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - tmake_file=i386/t-freebsd + tmake_file=t-freebsd ;; - i[[34567]]86-*-netbsd*) +changequote(,)dnl + i[34567]86-*-netbsd*) +changequote([,])dnl tm_file=i386/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes ;; - i[[34567]]86-*-openbsd*) - # Remove when the math emulator is fixed - target_cpu_default="MASK_NO_FANCY_MATH_387" - # we need collect2 until our bug is fixed... - use_collect2=yes - ;; - i[[34567]]86-*-coff*) +changequote(,)dnl + i[34567]86-*-openbsd*) +changequote([,])dnl + # we need collect2 until our bug is fixed... + use_collect2=yes + ;; +changequote(,)dnl + i[34567]86-*-coff*) +changequote([,])dnl tm_file=i386/i386-coff.h tmake_file=i386/t-i386bare ;; - i[[34567]]86-*-isc*) # 80386 running ISC system +changequote(,)dnl + i[34567]86-*-isc*) # 80386 running ISC system +changequote([,])dnl xm_file="${xm_file} i386/xm-isc.h" xm_defines="USG SVR3" case $machine in - i[[34567]]86-*-isc[[34]]*) +changequote(,)dnl + i[34567]86-*-isc[34]*) +changequote([,])dnl xmake_file=i386/x-isc3 ;; *) xmake_file=i386/x-isc ;; esac - if [[ x$gas = xyes -a x$stabs = xyes ]] + if test x$gas = xyes -a x$stabs = xyes then tm_file=i386/iscdbx.h tmake_file=i386/t-svr3dbx @@ -928,77 +1201,91 @@ for machine in $build $host $target; do fi install_headers_dir=install-headers-cpio ;; - i[[34567]]86-*-linux-gnuoldld*) # Intel 80386's running GNU/Linux - # with a.out format using +changequote(,)dnl + i[34567]86-*-linux-gnuoldld*) # Intel 80386's running GNU/Linux +changequote([,])dnl # with a.out format using # pre BFD linkers xmake_file=x-linux-aout tmake_file="t-linux-aout i386/t-crtstuff" tm_file=i386/linux-oldld.h - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 ;; - i[[34567]]86-*-linux-gnuaout*) # Intel 80386's running GNU/Linux - # with a.out format +changequote(,)dnl + i[34567]86-*-linux-gnuaout*) # Intel 80386's running GNU/Linux +changequote([,])dnl # with a.out format xmake_file=x-linux-aout tmake_file="t-linux-aout i386/t-crtstuff" tm_file=i386/linux-aout.h - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 ;; - i[[34567]]86-*-linux-gnulibc1) # Intel 80386's running GNU/Linux - # with ELF format using the +changequote(,)dnl + i[34567]86-*-linux-gnulibc1) # Intel 80386's running GNU/Linux +changequote([,])dnl # with ELF format using the # GNU/Linux C library 5 xmake_file=x-linux tm_file=i386/linux.h tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='single' fi ;; - i[[34567]]86-*-linux-gnu*) # Intel 80386's running GNU/Linux - # with ELF format using glibc 2 +changequote(,)dnl + i[34567]86-*-linux-gnu*) # Intel 80386's running GNU/Linux +changequote([,])dnl # with ELF format using glibc 2 # aka GNU/Linux C library 6 xmake_file=x-linux tm_file=i386/linux.h tmake_file="t-linux i386/t-crtstuff" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes float_format=i386 - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; - i[[34567]]86-*-gnu*) +changequote(,)dnl + i[34567]86-*-gnu*) float_format=i386 +changequote([,])dnl ;; - i[[34567]]86-go32-msdos | i[[34567]]86-*-go32*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 +changequote(,)dnl + i[34567]86-go32-msdos | i[34567]86-*-go32*) +changequote([,])dnl + echo "GO32/DJGPP V1.X is no longer supported. Use *-pc-msdosdjgpp for DJGPP V2.X instead." + exit 1 ;; - i[[34567]]86-pc-msdosdjgpp*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 +changequote(,)dnl + i[34567]86-pc-msdosdjgpp*) +changequote([,])dnl + xm_file=i386/xm-djgpp.h + tm_file=i386/djgpp.h + tmake_file=i386/t-djgpp + xmake_file=i386/x-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*) +changequote(,)dnl + i[34567]86-moss-msdos* | i[34567]86-*-moss*) +changequote([,])dnl tm_file=i386/moss.h tmake_file=t-libc-ok - fixincludes=Makefile.in gnu_ld=yes gas=yes ;; - i[[34567]]86-*-lynxos*) - if [[ x$gas = xyes ]] +changequote(,)dnl + i[34567]86-*-lynxos*) +changequote([,])dnl + if test x$gas = xyes then tm_file=i386/lynx.h else @@ -1008,13 +1295,17 @@ for machine in $build $host $target; do tmake_file=i386/t-i386bare xmake_file=x-lynx ;; - i[[34567]]86-*-mach*) +changequote(,)dnl + i[34567]86-*-mach*) +changequote([,])dnl tm_file=i386/mach.h # tmake_file=t-libc-ok use_collect2=yes ;; - i[[34567]]86-*-osfrose*) # 386 using OSF/rose - if [[ x$elf = xyes ]] +changequote(,)dnl + i[34567]86-*-osfrose*) # 386 using OSF/rose +changequote([,])dnl + if test x$elf = xyes then tm_file=i386/osfelf.h use_collect2= @@ -1027,30 +1318,37 @@ for machine in $build $host $target; do tmake_file=i386/t-osf extra_objs=halfpic.o ;; - i[[34567]]86-go32-rtems*) +changequote(,)dnl + i[34567]86-go32-rtems*) +changequote([,])dnl cpu_type=i386 xm_file=i386/xm-go32.h tm_file=i386/go32-rtems.h tmake_file="i386/t-go32 t-rtems" ;; - i[[34567]]86-*-rtemself*) +changequote(,)dnl + i[34567]86-*-rtemself*) +changequote([,])dnl cpu_type=i386 tm_file=i386/rtemself.h tmake_file="i386/t-i386bare t-rtems" ;; - i[[34567]]86-*-rtems*) +changequote(,)dnl + i[34567]86-*-rtems*) +changequote([,])dnl cpu_type=i386 tm_file=i386/rtems.h tmake_file="i386/t-i386bare t-rtems" ;; - i[[34567]]86-*-sco3.2v5*) # 80386 running SCO Open Server 5 +changequote(,)dnl + i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5 +changequote([,])dnl xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h" xm_defines="USG SVR3" xmake_file=i386/x-sco5 - fixincludes=fixinc.sco install_headers_dir=install-headers-cpio tm_file=i386/sco5.h - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="i386/sco5gas.h ${tm_file}" tmake_file=i386/t-sco5gas @@ -1059,13 +1357,14 @@ for machine in $build $host $target; do fi extra_parts="crti.o crtbegin.o crtend.o crtbeginS.o crtendS.o" ;; - i[[34567]]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system +changequote(,)dnl + i[34567]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system +changequote([,])dnl xm_file="${xm_file} i386/xm-sco.h" xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST" xmake_file=i386/x-sco4 - fixincludes=fixinc.sco install_headers_dir=install-headers-cpio - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=i386/sco4dbx.h tmake_file=i386/t-svr3dbx @@ -1077,11 +1376,13 @@ for machine in $build $host $target; do fi truncate_target=yes ;; - i[[34567]]86-*-sco*) # 80386 running SCO system +changequote(,)dnl + i[34567]86-*-sco*) # 80386 running SCO system +changequote([,])dnl xm_file=i386/xm-sco.h xmake_file=i386/x-sco install_headers_dir=install-headers-cpio - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=i386/scodbx.h tmake_file=i386/t-svr3dbx @@ -1093,10 +1394,12 @@ for machine in $build $host $target; do fi truncate_target=yes ;; - i[[34567]]86-*-solaris2*) +changequote(,)dnl + i[34567]86-*-solaris2*) +changequote([,])dnl xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=i386/sol2dbg.h else @@ -1105,34 +1408,34 @@ for machine in $build $host $target; do tmake_file=i386/t-sol2 extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" xmake_file=x-svr4 - case $machine in - *-*-solaris2.[[0-4]]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='solaris' fi ;; - i[[34567]]86-*-sysv5*) # Intel x86 on System V Release 5 +changequote(,)dnl + i[34567]86-*-sysv5*) # Intel x86 on System V Release 5 +changequote([,])dnl xm_file="xm-alloca.h xm-siglist.h ${xm_file}" xm_defines="USG POSIX" - tm_file=i386/sysv4.h - if [[ x$stabs = xyes ]] + tm_file=i386/sysv5.h + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi tmake_file=i386/t-crtpic xmake_file=x-svr4 extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.svr4 + if test x$enable_threads = xyes; then + thread_file='posix' + fi ;; - i[[34567]]86-*-sysv4*) # Intel 80386's running system V.4 +changequote(,)dnl + i[34567]86-*-sysv4*) # Intel 80386's running system V.4 +changequote([,])dnl xm_file="xm-siglist.h xm-alloca.h ${xm_file}" xm_defines="USG POSIX SMALL_ARG_MAX" tm_file=i386/sysv4.h - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -1140,12 +1443,24 @@ for machine in $build $host $target; do xmake_file=x-svr4 extra_parts="crtbegin.o crtend.o" ;; - i[[34567]]86-*-osf1*) # Intel 80386's running OSF/1 1.3+ +changequote(,)dnl + i[34567]86-*-udk*) # Intel x86 on SCO UW/OSR5 Dev Kit +changequote([,])dnl + xm_file="xm-alloca.h xm-siglist.h ${xm_file}" + xm_defines="USG POSIX" + tm_file=i386/udk.h + tmake_file="i386/t-crtpic i386/t-udk" + xmake_file=x-svr4 + extra_parts="crtbegin.o crtend.o" + install_headers_dir=install-headers-cpio + ;; +changequote(,)dnl + i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+ +changequote([,])dnl cpu_type=i386 xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h" xm_defines="USE_C_ALLOCA SMALL_ARG_MAX" - fixincludes=Makefile.in #Don't do it on OSF/1 - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=i386/osf1elfgdb.h else @@ -1155,12 +1470,14 @@ for machine in $build $host $target; do xmake_file=i386/x-osf1elf extra_parts="crti.o crtn.o crtbegin.o crtend.o" ;; - i[[34567]]86-*-sysv*) # Intel 80386's running system V +changequote(,)dnl + i[34567]86-*-sysv*) # Intel 80386's running system V +changequote([,])dnl xm_defines="USG SVR3" xmake_file=i386/x-sysv3 - if [[ x$gas = xyes ]] + if test x$gas = xyes then - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=i386/svr3dbx.h tmake_file=i386/t-svr3dbx @@ -1182,38 +1499,85 @@ for machine in $build $host $target; do tmake_file=i386/t-vsta xmake_file=i386/x-vsta ;; - i[[34567]]86-*-pe | i[[34567]]86-*-cygwin32) - xm_file="${xm_file} i386/xm-cygwin32.h" - tmake_file=i386/t-cygwin32 - tm_file=i386/cygwin32.h - xmake_file=i386/x-cygwin32 +changequote(,)dnl + i[34567]86-*-win32) +changequote([,])dnl + xm_file="${xm_file} i386/xm-cygwin.h" + tmake_file=i386/t-cygwin + tm_file=i386/win32.h + xmake_file=i386/x-cygwin + extra_objs=winnt.o + if test x$enable_threads = xyes; then + thread_file='win32' + fi + exeext=.exe + ;; +changequote(,)dnl + i[34567]86-*-pe | i[34567]86-*-cygwin*) +changequote([,])dnl + xm_file="${xm_file} i386/xm-cygwin.h" + tmake_file=i386/t-cygwin + tm_file=i386/cygwin.h + xmake_file=i386/x-cygwin extra_objs=winnt.o - fixincludes=Makefile.in - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe ;; - i[[34567]]86-*-mingw32*) +changequote(,)dnl + i[34567]86-*-mingw32*) +changequote([,])dnl tm_file=i386/mingw32.h xm_file="${xm_file} i386/xm-mingw32.h" - tmake_file="i386/t-cygwin32 i386/t-mingw32" + tmake_file="i386/t-cygwin i386/t-mingw32" extra_objs=winnt.o - xmake_file=i386/x-cygwin32 - fixincludes=Makefile.in - if [[ x$enable_threads = xyes ]]; then + xmake_file=i386/x-cygwin + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe case $machine in *mingw32msv*) ;; - *mingw32crt* | *mingw32*) + *minwg32crt* | *mingw32*) tm_file="${tm_file} i386/crtdll.h" ;; esac ;; - i[[34567]]86-*-winnt3*) +changequote(,)dnl + i[34567]86-*-uwin*) +changequote([,])dnl + tm_file=i386/uwin.h + xm_file="${xm_file} i386/xm-uwin.h" + xm_defines="USG NO_STAB_H NO_SYS_SIGLIST" + tmake_file="i386/t-cygwin i386/t-uwin" + extra_objs=winnt.o + xmake_file=i386/x-cygwin + if test x$enable_threads = xyes; then + thread_file='win32' + fi + exeext=.exe + ;; +changequote(,)dnl + i[34567]86-*-interix*) +changequote([,])dnl + tm_file="i386/i386-interix.h interix.h" + xm_file="i386/xm-i386-interix.h xm-interix.h" + xm_defines="USG NO_SYS_SIGLIST" + tmake_file="i386/t-interix" + extra_objs=interix.o + xmake_file=x-interix + if test x$enable_threads = xyes ; then + thread_file='posix' + fi + if test x$stabs = xyes ; then + tm_file="${tm_file} dbxcoff.h" + fi + ;; +changequote(,)dnl + i[34567]86-*-winnt3*) +changequote([,])dnl tm_file=i386/win-nt.h out_file=i386/i386.c xm_file="xm-winnt.h ${xm_file}" @@ -1221,23 +1585,23 @@ for machine in $build $host $target; do tmake_file=i386/t-winnt extra_host_objs="winnt.o oldnames.o" extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then extra_programs=ld.exe fi - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='win32' fi ;; - i[[34567]]86-dg-dgux*) +changequote(,)dnl + i[34567]86-dg-dgux*) +changequote([,])dnl xm_file="xm-alloca.h xm-siglist.h ${xm_file}" xm_defines="USG POSIX" out_file=i386/dgux.c tm_file=i386/dgux.h tmake_file=i386/t-dgux xmake_file=i386/x-dgux - fixincludes=fixinc.dgux install_headers_dir=install-headers-cpio ;; i860-alliant-*) # Alliant FX/2800 @@ -1249,7 +1613,7 @@ for machine in $build $host $target; do ;; i860-*-bsd*) tm_file="${tm_file} i860/bsd.h" - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="${tm_file} i860/bsd-gas.h" fi @@ -1327,7 +1691,7 @@ for machine in $build $host $target; do m68000-hp-hpux*) # HP 9000 series 300 xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [[ x$gas = xyes ]] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp310g.h @@ -1352,7 +1716,7 @@ for machine in $build $host $target; do m68000-att-sysv*) xm_file="m68k/xm-3b1.h ${xm_file}" xm_defines=USG - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=m68k/3b1g.h else @@ -1368,13 +1732,13 @@ for machine in $build $host $target; do extra_headers=math-68881.h extra_parts="crt1.o mcrt1.o maccrt1.o crt2.o crtn.o" tm_file= - if [[ "$gnu_ld" = yes ]] + if test "$gnu_ld" = yes then tm_file="${tm_file} m68k/auxgld.h" else tm_file="${tm_file} m68k/auxld.h" fi - if [[ "$gas" = yes ]] + if test "$gas" = yes then tm_file="${tm_file} m68k/auxgas.h" else @@ -1391,7 +1755,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-altos-sysv*) # Altos 3068 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=m68k/altos3068.h xm_defines=USG @@ -1402,9 +1766,9 @@ for machine in $build $host $target; do extra_headers=math-68881.h ;; m68k-bull-sysv*) # Bull DPX/2 - if [[ x$gas = xyes ]] + if test x$gas = xyes then - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=m68k/dpx2cdbx.h else @@ -1432,10 +1796,10 @@ for machine in $build $host $target; do tm_file=m68k/mot3300.h xm_file="xm-alloca.h m68k/xm-mot3300.h ${xm_file}" xm_defines=NO_SYS_SIGLIST - if [[ x$gas = xyes ]] + if test x$gas = xyes then xmake_file=m68k/x-mot3300-gas - if [[ x$gnu_ld = xyes ]] + if test x$gnu_ld = xyes then tmake_file=m68k/t-mot3300-gald else @@ -1444,7 +1808,7 @@ for machine in $build $host $target; do fi else xmake_file=m68k/x-mot3300 - if [[ x$gnu_ld = xyes ]] + if test x$gnu_ld = xyes then tmake_file=m68k/t-mot3300-gld else @@ -1504,7 +1868,6 @@ for machine in $build $host $target; do ;; m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd tm_file=m68k/hp3bsd44.h - xmake_file=m68k/x-hp3bsd44 use_collect2=yes extra_headers=math-68881.h float_format=m68k @@ -1516,7 +1879,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-isi-bsd*) - if [[ x$with_fp = xno ]] + if test x$with_fp = xno then tm_file=m68k/isi-nfp.h else @@ -1529,7 +1892,7 @@ for machine in $build $host $target; do m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7. xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [[ x$gas = xyes ]] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp320g.h @@ -1545,7 +1908,7 @@ for machine in $build $host $target; do m68k-hp-hpux*) # HP 9000 series 300 xm_file="xm_alloca.h ${xm_file}" xm_defines="USG NO_SYS_SIGLIST" - if [[ x$gas = xyes ]] + if test x$gas = xyes then xmake_file=m68k/x-hp320g tm_file=m68k/hp320g.h @@ -1565,7 +1928,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-sony-newsos3*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=m68k/news3gas.h else @@ -1576,7 +1939,7 @@ for machine in $build $host $target; do float_format=m68k ;; m68k-sony-bsd* | m68k-sony-newsos*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=m68k/newsgas.h else @@ -1602,14 +1965,15 @@ for machine in $build $host $target; do tmake_file=m68k/t-next xmake_file=m68k/x-next extra_objs=nextstep.o + extra_parts="crtbegin.o crtend.o" extra_headers=math-68881.h float_format=m68k - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='mach' fi ;; m68k-sun-sunos3*) - if [[ x$with_fp = xno ]] + if test x$with_fp = xno then tm_file=m68k/sun3n3.h else @@ -1620,7 +1984,7 @@ for machine in $build $host $target; do extra_headers=math-68881.h ;; m68k-sun-sunos*) # For SunOS 4 (the default). - if [[ x$with_fp = xno ]] + if test x$with_fp = xno then tm_file=m68k/sun3n.h else @@ -1649,8 +2013,14 @@ for machine in $build $host $target; do extra_headers=math-68881.h float_format=m68k ;; + m68020-*-elf* | m68k-*-elf*) + tm_file="m68k/m68020-elf.h libgloss.h" + xm_file=m68k/xm-m68kv.h + tmake_file=m68k/t-m68kelf + header_files=math-68881.h + ;; m68k-*-lynxos*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=m68k/lynx.h else @@ -1664,11 +2034,9 @@ for machine in $build $host $target; do ;; m68k*-*-netbsd*) tm_file=m68k/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd float_format=m68k + use_collect2=yes ;; m68k*-*-openbsd*) float_format=m68k @@ -1697,7 +2065,6 @@ for machine in $build $host $target; do xmake_file=x-linux tm_file=m68k/linux-aout.h tmake_file="t-linux-aout m68k/t-linux-aout" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes @@ -1709,7 +2076,6 @@ for machine in $build $host $target; do tm_file=m68k/linux.h tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes @@ -1721,11 +2087,10 @@ for machine in $build $host $target; do tm_file=m68k/linux.h tmake_file="t-linux m68k/t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. extra_headers=math-68881.h float_format=m68k gnu_ld=yes - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -1755,18 +2120,17 @@ for machine in $build $host $target; do esac extra_parts="crtbegin.o bcscrtbegin.o crtend.o m88kdgux.ld" xmake_file=m88k/x-dgux - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=m88k/t-dgux-gas fi - fixincludes=fixinc.dgux ;; m88k-dolphin-sysv3*) tm_file=m88k/dolph.h extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-dolph - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -1776,7 +2140,7 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-tekXD88 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -1791,7 +2155,7 @@ for machine in $build $host $target; do m88k-*-luna*) tm_file=m88k/luna.h extra_parts="crtbegin.o crtend.o" - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=m88k/t-luna-gas else @@ -1806,7 +2170,7 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" xm_file="m88k/xm-sysv3.h ${xm_file}" xmake_file=m88k/x-sysv3 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=m88k/t-m88k-gas fi @@ -1820,38 +2184,36 @@ for machine in $build $host $target; do mips-sgi-irix6*) # SGI System V.4., IRIX 6 tm_file=mips/iris6.h xm_file=mips/xm-iris6.h - fixincludes=fixinc.irix xmake_file=mips/x-iris6 tmake_file=mips/t-iris6 - if [[ x$enable_threads = xyes ]]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-wrs-vxworks) - tm_file="mips/elf.h libgloss.h" + tm_file="mips/elf.h libgloss.h mips/vxworks.h" tmake_file=mips/t-ecoff gas=yes gnu_ld=yes extra_parts="crtbegin.o crtend.o" -# thread_file='vxworks' + thread_file='vxworks' ;; mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 tm_file="mips/iris6.h mips/cross64.h" xm_defines=USG xm_file="mips/xm-iris5.h" - fixincludes=Makefile.in xmake_file=mips/x-iris tmake_file=mips/t-cross64 # See comment in mips/iris[56].h files. use_collect2=yes - if [[ x$enable_threads = xyes ]]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sni-sysv4) - if [[ x$gas = xyes ]] + if test x$gas = xyes then - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file=mips/iris5gdb.h else @@ -1863,16 +2225,16 @@ for machine in $build $host $target; do xm_defines=USG xmake_file=mips/x-sni-svr4 tmake_file=mips/t-mips-gas - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-sgi-irix5*) # SGI System V.4., IRIX 5 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file="mips/iris5.h mips/iris5gas.h" - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -1881,72 +2243,71 @@ for machine in $build $host $target; do fi xm_defines=USG xm_file="mips/xm-iris5.h" - fixincludes=fixinc.irix xmake_file=mips/x-iris # mips-tfile doesn't work yet tmake_file=mips/t-mips-gas # See comment in mips/iris5.h file. use_collect2=yes - if [[ x$enable_threads = xyes ]]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-irix4loser*) # Mostly like a MIPS. tm_file="mips/iris4loser.h mips/iris3.h ${tm_file} mips/iris4.h" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi - if [[ x$enable_threads = xyes ]]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-irix4*) # Mostly like a MIPS. tm_file="mips/iris3.h ${tm_file} mips/iris4.h" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi - if [[ x$enable_threads = xyes ]]; then -: not ported yet thread_file='irix' - fi +# if test x$enable_threads = xyes; then +# thread_file='irix' +# fi ;; mips-sgi-*) # Mostly like a MIPS. tm_file="mips/iris3.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-iris3 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -1960,66 +2321,72 @@ for machine in $build $host $target; do ;; mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL tm_file=mips/dec-osf1.h - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xmake_file=mips/x-dec-osf1 - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-dec-bsd*) # Decstation running 4.4 BSD tm_file=mips/dec-bsd.h - fixincludes= - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD tm_file=mips/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd ;; + mips*-*-linux*) # Linux MIPS, either endian. + xmake_file=x-linux + xm_file="xm-siglist.h ${xm_file}" + case $machine in + mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;; + *) tm_file="mips/elf.h mips/linux.h" ;; + esac + extra_parts="crtbegin.o crtend.o" + gnu_ld=yes + gas=yes + ;; mips*el-*-openbsd*) # mips little endian target_cpu_default="MASK_GAS|MASK_ABICALLS" tm_file=mips/openbsd.h - xmake_file=none ;; mips*-*-openbsd*) # mips big endian target_cpu_default="MASK_GAS|MASK_ABICALLS" tm_file=mips/openbsd-be.h - xmake_file=none ;; mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. tm_file="mips/news4.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -2029,31 +2396,31 @@ for machine in $build $host $target; do # That is based on svr4. # t-svr4 is not right because this system doesn't use ELF. tm_file="mips/news5.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xm_defines=USG - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-tandem-sysv4*) # Tandem S2 running NonStop UX tm_file="mips/svr4-5.h mips/svr4-t.h" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xm_defines=USG xmake_file=mips/x-sysv - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas extra_parts="crtbegin.o crtend.o" @@ -2061,151 +2428,163 @@ for machine in $build $host $target; do tmake_file=mips/t-mips extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-ultrix* | mips-dec-mach3) # Decstation. tm_file="mips/ultrix.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xmake_file=mips/x-ultrix - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else tmake_file=mips/t-ultrix extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-riscos[[56789]]bsd*) +changequote(,)dnl + mips-*-riscos[56789]bsd*) +changequote([,])dnl tm_file=mips/bsd-5.h # MIPS BSD 4.3, RISC-OS 5.0 - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-bsd-gas else tmake_file=mips/t-bsd extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[[1234]]bsd*) +changequote(,)dnl + mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd*) +changequote([,])dnl tm_file="mips/bsd-4.h ${tm_file}" # MIPS BSD 4.3, RISC-OS 4.0 - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-bsd-gas else tmake_file=mips/t-bsd extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-riscos[[56789]]sysv4*) +changequote(,)dnl + mips-*-riscos[56789]sysv4*) +changequote([,])dnl tm_file=mips/svr4-5.h # MIPS System V.4., RISC-OS 5.0 - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_file="xm-siglist.h ${xm_file}" xmake_file=mips/x-sysv - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-svr4-gas else tmake_file=mips/t-svr4 extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-sysv4* | mips-*-riscos[[1234]]sysv4* | mips-*-riscossysv4*) +changequote(,)dnl + mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4*) +changequote([,])dnl tm_file="mips/svr4-4.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-svr4-gas else tmake_file=mips/t-svr4 extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-riscos[[56789]]sysv*) +changequote(,)dnl + mips-*-riscos[56789]sysv*) +changequote([,])dnl tm_file=mips/svr3-5.h # MIPS System V.3, RISC-OS 5.0 - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-svr3-gas else tmake_file=mips/t-svr3 extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; mips-*-sysv* | mips-*-riscos*sysv*) tm_file="mips/svr3-4.h ${tm_file}" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi xm_defines=USG xmake_file=mips/x-sysv - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-svr3-gas else tmake_file=mips/t-svr3 extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi ;; - mips-*-riscos[[56789]]*) # Default MIPS RISC-OS 5.0. +changequote(,)dnl + mips-*-riscos[56789]*) # Default MIPS RISC-OS 5.0. +changequote([,])dnl tm_file=mips/mips-5.h - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -2214,65 +2593,65 @@ for machine in $build $host $target; do ;; mipsel-*-ecoff*) tm_file=mips/ecoffl.h - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi tmake_file=mips/t-ecoff ;; mips-*-ecoff*) tm_file="gofast.h mips/ecoff.h" - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi tmake_file=mips/t-ecoff ;; mipsel-*-elf*) tm_file="mips/elfl.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips-*-elf*) - tm_file="mips/elf.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elf.h" + tmake_file=mips/t-elf ;; mips64el-*-elf*) - tm_file="mips/elfl64.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elfl64.h" + tmake_file=mips/t-elf ;; mips64orionel-*-elf*) tm_file="mips/elforion.h mips/elfl64.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips64-*-elf*) - tm_file="mips/elf64.h libgloss.h" - tmake_file=mips/t-ecoff + tm_file="mips/elf64.h" + tmake_file=mips/t-elf ;; mips64orion-*-elf*) tm_file="mips/elforion.h mips/elf64.h libgloss.h" - tmake_file=mips/t-ecoff + tmake_file=mips/t-elf ;; mips64orion-*-rtems*) tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h" tmake_file="mips/t-ecoff t-rtems" ;; mipstx39el-*-elf*) - tm_file="mips/r3900.h mips/elfl.h mips/abi64.h libgloss.h" + tm_file="mips/r3900.h mips/elfl.h mips/abi64.h" tmake_file=mips/t-r3900 ;; mipstx39-*-elf*) - tm_file="mips/r3900.h mips/elf.h mips/abi64.h libgloss.h" + tm_file="mips/r3900.h mips/elf.h mips/abi64.h" tmake_file=mips/t-r3900 ;; mips-*-*) # Default MIPS RISC-OS 4.0. - if [[ x$stabs = xyes ]]; then + if test x$stabs = xyes; then tm_file="${tm_file} dbx.h" fi - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file=mips/t-mips-gas else extra_passes="mips-tfile mips-tdump" fi - if [[ x$gnu_ld != xyes ]] + if test x$gnu_ld != xyes then use_collect2=yes fi @@ -2280,7 +2659,7 @@ for machine in $build $host $target; do mn10200-*-*) cpu_type=mn10200 tm_file="mn10200/mn10200.h" - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -2289,7 +2668,7 @@ for machine in $build $host $target; do mn10300-*-*) cpu_type=mn10300 tm_file="mn10300/mn10300.h" - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -2334,10 +2713,10 @@ for machine in $build $host $target; do ;; ns32k-*-netbsd*) tm_file=ns32k/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" + xm_file="ns32k/xm-netbsd.h ${xm_file}" # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes ;; pdp11-*-bsd) tm_file="${tm_file} pdp11/2bsd.h" @@ -2364,7 +2743,6 @@ for machine in $build $host $target; do ;; powerpc-*-openbsd*) tmake_file="${tmake_file} rs6000/t-rs6000 rs6000/t-openbsd" - xmake_file=none ;; powerpc-*-beos*) cpu_type=rs6000 @@ -2378,7 +2756,7 @@ for machine in $build $host $target; do xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" extra_headers=ppc-asm.h - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else @@ -2389,52 +2767,47 @@ for machine in $build $host $target; do powerpc-*-eabiaix*) tm_file=rs6000/eabiaix.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-eabisim*) tm_file=rs6000/eabisim.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-eabi*) tm_file=rs6000/eabi.h - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-rtems*) tm_file=rs6000/rtems.h - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpc-*-linux-gnulibc1) tm_file=rs6000/linux.h xm_file=rs6000/xm-sysv4.h out_file=rs6000/rs6000.c - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm" fi xmake_file=x-linux - fixincludes=Makefile.in extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" extra_headers=ppc-asm.h - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -2443,17 +2816,16 @@ for machine in $build $host $target; do xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG ${xm_defines}" out_file=rs6000/rs6000.c - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm" fi xmake_file=x-linux - fixincludes=Makefile.in extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" extra_headers=ppc-asm.h - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; @@ -2470,7 +2842,7 @@ for machine in $build $host $target; do tm_file=rs6000/sysv4le.h xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else @@ -2482,38 +2854,34 @@ for machine in $build $host $target; do powerpcle-*-eabisim*) tm_file=rs6000/eabilesim.h tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpcle-*-eabi*) tm_file=rs6000/eabile.h - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi - fixincludes=Makefile.in extra_headers=ppc-asm.h ;; powerpcle-*-winnt* ) tm_file=rs6000/win-nt.h tmake_file=rs6000/t-winnt # extra_objs=pe.o - fixincludes=Makefile.in - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='win32' fi extra_headers=ppc-asm.h ;; - powerpcle-*-pe | powerpcle-*-cygwin32) - tm_file=rs6000/cygwin32.h - xm_file="rs6000/xm-cygwin32.h ${xm_file}" + powerpcle-*-pe | powerpcle-*-cygwin*) + tm_file=rs6000/cygwin.h + xm_file="rs6000/xm-cygwin.h ${xm_file}" tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin32 + xmake_file=rs6000/x-cygwin # extra_objs=pe.o - fixincludes=Makefile.in - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='win32' fi exeext=.exe @@ -2523,73 +2891,89 @@ for machine in $build $host $target; do tm_file=rs6000/sol2.h xm_file="xm-siglist.h rs6000/xm-sysv4.h" xm_defines="USG POSIX" - if [[ x$gas = xyes ]] + if test x$gas = xyes then tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" else tmake_file="rs6000/t-ppc rs6000/t-ppccomm" fi xmake_file=rs6000/x-sysv4 - case $machine in - *-*-solaris2.[[0-4]]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac extra_headers=ppc-asm.h ;; - rs6000-ibm-aix3.[[01]]*) +changequote(,)dnl + rs6000-ibm-aix3.[01]*) +changequote([,])dnl tm_file=rs6000/aix31.h xmake_file=rs6000/x-aix31 + float_format=none use_collect2=yes ;; - rs6000-ibm-aix3.2.[[456789]]* | powerpc-ibm-aix3.2.[[456789]]*) +changequote(,)dnl + rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*) +changequote([,])dnl tm_file=rs6000/aix3newas.h - if [[ x$host != x$target ]] + if test x$host != x$target then tmake_file=rs6000/t-xnewas else tmake_file=rs6000/t-newas fi + float_format=none use_collect2=yes ;; - rs6000-ibm-aix4.[[12]]* | powerpc-ibm-aix4.[[12]]*) +changequote(,)dnl + rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*) +changequote([,])dnl tm_file=rs6000/aix41.h - if [[ x$host != x$target ]] + if test x$host != x$target then tmake_file=rs6000/t-xnewas else tmake_file=rs6000/t-newas fi - xmake_file=rs6000/x-aix41 + if test "$gnu_ld" = yes + then + xmake_file=rs6000/x-aix41-gld + else + xmake_file=rs6000/x-aix41 + fi + float_format=none use_collect2=yes ;; - rs6000-ibm-aix4.[[3456789]].* | powerpc-ibm-aix4.[[3456789]].*) +changequote(,)dnl + rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*) +changequote([,])dnl tm_file=rs6000/aix43.h - if [[ x$host != x$target ]] + if test x$host != x$target then tmake_file=rs6000/t-xaix43 else tmake_file=rs6000/t-aix43 fi xmake_file=rs6000/x-aix43 + float_format=none use_collect2=yes ;; - rs6000-ibm-aix[[56789]].* | powerpc-ibm-aix[[56789]].*) +changequote(,)dnl + rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) +changequote([,])dnl tm_file=rs6000/aix43.h - if [[ x$host != x$target ]] + if test x$host != x$target then tmake_file=rs6000/t-xaix43 else tmake_file=rs6000/t-aix43 fi xmake_file=rs6000/x-aix43 + float_format=none use_collect2=yes ;; rs6000-ibm-aix*) + float_format=none use_collect2=yes ;; rs6000-bull-bosx) + float_format=none use_collect2=yes ;; rs6000-*-mach*) @@ -2639,10 +3023,8 @@ for machine in $build $host $target; do ;; sparc-*-netbsd*) tm_file=sparc/netbsd.h - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd + use_collect2=yes ;; sparc-*-openbsd*) # we need collect2 until our bug is fixed... @@ -2662,7 +3044,6 @@ for machine in $build $host $target; do xm_file="${xm_file} sparc/xm-linux.h" tm_file=sparc/linux-aout.h xmake_file=x-linux - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes ;; sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5 @@ -2671,7 +3052,6 @@ for machine in $build $host $target; do tm_file=sparc/linux.h tmake_file="t-linux t-linux-gnulibc1" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes ;; sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6 @@ -2680,14 +3060,13 @@ for machine in $build $host $target; do tm_file=sparc/linux.h tmake_file="t-linux" extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. gnu_ld=yes - if [[ x$enable_threads = xyes ]]; then + if test x$enable_threads = xyes; then thread_file='posix' fi ;; sparc-*-lynxos*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then tm_file=sparc/lynx.h else @@ -2701,8 +3080,38 @@ for machine in $build $host $target; do tmake_file="sparc/t-sparcbare t-rtems" tm_file=sparc/rtems.h ;; + sparcv9-*-solaris2*) + tm_file=sparc/sol2-sld-64.h + xm_file="sparc/xm-sysv4-64.h sparc/xm-sol2.h" + xm_defines="USG POSIX" + tmake_file="sparc/t-sol2 sparc/t-sol2-64" + xmake_file=sparc/x-sysv4 + extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o" + float_format=none + if test x${enable_threads} = x ; then + enable_threads=$have_pthread_h + if test x${enable_threads} = x ; then + enable_threads=$have_thread_h + fi + fi + if test x${enable_threads} = xyes ; then + if test x${have_pthread_h} = xyes ; then + thread_file='posix' + else + thread_file='solaris' + fi + fi + ;; + sparc-hal-solaris2*) + xm_file=sparc/xm-sol2.h + tm_file="sparc/sol2.h sparc/hal.h" + tmake_file="sparc/t-halos sparc/t-sol2" + xmake_file=sparc/x-sysv4 + extra_parts="crt1.o crti.o crtn.o gmon.o crtbegin.o crtend.o" + broken_install=yes + ;; sparc-*-solaris2*) - if [[ x$gnu_ld = xyes ]] + if test x$gnu_ld = xyes then tm_file=sparc/sol2.h else @@ -2714,20 +3123,23 @@ for machine in $build $host $target; do xmake_file=sparc/x-sysv4 extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" case $machine in - *-*-solaris2.[[0-4]]) - fixincludes=fixinc.svr4;; +changequote(,)dnl + *-*-solaris2.[0-4]) +changequote([,])dnl + float_format=i128 + ;; *) - fixincludes=fixinc.wrap;; + float_format=none + ;; esac - float_format=i128 - if [[ x${enable_threads} = x ]]; then + if test x${enable_threads} = x; then enable_threads=$have_pthread_h - if [[ x${enable_threads} = x ]]; then + if test x${enable_threads} = x; then enable_threads=$have_thread_h fi fi - if [[ x${enable_threads} = xyes ]]; then - if [[ x${have_pthread_h} = xyes ]]; then + if test x${enable_threads} = xyes; then + if test x${have_pthread_h} = xyes; then thread_file='posix' else thread_file='solaris' @@ -2743,7 +3155,7 @@ for machine in $build $host $target; do tm_file=sparc/sunos4.h tmake_file=sparc/t-sunos41 use_collect2=yes - if [[ x$gas = xyes ]]; then + if test x$gas = xyes; then tm_file="${tm_file} sparc/sun4gas.h" fi ;; @@ -2788,11 +3200,11 @@ for machine in $build $host $target; do extra_parts="crtbegin.o crtend.o" ;; sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux - tmake_file=sparc/t-sp64 + tmake_file="t-linux sparc/t-linux64" xm_file="sparc/xm-sp64.h sparc/xm-linux.h" tm_file=sparc/linux64.h xmake_file=x-linux - fixincludes=Makefile.in # The headers are ok already. + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" gnu_ld=yes ;; # This hasn't been upgraded to GCC 2. @@ -2807,7 +3219,14 @@ for machine in $build $host $target; do xm_file=arm/xm-thumb.h md_file=arm/thumb.md tmake_file=arm/t-thumb - fixincludes=Makefile.in # There is nothing to fix + ;; + thumb-wrs-vxworks) + tm_file=arm/tcoff.h + out_file=arm/thumb.c + xm_file=arm/xm-thumb.h + md_file=arm/thumb.md + tmake_file=arm/t-thumb + thread_file='vxworks' ;; # This hasn't been upgraded to GCC 2. # tron-*-*) @@ -2819,7 +3238,7 @@ for machine in $build $host $target; do tm_file="v850/v850.h" xm_file="v850/xm-v850.h" tmake_file=v850/t-v850 - if [[ x$stabs = xyes ]] + if test x$stabs = xyes then tm_file="${tm_file} dbx.h" fi @@ -2836,14 +3255,12 @@ for machine in $build $host $target; do ;; vax-*-netbsd*) tm_file="${tm_file} netbsd.h vax/netbsd.h" - xm_file="xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap tmake_file=t-netbsd float_format=vax + use_collect2=yes ;; vax-*-openbsd*) - tmake_file="${tm_file} vax/t-openbsd" + tmake_file="${tmake_file} vax/t-openbsd" ;; vax-*-ultrix*) # vaxen running ultrix tm_file="${tm_file} vax/ultrix.h" @@ -2883,13 +3300,10 @@ for machine in $build $host $target; do # GNU tools are the only tools. gnu_ld=yes gas=yes - # On GNU, the headers are already okay. - fixincludes=Makefile.in xmake_file=x-linux # These details are the same as Linux. tmake_file=t-gnu # These are not. ;; *-*-sysv4*) - fixincludes=fixinc.svr4 xmake_try_sysv=x-sysv install_headers_dir=install-headers-cpio ;; @@ -2907,7 +3321,14 @@ for machine in $build $host $target; do target_cpu_default2=1 ;; i586-*-*) - target_cpu_default2=2 + case $target_alias in + k6-*) + target_cpu_default2=4 + ;; + *) + target_cpu_default2=2 + ;; + esac ;; i686-*-* | i786-*-*) target_cpu_default2=3 @@ -2915,7 +3336,7 @@ for machine in $build $host $target; do alpha*-*-*) case $machine in alphaev6*) - target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_CIX|MASK_MAX" + target_cpu_default2="MASK_CPU_EV6|MASK_BWX|MASK_MAX|MASK_FIX" ;; alphapca56*) target_cpu_default2="MASK_CPU_EV5|MASK_BWX|MASK_MAX" @@ -2928,9 +3349,9 @@ for machine in $build $host $target; do ;; esac - if [[ x$gas = xyes ]] + if test x$gas = xyes then - if [[ "$target_cpu_default2" = "" ]] + if test "$target_cpu_default2" = "" then target_cpu_default2="MASK_GAS" else @@ -2950,7 +3371,7 @@ for machine in $build $host $target; do xarm[23678] | xarm250 | xarm[67][01]0 \ | xarm7m | xarm7dm | xarm7dmi | xarm7tdmi \ | xarm7100 | xarm7500 | xarm7500fe | xarm810 \ - | xstrongarm | xstrongarm110) + | xstrongarm | xstrongarm110 | xstrongarm1100) target_cpu_default2="TARGET_CPU_$with_cpu" ;; @@ -2960,7 +3381,7 @@ for machine in $build $host $target; do ;; *) - if [[ x$pass2done = xyes ]] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -2970,9 +3391,9 @@ for machine in $build $host $target; do ;; mips*-*-ecoff* | mips*-*-elf*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then - if [[ x$gnu_ld = xyes ]] + if test x$gnu_ld = xyes then target_cpu_default2=20 else @@ -2981,7 +3402,7 @@ for machine in $build $host $target; do fi ;; mips*-*-*) - if [[ x$gas = xyes ]] + if test x$gas = xyes then target_cpu_default2=16 fi @@ -2994,6 +3415,7 @@ for machine in $build $host $target; do xcommon | xpower | xpower2 | xpowerpc | xrios \ | xrios1 | xrios2 | xrsc | xrsc1 \ | x601 | x602 | x603 | x603e | x604 | x604e | x620 \ + | xec603e | x740 | x750 | x401 \ | x403 | x505 | x801 | x821 | x823 | x860) target_cpu_default2="\"$with_cpu\"" ;; @@ -3004,7 +3426,7 @@ for machine in $build $host $target; do ;; *) - if [[ x$pass2done = xyes ]] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -3017,11 +3439,11 @@ for machine in $build $host $target; do .) target_cpu_default2=TARGET_CPU_"`echo $machine | sed 's/-.*$//'`" ;; - .supersparc | .ultrasparc | .v7 | .v8 | .v9) + .supersparc | .hypersparc | .ultrasparc | .v7 | .v8 | .v9) target_cpu_default2="TARGET_CPU_$with_cpu" ;; *) - if [[ x$pass2done = xyes ]] + if test x$pass2done = xyes then echo "Unknown cpu used with --with-cpu=$with_cpu" 1>&2 exit 1 @@ -3031,9 +3453,9 @@ for machine in $build $host $target; do ;; esac - if [[ "$target_cpu_default2" != "" ]] + if test "$target_cpu_default2" != "" then - if [[ "$target_cpu_default" != "" ]] + if test "$target_cpu_default" != "" then target_cpu_default="(${target_cpu_default}|${target_cpu_default2})" else @@ -3052,9 +3474,9 @@ for machine in $build $host $target; do # 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 [[ x$pass1done = x ]] + if test x$pass1done = x then - if [[ x"$xm_file" = x ]] + if test x"$xm_file" = x then build_xm_file=$cpu_type/xm-$cpu_type.h else build_xm_file=$xm_file fi @@ -3063,14 +3485,14 @@ for machine in $build $host $target; do build_exeext=$exeext pass1done=yes else - if [[ x$pass2done = x ]] + if test x$pass2done = x then - if [[ x"$xm_file" = x ]] + if test x"$xm_file" = x then host_xm_file=$cpu_type/xm-$cpu_type.h else host_xm_file=$xm_file fi host_xm_defines=$xm_defines - if [[ x"$xmake_file" = x ]] + if test x"$xmake_file" = x then xmake_file=$cpu_type/x-$cpu_type fi host_xmake_file="$xmake_file" @@ -3086,48 +3508,50 @@ done extra_objs="${host_extra_objs} ${extra_objs}" # Default the target-machine variables that were not explicitly set. -if [[ x"$tm_file" = x ]] +if test x"$tm_file" = x then tm_file=$cpu_type/$cpu_type.h; fi -if [[ x$extra_headers = x ]] +if test x$extra_headers = x then extra_headers=; fi -if [[ x"$xm_file" = x ]] +if test x"$xm_file" = x then xm_file=$cpu_type/xm-$cpu_type.h; fi -if [[ x$md_file = x ]] +if test x$md_file = x then md_file=$cpu_type/$cpu_type.md; fi -if [[ x$out_file = x ]] +if test x$out_file = x then out_file=$cpu_type/$cpu_type.c; fi -if [[ x"$tmake_file" = x ]] +if test x"$tmake_file" = x then tmake_file=$cpu_type/t-$cpu_type fi -if [[ x$float_format = x ]] +if test x"$dwarf2" = xyes +then tm_file="tm-dwarf2.h $tm_file" +fi + +if test x$float_format = x then float_format=i64 fi -if [[ x$enable_haifa = x ]] +if test $float_format = none +then float_h_file=Makefile.in +else float_h_file=float-$float_format.h +fi + +if test x$enable_haifa = x then case $target in - alpha*-* | hppa1.?-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*) + alpha*-* | hppa*-* | powerpc*-* | rs6000-* | *sparc*-* | m32r*-*) enable_haifa=yes;; esac fi # Handle cpp installation. -if [[ x$enable_cpp != x ]] +if test x$enable_cpp != xno then tmake_file="$tmake_file t-install-cpp" - case x$enable_cpp in - xyes | xno) ;; - x/*) cpp_install_dir=$enable_cpp ;; - x.*) echo "alternate cpp script installation directory must be an absolute path" 1>&2 - exit 1 - ;; - esac fi # Say what files are being used for the output code and MD file. @@ -3138,7 +3562,7 @@ count=a for f in $tm_file; do count=${count}x done -if [[ $count = ax ]]; then +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:" @@ -3151,7 +3575,7 @@ count=a for f in $host_xm_file; do count=${count}x done -if [[ $count = ax ]]; then +if 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:" @@ -3160,12 +3584,12 @@ else done fi -if [[ "$host_xm_file" != "$build_xm_file" ]]; then +if test "$host_xm_file" != "$build_xm_file"; then count=a for f in $build_xm_file; do count=${count}x done - if [[ $count = ax ]]; then + if 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:" @@ -3175,8 +3599,8 @@ if [[ "$host_xm_file" != "$build_xm_file" ]]; then fi fi -if [[ x$thread_file = x ]]; then - if [[ x$target_thread_file != x ]]; then +if test x$thread_file = x; then + if test x$target_thread_file != x; then thread_file=$target_thread_file else thread_file='single' @@ -3189,14 +3613,14 @@ fi # auto-host.h is the file containing items generated by autoconf and is # the first file included by config.h. null_defines= -host_xm_file="auto-host.h ${host_xm_file}" +host_xm_file="auto-host.h gansidecl.h ${host_xm_file} hwint.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 # work to find out the build config parameters. -if [[ x$host = x$build ]] +if test x$host = x$build then - build_xm_file="auto-host.h ${build_xm_file}" + build_xm_file="auto-host.h gansidecl.h ${build_xm_file} hwint.h" else # We create a subdir, then run autoconf in the subdir. # To prevent recursion we set host and build for the new @@ -3218,18 +3642,21 @@ else mv auto-host.h ../auto-build.h cd .. rm -rf $tempdir - build_xm_file="auto-build.h ${build_xm_file}" + build_xm_file="auto-build.h gansidecl.h ${build_xm_file} hwint.h" fi +xm_file="gansidecl.h ${xm_file}" +tm_file="gansidecl.h ${tm_file}" + vars="host_xm_file tm_file xm_file build_xm_file" links="config.h tm.h tconfig.h hconfig.h" defines="host_xm_defines null_defines xm_defines build_xm_defines" rm -f config.bak -if [[ -f config.status ]]; then mv -f config.status config.bak; fi +if test -f config.status; then mv -f config.status config.bak; fi # Make the links. -while [[ -n "$vars" ]] +while test -n "$vars" do set $vars; var=$1; shift; vars=$* set $links; link=$1; shift; links=$* @@ -3239,13 +3666,27 @@ do # Define TARGET_CPU_DEFAULT if the system wants one. # This substitutes for lots of *.h files. - if [[ "$target_cpu_default" != "" -a $link = tm.h ]] + if test "$target_cpu_default" != "" -a $link = tm.h then echo "#define TARGET_CPU_DEFAULT ($target_cpu_default)" >>$link fi for file in `eval echo '$'$var`; do + case $file in + auto-config.h) + ;; + *) + echo '#ifdef IN_GCC' >>$link + ;; + esac echo "#include \"$file\"" >>$link + case $file in + auto-config.h) + ;; + *) + echo '#endif' >>$link + ;; + esac done for def in `eval echo '$'$define`; do @@ -3256,17 +3697,37 @@ do done # Truncate the target if necessary -if [[ x$host_truncate_target != x ]]; then +if test x$host_truncate_target != x; then target=`echo $target | sed -e 's/\(..............\).*/\1/'` fi # Get the version trigger filename from the toplevel -if [[ "${with_gcc_version_trigger+set}" = set ]]; then +if test "${with_gcc_version_trigger+set}" = set; then gcc_version_trigger=$with_gcc_version_trigger else gcc_version_trigger=${srcdir}/version.c fi -gcc_version=`sed -e 's/.*\"\([[^ \"]]*\)[[ \"]].*/\1/' < ${gcc_version_trigger}` +changequote(,)dnl +gcc_version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < ${gcc_version_trigger}` +changequote([,])dnl + +# Internationalization +PACKAGE=gcc +VERSION="$gcc_version" +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE") +AC_DEFINE_UNQUOTED(VERSION, "$VERSION") +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) + +ALL_LINGUAS="en_UK" + +# NLS support is still experimental, so disable it by default for now. +AC_ARG_ENABLE(nls, + [ --enable-nls use Native Language Support (disabled by default)], + , enable_nls=no) + +AM_GNU_GETTEXT +XGETTEXT="AWK='$AWK' \$(SHELL) \$(top_srcdir)/exgettext $XGETTEXT" # Get an absolute path to the GCC top-level source directory holddir=`pwd` @@ -3281,7 +3742,7 @@ host_overrides=Make-host dep_host_xmake_file= for f in .. ${host_xmake_file} do - if [[ -f ${srcdir}/config/$f ]] + if test -f ${srcdir}/config/$f then dep_host_xmake_file="${dep_host_xmake_file} ${srcdir}/config/$f" fi @@ -3294,7 +3755,7 @@ target_overrides=Make-target dep_tmake_file= for f in .. ${tmake_file} do - if [[ -f ${srcdir}/config/$f ]] + if test -f ${srcdir}/config/$f then dep_tmake_file="${dep_tmake_file} ${srcdir}/config/$f" fi @@ -3307,6 +3768,7 @@ 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)" else rm -f symtest.tem @@ -3317,6 +3779,7 @@ 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\`" fi rm -f symtest.tem @@ -3325,29 +3788,29 @@ out_object_file=`basename $out_file .c`.o tm_file_list= for f in $tm_file; do - tm_file_list="${tm_file_list} \$(srcdir)/config/$f" + case $f in + gansidecl.h ) + tm_file_list="${tm_file_list} $f" ;; + *) tm_file_list="${tm_file_list} \$(srcdir)/config/$f" ;; + esac done host_xm_file_list= for f in $host_xm_file; do - if test $f != "auto-host.h"; then - host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" - else - host_xm_file_list="${host_xm_file_list} auto-host.h" - fi + case $f in + auto-host.h | gansidecl.h | hwint.h ) + host_xm_file_list="${host_xm_file_list} $f" ;; + *) host_xm_file_list="${host_xm_file_list} \$(srcdir)/config/$f" ;; + esac done build_xm_file_list= for f in $build_xm_file; do - if test $f != "auto-build.h"; then - if test $f != "auto-host.h"; then - build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" - else - build_xm_file_list="${build_xm_file_list} auto-host.h" - fi - else - build_xm_file_list="${build_xm_file_list} auto-build.h" - fi + case $f in + auto-build.h | auto-host.h | gansidecl.h | hwint.h ) + build_xm_file_list="${build_xm_file_list} $f" ;; + *) build_xm_file_list="${build_xm_file_list} \$(srcdir)/config/$f" ;; + esac done # Define macro CROSS_COMPILE in compilation @@ -3355,7 +3818,7 @@ done # Also use all.cross instead of all.internal # and add cross-make to Makefile. cross_overrides="/dev/null" -if [[ x$host != x$target ]] +if test x$host != x$target then cross_defines="CROSS=-DCROSS_COMPILE" cross_overrides="${topdir}/cross-make" @@ -3365,7 +3828,7 @@ fi # This must come after cross-make as we want all.build to override # all.cross. build_overrides="/dev/null" -if [[ x$build != x$host ]] +if test x$build != x$host then build_overrides="${topdir}/build-make" fi @@ -3373,7 +3836,7 @@ fi # Expand extra_headers to include complete path. # This substitutes for lots of t-* files. extra_headers_list= -if [[ "x$extra_headers" = x ]] +if test "x$extra_headers" = x then true else # Prepend ${srcdir}/ginclude/ to every entry in extra_headers. @@ -3383,10 +3846,14 @@ else done fi +if test x$use_collect2 = xno; then + use_collect2= +fi + # Add a definition of USE_COLLECT2 if system wants one. # Also tell toplev.c what to do. # This substitutes for lots of t-* files. -if [[ x$use_collect2 = x ]] +if test x$use_collect2 = x then will_use_collect2= maybe_use_collect2= @@ -3402,7 +3869,7 @@ fi # building gcc with a cross compiler, use the cross compiler just # built. Otherwise, we can use the cpp just built. md_file_sub= -if [[ "x$md_cppflags" = x ]] +if test "x$md_cppflags" = x then md_file_sub=$srcdir/config/$md_file else @@ -3410,18 +3877,18 @@ else fi # If we have gas in the build tree, make a link to it. -if [[ -f ../gas/Makefile ]]; then +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 in the build tree, make a link to it. -if [[ -f ../binutils/Makefile ]]; then +if test -f ../binutils/Makefile; then rm -f nm; $symbolic_link ../binutils/nm-new$host_exeext nm$host_exeext 2>/dev/null fi # If we have ld in the build tree, make a link to it. -if [[ -f ../ld/Makefile ]]; then -# if [[ x$use_collect2 = x ]]; then +if test -f ../ld/Makefile; then +# if test x$use_collect2 = x; then # rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null # else rm -f collect-ld; $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext 2>/dev/null @@ -3432,40 +3899,96 @@ fi AC_MSG_CHECKING(assembler alignment features) gcc_cv_as= gcc_cv_as_alignment_features= -gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,gcc$,gas,'` -if [[ -x as$host_exeext ]]; then +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 [[ -f $gcc_cv_as_gas_srcdir/configure.in ]]; then +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_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 [[ x$gcc_cv_gas_version != x ]]; then +changequote(,)dnl + gcc_cv_gas_version=`grep '^VERSION=[0-9]*\.[0-9]*' $f` +changequote([,])dnl + 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]]*\)"` - if [[ x$gcc_cv_gas_major_version != x -a x$gcc_cv_gas_minor_version != x ]]; then +changequote(,)dnl + 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]*\)"` +changequote([,])dnl + 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 [[ "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 6 -o "$gcc_cv_gas_major_version" -gt 2 ]]; then + 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" AC_DEFINE(HAVE_GAS_BALIGN_AND_P2ALIGN) fi # Gas version 2.8 and later support specifying the maximum # bytes to skip when using .p2align. - if [[ "$gcc_cv_gas_major_version" -eq 2 -a "$gcc_cv_gas_minor_version" -ge 8 -o "$gcc_cv_gas_major_version" -gt 2 ]]; then + 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" AC_DEFINE(HAVE_GAS_MAX_SKIP_P2ALIGN) fi fi -elif [[ x$host = x$target ]]; then +elif test x$host = x$target; then # Native build. - gcc_cv_as=as$host_exeext + # 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. + as=as$host_exeext + + test_dirs="$test_prefix/lib/gcc-lib/$target/$gcc_version \ + $test_prefix/lib/gcc-lib/$target \ + /usr/lib/gcc/$target/$gcc_version \ + /usr/lib/gcc/$target \ + $test_prefix/$target/bin/$target/$gcc_version \ + $test_prefix/$target/bin \ + /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" + + for dir in $test_dirs; do + if test -f $dir/as$host_exeext; then + gcc_cv_as=$dir/as$host_exeext + break; + fi + done fi -if [[ x$gcc_cv_as != x ]]; then +if test x$gcc_cv_as != x; then # Check if we have .balign and .p2align echo ".balign 4" > conftest.s echo ".p2align 2" >> conftest.s @@ -3485,7 +4008,70 @@ if [[ x$gcc_cv_as != x ]]; then fi AC_MSG_RESULT($gcc_cv_as_alignment_features) +AC_MSG_CHECKING(assembler subsection support) +gcc_cv_as_subsections= +if 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 nm$host_exeext; then + gcc_cv_nm=./nm$host_exeext + elif test x$host = x$target; then + # Native build. + gcc_cv_nm=nm$host_exeext + fi + if test x$gcc_cv_nm != x; then + cat > 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" + AC_DEFINE(HAVE_GAS_SUBSECTION_ORDERING) + fi + fi + fi + fi + rm -f conftest.s conftest.o conftest.nm1 conftest.nm2 +fi +AC_MSG_RESULT($gcc_cv_as_subsections) + +AC_MSG_CHECKING(assembler instructions) +gcc_cv_as_instructions= +if 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" " + AC_DEFINE_UNQUOTED(HAVE_GAS_`echo "$1" | tr '[a-z ]' '[A-Z_]'`) + fi + shift 2 + done + rm -f conftest.s conftest.o +fi +AC_MSG_RESULT($gcc_cv_as_instructions) + # 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. +if test x"${enable_languages+set}" != xset; then + if test x"${LANGUAGES+set}" = xset; then + enable_languages="`echo ${LANGUAGES} | tr ' ' ','`" + else + enable_languages=all + fi +fi subdirs= for lang in ${srcdir}/*/config-lang.in .. do @@ -3493,14 +4079,47 @@ do ..) ;; # The odd quoting in the next line works around # an apparent bug in bash 1.12 on linux. - ${srcdir}/[[*]]/config-lang.in) ;; - *) subdirs="$subdirs `echo $lang | sed -e 's,^.*/\([[^/]]*\)/config-lang.in$,\1,'`" ;; +changequote(,)dnl + ${srcdir}/[*]/config-lang.in) ;; + *) + lang_alias=`sed -n -e 's,^language=['"'"'"'"]\(.*\)["'"'"'"'].*$,\1,p' -e 's,^language=\([^ ]*\).*$,\1,p' $lang` + if test "x$lang_alias" = x + then + echo "$lang doesn't set \$language." 1>&2 + exit 1 + fi + if test x"${enable_languages}" = xall; then + add_this_lang=yes + else + case "${enable_languages}" in + ${lang_alias} | "${lang_alias},"* | *",${lang_alias},"* | *",${lang_alias}" ) + add_this_lang=yes + ;; + * ) + add_this_lang=no + ;; + esac + fi + if test x"${add_this_lang}" = xyes; then + case $lang in + ${srcdir}/ada/config-lang.in) + if test x$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 # Make gthr-default.h if we have a thread file. gthread_flags= -if [[ $thread_file != single ]]; then +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 @@ -3512,18 +4131,23 @@ AC_SUBST(gthread_flags) lang_specs_files= lang_options_files= -rm -f specs.h options.h -touch specs.h options.h +lang_tree_files= +rm -f specs.h options.h gencheck.h +touch specs.h options.h gencheck.h for subdir in . $subdirs do - if [[ -f $srcdir/$subdir/lang-specs.h ]]; then + if test -f $srcdir/$subdir/lang-specs.h; then echo "#include \"$subdir/lang-specs.h\"" >>specs.h lang_specs_files="$lang_specs_files $srcdir/$subdir/lang-specs.h" fi - if [[ -f $srcdir/$subdir/lang-options.h ]]; then + if test -f $srcdir/$subdir/lang-options.h; then echo "#include \"$subdir/lang-options.h\"" >>options.h lang_options_files="$lang_options_files $srcdir/$subdir/lang-options.h" fi + if test -f $srcdir/$subdir/$subdir-tree.def; then + echo "#include \"$subdir/$subdir-tree.def\"" >>gencheck.h + lang_tree_files="$lang_tree_files $srcdir/$subdir/$subdir-tree.def" + fi done # These (without "all_") are set in each config-lang.in. @@ -3533,7 +4157,7 @@ all_boot_languages= all_compilers= all_stagestuff= all_diff_excludes= -all_outputs=Makefile +all_outputs='Makefile intl/Makefile po/Makefile.in fixinc/Makefile' # List of language makefile fragments. all_lang_makefiles= all_headers= @@ -3552,7 +4176,7 @@ oldstyle_subdirs= for s in .. $subdirs do - if [[ $s != ".." ]] + if test $s != ".." then language= boot_language= @@ -3563,14 +4187,14 @@ do outputs= lib2funcs= . ${srcdir}/$s/config-lang.in - if [[ "x$language" = x ]] + if test "x$language" = x then 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 ${srcdir}/$s/Makefile.in" all_languages="$all_languages $language" - if [[ "x$boot_language" = xyes ]] + if test "x$boot_language" = xyes then all_boot_languages="$all_boot_languages $language" fi @@ -3579,7 +4203,7 @@ do all_diff_excludes="$all_diff_excludes $diff_excludes" all_headers="$all_headers $headers" all_outputs="$all_outputs $outputs" - if [[ x$outputs = x ]] + if test x$outputs = x then oldstyle_subdirs="$oldstyle_subdirs $s" fi @@ -3601,10 +4225,10 @@ target_list="all.build all.cross start.encap rest.encap \ for t in $target_list do x= - for l in .. $all_languages + for lang in .. $all_languages do - if [[ $l != ".." ]]; then - x="$x $l.$t" + if test $lang != ".."; then + x="$x $lang.$t" fi done echo "lang.$t: $x" >> Make-hooks @@ -3612,14 +4236,14 @@ done # If we're not building in srcdir, create .gdbinit. -if [[ ! -f Makefile.in ]]; then +if test ! -f Makefile.in; then echo "dir ." > .gdbinit echo "dir ${srcdir}" >> .gdbinit - if [[ x$gdb_needs_out_file_path = xyes ]] + if test x$gdb_needs_out_file_path = xyes then echo "dir ${srcdir}/config/"`dirname ${out_file}` >> .gdbinit fi - if [[ "x$subdirs" != x ]]; then + if test "x$subdirs" != x; then for s in $subdirs do echo "dir ${srcdir}/$s" >> .gdbinit @@ -3633,7 +4257,7 @@ fi build_canonical=${build} host_canonical=${host} target_subdir= -if [[ "${host}" != "${target}" ]] ; then +if test "${host}" != "${target}" ; then target_subdir=${target}/ fi AC_SUBST(build_canonical) @@ -3645,7 +4269,7 @@ AC_SUBST(target_subdir) # libgcc.a, but that's OK because newib should have its own version of # assert.h. inhibit_libc= -if [[ x$with_newlib = xyes ]]; then +if test x$with_newlib = xyes; then inhibit_libc=-Dinhibit_libc fi AC_SUBST(inhibit_libc) @@ -3653,23 +4277,62 @@ AC_SUBST(inhibit_libc) # Override SCHED_OBJ and SCHED_CFLAGS to enable the Haifa scheduler. sched_prefix= sched_cflags= -if [[ x$enable_haifa = xyes ]]; then +if test x$enable_haifa = xyes; then echo "Using the Haifa scheduler." sched_prefix=haifa- sched_cflags=-DHAIFA fi AC_SUBST(sched_prefix) AC_SUBST(sched_cflags) -if [[ x$enable_haifa != x ]]; then +if test x$enable_haifa != x; then # Explicitly remove files that need to be recompiled for the Haifa scheduler. - for x in genattrtab.o toplev.o loop.o unroll.o *sched.o; do - if [[ -f $x ]]; then + for x in genattrtab.o toplev.o *sched.o; do + if test -f $x; then echo "Removing $x" rm -f $x fi done 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 +# $(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_alias)' +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 occurance of / 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_alias)" +changequote([, ])dnl +fi +AC_SUBST(gcc_tooldir) +AC_SUBST(dollar) + # Nothing to do for FLOAT_H, float_format already handled. objdir=`pwd` AC_SUBST(objdir) @@ -3679,51 +4342,56 @@ ${CONFIG_SHELL-/bin/sh} $srcdir/configure.frag $srcdir "$subdirs" "$dep_host_xma # Substitute configuration variables AC_SUBST(subdirs) -AC_SUBST(all_languages) AC_SUBST(all_boot_languages) AC_SUBST(all_compilers) -AC_SUBST(all_lang_makefiles) -AC_SUBST(all_stagestuff) AC_SUBST(all_diff_excludes) -AC_SUBST(all_lib2funcs) AC_SUBST(all_headers) +AC_SUBST(all_lang_makefiles) +AC_SUBST(all_languages) +AC_SUBST(all_lib2funcs) +AC_SUBST(all_stagestuff) +AC_SUBST(build_exeext) +AC_SUBST(build_install_headers_dir) +AC_SUBST(build_xm_file_list) +AC_SUBST(cc_set_by_configure) +AC_SUBST(quoted_cc_set_by_configure) +AC_SUBST(cpp_install_dir) AC_SUBST(cpp_main) -AC_SUBST(extra_passes) -AC_SUBST(extra_programs) -AC_SUBST(extra_parts) +AC_SUBST(dep_host_xmake_file) +AC_SUBST(dep_tmake_file) +AC_SUBST(extra_c_flags) AC_SUBST(extra_c_objs) +AC_SUBST(extra_cpp_objs) AC_SUBST(extra_cxx_objs) -AC_SUBST(extra_c_flags) +AC_SUBST(extra_headers_list) AC_SUBST(extra_objs) +AC_SUBST(extra_parts) +AC_SUBST(extra_passes) +AC_SUBST(extra_programs) +AC_SUBST(fixinc_defs) +AC_SUBST(float_h_file) +AC_SUBST(gcc_gxx_include_dir) +AC_SUBST(gcc_version) +AC_SUBST(gcc_version_trigger) +AC_SUBST(host_exeext) AC_SUBST(host_extra_gcc_objs) -AC_SUBST(extra_headers_list) -AC_SUBST(dep_host_xmake_file) -AC_SUBST(dep_tmake_file) -AC_SUBST(out_file) -AC_SUBST(out_object_file) -AC_SUBST(md_file) -AC_SUBST(tm_file_list) -AC_SUBST(build_xm_file_list) AC_SUBST(host_xm_file_list) -AC_SUBST(lang_specs_files) +AC_SUBST(install) +AC_SUBST(JAVAGC) AC_SUBST(lang_options_files) -AC_SUBST(thread_file) -AC_SUBST(gcc_version) -AC_SUBST(gcc_version_trigger) +AC_SUBST(lang_specs_files) +AC_SUBST(lang_tree_files) AC_SUBST(local_prefix) -AC_SUBST(gxx_include_dir) -AC_SUBST(fixincludes) -AC_SUBST(build_install_headers_dir) -AC_SUBST(build_exeext) -AC_SUBST(host_exeext) -AC_SUBST(float_format) -AC_SUBST(will_use_collect2) AC_SUBST(maybe_use_collect2) -AC_SUBST(cc_set_by_configure) +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(install) AC_SUBST(symbolic_link) -AC_SUBST(cpp_install_dir) +AC_SUBST(thread_file) +AC_SUBST(tm_file_list) +AC_SUBST(will_use_collect2) AC_SUBST_FILE(target_overrides) @@ -3735,7 +4403,7 @@ AC_SUBST_FILE(language_fragments) AC_SUBST_FILE(language_hooks) # Echo that links are built -if [[ x$host = x$target ]] +if test x$host = x$target then str1="native " else @@ -3743,25 +4411,25 @@ else str2=" from $host" fi -if [[ x$host != x$build ]] +if test x$host != x$build then str3=" on a $build system" fi -if [[ "x$str2" != x ]] || [[ "x$str3" != x ]] +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 [[ "x$str2" != x ]] || [[ "x$str3" != x ]] +if test "x$str2" != x || test "x$str3" != x then echo " ${str2}${str3}." 1>&2 fi # Truncate the target if necessary -if [[ x$host_truncate_target != x ]]; then +if test x$host_truncate_target != x; then target=`echo $target | sed -e 's/\(..............\).*/\1/'` fi @@ -3783,9 +4451,9 @@ esac # 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 [[ "$symbolic_link" = "ln -s" ]]; then +if test "$symbolic_link" = "ln -s"; then for d in .. ${subdirs} ; do - if [[ $d != .. ]]; then + if test $d != ..; then STARTDIR=`pwd` cd $d for t in stage1 stage2 stage3 stage4 include @@ -3797,6 +4465,11 @@ if [[ "$symbolic_link" = "ln -s" ]]; then 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 ], [ host='${host}' diff --git a/contrib/gcc/convert.c b/contrib/gcc/convert.c index e03d39b..bfcb5db 100644 --- a/contrib/gcc/convert.c +++ b/contrib/gcc/convert.c @@ -121,6 +121,14 @@ convert_to_integer (type, expr) int inprec = TYPE_PRECISION (intype); int outprec = TYPE_PRECISION (type); + /* An INTEGER_TYPE cannot be incomplete, but an ENUMERAL_TYPE can + be. Consider `enum E = { a, b = (enum E) 3 };'. */ + if (!TYPE_SIZE (type)) + { + error ("conversion to incomplete type"); + return error_mark_node; + } + switch (TREE_CODE (intype)) { case POINTER_TYPE: diff --git a/contrib/gcc/cp/ChangeLog b/contrib/gcc/cp/ChangeLog index 5102e32..82d1a8b 100644 --- a/contrib/gcc/cp/ChangeLog +++ b/contrib/gcc/cp/ChangeLog @@ -1,152 +1,5011 @@ -Sun Mar 14 02:38:07 PST 1999 Jeff Law (law@cygnus.com) +Mon Aug 16 01:29:24 PDT 1999 Jeff Law (law@cygnus.com) - * egcs-1.1.2 Released. + * gcc-2.95.1 Released. + +1999-08-12 Mark Mitchell + + * decl2.c (lang_decode_option): Deprecate signatures. + +1999-08-11 Martin v. Loewis + + * lex.c (do_identifier): If we find a hidden type after a global + was selected already, continue using the global. + +1999-08-10 Martin v. Loewis + + * decl2.c (set_decl_namespace): Do not complain about non-matching + decls if processing a template. + +1999-08-09 Jason Merrill + + * parse.y (function_try_block): Call end_protect_partials + before expand_start_all_catch. + +1999-08-06 Jason Merrill + + * pt.c (maybe_get_template_decl_from_type_decl): Make sure that + we're looking at a class. + + * decl.c (lookup_name_real): Set the complain flag if we're + looking for a namespace member. + + * decl.c (pushdecl): Only give an error for shadowing a parm + from *this* function. + + * decl2.c (build_expr_from_tree, case METHOD_CALL_EXPR): Only + build_expr_from_tree on the args of a TEMPLATE_ID_EXPR. + + * class.c (mark_overriders): Fix order of args to overrides. + (warn_hidden): Likewise. Fix for having virtual and non-virtual + functions with the same name. + + * cp-tree.h (DECL_VIRTUAL_CONTEXT): New macro. + * typeck.c (expand_ptrmemfunc_cst): Calculate delta correctly for + virtual functions and MI. Simplify. + + * typeck.c (c_expand_return): Downgrade pedwarn about returning NULL + from op new to warning. + + * decl2.c (reparse_absdcl_as_casts): Don't warn about old-style + casts in system headers or extern "C" blocks. + + * pt.c (do_decl_instantiation): Downgrade duplicate instantiation + errors to pedwarn. + + * error.c (dump_type_real): Handle TREE_LIST again. + + * typeck.c (comp_target_parms): Don't complain about + converting from () to (...) if !flag_strict_prototype. + + * class.c (instantiate_type): Downgrade errors for object-dependent + memfn refs to pedwarn. + +1999-08-06 Alexandre Oliva + + * pt.c (tsubst): Use build_index_type to build in-template array + index type. Fixes g++.oliva/dwarf1.C. + * decl.c (grokdeclarator): Likewise, just for consistency, as it + doesn't seem to trigger the bug without it. + +Thu Aug 5 02:40:42 1999 Jeffrey A Law (law@cygnus.com) + + * typeck2.c: Update URLs and mail addresses. + +1999-08-03 Mumit Khan + + * decl.c (start_decl): Set attributes before duplicate_decls call. + +Wed Jul 28 21:39:31 PDT 1999 Jeff Law (law@cygnus.com) + + * gcc-2.95 Released. + +Sun Jul 25 15:24:21 1999 Jeffrey A Law (law@cygnus.com) + + * g++FAQ.texi: Deleted per Joe Buck's request. + * Makefile.in: Corresponding changes. + +Sat Jul 17 23:50:47 1999 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (INTERFACE): Bump to 2. + +1999-07-17 Alexandre Oliva + + * typeck2.c (my_friendly_abort): Updated URL with bug reporting + instructions to gcc.gnu.org. Removed e-mail address. + +1999-07-15 Mark Mitchell + + * pt.c (check_default_tmpl_args): Handle friends defined in the + class just like member functions defined in the class. + +Thu Jul 15 01:26:49 1999 H.J. Lu + + * decl.c (duplicate_decls): Relax restriction for exception + checks on duplicate symbols. + +1999-07-07 Jason Merrill + + * decl.c (grokdeclarator): Update the names of all variants when + de-anonymizing. + +Wed Jul 7 01:26:47 1999 Alexandre Oliva + + * decl2.c (mark_vtable_entries): Fix check for rtti offset. + +1999-06-26 Richard Henderson + + * decl.c (cp_finish_decl): Fix typo in cp_warning_at call. + +1999-06-21 Mark Mitchell + + * init.c (expand_aggr_vbase_init): Rename to + construct_virtual_bases. Conditionalize construction here, + rather than ... + (emit_base_init): Here. + +1999-06-19 Mark Mitchell + + * semantics.c (finish_asm_statement): Apply decay conversions to + input operands. + + * decl.c (expand_static_init): When building an anonymous function + for use with atexit, compute its body before and after entering + the function. + +1999-06-18 Mark Mitchell + + * init.c (expand_aggr_vbase_init): Add flag parameter. + (build_partial_cleanup_for): Remove, inlining into .. + (expand_cleanup_for_base): ... here. Take flag parameter. + (emit_base_init): Pass the in_chrg parameter to + emit_aggr_vbase_init. + (emit_aggr_vbase_init): Pass it to expand_cleanup_for_base. + +1999-06-16 Mark Mitchell + + * decl2.c (import_export_decl): Use same_type_p, rather than + relying on pointer-equality for types. + + * method.c (do_build_copy_constructor): Simplify. + + * call.c (build_method_call): Remove bogus code for two-argument + delete. + * init.c (build_new_1): Expand on comment, and remove dead code. + + * init.c (expand_cleanup_for_base): New function, split out + from ... + (emit_base_init): Here. + (expand_aggr_vbase_init): Use it. + +1999-06-15 Mark Mitchell + + * cp-tree.h (class_cache_firstobj): Declare. + (maybe_push_cache_obstack): Rename to push_cache_obstack. + * class.c (permanent_obstack): Remove declaration. + (class_cache_firstobj): Make it global. + (add_method): Don't use permanent_obstack directly. + (pushclass): Only free the class_cache_obstack if we know how far + back to free it. + (maybe_push_cache_obstack): Rename to push_cache_obstack. + * decl.c: Remove dead comment. + (saved_scope): Add class_cache_firstobj. + (push_to_top_level): Save it. + (pop_from_top_level): Restore it. + (push_class_level_binding): Use push_cache_obstack, not + maybe_push_cache_obstack. + * search.c (push_class_decls): Likewise. + +1999-06-14 Nathan Sidwell + + * call.c (build_new_op): Remove REF_BIND from all operands. + +1999-06-07 Mark Mitchell + + * search.c (convert_pointer_to_single_level): Reimplement without + using get_binfo. + +1999-06-06 Mark Mitchell + + * method.c (is_back_referenceable_type): Back-reference bools when + not squangling. + +1999-06-04 Jason Merrill + + * semantics.c (finish_if_stmt_cond): Copy cond to permanent_obstack. + (finish_while_stmt_cond, finish_do_stmt, finish_for_cond): Likewise. + +1999-05-30 Mark Mitchell + + * lex.c (make_lang_type): Create TYPE_BINFO for + TEMPLATE_TYPE_PARMs just like for non-template types. + +1999-05-28 Nathan Sidwell + + * decl.c (complete_array_type): Allocate off same obstack. Fix + DO_DEFAULT comment to match reality. + +1999-05-22 Mark Mitchell + + * tree.c (mapcar): Handle NON_LVALUE_EXPR. + +1999-05-21 Mark Mitchell + + * typeck.c (build_ptrmemfunc): Handle PTRMEM_CSTs carefully to + reveal optimization opportunities. + +1999-05-20 Mark Mitchell + + * decl.c (grokdeclarator): Don't treat [] as indicating a + zero-sized array in a typedef. + + * call.c (build_object_call): Don't look at DECL_NAME for a type. + (pt.c): Or CP_TYPE_QUALS for an ERROR_MARK. + (typeck.c): Or TYPE_MAIN_VARIANT for a type. + +1999-05-20 Jason Merrill + + * tree.c (lvalue_p_1): A NOP_EXPR can be an lvalue. + (build_cplus_new): Make sure that what we return is of the right type. + +1999-05-20 Mark Mitchell + + * cp-tree.h (make_ptrmem_cst): New function. + * expr.c (cplus_expand_constant): Split out from ... + (cplus_expand_expr): Here. Use cplus_expand_constant. + (init_cplus_expand): Set lang_expand_constant. + * pt.c (convert_nontype_argument): Use make_ptrmem_cst. + * tree.c (make_ptrmem_cst): Define. + * typeck.c (unary_complex_lvalue): Use make_ptrmem_cst. + * typeck2.c (initializer_constant_valid_p): Use make_ptrmem_cst. + +1999-05-19 Mark Mitchell + + * decl2.c (start_static_storage_duration_function): Fix comment. + (finish_file): Create static storage duration functions lazily. + +Wed May 19 02:50:53 1999 Arvind Sankar + + * gxxint.texi: Fix typo. + +1999-05-18 Jason Merrill + + * call.c (joust): Compare the types of the conv ops, not the + target types of the conversions. + +Tue May 18 00:21:34 1999 Zack Weinberg + + * lang-specs.h: Define __GNUC__ and __GNUC_MINOR__ only if -no-gcc + was not given. + +1999-05-17 Mark Mitchell + + * cp-tree.def (TEMPLATE_ID_EXPR): Update documentation. + * decl.c (grokfndecl): Don't allow inline declarations of friend + template specializations, or friend template specializations with + default arguments. + * pt.c (tsubst): Handle substitution into array types that does + not yield a fixed upper bound, even when not processing a + template. + (tsubst_copy): Deal with the fact that the second operand to a + TEMPLATE_ID_EXPR may be NULL_TREE, a TREE_LIST, or a TREE_VEC. + * search.c (marked_pushdecls_p): Don't descend into + TEMPLATE_TYPE_PARMs and the like. + (unmarked_pushdecls_p): Likewise. + + * call.c (build_over_call): Don't throw away + initializations/copies of empty classes; use MODIFY_EXPR and + INIT_EXPR as for non-empty classes. + * class.c (finish_struct_1): Put the padding byte for an empty + class on the TYPE_NONCOPIED_PARTS list for the class. + +1999-05-16 Mark Mitchell + + * decl2.c (build_expr_from_tree): Handle COMPONENT_REFs that + indicate a reference to a field that is a qualified name. + +1999-05-16 Jason Merrill + + * decl2.c (finish_objects): Don't use .?tors.* if we don't have + ASM_OUTPUT_CONSTRUCTOR. + + * friend.c (do_friend): Add attrlist arg. Remove support for + getting a non-decl as 'decl'. + * decl.c (grokfndecl): Remove attrlist arg. Don't set attrs or + rtl. + (grokdeclarator): Adjust. + * cp-tree.h: Adjust. + +1999-05-16 Mark Mitchell + + * cp-tree.h (permanent_p): New function. + * init.c (build_new_1): Use mapcar, not copy_node, to copy a + possibly complex tree node. + * tree.c (mapcar): Adjust comments, and follow coding standards in + conditional. + (permanent_p): New function. + +1999-05-13 Per Bothner + + * class.c (push_lang_context): Turn off DECL_IGNORED_P for + primitive Java types, if we actually see `extern "Java"'. + +1999-05-10 18:21 -0400 Zack Weinberg + + * lang-specs.h: Pass -$ to the preprocessor. + +1999-05-10 Jason Merrill + + * init.c (build_offset_ref): Wrap baselinks in OFFSET_REF, too. + Don't bother wrapping an OFFSET_TYPE around unknown_type_node. + (resolve_offset_ref): Don't handle a raw baselink. + * cvt.c (build_expr_type_conversion): Likewise. + * typeck.c (decay_conversion, build_c_cast, convert_for_assignment, + convert_for_initialization): Likewise. + * class.c (instantiate_type): Handle seeing a baselink under an + OFFSET_REF. + * error.c (dump_expr): Likewise. + * pt.c (for_each_template_parm): Likewise. + (resolve_overloaded_unification): Likewise. + * tree.c (is_overloaded_fn, really_overloaded_fn): Likewise. + * typeck.c (expr_sizeof): Also complain about other permutations + of overloaded functions. + +1999-05-07 Jason Merrill + + * init.c (resolve_offset_ref): Don't return a raw method. + Use BASELINK_P. + * typeck.c (decay_conversion): Don't handle a raw method. + Resolve all OFFSET_REFs. + (get_member_function_from_ptrfunc): 0 is a valid vtable index. + (build_binary_op_nodefault): Handle resolving overloaded fns. Use + same_type_p for pmf bits. Don't use build_binary_op to compare + raw pointers to methods. + (convert_for_assignment): Check for OFFSET_REF, not OFFSET_TYPE, + to decide when to call resolve_offset_ref. + (build_c_cast, convert_for_initialization): Likewise. + * cvt.c (build_expr_type_conversion): Likewise. + +1999-05-06 Nathan Sidwell + + * call.c (build_new_method_call): Use TYPE_MAIN_VARIANT of class. + +1999-05-05 Mark Mitchell + + * decl2.c (start_objects): Don't let static constructors and + destructors get inlined. + + * parse.y (nested_name_specifier): Make sure ordinary types are + complete, just like template types. + * parse.c: Regenerated. + + * pt.c (check_explicit_specialization): Improve error messages. + +1999-05-04 Martin von Löwis + + * typeck.c (string_conv_p): Use same_type_p to check whether we + try to convert between char and wchar_t. + +1999-05-03 Mark Mitchell + + * search.c (lookup_field_r): Set the TREE_TYPE of an ambiguous + lookup to error_mark_node here. + (lookup_member): Revise documentation. Add comments. Don't set + the TREE_TYPE to error_mark_node here, and don't build up an extra + TREE_LIST for ambiguous lookups. + (setup_class_bindings): Adjust accordingly. + (push_class_decls): Revise out-of-date comments. + + * typeck.c (build_const_cast): Tighten checks for legality. + +1999-05-02 Martin von Löwis + + * init.c (build_member_call): Lookup names coming from + namespace-scoped LOOKUP_EXPR. + +1999-05-03 Jim Blandy + + * gxxint.texi: Add documentation for 'I'. + +1999-05-02 Martin von Löwis + + * tinfo.cc (operator==): Qualify type_info with std::. + +1999-05-02 Mark Mitchell + + * cp-tree.h (lang_decl_flags): Remove comdat. Updated dummy. + (DECL_COMDAT): Remove definition. + +1999-05-01 Mark Mitchell + + * decl.c (wrapup_globals_for_namespace): Fix thinko in previous + change. + +1999-04-30 Mark Mitchell + + * class.c (build_vtable): Use build_lang_decl when building + vtables, not just build_decl. + (prepare_fresh_vtable): Likewise. + * decl.c (wrapup_globals_for_namespace): Mark vtables as + DECL_EXTERNAL when calling wrapup_global_declarations. + * decl2.c (priority_info_s): Add initializations_p and + destructions_p members. + (finish_vtable_vardecl): Use TREE_SYMBOL_REFERENCED, not TREE_USED, + when deciding what vtables to write out. + (ssdf_decls): New variable. + (ssdf_decls_used): Likewise. + (start_static_storage_duration_function): Deal with being called + multiple times. Avoid inlining this function. + (generate_inits_for_priority): Deal with reuse of priority map. + (get_priority_info): Clear initializations_p and destructions_p. + (do_static_initialization): Tweak comment. + (do_static_destruction): Likewise. Fix condition on sentries for + destruction. + (generate_ctor_or_dtor_function): Call all of the static storage + duration functions. + (generate_ctor_or_dtor_function_for_priority): Check + initializations_p and destructions_p to see what priorities need + initialization functions. + (finish_file): Rework to generate multiple static storage duration + functions, rather than just one. + + * typeck.c (build_const_cast): Tweak last change to handle + templates correctly. + + * typeck.c (build_const_cast): Disallow use of const_cast to + anything but a pointer or reference type. + +1999-04-30 Nathan Sidwell + + * decl.c (cp_finish_decl): Don't permit arrays of abstract or + signature type. + +1999-04-29 Mark Mitchell + + * decl2.c (do_static_destruction): Remove obsolete FIXME comment. + (finish_file): Indent comments properly. + +1999-04-29 Richard Henderson + + * decl2.c (do_static_initialization): Call do_pending_stack_adjust. + (do_static_destruction): Likewise. + +1999-04-29 Nathan Sidwell + + * cp-tree.h (TYPE_NOTHROW_P): New macro. + * decl2.c (delete_sanity): Warn on deleting void *. + * init.c (build_new_1): Use TYPE_NOTHROW_P. + * typeck.c (c_expand_return): cp_pedwarn on returning NULL from + throwing operator new. + +1999-04-28 Nathan Sidwell + + * cp-tree.h (build_component_addr): Remove prototype. + * typeck.c (build_component_addr): Make static. Remove MSG + argument. + (build_component_addr): Remove MSG parameter, clean up + comment. + (build_x_function_call): Use cp_error. + (build_unary_op): Adjust call of build_component_addr. + +1999-04-28 Mark Mitchell + + * pt.c (tsubst_friend_class): Check for NULL. + +Wed Apr 28 11:42:22 1999 Andreas Schwab + + * search.c (binfo_for_vtable): Initialize bfvi.var. + +1999-04-27 Nathan Sidwell + + * rtti.c (build_x_typeid): Check rtti is enabled. + +1999-04-26 Mark Mitchell + + * search.c (is_subobject_of_p): Make sure we're looking at the + right baseclasses. + +1999-04-26 Marc Espie + + * Make-lang.in (cplib2.ready): Don't depend on phony targets. + +1999-04-23 Mark Mitchell + + * decl2.c (finish_file): Tweak handling of extern inlines so that + they are not unnecessarily put out. + + * search.c (is_subobject_of_p): Handle TEMPLATE_TYPE_PARMs and + such as base classes. + +1999-04-22 Brendan Kehoe + + * tree.c (build_exception_variant): Fix typo: use the chain of U, + not trying V, while cycling through U. + +1999-04-22 Mark Mitchell + + * cp-tree.h (lang_decl_flags): Remove returns_first_arg and + preserves_first_arg. Enlarge dummy accordingly. + (DECL_TINFO_FN_P): New macro. + (SET_DECL_TINFO_FN_P): Likeiwse. + (DECL_RETURNS_FIRST_ARG): Remove. + (DECL_PRESERVES_THIS): Likewise. + (DECL_INIT_PRIORITY): New macro. + (finish_struct_1): Change prototype. + (cat_namespace_levels): Remove prototype. + (vtable_decl_p): New prototype. + (vtype_decl_p): Likewise. + (sigtable_decl_p): Likewise. + (walk_globals_pred): New typedef. + (walk_globals_fn): Likewise. + (walk_globals): New prototype. + (walk_namespaces_fn): New typedef. + (walk_namespaces): New prototype. + (wrapup_globals_for_namespace): Likewise. + (walk_vtables): Remove prototype. + (walk_sigtables): Likewise. + (instantiate_pending_templates): New prototype. + * class.c (finish_struct_1): Don't return a value. + * decl.h (pending_statics): Remove declaration. + * decl.c (walk_namespaces_r): New function. + (walk_globals_r): Likewise. + (vtable_decl_p): Likewise. + (vtype_decl_p): Likewise. + (sigtable_decl_p): Likewise. + (walk_namespaces): Likewise. + (walk_globals_data): New type. + (walk_globals): New function. + (wrapup_globals_for_namespace): Likewise. + (expand_static_init): Remove assertion. Remove redundancy in + conditional. Don't put static data members in static_aggregates + Tidy. + (finish_function): Remove redundancy in conditional. Don't set + DECL_RETURNS_FIRST_ARG. + (cat_namespace_levels): Remove. + * decl2.c: Include splay-tree.h and varray.h. + (priority_info_s): New structure. + (finish_vtable_vardecl): Change prototype. Adjust for new calling + conventions. + (prune_vtable_vardecl): Likewise. + (finish_sigtable_vardecl): Likewise. + (setup_initp): Remove. + (do_dtors): Remove. + (do_ctors): Remove. + (start_static_storage_duration_function): New function. + (generate_inits_for_priority): Likewise. + (finish_static_storage_duration_function): Likewise. + (get_priority_info): Likewise. + (do_static_initialization): Likewise. + (do_static_destruction): Likewise. + (do_static_initialization_and_destruction): Likewise. + (generate_ctor_or_dtor_function): Likewise. + (generate_ctor_and_dtor_functions_for_priority): Likewise. + (pending_statics): Make it a varray. + (pending_statics_used): New variable. + (saved_inlines): Make it a varray. + (saved_inlines_used): New variable. + (finish_static_data_member): Change method of updating + pending_statics. + (mark_inline_for_output): Remove #if 0'd code. Change method of + updating saved_inlines. + (walk_vtables): Remove. + (walk_sigtables): Likewise. + (import_export_decl): Use DECL_TINFO_FN_P. + (pending_templates): Remove declaration. + (maybe_templates): Likewise. + (static_aggregates_initp): Likewise. + (setup_initp): Likewise. + (finish_objects): Simplify. + (INITIALIZE_P_IDENTIFIER): New macro. + (PRIORITY_IDENTIFIER): New macro. + (SSDF_IDENTIFIER): New macro. + (initialize_p_decl): New variable. + (priority_decl): Likewise. + (ssdf_decl): Likewise. + (priority_info_map): Likewise. + (finish_file): Recode output of static intializers and other + file-scope finalization tasks. + * error.c (OB_END_TEMPLATE_ID): New macro. + (dump_type_real): Use it. + (dump_decl): Likewise. + (dump_function_name): Likewise. + * lex.c (set_typedecl_interface_info): Adjust for new walk_globals + interface. + (check_newline): Use walk_globals, not walk_vtables. + * pt.c (pending_tempalte_expansions): Remove. + (set_vardecl_interface_info): Likewise. + (pending_templates): Make static. + (maybe_templates): Likewise. + (instantiate_class_template): Adjust call to finish_struct_1. + (instantiate_pending_templates): New function. + * rtti.c (get_tinfo_fn): Use SET_DECL_TINFO_FN_P. + * tree.c (static_aggregates_initp): Remove. + (cp_valid_lang_attribute): Don't use it; use DECL_INIT_PRIORITY + instead. + * Makefile.in (decl2.o): Depend on varray.h and splay-tree.h. + + * gxx.gperf (RETURN): Rename to RETURN_KEYWORD to avoid clashes + with the RTL code RETURN. + * hash.h: Regenerated. + * lex.c (reinit_parse_for_block): Use RETURN_KEYWORD. + * parse.y: Replace RETURN with RETURN_KEYWORD throughout. + * parse.c: Regenerated. + * pt.c: Include varray.h. Include rtl.h since varray.h requires + it. + (inline_parm_levels): New variable. + (inline_parm_levels_used): Likewise. + (maybe_begin_member_template_processing): Update them. + (maybe_end_member_template_processing): Use them, rather than + guessing how many levels to pop. + + * decl.c (make_typename_type): Tighten error-checking. + +1999-04-20 Mark Mitchell + + * cp-tree.h (build_binary_op): Remove unneeded parameter. + * class.c (build_vrable_entry_ref): Adjust call to + build_binary_op. + * decl.c (expand_static_init): Likewise. + (grokdeclarator): Likewise. + (finish_function): Likewise. + * decl2.c (delete_sanity): Likewise. + (do_dtors): Likewise. + (do_ctors): Likewise. + * error.c (dump_type_suffix): Likewise. + * expr.c (cplus_expand_expr): Likewise. + * init.c (resolve_offset_ref): Likewise. + (build_new): Likewise. + (build_new_1): Likewise. + (build_vec_delete_1): Likewise. + (expand_vec_init_catch_clause): Likewise. + (build_delete): Likewise. + * pt.c (tsubst): Likewise. + * rtti.c (synthesize_tinfo_fn): Likewise. + * search.c (expand_upcast_fixups): Likewise. + (expand_direct_vtbls_init): Likewise. + * typeck.c (get_member_function_from_ptrfunc): Likewise. + (build_binary_op_nodefault): Likewise. + (point_int_sum): Likewise. + (pointer_diff): Likewise. + (build_unary_op): Likewise. + (build_modify_expr): Likewise. + (get_delta_difference): Likewise. + (build_ptrmemfunc): Likewise. + (expand_ptrmemfunc_cst): Likewise. + +1999-04-20 Jason Merrill + + * decl.c (grokfndecl): Always call cplus_decl_attributes. + * decl2.c (grokfield): Pass attrlist to grokdeclarator. + +1999-04-19 Mark Mitchell + + * cp-tree.h (finish_static_data_member_decl): New function. + * decl2.c (finish_static_data_member_decl): Split out from ... + (grokfield): Here. + * pt.c (instantiate_class_template): Use it here instead of + trying to fake it. + (tsubst_decl): Don't set DECL_ASSEMBLER_NAME; + finish_static_data_member_decl will do that. Explicit set + DECL_EXTERNAL to match non-template processing. + +1999-04-18 Mark Mitchell + + * cp-tree.h (finish_class_definition): Add parameter. + * parse.y (structsp): Use it. Don't call pop_scope here. + * parse.c: Regenerated. + * semantics.c (finish_class_definition): Pop it here. + +1999-04-17 Mark Mitchell + + * decl.c (xref_tag): Revise handling of nested template + declarations. + * pt.c (check_explicit_specialization): Tweak handling of friend + templates in template classes. + (tsubst_friend_class): Handle friend declarations for nested + member template classes. + +1999-04-16 Mark Mitchell + + * class.c (finish_struct): Remove unused variable. + (pushclass): Likewise. + (invalidate_class_lookup_cache): Likewise. + * cp-tree.def (TYPENAME_TYPE): Improve documentation. + * decl.c (build_typename_type): Make sure TYPENAME_TYPE_FULLNAME + doesn't get obliterated. + (make_typename_type): Handle template classes correctly. + + * cp-tree.h (TREE_NONLOCAL_FLAG): Remove. + (storetags): Declare. + * class.c (finish_struct): Don't use TREE_NONLOCAL_FLAG. + (pushclass): Likewise. Use storetags to install tag declarations, + not pushtag. + (invalidate_class_lookup_cache): Don't use TREE_NONLOCAL_FLAG. + * decl.c (storetags): Make it global. + (push_class_binding): Set INHERITED_VALUE_BINDING_P for an + implicit typename declaration. + (pushtag): Tidy. Don't use TREE_NONLOCAL_FLAG. + * method.c (hack_identifier): Likewise. + * search.c (lookup_member): Likewise. + + * decl.c (warn_about_implicit_typename_lookup): New function. + (lookup_name_real): Use it. Rework handling of implicit typename + extension. + +1999-04-15 Mark Mitchell + + * cp-tree.h (lookup_nested_field): Remove. + * class.c (push_nested_class): Handle UNION_TYPEs. + (pop_nested_class): Likewise. + * decl.c (lookup_name_real): Don't call lookup_nested_field. + (start_decl): Use push_nested_class, not just pushclass. + (cp_finish_decl): Use pop_nested_class, not just popclass. + * search.c (lookup_nested_field): Remove. + + * cp-tree.h (lang_type): Add documentation. + * decl2.c (handle_class_head): Create template declarations here, + as appropriate. + * parse.y (class_head): Return whether or not we entered a new + scope, as well as the type named. + (named_class_head): Likewise. + (named_complex_class_head_sans_basetype): Likewise. + (structsp): Adjust accordingly. Pop scope when required. + * parse.c: Regenerated. + * pt.c (check_default_tmpl_args): Robustify. + (redeclare_class_template): Likewise. + (instantiate_class_template): An instantiation of an + anonymous union is itself an anonymous union. + * semantics.c (begin_class_definition): Don't create template + declarations here. + +1999-04-15 Jason Merrill + + * parse.y (after_type_declarator_intern): New nonterminal. + (after_type_declarator): Use it. + (direct_after_type_declarator): Likewise. Move above + nonnested_type to fix reduce/reduce conflict resolution. + (declmods): Reducing from just 'attributes' has EMPTY precedence. + * Makefile.in (CONFLICTS): Update. + + * decl.c (define_label): Downgrade error for jumping over a + non-POD decl to pedwarn. + +1999-04-14 Mark Mitchell + + * cp-tree.h (popclass): Change declaration. + (pop_nested_class): Likewise. + (poplevel_class): Remove declaration. + * call.c (convert_default_argument): Pass no arguments to + popclass. + * class.c (finish_struct_1): Likewise. + (finish_struct): Likewise. + (popclass): Remove argument. Simplify code accordingly. + (pop_nested_class): Likewise. + * decl.c (poplevel_class): Declare it here, and make it static. + (poplevel): Handle class scopes. + (poplevel_class): Don't take an rgument. Simplify. + (pop_everything): Pass no arguments to pop_nested_class. + (cp_finish_decl): Pass no arguments to popclass. + (grokdeclarator): Pass no arguments to pop_nested_class. + (finish_function): Likewise. + * decl2.c (grokfield): Likewise. + (pop_scope): Pass no arguments to popclass. + * lex.c (do_pending_defargs): Pass no arguments to pop_nested_class. + * pt.c (instantiate_class_template): Move call to pushclass, and + document. Pass no arguments to popclass. + (regenerate_decl_from_template): Likewise. + +1999-04-14 Jason Merrill + + * typeck.c (build_unary_op): Handle taking the address of a unique + bound non-static member function. + +1999-04-13 Martin von Loewis + + * lang-options.h (-Wdeprecated): New flag. + * decl2.c (warn_deprecated): New flag. + (lang_decode_option): Deprecated this-is-variable, + external-templates, alt-external-templates. + Support -Wdeprecated. + * errfn.c (cp_deprecated): New function. + +1999-04-13 Jason Merrill + + * decl2.c (setup_initp): Compare DECL_ASSEMBLER_NAME instead + of the decls themselves. + + * pt.c (tsubst_function_type): Copy attributes over. + + * tree.c (cp_valid_lang_attribute): New fn. Handle init_priority + and com_interface. + * cp-tree.h: Add prototype. + * decl.c (init_decl_processing): Set valid_lang_attribute. + +1999-04-13 Mark Mitchell + + * class.c (finish_struct_1): Look at the const-ness of the field's + type, not the TREE_READONLY-ness of the declaration. + * method.c (synthesize_method): Likewise. + * pt.c (tsubst_decl): Call c_apply_type_quals_to_decl when + creating new declarations. + +1999-04-13 Mike Stump + + * decl2.c (import_export_decl): Because vtables always reference + virtual functions, even if they are inlined, don't allow + -fno-implement-inlines to not emit them, instead, emit them with + the vtable. + * decl.c (start_function): Likewise. + +1999-04-12 Jason Merrill + + * cp-tree.h (struct lang_type): Add com_interface. + (CLASSTYPE_COM_INTERFACE): New macro. + * class.c (set_rtti_entry): COM interface classes have no RTTI + entries in their vtables; adjust. + (add_virtual_function, finish_base_struct, skip_rtti_stuff, + modify_one_vtable, fixup_vtable_deltas1, override_one_vtable, + finish_struct_1): Likewise. + * decl2.c (mark_vtable_entries): Likewise. + * rtti.c (build_headof, get_tinfo_fn_dynamic): Likewise. + * search.c (get_abstract_virtuals_1, get_abstract_virtuals, + expand_upcast_fixups): Likewise. + * tree.c (debug_binfo): Likewise. + + * cp-tree.h (COMPARE_NO_ATTRIBUTES): New macro. + * typeck.c (comptypes): If we get it, ignore attributes. + * class.c (instantiate_type): Use BASELINK_P. Change complain + parameter to flags; 2 means ignore attributes. + * call.c (build_op_delete_call): Pass it. + + * decl.c (xref_tag): Only complain once about using a typedef-name + with 'struct'. Downgrade to pedwarn. + + * decl.c (grokdeclarator): Allow [] syntax for zero-length array. + + * parse.y (absdcl_intern): New nonterminal. + (absdcl, direct_abstract_declarator): Use it. + + * pt.c (lookup_template_class): Look through implict typename. + +1999-04-11 Mark Mitchell + + * friend.c (add_friend): Deal gracefully with error_mark_node. + * method.c (build_overload_value): Handle pointers-to-members as + template parameters. + + * decl.c (push_binding): Fix typo in comment. + +1999-04-10 Mark Mitchell + + * error.c (dump_type_real): If a typename is a template-id, put + out the template arguments. + (dump_expr): Handle TEMPLATE_ID_EXPR. + * pt.c (lookup_template_class): Now that full arguments are + available everywhere, remove code that tried to guess them. + +1999-04-09 Mark Mitchell + + * decl.c (make_typename_type): Complain if we don't find a type + when trying to make a typename type for a non-template type. + +1999-04-09 Jason Merrill + + * decl.c (start_decl): Pass attributes to grokdeclarator. + (grokdeclarator): Handle attributes on constructor-syntax + initializers. + +1999-04-08 Mark Mitchell + + * error.c (dump_expr): Don't crash on INDIRECT_REFs whose operands + don't have types. + + * search.c (template_self_reference_p): Tweak. + +1999-04-07 Mark Mitchell + + * init.c (build_offset_ref): Don't build yet another weird data + structure to describe overloaded functions. + +1999-04-06 Mark Mitchell + + * cp-tree.h (BASELINK_P): New macro. + (SET_BASELINK_P): Likewise. + * init.c (build_member_call): Remove needless assignment in if + statement. + * search.c (lookup_field_r): Fix handling when we are looking + specifically for a type; these are not hidden by functions and + variables. + (lookup_member): Use SET_BASELINK_P. + * tree.c (is_overloaded_fn): Use BASELINK_P. + (really_overloaed_fn): Likewise. + (get_first_fn): Likewise. + +1999-04-05 Mark Mitchell + + * decl.c (lookup_name_current_level): Tweak, and improve + documentation. + + * class.c (maybe_fixup_vptrs): Remove declaration. + (build_class_init_list): Likewise. + * decl.c (pushdecl_class_level): Call check_template_shadow here + ... + (push_class_level_binding): ... not here. + * search.c (dfs_push_type_decls): Only avoid + template-self-reference TYPE_DECLs if they are from base classes. + +1999-04-04 Mark Mitchell + + * pt.c (check_template_shadow): Don't treat OVERLOADs as _DECL + nodes. Tidy. + +1999-04-03 Jason Merrill + + * class.c (maybe_fixup_vptrs, build_class_init_list): Lose. + (finish_struct_1): Don't call build_class_init_list. + +1999-04-02 Mark Mitchell + + * tinfo.h (__class_type_info): Fix illegal declaration. + + * cp-tree.def (TEMPLATE_ID_EXPR): Update comment. + * cp-tree.h (INHERITED_VALUE_BINDING_P): New macro. + (IDENTIFIER_CLASS_VALUE): Improve documentation. + (is_properly_derived_from): Declare. + (invalidate_class_lookup_cache): Likewise. + (maybe_maybe_note_name_used_in_class): Likewise. + (note_name_declared_in_class): Likewise. + (push_using_decl): Remove duplicate declaration. + (id_in_current_class): Remove declaration. + (push_class_binding): Change prototype. + (clear_identitifer_class_values): Declare. + * call.c (is_properly_derived_from): Make it global. + (build_new_function_call): Be careful about updating candidates. + (build_new_method_call): Handle COMPONENT_REFs. Don't crash when + asked to make illegal calls. + * class.c: Include splay-tree.h. + (class_stack_node): Add names_used slot. + (check_member_decl_is_same_in_complete_scope): Remove. + (add_method): Fix comment. Push the declaration into class + scope. + (finish_struct_1): When popping the class, pop the bindings too. + Remove check for data member/function member conflict. + (finish_struct): Remove calls to + check_member_decl_is_same_in_complete_scope. Change calls to + popclass. + (pushclass): Clear names_used in the class stack entry. + Use invalidate_class_lookup_cache to remove cached entries, rather + than magic values with popclass. Clear IDENTIFIER_CLASS_VALUE + before entering a new class. Remove dead code. Don't mess with + current_function_decl when pushing declarations. + (invalidate_class_lookup_cache): New function, split out from ... + (popclass): Here. Clean up names_used on our way out. + (instantiate_type): Adjust. + (build_self_reference): Don't push the declaration here. + (maybe_note_name_used_in_class): New function. + (note_name_declared_in_class): Likewise. + * decl.c (add_binding): Change prototype. + (find_class_binding_level): New function. + (innermost_nonclass_level): Likewise. + (current_binding_level): Update documentation. + (inner_binding_level): Remove. Replace with current_binding_level + throughout. + (push_binding_level): Remove special handling of + class_binding_level. + (pop_binding_level): Likewise. Use find_class_binding_level. + (suspend_binding_level): Likewise. + (global_bindings_p): Use innermost_nonclass_level. + (toplevel_bindings_p): Likewise. + (namespace_bindings_p): Likewise. + (pseudo_global_level_p): Likewise. + (push_binding): Clear INHERITED_VALUE_BINDING_P. + (add_binding): Check for illegal multiple declarations. Return a + value indicating whether or not the new binding was legal. + (push_local_binding): Skip over class binding levels. Check + return value from add_binding. + (push_class_binding): Set INHERITED_VALUE_BINDING_P. Call + note_name_declared_in_class. + (pushlevel_class): Remove "fake out the rest of the compiler" + code. + (poplevel_class): Reset IDENTIFIER_CLASS_VALUEs. + (clear_identifier_class_values): New function. + (pop_from_top_level): Use it. + (pop_everything): Tweak. + (maybe_process_template_type_declaration): Don't push the + declaration for the template here. + (pushtag): Don't push tag declarations into class scope here. + (pushdecl): Apply DeMorgan's law for readability. + (pushdecl_class_level): Remove special-case code for + TYPE_BEING_DEFINED. Handle OVERLOADs and anonymous unions. + (push_class_level_bindng): Deal with inherited bindings. + (lookup_name_real): Remove special-case code for + TYPE_BEING_DEFINED, and some implicit typename magic. + (grokdeclarator): Handle COMPONENT_REF for a template function. + (build_enumerator): Don't call pushdecl_class_level here. + (id_in_current_class): Remove. + * decl2.c (grokfield): Don't call pushdecl_class_level or + check_template_shadow. + * errfn.c (cp_file_of): Don't declare. + (cp_line_of): Likewise. + * error.c (dump_decl): Handle an OVERLOAD. + (cp_file_of): Likewise. + (cp_line_of): Likewise. + * init.c (build_member_call): Handle a COMPONENT_REF. + * lex.c (do_identifier): Call maybe_note_name_used_in_class, not + pushdecl_class_level. + * method.c (hack_identifier): Build COMPONENT_REFs for references + to member templates as well as member functions. Remove dead + code. + * parse.y (left_curly): Remove. + (nonnested_type): Call maybe_note_name_used_in_class, not + pushdecl_class_level. + * parse.c: Regenerated. + (nested_name_specifier_1): Likewise. + * pt.c (check_explicit_specialization): Adjust, for robustness. + (check_template_shadow): Handle OVERLOADs. + (build_template_decl): Set DECL_CONSTRUCTOR_P on the + TEMPLATE_DECL, if appropriate. + * search.c (envelope_add_decl): Remove. + (dfs_pushdecls): Likewise. + (dfs_compress_decls): Likewise. + (dfs_push_decls): New function. + (dfs_push_type_decls): Likewise. + (setup_class_bindings): Likewise. + (template_self_reference_p): Likewise. + (lookup_field_r): Use it. + (looup_member): Remove old comment. Deal with ambiguity. + (push_class_decls): Use dfs_push_decls and dfs_push_type_decls, + and remove envelope processing. + * semantics.c (begin_class_definition): Let pushclass push + declarations for base classes. + (finish_member_declaration): Push declarations into class scope. + * typeck.c (build_component_ref): Just put an OVERLOAD into the + COMPONENT_REF, not a TREE_LIST of an OVERLOAD. + (build_x_function_call): Deal with OVERLOAD. Handle template-ids. + * Makefile.in (class.o): Depend on splay-tree.h. + +Wed Mar 31 11:30:43 1999 Nathan Sidwell + + * cvt.c (convert_pointer_to_real): Use same_type_p. + * typeck.c (comp_target_types): Use same_type_p. + +1999-03-31 Jason Merrill + + * semantics.c (begin_inline_definitions, + finish_inline_definitions): Rename from finish_default_args and + begin_inline_definitions, respectively, to something that isn't a + total lie. :) + * parse.y (structsp): Adjust. + + * tree.c (hash_tree_cons): Remove obsolete via_* parms. + (list_hash_lookup): Likewise. + (hash_tree_chain): Adjust. + * pt.c (tsubst): Adjust. + (tsubst_arg_types): Use plain hash_tree_cons. + * cp-tree.h (hash_tree_cons_simple): Lose. + * parse.y (declmods, nonempty_cv_qualifiers): Use hash_tree_cons. + +Wed Mar 31 10:48:29 1999 Kaveh R. Ghazi + + * Makefile.in (hash.h): Generate using gperf language 'C', not + 'KR-C', so gperf uses the `const' keyword on strings. + + * gxx.gperf (resword): Const-ify a char*. + +1999-03-30 Jason Merrill + + * cp-tree.h (IDENTIFIER_AS_DESC, IDENTIFIER_AS_LIST, + CLASSTYPE_BASELINK_VEC, CLASSTYPE_N_SUPERCLASSES, + CLASSTYPE_N_BASECLASSES, CLASSTYPE_MAX_DEPTH, + CLASSTYPE_BASE_INIT_LIST, CLASSTYPE_AS_LIST, CLASSTYPE_ID_AS_LIST, + CLASSTYPE_BINFO_AS_LIST): Remove cruft. + * class.c, lex.c, parse.y, ptree.c, search.c, semantics.c, + tree.c: Adjust. + +1999-03-29 Jason Merrill + + * decl2.c (lang_decode_option): Remove -Wsign-promo from -Wall. + +1999-03-28 Jason Merrill + + * pt.c (fn_type_unification): Ignore 'this' parm from conversion ops. + +1999-03-27 Mark Mitchell + + * cp-tree.h (add_friend): Declare. + (add_friends): Likewise. + * friend.c (add_friend): Make it global. Don't add to + DECL_BEFRIENDING_CLASSES if the befriending class is a template. + (add_friends): Make it global. + (make_friend_class): Don't add to DECL_BEFRIENDING_CLASSES if the + befriending class is a template. + * parse.y (component_decl_1): Fix typo in comment. + * parse.c: Regenerated. + * pt.c (instantiate_class_template): Use add_friend and + add_friends rather that duplicating some of their functionality + here. + +1999-03-27 Jason Merrill + + * call.c (build_field_call): Unify 'this' and non-'this' cases. + + * typeck.c (build_indirect_ref): Check for 'this' sooner. + +Fri Mar 26 10:20:34 1999 Kaveh R. Ghazi + + * call.c (op_error): Const-ify a char*. + (add_candidate, source_type, add_warning): Add static prototype. + (print_z_candidates): Const-ify a char*. + + * class.c (resolve_address_of_overloaded_function, + fixed_type_or_null, build_vtable_entry_ref): Add static prototype. + (get_vtable_name, finish_struct_1): Const-ify a char*. + + * cvt.c (convert_to_reference): Likewise. + + * decl.c (redeclaration_error_message, record_builtin_type, + record_unknown_type, member_function_or_else, bad_specifiers): + Likewise. + (find_binding, select_decl, unqualified_namespace_lookup, + lookup_flags, qualify_lookup, record_builtin_java_type, tag_name): + Add static prototype. + (warn_extern_redeclared_static, duplicate_decls, pushdecl, + implicitly_declare, record_builtin_java_type, define_function, + grok_op_properties, tag_name): Const-ify a char*. + + * cp-tree.h (FORMAT_VBASE_NAME): Allow parameter `BUF' to be const. + (define_function, finish_builtin_type): Const-ify a char*. + (cp_error, cp_error_at, cp_warning, cp_warning_at, cp_pedwarn, + cp_pedwarn_at, cp_compiler_error, cp_sprintf): Add prototype args. + (file_name_nondirectory): Const-ify a char*. + (init_filename_times): Don't prototype. + (compiler_error): Prototype. + (yyerror, init_repo): Const-ify a char*. + (build_srcloc): Don't prototype. + (build_x_indirect_ref, build_indirect_ref, build_component_addr): + Const-ify a char*. + (warn_for_assignment): Don't prototype. + (convert_for_initialization, readonly_error, check_for_new_type, + GNU_xref_begin, GNU_xref_file, GNU_xref_ref, GNU_xref_call): + Const-ify a char*. + + * decl2.c (acceptable_java_type, output_vtable_inherit, + setup_initp, start_objects, finish_objects, do_dtors, do_ctors, + merge_functions, decl_namespace, validate_nonmember_using_decl, + do_nonmember_using_decl): Add static prototype. + (lang_f_options): Const-ify a char*. + (finish_builtin_type): Likewise. + (add_function, arg_assoc_namespace, arg_assoc_class): Add static + prototype. + + * errfn.c: Include cp-tree.h. + (cp_thing): Add static prototype. + (compiler_error): Don't protoptype. + (cp_compiler_error): Cast `compiler_error' to `errorfn' before + passing it to `cp_thing'. + + * error.c (interesting_scope_p): Add static prototype. + + * except.c (build_eh_type_type, build_eh_type_type_ref): Const-ify + a char*. + + * init.c (compiler_error): Don't prototype. + (member_init_ok_or_else): Const-ify a char*. + (build_java_class_ref): Add static prototype. + + * lex.c (compiler_error): Don't prototype. + (get_time_identifier, interface_strcmp, extend_token_buffer, + handle_cp_pragma): Const-ify a char*. + (is_global, init_filename_times): Add static prototype. + (file_name_nondirectory, cplus_tree_code_name): Const-ify a char*. + (compiler_error): Change from fixed args to variable args. + (yyerror): Const-ify a char*. + + * parse.y (cond_stmt_keyword): Const-ify a char*. + (parse_decl): Add static prototype. + + * pt.c (template_args_equal, print_template_context): Likewise. + (print_candidates, check_default_tmpl_args): Const-ify a char*. + (instantiate_class_template): Likewise. + + * repo.c (get_base_filename, open_repo_file, init_repo): Likewise. + + * rtti.c (call_void_fn, expand_generic_desc, expand_si_desc, + expand_class_desc, expand_ptr_desc, expand_attr_desc): Likewise. + + * search.c (lookup_field_info, lookup_member): Likewise. + (lookup_member): Cast the first argument of `bzero' to a PTR. + + * sig.c (compiler_error): Don't prototype. + (build_signature_pointer_or_reference_nam): Const-ify a char*. + (get_sigtable_name, build_member_function_pointer): Likewise. + + * tree.c (compiler_error): Don't prototype. + (no_linkage_helper, build_srcloc): Add static prototype. + (build_vbase_pointer_fields): Const-ify a char*. + (__eprintf): Don't unnecessarily handle `const' when !__STDC__. + + * typeck.c (compiler_error): Don't prototype. + (convert_for_assignment): Const-ify a char*. + (comp_cv_target_types): Add static prototype. + (build_x_indirect_ref, build_indirect_ref, convert_arguments, + build_component_addr, build_unary_op, convert_for_initialization): + Const-ify a char*. + + * typeck2.c (ack): Add static prototype and change from fixed args + to variable args. + (readonly_error, check_for_new_type): Const-ify a char*. + + * xref.c (_XREF_FILE, find_file, filename, fctname, declname, + fixname, open_xref_file, classname, GNU_xref_begin): Likewise. + (GNU_xref_file): Likewise. Also use `xmalloc' instead of `malloc'. + (GNU_xref_end_scope, GNU_xref_ref, GNU_xref_decl, GNU_xref_call, + gen_assign, GNU_xref_member): Const-ify a char*. + +1999-03-25 Martin von Löwis + + * gxxint.texi: Remove old discussion on copying virtual bases. + +1999-03-25 Zack Weinberg + + * Make-lang.in: Remove all references to g++.o/g++.c. + Link g++ from gcc.o. + +1999-03-25 Jason Merrill + + * decl2.c (comdat_linkage): Treat vtables like functions. + +1999-03-25 Mark Mitchell + + * pt.c (tsubst_decl): tsubst into DECL_BEFRIENDING_CLASSES. + +1999-03-25 Nathan Sidwell + + * decl.c (init_decl_processing): Add `signed' type as a synonym + for `int'. + +1999-03-25 Jason Merrill + + * typeck.c (common_type): Handle cv-qual unification for pointers + to members. + + * decl.c (unqualified_namespace_lookup): Return error_mark_node + on error. + (lookup_name_real): Set LOOKUP_COMPLAIN when *not* parsing. + * lex.c (do_identifier): If we got error_mark_node, call + lookup_name again. + +1999-03-24 Martin von Löwis + + * class.c (finish_struct_1): Always reset TYPE_FIELDS for empty + classes. + +1999-03-24 Jason Merrill + + * decl.c (lookup_name_real): Do nested field lookup regardless of + TYPE_BEING_DEFINED. + +1999-03-24 Mark Mitchell + + * cp-tree.h (lang_type): Remove has_assignment and + has_real_assignment. Add befriending_classes. + (TYPE_HAS_ASSIGNMENT): Remove. + (TYPE_HAS_REAL_ASSIGNMENT): Likewise. + (CLASSTYPE_BEFRIENDING_CLASSES): New macro. + (lang_decl): Document. + (DECL_BEFRIENDING_CLASSES): New macro. + (FRIEND_NAME): Move declaration to more obvious location. + (FRIEND_DECLS): Likewise. + * class.c (finish_struct_1): Don't use TYPE_HAS_REAL_ASSIGNMENT. + * decl.c (duplicate_decls): Copy DECL_BEFRIENDING_CLASSES. + (fixup_anonymous_union): Don't use TYPE_HAS_ASSIGNMENT. + (grok_op_properties): Likewise. + * friend.c (is_friend): Use FRIEND_NAME and FRIEND_DECLS. + (add_friend): Likewise. Don't do weird things with assignment + operators. Update DECL_BEFRIENDING_CLASSES. + (add_friends): Don't do weird things with assignment operators. + (make_friend_class): Likewise. Update + CLASSTYPE_BEFRIENDING_CLASSES. + * pt.c (instantiate_class_template): Don't set + TYPE_HAS_ASSIGNMENT. + (tsubst_copy): Substitute the TREE_TYPE for more unary + expressions. + * ptree.c (print_lang_type): Don't look at TYPE_HAS_ASSIGNMENT. + * search.c (protected_accessible_p): New function. + (friend_accessible_p): Likewise. + (accessible_p): Use them. + +1999-03-23 Mark Mitchell + + * pt.c (convert_nontype_argument): Don't create things that aren't + PTRMEM_CSTs when applying a qualification conversion to a + PTRMEM_CST. + +1999-03-23 Mark Mitchell + + * Makefile.in (OBJS): Don't mention hash.o. + (OBJDEPS): Likewise. + +1999-03-23 Jason Merrill + + * decl2.c (finish_file): Set at_eof to 2 after expanding ctors. + * decl.c (expand_static_init): Make sure we don't add any after + then. + + * decl.c (cp_finish_decl): Move intelligence about handling + DECL_COMDAT for variables from here... + * decl2.c (comdat_linkage): ...to here. + (maybe_make_one_only): Tweak. + (import_export_decl): Call comdat_linkage for variables, too. + (finish_file): Handle template statics properly. + +1999-03-22 Mark Mitchell + + * cp-tree.h (TYPE_PTRMEMFUNC_P): Use TYPE_PTRMEMFUNC_FLAG. + Document internals of pointer-to-member-functions. + (DELTA2_FROM_PTRMEMFUNC): Make it call delta2_from_ptrmemfunc. + (PFN_FROM_PTRMEMFUNC): Likewise. + (build_type_conversion): Remove unused parameter. + (build_ptrmemfunc1): Declare. + (expand_ptrmemfunc_cst): New function. + (delta2_from_ptrmemfunc): Likewise. + (pfn_from_ptrmemfunc): Likewise. + * cvt.c (cp_convert_to_pointer): Remove unused parameter to + build_type_conversion. Use TYPE_PTRMEM_P for readability. + (convert_to_reference): Remove unused parameter to + build_type_conversion. + (ocp_convert): Likewise. + (build_user_type_conversion): Likewise. + * error.c (dump_expr): Handle NULL pointer-to-member functions. + * expr.c (cplus_expand_expr): Handle PTRMEM_CSTs for functions. + * method.c (build_overload_value): Don't go splitting CONSTRUCTORs + open when handling pointer-to-member functions. + * pt.c (convert_nontype_argument): Clean up error messages. Be + more stringent with pointers-to-members. + * typeck.c (build_ptrmemfunc1): Don't declare. Make it global. + (build_unary_op): Tidy ever-so-slightly. + (build_conditional_expr): Remove extra parameter to + build_type_conversion. + (build_ptrmemfunc): Build PTRMEM_CSTs if we know what function + we're using. + (expand_ptrmemfunc_cst): Define. + (delta2_from_ptrmemfunc): Likewise. + (pfn_from_ptrmemfunc): Likewise. + +1999-03-19 Mark Mitchell + + * init.c (build_member_call): Handle template-id expressions + correctly. + * typeck.c (build_x_function_call): Likewise. + +1999-03-19 Chip Salzenberg + + * friend.c (make_friend_class): Avoid core dump when + not-yet-defined friend type lacks TYPE_LANG_SPECIFIC(). + +1999-03-18 Jason Merrill + + * decl.c (start_function): Suppress normal linkage heuristics + for #pragma interface under MULTIPLE_SYMBOL_SPACES. + +1999-03-19 Alexandre Oliva + + * Make-lang.in: ($(INTL_TARGETS)): Depend on cp/parse.c. + ($(srcdir)/cp/parse.c): Moved from ../Makefile.in. + +1999-03-17 Martin von Löwis + + * parse.y (named_complex_class_head_sans_basetype): + Do not push a scope for error_mark_node. + (maybe_base_class_list): Likewise. + + * decl.c (start_decl): Check for error_mark_node as a type. + Detected by g++.brendan/array-refs.C. + (start_decl_1): Likewise. Detected by g++.bugs/900322_01.C. + (maybe_build_cleanup_1): Likewise. Detected by + g++.jason/incomplete1.C. + + * tree.c (build_dummy_object): Use void_zero_node instead of the + error_mark_node. + (is_dummy_object): Check for such a node. + Detected by g++.bob/inherit1.C + +1999-03-16 Jason Merrill + + * method.c (old_backref_index): Split out... + (flush_repeats): From here. Rename back from try_old_backref. + (build_mangled_name): Put back some old-style repeat handling. + +Mon Mar 15 21:57:16 1999 Kaveh R. Ghazi + + * lex.c: Don't include setjmp.h. + (parse_float): New static function. + (pf_args): New struct. + (real_yylex): Use them in call to `do_float_handler'. + +1999-03-15 Mark Mitchell + + * decl.c (xref_basetypes): Set CLASSTYPE_VBASECLASSES here. + * tree.c (layout_basetypes): Not here. + * search.c (dfs_search): Remove; no longer used. + +1999-03-12 Mark Mitchell + + * decl2.c (validate_nonmember_using_decl): Issue sensible + error-messages on bogus qualifiers. + +1999-03-14 Jason Merrill + + * call.c (add_function_candidate): Fix uninitialized variable. + + * Makefile.in (search.o): Add dependency on varray.h. + +1999-03-13 Jason Merrill + + * decl.c (duplicate_decls): Use same_type_p. + * method.c (try_old_backref): Renamed from flush_repeats. Use + same_type_p. Don't try to handle repeats. Return success. + (is_back_referenceable_type): Return 0 if TYPE_FOR_JAVA. Support + calls from old-style code, too. + (check_ktype): Use same_type_p. + (check_btype): Use same_type_p. Don't pull out TYPE_MAIN_VARIANT. + (build_qualified_name): Simplify logic. + (process_overload_item): Strip typedefs and quals at the top. + (build_mangled_name_for_type_with_Gcode): Remove call to + type_canonical_variant. + (build_mangled_name): Likewise. Remove support for old-style + repeats, which have been disabled since 2.7.2. Don't mess with + TREE_USED. + (build_decl_overload_real): Don't mess with TREE_USED. + +1999-03-13 Nathan Sidwell + + * error.c (cp_printers): Add 'F' escape character. + (dump_type_real): Remove TREE_LIST (fnargs) printing. + Functionality moved to dump_parameters. + (dump_type_suffix): Use dump_parameters and dump_exception_spec. + (dump_function_decl): Extend meaning of V parameter. Use + dump_parameters and dump_exception_spec. + (dump_parameters): New static function. + (dump_exception_spec): New static function. + (fndecl_as_string): Change argument semantics. Use + dump_function_decl directly. + + * sig.c (build_signature_table_constructor): Use cp_error. + +1999-03-13 Martin von Löwis + + * semantics.c (finish_switch_cond): Handle error cases gracefully. + Detected by g++.law/enum5.C. + + * typeck.c (build_modify_expr): Check for errors after resolving + offsets. Detected by g++.brendan/static1.C. + + * decl.c (complete_array_type): Ignore initial_value if it is an + error. Detected by g++.benjamin/17930.C. + + * typeck2.c (process_init_constructor): Return error if one argument + is in error. Detected by g++.benjamin/13478.C. + +1999-03-12 Martin von Löwis + + * decl.c (select_decl): Allow class templates when we need types. + * decl2.c (ambiguous_decl): Likewise. + +1999-03-12 Mark Mitchell + + * lex.c (do_identifier): Correct call to enforce_access. + * search.c (accessible_p): Tweak comment. + +1999-03-10 Mark Mitchell + + * semantics.c (begin_class_definition): Call build_self_reference. + (finish_member_declaration): Set DECL_CONTEXT for TYPE_DECLs. + + * search.c (assert_canonical_unmarked): Fix typo in prototype. + + * search.c (dfs_canonical_queue): New function. + (dfs_assert_unmarked_p): Likewise. + (assert_canonical_unmarked): Likewise. + (access_in_type): Use it. + (accessible_p): Likewise. Walk the whole tree when umarking. + + * sig.c (build_signature_table_constructor): Use accessible_p + instead of compute_access. + +1999-03-09 Jason Merrill + + * call.c (add_builtin_candidates): Handle overloaded conversion ops. + +1999-03-09 Mark Mitchell + + * cp-tree.h (flag_access_control): Declare. + (TREE_VIA_PPUBLIC): Document. + (DECL_NONSTATIC_MEMBER_P): New macro. + (enforce_access): Return an indication of whether or not access + was permitted. + (build_self_reference): Change prototype. + (compute_access): Replace with ... + (accessible_p): New function. + (dfs_walk): Change prototype. + (dfs_unmark): Likewise. + (markedp): Likewise. + * call.c (enforce_access): Use accessible_p. + * class.c (build_self_reference): Insert the declaration into the + list of members for this type, and make it public. + * decl.c (xref_basetypes): Avoid ill-timed recursion. + * init.c (build_offset_ref): Use lookup_member, not three separate + name-lookups. Call enforce_access rather than checking for + illegal accesses here. + (resolve_offset_ref): Likewise. + * lex.c (do_identifier): Likewise. + * method.c (hack_identifier): Likewise. + * parse.y (self_reference): Remove. + (opt_component_decl_list): Don't use it. + * parse.c: Regenerated. + * pt.c (print_candidates): Generalize to handle lists of + overloaded functions. + (instantiate_class_template): Don't rely on TREE_VIA_PRIVATE; it's + not set. + (get_template_base): Use new calling convention for dfs_walk. + * search.c: Include varray.h. Add prototypes. + (dfs_walk): Accept a data pointer to pass to the work functions. + All callers changed. All work functions changed. + (breadth_first_search): Rename to bfs_walk, and make consistent + with dfs_walk. + (dfs_walk_real): New function. + (canonical_binfo): New function. + (context_for_name_lookup): Likewise. + (shared_marked_p): Likewise. + (shared_unmarked_p): Likewise. + (lokup_field_queue_p): Likewise. + (lookup_field_r): Generalize to handle both functions and fields. + (lookup_field): Just call lookup_member. + (lookup_fnfields): Likewise. + (lookup_member): Move body of lookup_field here and generalize. + (dfs_accessible_queue_p): Likewise. + (dfs_accessible_p): Likewise. + (dfs_access_in_type): Likewise. + (access_in_type): Likewise. + (compute_access): Remove, and replace with ... + (accessible_p): New function. + (vbase_types): Remove. + (vbase_decl_ptr_intermediate): Likewise. + (vbase_decl_ptr): Likewise. + (vbase_init_result): Likewise. + (closed_envelopes): Likewise. + (bvtable): Likewise. + +1999-03-09 Jason Merrill + + * call.c (add_function_candidate): Check for proper number of args + before checking the validity of those args. + +1999-03-06 Jason Merrill + + * cp-tree.h (struct lang_type): Add anon_union field. + (ANON_UNION_TYPE_P): Use it instead of examining type. + (SET_ANON_UNION_TYPE_P): New macro. + * decl.c (check_tag_decl): Use it. + + * search.c (compute_access): Handle non-type contexts earlier, and + handle NULL_TREE. + + * tree.c (build_exception_variant): Use copy_to_permanent. + + * decl2.c (setup_initp): Give statics with no priority the default + priority here. + (do_dtors, do_ctors, finish_file): Remove special handling of + non-prioritized statics. + +1999-03-05 Mark Mitchell + + * cp-tree.h (ANON_UNION_TYPE_P): Robustify. + * decl.c (make_typename_type): Don't issue an error if an + immediate lookup fails; it migt be resolved later. + * friend.c (is_friend): Add comment. + * search.c (breadth_first_search): Add POSTFN and DATA + parameters. Tidy. All callers changed. + (lookup_field_queue_p): New function. + (lookup_field_r): Likewise. + (lookup_field_post): Likewise. + (lookup_field): Use them, via breadth_first_search, instead of + duplicating logic. + (compute_access): Robustify. + (lookup_fnfield_info): New structure. + +1999-03-05 Jason Merrill + + * pt.c (tsubst, case ARRAY_REF): Use tsubst_expr again. + +1999-03-03 Jason Merrill + + * class.c, decl2.c, method.c, pt.c: Add 'static' to make SunOS 4 + cc happy. + + * decl2.c (import_export_class): Also return if + CLASSTYPE_INTERFACE_ONLY is set. + +1999-03-03 Martin von Löwis + + * decl.c (push_overloaded_decl): Only overwrite the old binding if + there was one. + * decl2.c (do_local_using_decl): Fix loop termination. + +1999-03-02 Mark Mitchell + + * cp-tree.h (determine_specialization): Don't declare. + * pt.c (determine_specialization): Make it static. Eliminate + complain parameter. Note that decl is always non-NULL now, and + simplify accordingly. + + * decl.c (maybe_push_to_top_level): Always call + push_cp_function_context. + (pop_from_top_level): Always call pop_cp_function_context. + +1999-02-26 Nathan Sidwell + + * typeck.c (complete_type_or_else): Add VALUE arg, for helpful + diagnostics. + * cp-tree.h (complete_type_or_else): Added VALUE parameter. + * init.c (build_new_1): Extra arg to complete_type_or_else. + (build_delete): Likewise. + * typeck.c (require_complete_type): Likewise. + (pointer_int_sum): Likewise. + (pointer_diff): Likewise. + (build_component_ref): Likewise. + + * typeck2.c (incomplete_type_error): Always use cp_error. + Show declaration of undefined type, if appropriate. + Deal with UNKNOWN_TYPE nodes. + + * typeck.c (require_complete_type): Use TYPE_SIZE as + size_zero_node to mean incomplete type. + (require_complete_type_in_void): New function. + (build_compound_expr): Call complete_type_in_void for LHS. + (build_c_cast): Call complete_type_in_void for void cast. + * cvt.c (ocp_convert): Call complete_type_in_void for void cast. + * decl.c (cplus_expand_expr_stmt): Void expression checks moved to + require_complete_type_in_void. Call it. + * cp-tree.h (require_complete_type_in_void): Prototype new function. + + * typeck.c (convert_arguments): Use alternative format for + function decls. Don't require_complete_type here. Simplify + diagnostic printing. + (convert_for_initialization): Don't require_complete_type on RHS yet. + * call.c (convert_arg_to_ellipsis): Call require_complete_type. + + * call.c (build_over_call): Cope with qualified void return type. + * semantics.c (finish_call_expr): Likewise. + * typeck.c (build_function_call_real): Likewise. + (c_expand_return): Likewise. + * decl2.c (reparse_absdcl_as_expr): Cope with qualified void type. + + * call.c (print_z_candidates): Use alternate print format, to be + consistent with (pt.c) print_candidates. + * method.c (hack_identifier): List candidate members. + * search.c (lookup_field): Build ambiguous list, and show it, if + ambiguous. + +1999-02-26 Mark Mitchell + + * typeck.c (decay_conversion): Don't confuse constant array + variables with their initializers. + + * decl.c (duplicate_decls): Copy DECL_TEMPLATE_INSTANTIATED when + merging decls. + * pt.c (regenerate_decl_from_template): Tweak for clarity. + (instantiate_decl): Mark a decl instantiated before regenerating + it to avoid recursion. + * tree.c (mapcar): Don't call decl_constant_value unless we know + something is TREE_READONLY_DECL_P. + + * class.c (check_for_override): Don't stop checking when we find + the first overridden function. Delete #if 0'd code. + * search.c (get_matching_virtual): Likewise. + +1999-02-25 Richard Henderson + + * lang-specs.h: Define __FAST_MATH__ when appropriate. + +1999-02-24 Mike Stump + + * typeck.c (convert_for_assignment): Allow boolean integral constant + expressions to convert to null pointer. + +1999-02-24 Martin von Loewis + + * decl.c (lookup_namespace_name): Resolve namespace aliases. + + * class.c (push_nested_class): Allow namespaces. + + * decl2.c (set_decl_namespace): Add friendp parameter. + * decl.c (grokfndecl): Pass it. + (grokvardecl): Likewise. + * cp-tree.h: Change declaration. + +1999-02-24 Jason Merrill + + * pt.c (tsubst): Allow an array of explicit size zero. + +1999-02-23 Jason Merrill + + * errfn.c: Change varargs code to look like toplev.c. + + * method.c (process_modifiers): Don't prepend 'U' for char or + wchar_t. + +1999-02-20 Craig Burley + + * Make-lang.in (cplib2.ready): Don't consider updating + cplib2 stuff if the current directory isn't writable, as + it won't work (such as during a `make install'). Sun Feb 21 20:38:00 1999 H.J. Lu (hjl@gnu.org) - * decl2.c (start_objects): Make file scope constructors and - destructors local to the file if ASM_OUTPUT_CONSTRUCTOR and - ASM_OUTPUT_DESTRUCTOR are defined. + * decl2.c (start_objects): Make file scope constructors and + destructors local to the file if ASM_OUTPUT_CONSTRUCTOR and + ASM_OUTPUT_DESTRUCTOR are defined. + +1999-02-19 Mark Mitchell + + * cp-tree.h (CLASSTYPE_METHOD_VEC): Adjust comment. + (fn_type_unification): Adjust prototype. + (lookup_fnfields_1): Declare. + * call.c (add_template_candidate_real): Adjust call to + fn_type_unification. + * class.c (add_method): Don't allow duplicate declarations of + constructors or destructors. + (resolve_address_of_overloaded_function): Remove unused variable. + Adjust call to fn_type_unification. + * decl.c (grokfndecl): Be more robust in the face of illegal + specializations. + * decl2.c (check_classfn): Remove hokey handling of member + templates. + * pt.c (determine_specialization): Improve comments. Adjust to + handle template argument deduction as per the standard. + (check_explicit_specialization): Fix comment spacing. Handle + type-conversion operators correctly. Improve error-recovery. + (fn_type_unification): Remove EXTRA_FN_ARG parameter. + (get_bindings_real): Simplify handling of static members. + * search.c (lookup_fnfields_1): Make it have external linkage. + * typeck.c (compparms): Fix comment. + (build_unary_op): Don't try to figure out which template + specialization is being referred to when when the address-of + operator is used with a template function. + +Thu Feb 18 23:40:01 1999 Kaveh R. Ghazi + + * cp-tree.h (lvalue_or_else): Qualify a char* with the `const' + keyword to match an analogous change at the top level. + + * tree.c (lvalue_or_else): Likewise. + +1999-02-17 Mark Mitchell + + * decl.c (xref_basetypes): Comment. + * pt.c (instantiate_class_template): Use xref_basetypes. + +1999-02-16 Mark Mitchell + + * cp-tree.h (tsubst): Change prototype. + (tsubst_expr): Likewise. + (tsubst_copy): Likewise. + (type_unification): Remove prototype. + * call.c (convert_default_arg): Adjust call to tsubst_expr. + * class.c (resolve_address_of_overloaded_function): Just use + fn_type_unification. + * decl.c (grokdeclarator): Adjust call to tsubst. + * method.c (build_template_parm_names): Likewise. + * pt.c (GTB_VIA_VIRTUAL): New macro. + (GTB_IGNORE_TYPE): Likewise. + (resolve_overloaded_unification): Add `complain' parameter. + (try_one_overload): Likewise. + (tsubst_template_arg_vector): Likewise. + (tsubst_template_parms): Likewise. + (tsubst_aggr_type): Likewise. + (tsubst_arg_types): Likewise. + (tsubst_call_declarator_parms): Likewise. + (unify): Remove explicit_mask. + (type_unification_real): Likewise. + (get_template_base_recursive): Likewise. + (coerce_template_template_parms): Provide prototype. + (tsubst_function_type): Likewise. + (try_class_unification): New function. + All callers changed to use new complain parameter. + (get_template_base): Use try_class_unification. + (unify): Adjust handling of classes derived from template types. + (fn_type_unification): Substitute explicit arguments before + unification. + +1999-02-16 Kriang Lerdsuwanakij + + * decl.c (pushdecl): Remove dead code. + +1999-02-16 Jason Merrill + + * decl2.c (finish_objects): Fix code I missed in previous change. + +1999-02-13 Jason Merrill + + * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node. + (grokdeclarator): Don't expect error_mark_node from grokfndecl. + + * pt.c (maybe_process_partial_specialization): Complain about + 'template <>' on non-specialization. + +1999-02-10 Jason Merrill + + * decl.c (grokdeclarator): Catch wierd declarators. + * decl2.c (finish_file): Don't abort because of namespace parsing + failure. + (check_decl_namespace): Remove. + +1999-02-09 Mark Mitchell + + * cp-tree.h (get_template_base): Don't declare. + (dfs_walk): Declare. + (dfs_unmark): Likewise. + (markedp): Likewise. + * pt.c (unify): Remove duplicate declaration. Pass tparms and + targs to get_template_base. + (get_template_base_recursive): Move here from search.c. Check to + see that the base found can be instantiated to form the desired + type. + (get_template_base): Likewise. + (get_class_bindings): Simplify. + * search.c (get_template_base_recursive): Move to pt.c. + (get_template_base): Likewise. + (markedp): Make it global. + (dfs_walk): Likewise. + (dfs_unmark): Likewise. + +1999-02-07 Jason Merrill + + * pt.c (maybe_process_partial_specialization): Complain about + specialization in wrong namespace. + * tree.c (decl_namespace_context): New fn. + +1999-02-06 Kriang Lerdsuwanakij + + * decl2.c (arg_assoc_type): Handle TEMPLATE_TEMPLATE_PARM. + * pt.c (coerce_template_template_parms): Handle nested + template template parameters. + +Sat Feb 6 18:08:40 1999 Jeffrey A Law (law@cygnus.com) + + * typeck2.c: Update email addresses. + +1999-02-04 Kriang Lerdsuwanakij + + * pt.c (unify): Call coerce_template_parms with the COMPLAIN flag + turned off. + +1999-02-04 Jason Merrill + + * lex.c (retrofit_lang_decl): Split out... + (build_lang_decl): From here. + * decl.c (pushdecl): Call it for functions generated by the middle + end that don't have DECL_LANG_SPECIFIC. + * cp-tree.h: Declare it. + + * decl2.c: Remove flag_init_priority. Always enable initp stuff. + (start_objects, finish_objects): Only use special + init_priority code if the user specified a priority. + (do_ctors, do_dtors): Use DEFAULT_INIT_PRIORITY for the non-initp + objects. + +Wed Feb 3 22:50:17 1999 Marc Espie + + * Make-lang.in (GXX_OBJS): Remove choose-temp.o, pexecute.o and + mkstemp.o. Get them from libiberty now. + (DEMANGLER_PROG): Simlarly, remove getopt.o getopt1.o. + +Tue Feb 2 22:38:48 1999 Theodore Papadopoulo + + * decl2.c (lang_decode_option): Use read_integral_parameter. + +1999-02-01 Mark Mitchell + + * pt.c (tsubst, case TYPENAME_TYPE): Check TYPE_BEING_DEFINED + before calling complete_type_or_else. + +Mon Feb 1 09:49:52 1999 Kaveh R. Ghazi + + * input.c (inline): Don't define, its handled by system.h. + +Sun Jan 31 20:34:29 1999 Zack Weinberg + + * decl2.c: Don't define flag_no_ident here. Don't process + -f(no-)ident here. + * cp-tree.h: Don't declare flag_no_ident here. + * lang-specs.h: Map -Qn to -fno-ident. + +1999-01-28 Jason Merrill + + * cp-tree.h (struct tree_binding): Replace scope field with a union. + (BINDING_SCOPE): Adjust. + * decl.c (BINDING_LEVEL): Adjust. + +1999-01-26 Jason Merrill + + * pt.c (instantiate_class_template): Set up the DECL_INITIAL of + member constants. + + * init.c (expand_member_init): Pull out TYPE_MAIN_VARIANT in + a ctor initializer. + + * tree.c (equal_functions): Fix name in prototype. + + * decl.c (push_local_binding): Add FLAGS argument. + (pushdecl, push_overloaded_decl): Pass it. + * decl2.c (do_local_using_decl): Likewise. + * cp-tree.h: Adjust prototype. + * decl.c (poplevel): Fix logic. + + * decl.c (push_local_binding): Also wrap used decls in a TREE_LIST. + (poplevel): Handle that. Fix logic for removing TREE_LISTs. + (cat_namespace_levels): Don't loop forever. + +1999-01-25 Richard Henderson + + * typeck.c (build_reinterpret_cast): Fix typo in duplicated test. + +1999-01-25 Jason Merrill + + * class.c (resolve_address_of_overloaded_function): Mark the + chosen function used. + + * call.c (build_call): Make sure that a function coming in has + been marked used already. + * decl.c (expand_static_init): Call mark_used instead of + assemble_external. + * except.c (call_eh_info, do_pop_exception, expand_end_eh_spec, + alloc_eh_object, expand_throw): Likewise. + * init.c (build_builtin_delete_call): Likewise. + * rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1, + expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc, + expand_generic_desc): Likewise. + +1999-01-25 Martin von Löwis + + * tree.c (equal_functions): New function. + (ovl_member): Call it. + +1999-01-24 Jason Merrill + + * cvt.c (cp_convert_to_pointer): Fix conversion of 0 to pmf. + +1999-01-25 Martin von Loewis + + * decl.c (decls_match): Return 1 if old and new are identical. + (push_overloaded_decl): Set OVL_USED when PUSH_USING. + +1999-01-24 Jason Merrill + + * decl.c (start_function): Make member functions one_only on windows. + * decl2.c (import_export_decl): Likewise. + + * decl.c (grokdeclarator): Don't complain about implicit int in + a system header. Change same-name field check to not complain in + a system header instead of within extern "C". + +1999-01-21 Mark Mitchell + + * cp-tree.h (PUSH_GLOBAL): New macro. + (PUSH_LOCAL): Likewise. + (PUSH_USING): Likewise. + (namespace_bindings_p): Declare. + (push_overloaded_decl): Likewise. + * decl.c (push_overloaded_decl): Don't make it static. Check for + illegal declarations after using declarations here. + (namespace_bindings_p): Likewise. + (duplicate_decls): Don't consider declarations from different + namespaces to be the same. + (pushdecl): Use symbolic PUSH_ constants in calls to + push_overloaded_decl. + (push_overloaded_decl_1): Likewise. + * decl2.c (validate_nonmember_using_decl): Tweak `std' handling. + (do_nonmember_using_decl): Check for illegal using declarations + after ordinary declarations here. + (do_local_using_decl): Call pushdecl to insert declarations. + +1999-01-21 Jason Merrill + + * decl.c (grokdeclarator): Fix lang_c -> lang_name_c typo. + +1999-01-21 Mark Mitchell + + * tree.c (build_cplus_array_type_1): Don't call build_array_type + for types involving template parameters. + + * cp-tree.h (PARM_DECL_EXPR): Delete. + (convert_default_arg): Change prototype. + (check_default_argument): Declare. + (search_tree): Likewise. + * call.c (convert_default_arg): Take the function to which the + default argument belongs as a parameter, and do any necessary + instantiation here, instead of ... + (build_over_call): Here. + * decl.c (local_variable_p): New function. + (check_default_argument): Likewise, split out and tidied from ... + (grokparms): Here. + * error.c (dump_expr): Don't set PARM_DECL_EXPR. + * pt.c (tsubst_call_declarator_parms): New function. + (for_each_template_parm): Handle ARRAY_REFs. Do the obvious thing + with CALL_EXPRs, rather than trying to be clever. + (tsubst): Use tsubst_call_declarator_parms. + * tree.c (search_tree): Don't make it static. + * typeck.c (convert_arguments): Use new interface to + convert_default_arg. + +1999-01-20 Mark Mitchell + + * error.c (dump_function_decl): Don't print the argument types for + a function when the verbosity level is negative. + + * call.c (build_over_call): Check format attributes at call-time. + + * pt.c (tsubst_copy): Fix comment. + (unify): Don't allow unification with variable-sized arrays. + + * semantics.c (finish_stmt_expr): When processing a template make + the BIND_EXPR long-lived. + +1999-01-19 Jason Merrill + + * decl2.c (finish_vtable_vardecl): Make vtables comdat here. + (import_export_vtable): Not here. + +1999-01-18 Jason Merrill + + * typeck.c (build_component_ref): Wrap an OVERLOAD around a unique + non-static member function. + +1999-01-18 Nathan Sidwell + + * class.c (instantiate_type): Only diagnose illegal address of member + function if complaining. + + * decl.c (lookup_name_real): Remove duplicate code. + +1999-01-18 Jason Merrill + + * tree.c (copy_template_template_parm): Use permanent_obstack. + +1999-01-18 Kriang Lerdsuwanakij + + * pt.c (unify): Remove restrictions on deduction of argument + of template template parameters. + +1999-01-18 Nathan Sidwell + + * rtti.c (build_dynamic_cast_1): Resolve OFFSET_REF exprs. + + * class.c (resolve_address_of_overloaded_function): Show list of + all candidates, when none of them match. + +1999-01-18 Chip Salzenberg + + * typeck.c (comp_ptr_ttypes_reinterpret): Per ANSI, tighten up + definition of 'casting away const' in reinterpret_cast<>. + +1999-01-18 Graham + + * cvt.c: Add include for decl.h, remove extern for + static_aggregates which is now provided by decl.h. + + * Makefile.in (cvt.o): Add dependency for decl.h and missing + dependencies for convert.h and flags.h. + +1999-01-18 Nathan Sidwell + + * decl2.c (do_dtors): Set current location to that of the + decl, for sensible diagnostics and debugging. + (check_classfn): Issue `incomplete type' error, if + class is not defined. + +1999-01-16 Jason Merrill + + * cp-tree.h: Add prototype for bound_pmf_p. + +1999-01-16 Jason Merrill + Manfred Hollstein + + * decl.c (grokdeclarator): Don't make 'main(){}' an error with only + -Wreturn-type. + +1999-01-16 Nathan Sidwell + + * cp-tree.h (struct lang_type): Added has_mutable flag. + (CLASSTYPE_HAS_MUTABLE): New macro to access it. + (TYPE_HAS_MUTABLE_P): New macro to read it. + (cp_has_mutable_p): Prototype for new function. + * class.c (finish_struct_1): Set has_mutable from members. + * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if + it contains a mutable. + * typeck.c (cp_has_mutable_p): New function. + +1999-01-15 Mark Mitchell + + * pt.c (process_template_parm): Ignore top-level qualifiers on + non-type parameters. + + * decl.c (start_function): Use current_function_parms in the call + to require_complete_type_for_parms, not the probably empty + DECL_ARGUMENTS. + +1999-01-14 Jason Merrill + + * semantics.c (finish_asm_stmt): Don't warn about redundant volatile. + + * decl2.c (import_export_class): MULTIPLE_SYMBOL_SPACES only means + that we don't suppress the other copies. + * lex.c (handle_cp_pragma): Likewise. + +1999-01-13 Mark Mitchell + + * decl.c (grokdeclarator): Undo 1998-12-14 change. + * tree.c (build_cplus_array_type_1): Likewise. + * pt.c (instantiate_class_template): Remove misleading comment. + (tsubst_aggr_type): Substitute if there are template parameters, + regardless of whether or not they use template arguments. + (unify): Likewise, but for unification. + +1999-01-12 Richard Henderson + + * cp-tree.h (flag_permissive): Declare extern. + +1999-01-06 Mark Mitchell + + * cp-tree.h (IDENTIFIER_TYPENAME_P): Use OPERATOR_TYPENAME_FORMAT + here. + (lang_type): Add is_partial_instantiation. Decrease width of + dummy. + (PARTIAL_INSTANTIATION_P): New macro. + (OPERATOR_TYPENAME_P): Remove. + * decl.c (unary_op_p): Use IDENTIFIER_TYPENAME_P, not + OPERATOR_TYPENAME_P. + (grok_op_properties): Likewise. + * friend.c (do_friend): Handle friends that are member functions + correctly. + * lex.c (init_parse): Use OPERATOR_TYPENAME_FORMAT. + * pt.c (instantiate_class_template): Rework for clarity. Avoid + leaving TYPE_BEING_DEFINED set in obscure cases. Don't do + any more partial instantiation than is absolutely necessary for + implicit typename. Set PARTIAL_INSTANTIATION_P. + (tsubst_decl): Use IDENTIFIER_TYPENAME_P. + * semantics.c (begin_class_definition): Handle partial + specializations of a type that was previously partially + instantiated. + +Wed Jan 6 03:18:53 1999 Mark Elbrecht + + * Make-lang.in (g++.o): Depend on prefix.h. + +1999-01-04 Jason Merrill + + * tree.c (bound_pmf_p): New fn. + * typeck.c (build_c_cast): Use it. + + * decl.c (grok_op_properties): Use same_type_p. + +Tue Dec 22 15:09:25 1998 Kaveh R. Ghazi + + * Makefile.in (cvt.o): Depend on toplev.h. + + * cp-tree.h (check_template_shadow, pod_type_p): Add prototypes. + + * cvt.c: Include toplev.h. + + * except.c (get_eh_caught, get_eh_handlers): Hide prototypes and + definitions. + + * init.c (expand_vec_init): Initialize variable `itype'. + + * lex.c (yyerror): Cast the argument passed to a ctype function to + an unsigned char. + + * method.c (build_mangled_C9x_name): Wrap prototype and definition + in "HOST_BITS_PER_WIDE_INT >= 64". + + * typeck.c (build_binary_op): Mark parameter `convert_p' with + ATTRIBUTE_UNUSED. + +1998-12-22 Mark Mitchell + + * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Improve documentation. + * tree.c (build_exception_variant): Don't crash on empty throw + specs. + +1998-12-18 DJ Delorie + + * cvt.c (convert_to_reference): Check for both error_mark_node + and NULL_NODE after call to convert_for_initialization. + +1998-12-17 Jason Merrill + + * error.c (interesting_scope_p): New fn. + (dump_simple_decl): Use it. + (dump_expr, case CONSTRUCTOR): Force a & for a PMF. + (dump_expr, case OFFSET_REF): Print ->* if appropriate. + +1998-12-16 Mark Mitchell + + * class.c (resolve_address_of_overloaded_function): Do conversion + to correct type here, rather than ... + (instantiate_type): Here. + + * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro. + (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it. + (decl_template_parm_p): Remove. + * decl.c (pushdecl): Don't set DECL_CONTEXT for a template + parameter. + * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P. + * pt.c (push_inline_template_parms_recursive): Set it. + (decl_template_parm_p): Remove. + (check_template_shadow): Use DECL_TEMPLATE_PARM_P. + (process_template_parm): Set it. + +Wed Dec 16 16:33:58 1998 Dave Brolley + + * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus + if configured with cpplib. + +1998-12-15 Mark Mitchell + + * decl.c (poplevel): Make sure ns_binding is initialized. + + * decl.c (finish_function): Undo inadvertent change in previous + patch. + +1998-12-14 Mark Mitchell + + * class.c (pushclass): Tweak handling of class-level bindings. + (resolve_address_of_overloaded_function): Update pointer-to-member + handling. + (instantiate_type): Likewise. + * cvt.c (cp_convert_to_pointer): Likewise. + * decl.c (pop_binding): Take the DECL to pop, not just the name. + Deal with `struct stat' hack. + (binding_level): Add to documentation. + (push_binding): Clear BINDING_TYPE. + (add_binding): New function. + (push_local_binding): Use it. + (push_class_binding): Likewise. + (poplevel): Adjust calls to pop_binding. + (poplevel_class): Likewise. + (pushdecl): Adjust handling of TYPE_DECLs; add bindings for hidden + declarations to current binding level. + (push_class_level_binding): Likewise. + (push_overloaded_decl): Adjust handling of OVERLOADs in local + bindings. + (lookup_namespace_name): Don't crash when confronted with a + TEMPLATE_DECL. + (lookup_name_real): Do `struct stat' hack in local binding + contexts. + (build_ptrmemfunc_type): Adjust documentation. + (grokdeclarator): Don't avoid building real array types when + processing templates unless really necessary. + (finish_method): Adjust calls to pop_binding. + * decl2.c (reparse_absdcl_as_expr): Recursively call ourselves, + not reparse_decl_as_expr. + (build_expr_from_tree): Deal with a template-id as the function to + call in a METHOD_CALL_EXPR. + * pt.c (convert_nontype_argument): Tweak pointer-to-member handling. + (maybe_adjust_types_For_deduction): Don't do peculiar things with + METHOD_TYPEs here. + (resolve_overloaded_unification): Handle COMPONENT_REFs. Build + pointer-to-member types where necessary. + * tree.c (build_cplus_array_type_1): Don't avoid building real + array types when processing templates unless really necessary. + (build_exception_variant): Compare the exception lists correctly. + +1998-12-13 Mark Mitchell + + * cp-tree.def (CPLUS_BINDING): Update documentation. + * cp-tree.h (LOCAL_BINDING_P): New macro. + (lang_identifier): Rename local_value to bindings. + (tree_binding): Make `scope' of type `void*', not `tree'. + (BINDING_SCOPE): Update documentation. + (IDENTIFIER_LOCAL_VALUE): Remove. + (IDENTIFIER_CLASS_VALUE): Document. + (IDENTIFIER_BINDING): New macro. + (IDENTIFIER_VALUE): Likewise. + (TIME_IDENTIFIER_TIME): Likewise. + (TIME_IDENTIFIER_FILEINFO): Likewise. + (IMPLICIT_TYPENAME_P): Likewise. + (set_identifier_local_value): Remove. + (push_local_binding): New function. + (push_class_binding): Likewise. + * class.c (pushclass): Update comments; use push_class_binding. + * decl.c (set_identifier_local_value_with_scope): Remove. + (set_identifier_local_value): Likewise. + (push_binding): New function. + (pop_binding): Likewise. + (binding_level): Update documentation. Remove shadowed. + (BINDING_LEVEL): New macro. + (free_binding_nodes): New variable. + (poplevel): Adjust for new name-lookup scheme. Don't mess up + BLOCK_VARs when doing for-scope extension. Remove effectively + dead code. + (pushlevel_class): Tweak formatting. + (poplevel_class): Adjust for new name-lookup scheme. + (print_binding_level): Likewise. + (store_bindings): Likewise. + (pushdecl): Likewise. + (pushdecl_class_level): Likewise. + (push_class_level_binding): Likewise. + (push_overloaded_decl): Update comments. Adjust for new + name-lookup scheme. + (lookup_name_real): Likewise. + (lookup_name_current_level): Likewise. + (cp_finish_decl): Likewise. + (require_complete_types_for_parms): Likewise. Remove misleading + #if 0'd code. + (grok_parms): Likewise. Don't call + require_complete_types_for_parms here. + (grok_ctor_properties): Don't treat templates as copy + constructors. + (grop_op_properties): Or as assignment operators. + (start_function): Document. Adjust for new name-lookup scheme. + (finish_function): Likewise. + * decl2.c (do_local_using_decl): Use push_local_binding. + * lex.c (begin_definition_of_inclass_inline): New function, split + out from ... + (do_pending_inlines): Here, and ... + (process_next_inline): Here. + (get_time_identifier): Use TIME_IDENTIFIER_* macros. + (init_filename_times): Likewise. + (extract_interface_info): Likewise. + (ste_typedecl_interface_info): Likewise. + (check_newline): Likewise. + (dump_time_statistics): Likewise. + (handle_cp_pragma): Likewise. + (do_identifier): Adjust for new name-lookup scheme. + * parse.y (function_try_block): Return ctor_initializer_opt value. + (fndef): Use it. + (fn.defpen): Pass appropriate values to start_function. + (pending_inline): Use functor_try_block value, and pass + appropriate values to finish_function. + * pt.c (is_member_template): Update documentation; remove handling + of FUNCTION_DECLs. As per name, this function should deal only in + TEMPLATE_DECLs. + (decl_template_parm_p): Change name of olddecl parameter to decl. + (check_template_shadow): Adjust for new name-lookup scheme. + (lookup_template_class): Likewise. + (tsubst_decl): Tweak so as not to confuse member templates with + copy constructors and assignment operators. + (unify): Handle UNION_TYPEs. + * ptree.c (print_lang_identifier): Adjust for new name-lookup scheme. + (lang_print_xnode): Adjust for new name-lookup scheme. + * typeck.c (mark_addressable): Likewise. + (c_expand_return): Likewise. + +1998-12-08 Jason Merrill + + * decl.c (grokdeclarator): Allow field with same name as class + in extern "C". + + * decl.c (lookup_name_real): Don't limit field lookup to types. + * class.c (check_member_decl_is_same_in_complete_scope): No error + if icv and x are the same. + * lex.c (do_identifier): Tweak error message. + +1998-12-10 Mark Mitchell + + * decl.c (start_enum): Use push_obstacks, not + end_temporary_allocation. + (finish_enum): Call pop_obstacks. + +1998-12-10 Mark Mitchell + + * class.c (instantiate_type): Return error_mark_node rather than + junk. + +1998-12-09 Mark Mitchell + + * cp-tree.h (most_specialized_instantiation): New function. + (print_candidates): Likewise. + * class.c (validate_lhs): Remove. + (resolve_address_of_overloaded_function): New function, split out + and then substantially reworked, from ... + (instantiate_type): Use it. Simplify. + * cvt.c (convert_to_reference): Complain when caller has indicated + that's the right thing to do. Don't crash if instantiate_type + fails. + * pt.c: Substitute `parameters' for `paramters' throughout. + (print_candidates): Don't make it static. + (most_specialized_instantiation): Split out from ... + (most_specialized): Here. + +Wed Dec 9 15:33:01 1998 Dave Brolley + + * lex.c (lang_init_options): Initialize cpplib. + * decl2.c (parse_options,cpp_initialized): Removed. + (lang_decode_option): Move initialization of cpplib to + lang_init_options. + +1998-12-09 Mark Mitchell + + * decl.c (grokdeclarator): Update the name of the TEMPLATE_DECL, as + well as the TYPE_DECL, when a typedef name is assigned to a + previously anonymous type. + +1998-12-08 Andrew MacLeod + + * cp/except.c (call_eh_info): Use __start_cp_handler instead of + __cp_eh_info for getting the eh info pointer. Add table_index to + field list. + (push_eh_cleanup): Don't increment 'handlers' data field. + (process_start_catch_block): Don't set the 'caught' field. + + * cp/exception.cc (CP_EH_INFO): New macro for getting the + exception info pointer within library routines. + (__cp_eh_info): Use CP_EH_INFO. + (__start_cp_handler): Get exception info pointer, set caught field, + and increment the handlers field. Avoids this being done by handlers. + (__uncatch_exception, __check_eh_spec): Use CP_EH_INFO macro. + (uncaught_exception): Use CP_EH_INFO macro. + +Tue Dec 8 10:48:21 1998 Jeffrey A Law (law@cygnus.com) + + * Make-lang.in (cxxmain.o): Depend on $(DEMANGLE_H), not demangle.h + +Mon Dec 7 17:56:06 1998 Mike Stump + + * lex.c (check_newline): Add support for \ as `natural' + characters in file names in #line to be consistent with #include + handling. We support escape processing in the # 1 "..." version of + the command. See also support in cp/lex.c. + +1998-12-07 Zack Weinberg + + * cp/decl2.c: s/data/opts/ when initializing cpp_reader + structure. + +1998-12-07 Jason Merrill + + * decl.c (build_typename_type): Set DECL_ARTIFICIAL. + + * error.c (dump_simple_decl): Also print namespace context. + (dump_function_decl): Likewise. + + * decl2.c (ambiguous_decl): Don't print old value if it's + error_mark_node. + + * decl.c (lookup_name_real): Fix handling of local types shadowed + by a non-type decl. Remove obsolete code. + * cp-tree.h (DECL_FUNCTION_SCOPE_P): New macro. + + * lang-options.h: Add -fpermissive. + * decl2.c: Likewise. + * cp-tree.h: Add flag_permissive. + * decl.c (init_decl_processing): If neither -fpermissive or -pedantic + were specified, set flag_pedantic_errors. + * call.c (build_over_call): Turn dropped qualifier messages + back into pedwarns. + * cvt.c (convert_to_reference): Likewise. + * typeck.c (convert_for_assignment): Likewise. + +1998-12-05 Jason Merrill + + * decl2.c (coerce_new_type): Use same_type_p. + (coerce_delete_type): Likewise. + + * call.c (check_dtor_name): Return 1, not error_mark_node. + +1998-12-04 Jason Merrill + + * lex.c (handle_cp_pragma): Disable #pragma interface/implementation + if MULTIPLE_SYMBOL_SPACES. + + * pt.c (check_template_shadow): New fn. + * decl2.c (grokfield): Use it. + * decl.c (pushdecl): Likewise. + (pushdecl_class_level): Likewise. + (start_method): Likewise. + (xref_tag): Don't try to use 't' if we're defining. + + * call.c (check_dtor_name): Just return an error_mark_node. + * pt.c (lookup_template_class): Complain about using non-template here. + * parse.y (apparent_template_type): Not here. + + * pt.c (check_explicit_specialization): Complain about specialization + with C linkage. + + * lang-options.h: Add -f{no-,}implicit-inline-templates. + + * pt.c (convert_nontype_argument): Don't assume that any integer + argument is intended to be a constant-expression. + +1998-12-03 Mark Mitchell + + * class.c (handle_using_decl): Fix comment. Don't lookup + constructors in base classes. + (validate_lhs): Fix typo in comment. + * search.c (lookup_field_1): Don't return a USING_DECL. + + * cp-tree.h (DECL_ACCESS): Improve documentation. + + * decl.c (expand_static_init): Don't set the initialization-done + flag until the initialization is done. + +1998-12-02 Mark Mitchell + + * decl2.c (validate_nonmember_using_decl): Complain about using + declarations for class members. + +1998-11-29 Jason Merrill + + * typeck2.c (process_init_constructor): Use same_type_p. + + * decl.c (check_tag_decl): Don't warn about null decl inside a + class. + + * pt.c (unify, case OFFSET_TYPE): Pass down 'strict' rather than + UNIFY_ALLOW_NONE. + (convert_nontype_argument): Use TYPE_PTRMEMFUNC_FN_TYPE. + (resolve_overloaded_unification): Strip baselinks. + +Fri Nov 27 13:07:23 1998 Kaveh R. Ghazi + + * g++spec.c: Don't prototype xmalloc. + +1998-11-25 Jason Merrill + + * except.c (expand_throw): Use TYPE_PTR_P to check for pointers. + + * decl.c (check_tag_decl): Do complain about null friend decl at + file scope. + +1998-11-25 Andreas Schwab + + * lex.c (make_lang_type): Clear the whole struct lang_type, not + only the first multiple of sizeof (int). + +1998-11-24 Jason Merrill + + * decl.c (start_decl): An explicit specialization of a static data + member is only a definition if it has an initializer. + + * except.c (expand_throw): Use cp_finish_decl for the throw temp. + * cvt.c (build_up_reference): Pass DIRECT_BIND down into + cp_finish_decl. + * init.c (expand_default_init): Check for DIRECT_BIND instead of + DECL_ARTIFICIAL. + + * call.c (build_over_call): Use build_decl. + + * except.c (expand_throw): Just use convert, not + build_reinterpret_cast. + + * lex.c (handle_generic_pragma): Use token_buffer. + + * decl.c (check_tag_decl): Don't complain about null friend decl. + +1998-11-24 Dave Pitts + + * Make-lang.in (DEMANGLER_PROG): Move the output arguments to the + first position. + * lex.c (check_newline): Use ISALPHA. + (readescape): Use ISGRAPH. + (yyerror): Use ISGRAPH. + +1998-11-24 Nathan Sidwell + + * search.c (get_abstract_virtuals): Do not use initial + CLASSTYPE_ABSTRACT_VIRTUALS. + * typeck2.c (abstract_virtuals_error): Show location of abstract + declaration. + * call.c (build_new_method_call): Use + CLASSTYPE_ABSTRACT_VIRTUAL, rather than recalculate. + * class.c (finish_struct_bits): Don't bother working out whether + get_abstract_virtuals will do anything, just do it. + +1998-11-24 Graham + + * typeck.c (build_component_ref): Remove unused statement. + +1998-11-24 Jason Merrill + + * class.c (add_method): Catch invalid overloads. + + * class.c (add_method): Build up OVERLOADs properly for conversion ops. + * search.c (lookup_conversions): Handle getting real OVERLOADs. + (add_conversions): Likewise. Revert last change. + * call.c (add_conv_candidate): Pass totype to add_candidate instead + of fn. Don't add a new candidate if the last one was for the same + type. + (print_z_candidates): Handle getting a type as a function. + (joust): If we got two conversion candidates to the same type, + just pick one. + (build_object_call): Lose 'templates'. + (build_user_type_conversion_1): Handle getting real OVERLOADs. + +1998-11-23 Jason Merrill + + * typeck2.c (process_init_constructor): If there are elements + that don't have initializers and they need to have constructors + run, supply them with initializers. + + * class.c (finish_struct_1): A class with a 0-width bitfield is + still empty. + +1998-11-23 Mark Mitchell + + * pt.c (instantiate_class_template): Don't try to figure out what + specialization to use for a partial instantiation. Correct + typos in a couple of comments. Avoid calling uses_template_parms + multiple times. + +1998-11-23 Benjamin Kosnik + + * method.c (process_overload_item): Add call to + build_mangled_C9x_name for intTI_type_nodes. + (build_mangled_C9x_name): Add prototype, define. + * decl.c (init_decl_processing): Add names for + TImode_type_node. + +1998-11-23 Jason Merrill + + * parse.y (named_class_head): Update CLASSTYPE_DECLARED_CLASS. + + * class.c (finish_struct_1): Set things up for 0-width bitfields + like we do for others. + + * decl.c (check_tag_decl): New fn. + (shadow_tag): Split out from here. + * decl2.c (grok_x_components): Call it. + +1998-11-22 Jason Merrill + + * decl.c: Lose warn_about_return_type. + (grokdeclarator): Always complain about implicit int, except for + `main () { ... }'. + + * decl.c (tag_name): New fn. + (xref_tag): Complain about using typedef-name after class-key. + + * init.c (expand_vec_init): Also keep going if from_array. + + * tree.c (is_overloaded_fn): Also handle the output of + build_offset_ref. + + * decl.c (grokdeclarator): Use constructor_name when comparing + field name against enclosing class. + * class.c (finish_struct_anon): Likewise. + +1998-11-22 Mark Mitchell + + * decl.c (poplevel): Remove code to handle KEEP == 2. + (finish_function): Don't confuse BLOCK-order when + processing a destructor. + +1998-11-21 Jason Merrill + + * decl.c (require_complete_types_for_parms): Call layout_decl + after we've completed the type. + +1998-11-21 Martin von Löwis + + * decl2.c (validate_nonmember_using_decl): Allow using templates + from the global namespace. + +1998-11-21 Jason Merrill + + Handle specifying template args to member function templates. + * tree.c (build_overload): Always create an OVERLOAD for a template. + * search.c (add_conversions): Handle finding an OVERLOAD. + * decl2.c (check_classfn): Likewise. + * lex.c (identifier_type): See through a baselink. + * parse.y (do_id): Don't call do_identifier if we got a baselink. + * class.c (instantiate_type, case TREE_LIST): Recurse. + + * decl.c (grokdeclarator): Allow a boolean constant for array + bounds, odd as that sounds. + + * pt.c (unify): Be more strict about non-type parms, except for + array bounds. + (UNIFY_ALLOW_INTEGER): New macro. + +1998-11-19 Manfred Hollstein + + * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir). + +1998-11-19 Jason Merrill + + * semantics.c (begin_class_definition): Call + maybe_process_partial_specialization before push_template_decl. + Don't call push_template_decl for a specialization. + * search.c (lookup_field): Do return a member template class. + * decl2.c (handle_class_head): Handle member template classes. + + * decl.c (grokdeclarator): A parm type need not be complete. + + * pt.c (convert_nontype_argument): Fix thinko. + +1998-11-18 Mark Mitchell + + * cp-tree.h (PTRMEM_CST_CLASS): Fix typo. + (global_delete_fndecl): New variable. + * decl.c (global_delete_fndecl): Define it. + (init_decl_processing): Set it. + * init.c (build_builtin_delete_call): Use it. + * tree.c (mapcar): Recursively call mapcar for the type of EXPR + nodes. + +1998-11-18 Jason Merrill + + * decl.c (cplus_expand_expr_stmt): Always complain about unresolved + type. + + * tree.c (lvalue_p_1): An INDIRECT_REF to a function is an lvalue. + * call.c (build_object_call): Also support references to functions. + * typeck.c (convert_for_initialization): Don't decay a function + if the target is a reference to function. + + * search.c (add_conversions): Get all the overloads from a class. + + * decl.c (grok_ctor_properties): Complain about any constructor + that will take a single arg of the class type by value. + + * typeck2.c (build_functional_cast): Can't create objects of + abstract classes this way. + * cvt.c (ocp_convert): Likewise. + + * decl.c (grokfndecl): Member functions of local classes are not + public. + +1998-11-18 Mark Mitchell + + * Make-lang.in (cc1plus): Add dependency on hash.o. + +1998-11-18 Jason Merrill + + * search.c (get_abstract_virtuals): Complain about virtuals with + no final overrider. + * typeck2.c (abstract_virtuals_error): Remove handling for virtuals + with no final overrider. + * class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P + on virtuals with no final overrider. + + * lex.c (reinit_parse_for_block): Add a space after the initial ':'. + + * class.c (finish_struct_1): Don't remove zero-width bit-fields until + after layout_type. + + * friend.c (do_friend): Don't set_mangled_name_for_decl. + + * class.c (finish_struct_anon): Complain about non-fields. + * decl2.c (build_anon_union_vars): Likewise. + + * decl.c (grokdeclarator): Normal data members can't have the same + name as the class, either. + * class.c (finish_struct_anon): Neither can members of an + anonymous union. + +1998-11-17 Mark Mitchell + + * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses. + (TYPE_BINFO): Likewise. + (IS_AGGR_TYPE): Tweak. + (SET_IS_AGGR_TYPE): New macro. + (CLASS_TYPE_P): Tweak. + (lang_type): Group mark bitfields together. Remove linenum. + (CLASSTYPE_SOURCE_LINE): Remove macro. + (CLASSTYPE_MARKED_N): New macro. + (SET_CLASSTYPE_MARKED_N): Likewise. + (CLEAR_CLASSTYPE_MARKED_N): Likewise. + (CLASS_TYPE_MARKED_*): Use them. + (SET_CLASSTYPE_MARKED_*): Likewise. + (CLEAR_CLASSTYPE_MARKED_*): Likewise. + (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise. + (TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well. + (TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE. + * class.c (class_cache_obstack): New variable. + (class_cache_firstobj): Likewise. + (finish_struct): Don't set CLASSTYPE_SOURCE_LINE. + (pushclass): Free the cache, when appropriate. + (popclass): Tidy. + (maybe_push_cache_obstack): Use class_cache_obstack. + * decl.c (include hash.h). + (typename_hash): New function. + (typename_compare): Likewise. + (build_typename_type): Check the hash table to avoid creating + duplicates. + (build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE. + (grokdeclarator): Use CLASS_TYPE_P. + (xref_basetypes): Likewise. + (start_function): Likewise. Don't put current_class_ref on the + permanent obstack. + * error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO + and TYPE_TI_ARGS. + * lex.c (note_got_semicolon): Use CLASS_TYPE_P. + (make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated + fields for types other than class types. Do clear TYPE_ALIAS_SET + for types other than class types, though. + * method.c (build_overload_identifier): Use CLASS_TYPE_P and + TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. + * pt.c (process_template_parm): Don't set + CLASSTYPE_GOT_SEMICOLON. + (lookup_template_class): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. + Coerce arguments on the momentary obstack. + (for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. + (instantiate_class_template): Calculate template arguments on the + momentary obstack. Tidy. + (tsubst_template_arg_vector): Use make_temp_vec. + (tsubst_aggr_type): Put template arguments on the momentary + obstack. + (tsubst_decl): Likewise. + (tsubst): Copy the array bounds index to the permanent obstack + before building index types. Use new macros. + (unify): Use new macros. + (do_type_instantiation): Likewise. + * search.c (lookup_fnfields_1): Use new macros. + (dfs_pushdecls): Build envelopes on the cache obstack. + (dfs_compress_decls): Use new macros. + (push_class_decls): Build on the cache obstack. + * semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON. + * sign.c (build_signature_pointer_or_reference_type): Use + SET_IS_AGGR_TYPE. + * tree.c (make_binfo): Check CLASS_TYPE_P. + (copy_template_template_parm): Adjust. + (make_temp_vec): Use push_expression_obstack. + * typeck.c (complete_type): Use new macros. + (comptypes): Likewise. + +1998-11-17 Jason Merrill + + * pt.c (tsubst): Add diagnostics for invalid array, reference + and pointer to member types. + +1998-11-16 Jason Merrill + + * typeck2.c (my_friendly_abort): Don't fatal twice in a row. + + * typeck.c (c_expand_start_case): Use build_expr_type_conversion. + Simplify. + + * parse.y (structsp): Fix cut-and-paste error. + + * init.c (build_new): Complain about non-integral size. + + * parse.y (unary_expr): Complain about defining types in sizeof. + + * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn. + + * rtti.c (build_x_typeid): Complain about typeid without + including . + (get_typeid): Likewise. Complain about typeid of incomplete type. + (get_tinfo_fn_dynamic): Likewise. + (get_typeid_1): Not static anymore. + * except.c (build_eh_type_type): Use get_typeid_1. + + * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to + ambiguous or private bases. Fix warning for reference cast. + +1998-11-16 Mark Mitchell + + * cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro. + * decl.c (duplicate_decls): Remove special-case code to deal with + template friends, and just do the obvious thing. + * pt.c (register_specialization): Tweak for clarity, and also to + clear DECL_INITIAL for an instantiation before it is merged with a + specialization. + (check_explicit_specialization): Fix indentation. + (tsubst_friend_function): Handle both definitions in friend + declaration and outside friend declarations. + (tsubst_decl): Don't clear DECL_INITIAL for an instantiation. + (regenerate_decl_from_template): Tweak accordingly. + (instantiate_decl): Likewise. + +1998-11-16 Jason Merrill + + * decl.c (cplus_expand_expr_stmt): Promote warning about naked + member function reference to error. + * cvt.c (ocp_convert): Complain about converting an overloaded + function to void. + + * init.c (build_offset_ref): Just return a lone static member + function. + + * decl.c (cp_finish_decl): Only complain about real CONSTRUCTORs, + not internal ones. + + * typeck.c (build_binary_op_nodefault): Improve error handling. + + * decl.c (grokfndecl): Complain about making 'main' a template. + + * typeck.c (string_conv_p): Don't convert from wchar_t[] to char*. + + * call.c (build_method_call): Handle a BIT_NOT_EXPR around a + TYPE_DECL in a template. + +1998-11-15 Jason Merrill + + * typeck2.c (my_friendly_abort): Add URL in the other case, too. + + * decl.c (struct cp_function): Add named_label_uses. + (push_cp_function_context): Save it. + (pop_cp_function_context): Restore it. + (define_label): Also complain about jumping into the scope of + non-POD objects that don't have constructors. + * tree.c (pod_type_p): New fn. + + * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner. + * rtti.c (synthesize_tinfo_fn): Call import_export_decl here. + (get_tinfo_fn): Not here. + * repo.c (repo_get_id): Abort if we get called for an incomplete + type. + +1998-11-13 Mark Mitchell + + * except.c (expand_throw): Make sure first argument to + __cp_push_exception is of type `void*' to avoid spurious error + messages. + +1998-11-11 Jason Merrill + + * pt.c (try_one_overload): Take orig_targs again. Only check for + mismatches against them; we don't care what a previous call found. + (resolve_overloaded_unification): Adjust. + + * search.c (lookup_field): Don't return anything for a non-type + field from a dependent type. + * decl.c (grokdeclarator): Resolve SCOPE_REFs of the current class + in an array declarator. + (start_decl): Push into the class before looking for the field. + +1998-11-08 Mark Mitchell + + * method.c (build_overload_value): Handle REFERENCE_TYPE. + +1998-11-08 Martin von Löwis + + * decl.c (grokdeclarator): Allow namespace-scoped members if they + are friends. + +1998-11-08 Jason Merrill + + * pt.c (tsubst_decl): Don't mess with the global value of an + un-mangled DECL_ASSEMBLER_NAME. + +1998-11-03 Christopher Faylor + + * decl.c (init_decl_processing): Remove CYGWIN conditional + since CYGWIN is now able to deal with trapping signals. + +Sat Nov 7 15:48:02 1998 Kaveh R. Ghazi + + * cp-tree.h: Don't include gansidecl.h. + * exception.cc: Include gansidecl.h (since we don't include config.h) + * g++spec.c: Don't include gansidecl.h. + +1998-11-06 Mark Mitchell + + * cp-tree.h (lang_decl_flags): Add defined_in_class. Decrease + size of dummy. + (DECL_DEFINED_IN_CLASS_P): New macro. + (TEMPLATE_PARMS_FOR_INLINE): Document. + (check_static_variable_definition): New function. + * decl.c (cp_finish_decl): Set DECL_DEFINED_IN_CLASS_P, if + appropriate. + (check_static_variable_definition): Split out from ... + (grokdeclarator): Here. + * pt.c (check_default_tmpl_args): New function, split out from ... + (push_template_decl_real): Here. + (instantiate_template): Fix comment. + +1998-11-04 Mark Mitchell + + * cp-tree.h (CP_TYPE_CONST_P): Make {0,1}-valued. + (CP_TYPE_VOLATILE_P): Likewise. + (CP_TYPE_RESTRICT_P): Likewise. + +1998-11-03 Mark Mitchell + + * pt.c (tsubst): Use build_index_type, not build_index_2_type. + +1998-11-02 Jason Merrill + + * class.c (instantiate_type): Be more helpful. + + * decl2.c (import_export_decl): Call import_export_class. + + * cp-tree.h (EMPTY_CONSTRUCTOR_P): Check !TREE_HAS_CONSTRUCTOR. + * decl2.c (build_expr_from_tree): Propagate TREE_HAS_CONSTRUCTOR. + * pt.c (tsubst_copy): Likewise. + +1998-11-02 Mark Mitchell + + * init.c (expand_vec_init): Fix off-by-one error. + +1998-11-02 Alexandre Oliva + + * parse.y (apparent_template_type): New type. + (named_complex_class_head_sans_basetype): Use it. + * Makefile.in (CONFLICTS): One new conflict. + * parse.c: Regenerated. + +1998-11-01 Mark Mitchell + + * cp-tree.h (COMPARE_STRICT): New macro. + (COMPARE_BASE): Likewise. + (COMPARE_RELAXED): Likewise. + (COMPARE_REDECLARATION): Likewise. + (same_type_p): Likewise. + (same_or_base_type_p): Likewise. + * call.c (standard_conversion): Use them, in place of comptypes + with numeric arguments. + (reference_binding): Likewise. + (convert_like): Likewise. + (build_over_call): Likewise. + (is_subseq): Likewise. + (is_properly_derived_from): Likewise. + (compare_ics): Likewise. + (joust): Likewise. + * class.c (delete_duplicate_fields_1): Likewise. + (resolves_to_fixed_type_p): Likewise. + (instantiate_type): Likewise. Remove #if 0'd code. + * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here. + (pushdecl): Likewise. + (lookup_name_real): Likewise. + (grokdeclarator): Likewise. Check for illegal array declarations. + (grokparms): Likewise. + (grok_op_properties): Likewise. + * decl2.c (check_classfn): Likewise. + * friend.c (is_friend): Likewise. + (make_friend_class): Likewise. + * init.c (expand_aggr_init): Likewise. + (expand_vec_init): Likewise. + * pt.c (is_member_template_class): Remove declaration. + (is_specialization_of): Use COMPARE_* and new macros. + (comp_template_parms): Likewise. + (convert_nontype_argument): Likewise. + (coerce_template_template_parms): Likewise. + (template_args_equal): Likewise. + (lookup_template_class): Likewise. + (type_unification_real): Likewise. + (unify): Likewise. + (get_bindings_real): Likewise. + * search.c (covariant_return_p): Likewise. + (get_matching_virtual): Likewise. + * sig.c (match_method_types): Likewise. + * tree.c (vec_binfo_member): Likewise. + (cp_tree_equal): Likewise. + * typeck.c (common_type): Likewise. + (comp_array_types): Likewise. Get issues involving unknown array + bounds right. + (comptypes): Update comments. Use new flags. + (comp_target_types): Use new macros. + (compparms): Likewise. + (comp_target_parms): Likewise. + (string_conv_p): Likewise. + (build_component_ref): Likewise. + (build_indirect_ref): Likewise. + (build_conditional_expr): Likewise. + (build_static_cast): Likewise. + (build_reinterpret_cast): Likewise. + (build_const_cast): Likewise. + (build_modify_expr): Likewise. + (convert_for_assignment): Likewise. + (comp_ptr_ttypes_real): Likewise. + (ptr_reasonably_similar): Likewise. + (comp_ptr_ttypes_const): Likewise. + +1998-10-31 Jason Merrill + + * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error. + +1998-10-30 Mark Mitchell + + * decl2.c (delete_sanity): Pass integer_zero_node, not + integer_two_node, to build_vec_delete. + * init.c (build_array_eh_cleanup): Remove. + (expand_vec_init_try_block): New function. + (expand_vec_init_catch_clause): Likewise. + (build_vec_delete_1): Don't deal with case that auto_delete_vec + might be integer_two_node anymore. + (expand_vec_init): Rework for initialization-correctness and + exception-correctness. + * typeck2.c (process_init_constructor): Make mutual exclusivity + of cases more obvious. + +1998-10-29 Jason Merrill + + * decl.c (lookup_name_real): OK, only warn if not lexing. + Simplify suggested fix. + + * cp-tree.h (IDENTIFIER_MARKED): New macro. + * search.c (lookup_conversions): Use breadth_first_search. + (add_conversions): Avoid adding two conversions to the same type. + (breadth_first_search): Work with base binfos, rather + than binfos and base indices. + (get_virtual_destructor): Adjust. + (tree_has_any_destructor_p): Adjust. + (get_matching_virtual): Adjust. + + * pt.c (push_template_decl_real): Generalize check for incorrect + number of template parms. + (is_member_template_class): #if 0. + +1998-10-29 Richard Henderson + + * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@, + last. + +1998-10-28 Zack Weinberg + + * lex.c: Call check_newline from lang_init always. After + calling cpp_start_read, set yy_cur and yy_lim to read from the + cpplib token buffer. + +1998-10-28 Jason Merrill + + * class.c (instantiate_type): Don't consider templates for a normal + match. + + * class.c (finish_struct_1): Don't complain about non-copy + assignment ops in union members. + + * class.c (build_vtable): Don't pass at_eof to import_export_vtable. + (prepare_fresh_vtable): Likewise. + (finish_struct_1): Don't call import_export_class. + * decl2.c (finish_vtable_vardecl): Do import/export stuff. + (finish_prevtable_vardecl): Lose. + (finish_file): Don't call it. + * pt.c (instantiate_class_template): Likewise. + * cp-tree.h: Remove it. + + * init.c (build_delete): Reset TYPE_HAS_DESTRUCTOR here. + * decl.c (finish_function): Not here. + (start_function): Do set DECL_INITIAL. + + * pt.c (push_template_decl_real): Complain about default template + args for enclosing classes. + + * call.c (add_function_candidate): Treat conversion functions + as coming from the argument's class. + * cp-tree.h (DECL_CONV_FN_P): New fn. + (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE. + * class.c (add_method): Use DECL_CONV_FN_P. + * decl2.c (check_classfn): Likewise. + * error.c (dump_function_name): Likewise. + (dump_function_decl): Likewise. + * pt.c (fn_type_unification): Likewise. + * search.c (add_conversions): Likewise. + +1998-10-27 Jason Merrill + + * lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL. + * method.c (hack_identifier): Also check for using RESULT_DECL + from outer context. + +1998-10-27 Mark Mitchell + + * decl.c (grokdeclarator): Use type_quals, rather than constp, + consistently. + +1998-10-27 Jason Merrill + + * call.c (standard_conversion): instantiate_type here. + (reference_binding): And here. + (implicit_conversion): Not here. + (build_op_delete_call): No need to cons up an OVERLOAD. + * cvt.c (cp_convert_to_pointer): instantiate_type here. + (convert_to_reference): And here. + * decl.c (grok_reference_init): Not here. + (grokparms): Or here. + * typeck2.c (digest_init): Or here. + * typeck.c (decay_conversion): Take the address of overloaded + functions, too. + (require_instantiated_type): Lose. + (convert_arguments): Don't handle unknown types here. + (build_c_cast): Likewise. + (build_binary_op): Gut. + (build_conditional_expr): Don't require_instantiated_type. + (build_modify_expr): Likewise. + (build_static_cast): Don't instantiate_type. + (build_reinterpret_cast): Likewise. + (build_const_cast): Likewise. + (convert_for_initialization): Likewise. + (build_ptrmemfunc): Use type_unknown_p. + (convert_for_assignment): Also do default_conversion on overloaded + functions. Hand them off to ocp_convert. + +1998-10-26 Mark Mitchell + + * error.c (dump_decl): Deal with TEMPLATE_DECLs that are + VAR_DECLs. Handle vtables whose DECL_CONTEXT is not a type. + + * class.c (finish_struct_1): Use build_cplus_array_type to build + array types. + * decl.c (init_decl_processing): Likewise. + * except.c (expand_end_eh_spec): Likewise. + * search.c (expand_upcast_fixups): Simplify very slightly. + +1998-10-26 Jason Merrill + + * decl.c (grokdeclarator): Complain about a variable using + constructor syntax coming back null from start_decl. + + * friend.c (make_friend_class): Complain about trying to make + a non-class type a friend. + + * decl.c (grokfndecl): Set DECL_INITIAL for a defn here. + (start_function): Not here. + +1998-10-26 Brendan Kehoe + + * decl.c (grokdeclarator): Disallow `explicit' in a friend declaration. + +1998-10-26 Jason Merrill + + * typeck2.c (process_init_constructor): Only skip anonymous fields + if they are bitfields. + + * cp-tree.def (TYPEOF_TYPE): New code. + * error.c (dump_type_real): Handle it. + * pt.c (tsubst): Likewise. + * tree.c (search_tree): Likewise. + * semantics.c (finish_typeof): New fn. + * parse.y (typespec): Use it. + * cp-tree.h: Declare it. + +1998-10-26 Manfred Hollstein + + * cp-tree.h (FORMAT_VBASE_NAME): Make definition unconditional. + +1998-10-26 Jason Merrill + + * typeck.c (convert_arguments): Don't handle pmf references + specially. + + * init.c (build_member_call): Don't try to convert to the base type + if it's ambiguous or pedantic. + + * typeck2.c (check_for_new_type): Only depend on pedantic for + C-style casts. + +1998-10-25 Mark Mitchell + + * decl.c (grokdeclarator): Set DECL_NONCONVERTING_P for all + non-converting constructors. + +1998-10-24 Martin von Löwis + + * gxxint.texi: Correct documentation for n, N, Q, and B. + +1998-10-23 Martin von Löwis + + * parse.y (condition): Convert VAR_DECL from reference to indirect + reference. + +1998-10-23 Andrew MacLeod + + * exception.cc (__cp_pop_exception): Free the original exception + value, not the potentially coerced one. + +1998-10-23 Mark Mitchell + + * Makefile.in (hash.h): Run gperf when necessary. + + * cp-tree.h (CP_TYPE_READONLY): Remove. + (CP_TYPE_VOLATILE): Likewise. + (CP_TYPE_QUALS): New macro. + (CP_TYPE_CONST_P): Likewise. + (CP_TYPE_VOLATILE_P): Likewise. + (CP_TYPE_RESTRICT_P): Likewise. + (CP_TYPE_CONST_NON_VOLATILE_P): Likewise. + (cp_build_type_variant): Rename to ... + (cp_build_qualified_type): New function. + (c_apply_type_quals_to_decl): Declare. + (SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'. + (SIGNATURE_REFERENCE_NAME_FORMAT): Likewise. + (cp_type_qual_from_rid): New function. + (compparms): Remove unused parameter. All callers changed. + (cp_type_quals): New function. + (at_least_as_qualified_p): Likewise. + (more_qualified_p): Likewise. + + * call.c (standard_conversion): Replace calls to + cp_build_type_variant with cp_build_qualified_type. Use + CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to + compare them. Use CP_TYPE_* macros to check qualifiers. + (reference_binding): Likewise. + (implicit_conversion): Likewise. + (add_builtin_candidates): Likewise. + (build_over_call): Likewise. + * class.c (overrides): Compare all qualifiers, not just `const', + on method declarations. + * cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc. + (convert_pointer_to_real): Likewise. + (type_promotes_to): Likewise. + * decl.c (check_for_uninitialized_const_var): New function. + (init_decl_processing): More CP_TYPE_QUALS conversion, etc. + (cp_finish_decl): Use check_for_uninitialized_const_var. + (grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to + handle `restrict'. + (grok_ctor_properties): Likewise. + (grok_op_properties): Likewise. + (start_function): Likewise. + (rever_static_member_fn): Likewise. + * decl2.c (grok_method_quals): Likewise. + (grokfield): Likewise. + * error.c (dump_readonly_or_volatile): Rename to ... + (dump_qualifiers): New function. Handle `restrict'. + (dump_type_real): Use it. + (dump_aggr_type): Likewise. + (dump_type_prefix): Likewise. + (dump_type_suffix): Likewise. + (dump_function_decl): Likewise. + (cv_as_string): Likewise. + * gxx.gperf: Add __restrict and __restrict__. + * gxxint.texi: Document `u' as used for `__restrict', and a few + other previously undocumented codes. + * hash.h: Regenerated. + * init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc. + (build_member_call): Likewise. + (build_new_1): Likewise. + * lex.c (init_parse): Add entry for RID_RESTRICT. + (cons_up_default_function): More CP_TYPE_QUALS conversion, etc. + (cp_type_qual_from_rid): Define. + * lex.h (enum rid): Add RID_RESTRICT. + * method.c (process_modifiers): Deal with `restrict'. + * parse.y (primary): More CP_TYPE_QUALS conversion, etc. + * parse.c: Regenerated. + * pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc. + (tsubst_aggr_type): Likewise. + (tsubst): Likewise. + (check_cv_quals_for_unify): Likewise. + (unify): Likewise. + * rtti.c (init_rtti_processing): Likewise. + (build_headof): Likewise. + (get_tinfo_var): Likewise. + (buidl_dynamic_cast_1): Likewise. Fix `volatile' handling. + (expand_class_desc): Likewise. + (expand_attr_desc): Likewise. + (synthesize_tinfo_fn): Likewise. + * search.c (covariant_return_p): Likewise. Fix `volatile' handling. + (get_matching_virtual): Likewise. + (expand_upcast_fixups): Likewise. + * sig.c (build_signature_pointer_or_reference_name): Take + type_quals, not constp and volatilep. + (build_signature_pointer_or_reference_type): Likewise. + (match_method_types): More CP_TYPE_QUALS conversion, etc. + (build_signature_pointer_constructor): Likewise. + (build_signature_method_call): Likewise. + * tree.c (build_cplus_array_type): Likewise. + (cp_build_type_variant): Rename to ... + (cp_build_qualified_type): New function. Deal with `__restrict'. + (canonical_type_variant): More CP_TYPE_QUALS conversion, etc. + (build_exception_variant): Likewise. + (mapcar): Likewise. + * typeck.c (qualif_type): Likewise. + (common_type): Likewise. + (comptypes): Likewise. + (comp_cv_target_types): Likewise. + (at_least_as_qualified_p): Define. + (more_qualified_p): Likewise. + (comp_cv_qualification): More CP_TYPE_QUALS conversion, etc. + (compparms): Likewise. + (inline_conversion): Likewise. + (string_conv_p): Likewise. + (build_component_ref): Likewise. + (build_indirect_ref): Likewise. + (build_array_ref): Likewise. + (build_unary_op): Likewise. + (build_conditional_expr): Likewise. + (build_static_cast): Likewise. + (build_c_cast): Likewise. + (build_modify_expr): Likewise. + (convert_For_assignment): Likewise. + (comp_ptr_ttypes_real): Likewise. + (cp_type_quals): New function. + +1998-10-23 Jason Merrill + + * cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays. + (CP_TYPE_VOLATILE): Likewise. + * decl.c (grokdeclarator): Use them. + * tree.c (canonical_type_variant): Likewise. + +1998-10-22 Martin von Löwis + + * parse.y (named_class_head): Push into class while parsing the + base class list. + * decl2.c (push_scope, pop_scope): New functions. + * cp-tree.h: Declare them. + * init.c (build_new_1): Delay cleanup until end of full expression. + +1998-10-21 Jason Merrill + + * typeck.c (build_component_ref): Use of a type here is an error. + +1998-10-19 Jason Merrill + + Revamp references to member functions. + * method.c (hack_identifier): Call build_component_ref for a + reference to a member function. + * typeck.c (build_component_ref): Only return a single function + if it's static. Otherwise, return a COMPONENT_REF. + (build_x_function_call): Handle a COMPONENT_REF. + (build_unary_op): Handle all unknown-type things. + * decl2.c (arg_assoc): Handle COMPONENT_REF. + * class.c (instantiate_type): Complain if the function we get is a + nonstatic member function. Remove code for finding "compatible" + functions. + * pt.c (tsubst_copy): Handle NOP_EXPR. + * tree.c (build_dummy_object): New fn. + (maybe_dummy_object): New fn. + (is_dummy_object): New fn. + * cp-tree.h: Declare them. + * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object. + * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object. + * init.c (build_member_call): Use maybe_dummy_object and + is_dummy_object. + (build_offset_ref): Use maybe_dummy_object. + (resolve_offset_ref): Use is_dummy_object. + * typeck.c (build_x_function_call): Call build_dummy_object. + (unary_complex_lvalue): Call is_dummy_object. + + * typeck.c (build_component_addr): Make sure field is a field. + + * call.c (build_new_op): Delete obsolete code. + + * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args. + +1998-10-18 Martin von Löwis + + * decl2.c (validate_nonmember_using_decl): Fix using-directives of + std if std is ignored. + +1998-10-18 Jason Merrill + + * decl.c (grokvardecl): Fix thinko. + + * decl.c (grokdeclarator): Embedded attrs bind to the right, + not the left. + + * parse.y (fn.def2): Fix 'attrs' format. + +1998-10-18 Alastair J. Houghton + + * Makefile.in (CONFLICTS): Update. + * parse.y (expr_or_declarator_intern): New rule. + (expr_or_declarator, direct_notype_declarator, primary, + functional_cast): Use it. + (notype_declarator_intern): New rule. + (notype_declarator, complex_notype_declarator): Use it. + +1998-10-17 Jason Merrill + + * decl.c (grokfndecl): Set DECL_CONTEXT to namespace if appropriate. + (grokvardecl): Likewise. + +Sat Oct 17 23:27:20 1998 Kaveh R. Ghazi + + * class.c (make_method_vec): Cast 1st argument of `bzero' to (PTR). + (add_method): Likewise for arguments 1 & 2 of `bcopy'. + + * decl.c (signal_catch): Mark with ATTRIBUTE_NORETURN. + + * pt.c (process_partial_specialization): Cast 1st argument of + `bzero' to (PTR). + + * tree.c (build_base_fields): Cast `base_align' to (int) when + comparing against one. + +1998-10-16 Mark Mitchell + + * decl.c (lookup_name_real): Handle template parameters for member + templates where said parameters have the same name as the + surrounding class. + + * decl.c (expand_static_init): Build cleanups before entering the + anonymous function used to do them to avoid access-checking + confusion. + + * decl.c (grokfndecl): Add back call to cplus_decl_attributes + accidentally removed by previous change, and make DECL_RTL here. + * class.c (add_method): Don't make DECL_RTL here. + + * pt.c (for_each_template_parm): Don't examine uninstantiated + default arguments. + +1998-10-16 Dave Brolley + + * lex.c (real_yylex): Fix unaligned access of wchar_t. + +1998-10-16 Mark Mitchell + + * class.c (add_method): Fix documentation to reflect previous + changes. Check for duplicate method declarations here. + * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL + correctly; such things never match. + (grokfndecl): Don't look for duplicate methods here. + * decl2.c (check_classfn): Don't assume names are mangled. + Don't add bogus member function declarations to a class before the + class type is complete. + (grokfield): Reformat error message. + * method.c (set_mangled_name_for_decl): Don't mangle names while + processing_template_decl. + +1998-10-16 Jason Merrill + + * typeck.c (build_indirect_ref): Complain about a pointer to data + member, too. + * typeck2.c (build_m_component_ref): Don't indirect a pointer to + data member. + * init.c (resolve_offset_ref): Don't undo the above. + + * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros. + (struct lang_decl_flags): Add `bitfield'. + * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of + DECL_BIT_FIELD. + * decl2.c (grokbitfield, grok_alignof): Likewise. + * init.c (build_offset_ref): Likewise. + * typeck.c (build_component_addr, expr_sizeof): Likewise. + * cvt.c (build_up_reference): Don't crash if taking the address + returns error_mark_node. + + * decl.c (grokfndecl): Also check ctype when checking for ::main(). + +1998-10-15 Jason Merrill + + * decl.c (grokfndecl): ::main and __builtin_* get C linkage. + Do mangling here. + (grokdeclarator): Instead of here. + * friend.c (do_friend): Lose special handling of ::main and + __builtin_*. + * cp-tree.h (DECL_MAIN_P): Check for C linkage. + + * spew.c (yylex): Clear looking_for_typename if we got + 'enum { ... };'. + +1998-10-15 Mark Mitchell + + * class.c (maybe_warn_about_overly_private_class): Improve error + messages for class with only private constructors. + + * cp-tree.def (TYPENAME_TYPE): Add to documentation. + * cp-tree.h (TYPENAME_TYPE_FULLNAME): Document. + (build_typename_type): New function. + * decl.c (build_typename_type): Broken out from ... + (make_typename_type): Use it. + * search.c (lookup_field): Likewise. + +1998-10-14 Benjamin Kosnik + + * pt.c (convert_nontype_argument): Check against type_referred_to. + * decl.c (grokvardecl): Check for declarator name before building + DECL_ASSEMBLER_NAME. + +1998-10-14 Mark Mitchell + + * pt.c (lookup_template_class): Add comment. + (instantiate_class_template): Don't mark the _TYPE node for + member class templates as an instantiation. + +1998-10-14 Jason Merrill + + * decl.c (grokfndecl): Fix my thinko. + +1998-10-13 Jason Merrill + + * tinfo2.cc (fast_compare): Remove. + (before): Just use strcmp. + * tinfo.cc (operator==): Just use strcmp. + +1998-10-13 Klaus-Georg Adams + + * decl.c (grokfndecl): Don't check for linkage in `extern "C"' + declarations. + +1998-10-13 Mark Mitchell + + * cp-tree.h (specializations_of_same_template_p): Remove. + * search.c (get_template_base): Don't use it. + (get_template_base_recursive): Likewise. + * pt.c (specializations_of_same_template_p): Remove. + (unify): Don't use it. + (lookup_template_class): Find the correct parent when setting + CLASSTYPE_TI_TEMPLATE. + +1998-10-12 Jason Merrill + + * tinfo.cc (operator==): Always compare names. + +1998-10-12 Herman ten Brugge + + * decl.c (start_function): Fix cut-and-paste error. + +1998-10-12 Jason Merrill + + * inc/typeinfo: Add #pragma interface. + (operator!=): Just call operator==. + * tinfo.cc: Add #pragma implementation. + (operator==): Move from inc/typeinfo and tinfo2.cc. + Check __COMMON_UNRELIABLE instead of _WIN32. + + * typeck2.c (my_friendly_abort): Add URL. + +1998-10-12 Alastair J. Houghton + + * decl.c (start_method): Added extra parameter for attributes. + * cp-tree.h (start_method): Update prototype. + * parse.y (fn.def2): Update start_method parameter list. + +1998-10-11 Mark Mitchell + + * cp-tree.h (specializations_of_same_template_p): Declare. + * pt.c (specializations_of_same_template_p): New function. + (unify): Use it. + * search.c (get_template_base): Use it. + (get_template_base_recursive): Likewise. + +1998-10-10 Manfred Hollstein + + * decl2.c (start_objects): Add new variable `joiner' and + initialize it properly. + +1998-10-09 Mark Mitchell + + * search.c (expand_upcast_fixups): Tweak to match 1998-10-07 + change to vtable types. + + * cvt.c (ocp_convert): Avoid infinite recursion caused by + 1998-10-03 change. + +1998-10-08 Jason Merrill + + * pt.c (resolve_overloaded_unification): New fn. + (try_one_overload): Likewise. + (unify): Don't fail on unknown type. + (type_unification_real): Likewise. Use resolve_overloaded_unification + to handle an overloaded argument. + (template_args_equal): Split out... + (comp_template_args): From here. + (determine_specialization): Also allow a template with more + parms than were explicitly specified. + * cp-tree.h: Add template_args_equal. + * call.c (resolve_args): Remove TEMPLATE_ID_EXPR code. + +Thu Oct 8 15:58:30 1998 Anthony Green + + * semantics.c (finish_asm_stmt): Revert my 1998-09-28 + change. + +Thu Oct 8 06:00:19 1998 Jeffrey A Law (law@cygnus.com) + + * typeck.c (unsigned_type): Only return TItype nodes when + HOST_BITS_PER_WIDE_INT is >= 64 bits. + (signed_type): Likewise. + * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare + when HOST_BITS_PER_WIDE_INT is >= 64 bits. + (init_decl_processing): Only create TItype nodes when + HOST_BITS_PER_WIDE_INT is >= 64 bits. + * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare + when HOST_BITS_PER_WIDE_INT is >= 64 bits. + +Wed Oct 7 12:32:44 1998 Kaveh R. Ghazi + + * Makefile.in (hash.h): Add -L KR-C -F ', 0, 0' flags to gperf. + (gxx.gperf): Update comments describing invocation flags. + (hash.h): Regenerate using gperf 2.7.1 (19981006 egcs). + +1998-10-07 Mark Mitchell + + * class.c (finish_struct_1): Add commentary on previous change. + + * cp-tree.h (vtbl_ptr_type_node): New variable. + * class.c (build_vtbl_ref): Don't indirect through the vptr; it's + already of the right type. + (finish_struct_1): Make the vptr be of type vtbl_ptr_type_node. + Simplify code to grow vtable. + * decl.c (vtbl_ptr_type_node): Define. + (init_decl_processing): Initialize it. + +1998-10-06 Mark Mitchell + + * cp-tree.def (PTRMEM_CST): New tree node. + * cp-tree.h (ptrmem_cst): New type. + (lang_type): Remove local_typedecls. + (dummy): Increase to 12 bits from 11. + (CLASSTYPE_LOCAL_TYPEDECLS): Remove. + (PTRMEM_CST_CLASS): New macro. + (PTRMEM_CST_MEMBER): Likewise. + (current_access_specifier): New variable. + (current_class_type): Remove duplicate declaration. + (finish_struct): Change prototype. + (unreverse_member_declarations): New function. + (pushdecl_class_level): Change prototype. + (grok_enum_decls): Remove. + (fixup_anonymous_union): New function. + (grok_x_components): Change prototype. + (tsubst_chain): Remove. + (finish_member_template_decl): Likewise. + (check_explicit_specialization): Fix indentation. + (finish_class_definition): Change prototype. + (finish_member_class_template): Likewise. + (finish_member_declaration): New function. + (check_multiple_declarators): Likewise. + * class.c (class_stack_node_t): New type. + (current_class_base): Remove. + (current_class_stack): Change type. + (current_access_specifier): New variable. + (grow_method): Remove. + (check_member_decl_is_same_in_complete_scope): Break out from + finish_struct. + (make_method_vec): New function. + (free_method_vec): Likewise. + (add_implicitly_declared_members): Break out from finish_struct_1. + (free_method_vecs): New variable. + (add_method): Rework for direct use from parser. + (handle_using_decl): Watch for NULL_TREE while iterating through + CLASSTYPE_METHOD_VEC. + (finish_struct_methods): Don't build CLASSTYPE_METHOD_VEC here; + just do some error-checking. + (warn_hidden): Change iteration through CLASSTYPE_METHOD_VEC. + (finish_struct_1): Simplify. Use add_implicitly_declared_members. + (finish_struct): Change prototype. Simplify; fields and methods + are already set up at this point. + (init_class_processing): Set up current_class_stack. + (pushclass): Save current_access_specifier. + (popclass): Restore it. + (currently_open_class): Simplify. + (build_self_reference): Remove use of CLASSTYPE_LOCAL_TYPEDECLS. + * decl.c (saved_scope): Add access_specifier. + (maybe_push_to_top_level): Save it. + (pop_from_top_level): Restore it. + (maybe_process_template_type_declaration): Use + finish_member_declaration. + (pushtag): Likewise. + (pushdecl_class_level): Don't return a value. + (fixup_anonymous_union): Break out from grok_x_components. + (shadow_tag): Use it. + (xref_tag): Complain about using an elaborated type specifier to + reference a template type parameter or typedef name. + (xref_basetypes): Don't set CLASSTYPE_LOCAL_TYPEDECLS. + (current_local_enum): Remove. + (build_enumerator): Call finish_member_declaration. + (grok_enum_decls): Remove. + * decl2.c (grok_x_components): Simplify. + (check_classfn): Change iteration through CLASSTYPE_METHOD_VEC. + (grokfield): Don't set CLASSTYPE_LOCAL_TYPEDECLS. + (merge_functions): Add to comment. + (arg_assoc_type): Prototype. + (arg_assoc): Pass as many arguments as there are parameters. + * error.c (dump_expr): Handle PTRMEM_CST. Improve handling of + OFFSET_REF. + * expr.c (cpls_expand_expr): Remove dead code. Handle + PTRMEM_CST. + * friend.c (do_friend): Lookup friends when in nested classes. + Change comments. + * init.c (build_offset_ref): Do lookup even for classes that are + only partially defined. + (decl_constant_value): Remove dead code. + * method.c (build_overload_value): Remove hack where by TYPE was + not a TYPE. Handle PTRMEM_CST. + (build_template_parm_names): Don't pass a PARM_DECL where a TYPE + should go. + * parse.y (components, notype_components, component_decl, + component_decl_1, component_declarator, component_declarator0): + Now all are itype rather than ttype. Rework to add members to + classes on the fly. + (typesqpecqual_reserved): Use check_multiple_declarators. + (structsp): Update class to finish_class_definition. + (do_xref_defn): Unsplit into named_class_head. + (access_specifier): Set current_access_specifier. + * pt.c (set_current_access_from_decl): New function. + (finish_member_template_decl): Don't take the parameters. + (comp_template_args): Make more robust. + (lookup_template_class): Don't use current_local_enum. + (for_each_template_parm): Handle PTRMEM_CST. + (instantiate_class_template): Use set_current_access_from_decl, + finish_member_declaration and unreverse_member_declarations. Set + lineno/input_filename before generating implicit member functions. + (type_unification_real): Don't assume back-unification happens + only for the last argument. + (regenerate_decl_from_template): Call pushclass a bit earlier. + (tsubst_chain): Remove. + (tsubst_enum): Use set_current_access_from_decl. + (set_mangled_name_for_template_decl): Fix indentation. + * search.c (lookup_fnfields_1): Change iteration through + CLASSTYPE_METHOD_VEC. + (dfs_pushdecls): Likewise. + (dfs_compress_decls): Likewise. + (add_conversions): Likewise. + * semantics.c (finish_class_definition): Don't take components. + Change call to finish_struct. + (finish_member_declaration): New function. + (finish_member_class_template): Don't take template parameters. + Change call to grok_x_components. Call finish_member_template_decl. + (check_multiple_declarators): New function. + * sig.c (append_signature_fields): Work from the TYPE_METHODS, not + a passed in fieldlist. + * tree.c (search_tree): Handle PTRMEM_CST. + (mapcar): Likewise. + * typeck.c (unary_complex_lvalue): Build PTRMEM_CSTs, not + INTEGER_CSTs, for pointer-to-data members. + + * call.c (resolve_args): Resolve template specializations, if + possible. + +Tue Oct 6 07:57:26 1998 Kaveh R. Ghazi + + * Makefile.in (spew.o): Depend on toplev.h. + + * call.c (compare_ics): Initialize variables `deref_from_type2', + `deref_to_type1' and `deref_to_type2'. + + * except.c (get_eh_type): Hide prototype and definition. + (process_start_catch_block_old): Remove unused static prototype. + + * pt.c (tsubst_decl): Initialize variable `argvec'. + + * spew.c: Include toplev.h. + +1998-10-05 Jason Merrill -Sat Feb 20 15:08:42 1999 Jeffrey A Law (law@cygnus.com) + * pt.c (instantiate_decl): Do save and restore file position. - 1999-01-25 Martin von Löwis - * tree.c (equal_functions): New function. - (ovl_member): Call it. +1998-10-05 Martin von Löwis -Sat Feb 6 17:00:48 1999 Jeffrey A Law (law@cygnus.com) + * method.c (build_decl_overload_real): Clear + numeric_output_need_bar after __. - * typeck2.c: Update email addresses. +1998-10-05 Nathan Sidwell -1998-11-16 Jason Merrill + * call.c (build_new_method_call): Issue 'incomplete type' error, + if class is not defined. - * typeck2.c (my_friendly_abort): Don't fatal twice in a row. +1998-10-05 Kaveh R. Ghazi -1998-11-15 Jason Merrill + * call.c (build_object_call): Move declaration of variable + `fn' into the scope where it is used. Don't access variable + `fn' when it is uninitialized, instead use `fns'. - * typeck2.c (my_friendly_abort): Add URL in the other case, too. +1998-10-04 Theodore Papadopoulo -1998-11-13 Jason Merrill + * errfn.c (cp_thing): Print buf as a string not as a printf format + to avoid problems with the operator%. Consequently, `%%' sequences + in format are copied as `%' in buf. - * rtti.c (synthesize_tinfo_fn): Call import_export_decl here. - (get_tinfo_fn): Not here. +1998-10-04 Jason Merrill -1998-11-08 Mark Mitchell + * pt.c (pop_tinst_level): Call extract_interface_info. + (instantiate_decl): Don't save and restore file position. + + * decl.c (cp_finish_decl): Make statics in extern inlines and + templates common, if possible and the target doesn't support weak + symbols. + + * decl.c (grokdeclarator): Remove redundant calls to + build_type_variant and some duplicated code. + * sig.c (build_signature_reference_type): Only take the type parm. + (build_signature_pointer_type): Likewise. + * tree.c (build_cplus_method_type): Adjust. + * cp-tree.h: Update. + +1998-10-04 Mark Mitchell + + * call.c (build_over_call): Make pedwarns about dropped qualifiers + into full-fledged errors. + * cvt.c (convert_to_reference): Likewise. + * typeck.c (convert_for_assignment): Likewise. + + * search.c (expand_upcast_vtables): In addition to unsetting + TREE_READONLY, remove top-level const type qualifier. + +1998-10-03 Mark Mitchell + + * class.c (current_class_ptr, current_class_ref): Clarify + documentation. + * cvt.c (ocp_convert): Don't expect fold to remove all trivial + NOP type conversions. + * decl.c (decls_match): Use comptypes directly; ignore + qualifiers on the DECL. + (duplicate_decls): Remove qualifier checks on DECL. + (grokdeclarator): Make the type built up include top-level + qualifiers. + * decl2.c (do_dtors): Fix spelling error. + * error.c (dump_simple_decl): Don't look at qualifiers on the decl + when printing type information. + * init.c (build_new_1): Add documentation. Deal with the fact + that type of allocated memory now contains qualifiers. + * lex.c (is_global): Improve error-recovery. + * sig.c (build_member_function_pointer): Don't cast away const + on fields of sigtable_entry_type. + * tree.c (lvalue_type): Don't look at top-level qualifiers on + expressions. + * typeck.c (decay_conversion): Likewise. + (build_component_ref): Make sure the type of the COMPONENT_REF + contains top-level qualifiers, as appropriate. Improve + error-handling. + (build_indirect_ref): Simplify. Don't strip top-level qualifiers. + (build_array_ref): Likewise. + (build_unary_op): Improve error-recovery. + (unary_complex_lvalue): Make taking the address a bound member + function an error, not a sorry. + (build_conditional_expr): Look at the type qualifiers, not the + qualifiers on the expression itself. + +1998-10-03 Jason Merrill + + * decl2.c (merge_functions): Remove duplicates. + + * decl2.c: Add -f{no-,}implicit-inline-templates. + (import_export_decl): Check it. + + * decl.c (lookup_name_real): Template parms also take precedence + over implicit typename. Only warn if yylex. + + * typeck.c (build_conditional_expr): Only fold if ifexp is an + INTEGER_CST. + + * decl2.c (finish_vtable_vardecl): Check DECL_INTERFACE_KNOWN + instead of linkage. + +1998-10-01 Jason Merrill + + * cp-tree.h (FORMAT_VBASE_NAME): New macro. + * class.c (build_vbase_pointer): Use it. + * rtti.c (expand_class_desc): Likewise. + * tree.c (build_vbase_pointer_fields): Likewise. + +Thu Oct 1 10:43:45 1998 Nick Clifton + + * decl.c (start_decl): Add invocation of + SET_DEFAULT_DECL_ATTRIBUTES, if defined. + (start_function): Add invocation of + SET_DEFAULT_DECL_ATTRIBUTES, if defined. + + * lex.c: Replace occurrences of HANDLE_SYSV_PRAGMA with + HANDLE_GENERIC_PRAGMAS. + +1998-09-28 Anthony Green + + * semantics.c (finish_asm_stmt): Always permit volatile asms. + +1998-09-28 Mark Mitchell * decl.c (grokdeclarator): Tighten checks for invalid destructors. Improve error-messages and error-recovery. - * decl2.c (check_classfn): Don't assume that mangled destructor + * decl2.c (check_classfn): Don't assume that mangled destructor names contain type information. -1998-11-02 Jason Merrill +1998-09-25 Jason Merrill - * decl2.c (import_export_decl): Call import_export_class. + * search.c (get_base_distance): Remove assert. -1998-10-28 Jason Merrill + * decl2.c (build_anon_union_vars): Don't process a field with no + name. + (finish_anon_union): Also complain about local anon unions with no + members. - * class.c (finish_struct_1): Don't complain about non-copy - assignment ops in union members. +1998-09-25 Martin von Löwis - * class.c (build_vtable): Don't pass at_eof to import_export_vtable. - (prepare_fresh_vtable): Likewise. - (finish_struct_1): Don't call import_export_class. - * decl2.c (finish_vtable_vardecl): Do import/export stuff. - (finish_prevtable_vardecl): Lose. - (finish_file): Don't call it. + * decl.c (lookup_namespace_name): If the name is a namespace, + return it immediately. + +Fri Sep 25 11:45:38 1998 Kaveh R. Ghazi + + * cp-tree.h (define_case_label): Remove unused parameter. + (check_java_method): Likewise. + (grokclassfn): Likewise. + (expand_aggr_init): Likewise. + (build_x_delete): Likewise. + (maybe_end_member_template_processing): Likewise. + (unshare_base_binfos): Add prototype. + (string_conv_p): Likewise. + (my_friendly_abort): Mark with ATTRIBUTE_NORETURN. + + * cvt.c (build_up_reference): Remove unused parameter + `checkconst', all callers changed. + (build_type_conversion): Mark parameter `code' with + ATTRIBUTE_UNUSED. + (build_expr_type_conversion): Initialize variable `conv'. + + * decl.c (push_namespace): Initialize variable `d'. + (define_case_label): Remove unused parameter `decl', all callers + changed. + + * decl2.c (lang_decode_option): If !USE_CPPLIB, mark parameter + `argc' with ATTRIBUTE_UNUSED. + (grokclassfn): Remove unused parameter `cname', all callers + changed. + (check_java_method): Likewise for parameter `ctype'. + (copy_assignment_arg_p): Mark parameter `virtualp' with + ATTRIBUTE_UNUSED. + (finish_prevtable_vardecl): Likewise for parameter `prev'. + + * expr.c (extract_init): Likewise for parameters `decl' and `init'. + + * init.c (expand_aggr_init_1): Remove unused parameter + `alias_this', all callers changed. + (expand_aggr_init): Likewise. + (expand_default_init): Likewise. + (build_new_1): Initialize variable `susp'. + (build_x_delete): Remove unused parameter `type', all callers + changed. + + * lex.c (set_typedecl_interface_info): Mark parameter `prev' with + ATTRIBUTE_UNUSED. + (readescape): Use (unsigned) value in shift. + (real_yylex): Likewise. Likewise. Also cast `sizeof' to int when + comparing to a signed quantity. + + * pt.c (maybe_end_member_template_processing): Remove unused + parameter `decl', all callers changed. + (check_explicit_specialization): Add braces around empty body in + an else-statement. + (current_template_args): Initialize variable `args'. + (lookup_template_class): Likewise for variable `prev_local_enum'. + (tsubst_decl): Likewise for variable `r'. + (set_mangled_name_for_template_decl): Initialize variable + `context'. + + * spew.c (scan_tokens): Change type of parameter `n' to unsigned. + Likewise for variable `i'. + (yylex): Initialize variable `trrr'. + + * typeck.c (compparms): Mark variable `strict' with + ATTRIBUTE_UNUSED. + + * xref.c (simplify_type): Cast argument of ctype function to + `unsigned char'. + +1998-09-24 Mark Mitchell + + * cp-tree.h (language_lvalue_valid): Remove. + * decl.c (grokdeclarator): Don't disallow references to functions. + * tree.c (lvalue_p_1): New function, combining duplicated + code from ... + (lvalue_p): Use it. + (real_lvalue_p): Likewise. + * typeck.c (language_lvalue_valid): Remove. + (build_modify_expr): Treat FUNCTION_TYPEs as readonly, even though + they don't have TREE_READONLY set. + * typeck2.c (readonly_error): Add case for FUNCTION_DECLs. + +1998-09-24 Benjamin Kosnik + + * spew.c (yylex): Give diagnostic. + * hash.h (is_reserved_word): Add export. + * gxx.gperf: Likewise. + * lex.h (rid): Add RID_EXPORT. + * lex.c (init_parse): Likewise. + +Tue Sep 22 21:01:19 1998 Gerald Pfeifer + + * friend.c (do_friend): Make warning a full sentence. + +1998-09-22 Mark Mitchell + + * parse.y (component_decl_list): Improve error-recovery. + +1998-09-22 Benjamin Kosnik + + * decl.c (make_typename_type): Move error to point where name + variable can be used by dump_type. + +1998-09-22 Mark Mitchell + + * decl.c (grokfndecl): Improve error-recovery. + * decl2.c (grokfield): Likewise. + * pt.c (finish_member_template_decl): Likewise. + +1998-09-20 Martin von Löwis + + * method.c (hack_identifier): Finding multiple members is always + an error. + +1998-09-21 Per Bothner + + * Make-lang.in (c++-filt): Link libiberty.a after cxxmain.o. + +Mon Sep 21 01:53:05 1998 Felix Lee + + * lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT (). + +1998-09-20 Mark Mitchell + + * class.c (maybe_warn_about_overly_private_class): Reformat. + +1998-09-17 Andrew MacLeod + + * exception.cc (__cplus_type_matcher): Realign some code. + +1998-09-16 Mark Mitchell + + * Make-lang.in (tinfo.o): Use CXXFLAGS when compiling. + (tinfo2.o): Likewise. + (exception.o): Likewise. + (new.o): Likewise. + (opnew.o): Likewise. + (opnewnt.o): Likewise. + (opvnew.o): Likewise. + (opvnewnt.o): Likewise. + (opdel.o): Likewise. + (opdelnt.o): Likewise. + (opvdel.o): Likewise. + (opvdelnt.o): Likewise. + +1998-09-16 Richard Henderson + + * decl.c (init_decl_processing): Kill __builtin_fp and __builtin_sp. + +1998-09-15 Alexandre Oliva + + * call.c (build_field_call): Handle static data members too. + + * typeck.c (comptypes): When comparing pointer types, check + whether referred types match even in strictest modes. + +1998-09-15 Mark Mitchell + + * cp-tree.h: Revert previous change. + (finish_struct_methods): Remove declaration. + * class.c: Revert previous change. + (maybe_warn_about_overly_private_class): New function. + (finish_struct_methods): Declare here, and make static. Remove + unnecessary parameters. Tidy slightly. Use + maybe_warn_about_overly_private_class. + (finish_struct_1): Adjust. Remove check for private constructors, + now done elsewhere. + (finish_struct): Adjust. + +1998-09-15 Andrew MacLeod + + * except.c (expand_start_catch_block): No need to check for new + exception model. + (process_start_catch_block_old): Deleted. + (process_start_catch_block): Add call to start_decl_1(). + (expand_end_catch_block): Add call to end_catch_handler(). + * exception.cc (__cplus_type_matcher): Only check the exception + language if there is an exception table. + +1998-09-15 Andrew MacLeod + + * search.c (expand_indirect_vtbls_init): Mark temporary stack slots + as used to prevent conflicts with virtual function tables. + +1998-09-14 Mark Mitchell + + * cp-tree.h (lang_type): Add has_non_private_static_mem_fn. + (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN): New macro, to access it. + * class.c (maybe_class_too_private_p): New function. + (finish_struct_methods): Use it. + (finish_struct_1): Likewise. + (finish_struct): Set CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN if + appropriate. + + * pt.c (check_specialization_scope): Fix spelling error. + (check_explicit_specialization): Remove code to handle explicit + specializations in class scope; they are now correctly diagnosed + as errors. + +1998-09-10 Mark Mitchell + + * decl.c (pushdecl): Don't copy types if the + DECL_ABSTRACT_ORIGIN of the new decl matches the TYPE_NAME of the + type. + +1998-09-09 Kriang Lerdsuwanakij + + * class.c (get_enclosing_class): New function. + (is_base_of_enclosing_class): Likewise. + * cp-tree.h (get_enclosing_class): Declare. + (is_base_of_enclosing_class): Likewise. + * pt.c (coerce_template_parms): Use them. + +1998-09-09 Jason Merrill + + * g++spec.c (lang_specific_driver): Check whether MATH_LIBRARY is + null to decide whether to use it. + + * error.c (dump_type_real): Handle NAMESPACE_DECL. + * parse.y (base_class.1): Avoid crash on error. + +1998-09-08 Martin von Löwis + + * decl.c (make_typename_type): If context is a namespace, the code + is in error. + +1998-09-08 Mumit Khan + + * parse.y (nomods_initdcl0): Set up the parser stack correctly. + +1998-09-08 Mark Mitchell + + * cp-tree.h (anonymous_namespace_name): Declare. + * decl.c: Define it. + (push_namespace): Use anonymous_namespace_name, rather than local + static anon_name. + * error.c (dump_decl): If a namespace is named + anonymous_namespace_name, call it {anonymous}. + + * decl.c (grokparms): Distinguish between references and pointers + in error message. + +1998-09-08 Richard Henderson + Mark Mitchell + + * pt.c (process_partial_specialization): Consistently allocate + and zero tpd.parms based on ntparms. Use tpd2.parms, not + tpd.parms, where appropriate. + +Sun Sep 6 00:00:51 1998 Jeffrey A Law (law@cygnus.com) + + * Makefile.in (INCLUDES): Update after recent toplevel gcc + reorganizations. + +1998-09-05 Mark Mitchell + + * cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove. + * class.c (finish_struct): Remove hackery to deal with explicit + specializations in class scope. + * decl.c (grokfndecl): Improve error-recovery. + * decl2.c (grokfield): Likewise. + * pt.c (check_specialization_scope): New function. + (begin_specialization): Call it. + (process_partial_specialization): New function, split out from + push_template_decl. Check partial specializations more + stringently. + (push_template_decl): Call it. + (check_explicit_specialization): Don't attempt to handle explicit + specializations in class scope. + (template_parm_data): Document. Add current_arg and + arg_uses_template_parms. + (mark_template_parm): Set it. + (tsubst_arg_types): Remove unused variable. + * semantics.c (begin_class_definition): Tweak. + +1998-09-04 Mark Mitchell + + * inc/typeinfo (type_info::type_info(const char*)): Make + `explicit'. + + * cp-tree.h (hash_tree_cons_simple): New macro. + * pt.c (tsubst_arg_types): New function. Use hash_tree_cons. + (coerce_template_parms): Use make_temp_vec, instead of + make_tree_vec. Document this behavior. + (lookup_template_class): Likewise. + (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types. + Remove dead code (and add assertion to check its deadness). Fix + bug w.r.t. exception specifications. + +1998-09-03 Jason Merrill + + * decl2.c (import_export_vtable): Always make artificials comdat. + (import_export_decl): Likewise. + * pt.c (mark_decl_instantiated): Likewise. + +1998-09-03 Mark Mitchell + + * cp-tree.h (finish_globally_qualified_member_call_expr): + Rename to ... + (finish_qualified_call_expr). + * semantics.c: Likewise. + * parse.y (primary): Use it. + * method.c (hack_identifier): Remove redundant code. + + * init.c (resolve_offset_ref): Call convert_from_reference to + handle members of reference type. Improve error recovery. + +1998-09-03 Benjamin Kosnik + + * cp-tree.h: Declare warn_nontemplate_friend. + * decl2.c (lang_decode_option): Set. + * lang-options.h: Add -Wnon-template-friend. + * friend.c (do_friend): Use to toggle non-template function warning. + +1998-09-03 Mark Mitchell + + * decl.c (finish_enum): Don't resolve CONST_DECLs to their + corresponding INTEGER_CSTs when processing_template_decl. + * pt.c (tsubst_enum): Tweak accordingly. + +1998-09-03 Benjamin Kosnik + + * decl.c (pushdecl_class_level): Add warning here. + (pushdecl): Tweak. + +1998-09-02 Jason Merrill + + * cvt.c (convert_pointer_to_real): Tidy. + * search.c (get_base_distance_recursive): Simplify. + (get_base_distance): Likewise. + + * pt.c (unify): Only special-case INTEGER_TYPE if it uses template + parms. + +Wed Sep 02 09:25:29 1998 Nick Clifton + + * lex.c (check_newline): Call HANDLE_PRAGMA before + HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages + if unknown pragmas are encountered. + (handle_sysv_pragma): Interpret return code from + handle_pragma_token (). Return success/failure indication rather + than next unprocessed character. + (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. + +1998-09-01 Jason Merrill + + * decl2.c (output_vtable_inherit): Use %cDIGIT in the operands. + * class.c (build_vtable_entry_ref): Likewise. + +1998-09-01 Mark Mitchell + + * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. + * decl2.c (import_export_decl): Likewise. + * pt.c (instantiate_decl): Use it. + +1998-09-01 Jason Merrill + + * decl.c (lookup_name_real): Also do implicit typename thing for + artificial TYPE_DECLs. + * search.c (lookup_field): Likewise. + (lookup_fnfields, lookup_field): Adjust for implicit typename kludge. + * semantics.c (begin_constructor_declarator): Use enter_scope_of. + (enter_scope_of): Extract type from implicit typename. + (begin_class_definition): Likewise. + * lex.c (identifier_type): Handle implicit typename when checking + for SELFNAME. + + * cp-tree.h: Declare flag_strict_prototype. + * lex.c (do_scoped_id, do_identifier): Don't implicitly_declare if + -fstrict-prototype. + * decl.c (init_decl_processing): If -f{no,-}strict-prototype wasn't + specified, set it to the value of pedantic. + +1998-09-01 Mark Mitchell + + * decl2.c (arg_assoc): Handle template-id expressions as arguments. + +1998-08-31 Mark Mitchell + + * decl.c (finish_enum): Handle member enums of classes declared in + template functions. + + * decl2.c (grok_x_components): Strip attributes before calling + groktypename. + +1998-08-31 Jason Merrill + + * cp-tree.h, decl2.c: Remove support for -fall-virtual, + -fenum-int-equivalence and -fno-nonnull-objects. + * class.c (check_for_override): Remove support for -fall-virtual. + (finish_struct_1): Likewise. + * call.c (build_new_op): Remove support for -fenum-int-equivalence. + * typeck.c (build_binary_op_nodefault): Likewise. + * cvt.c (ocp_convert): Likewise. + * call.c (build_vfield_ref): Remove support for -fno-nonnull-objects. + * class.c (build_vbase_path): Likewise. + +Sun Aug 30 22:16:31 1998 H.J. Lu (hjl@gnu.org) + + * Makefile.in (INTERFACE): New, set to 1. + +1998-08-30 Mark Mitchell + + * error.c (dump_decl): Use CP_DECL_CONTEXT, not DECL_CONTEXT, when + comparing with global_namespace. + (dump_aggr_type): Likewise. + + * decl.c (grokfndecl): Issue error on declaration of friend + templates with explicit template arguments. + + * pt.c (convert_template_argument): New function, split out + from... + (coerce_template_parms): Here. + (tsubst): Attempt better error-recovery. + +1998-08-28 Benjamin Kosnik + + * pt.c (decl_template_parm_p): Add checks for + TEMPLATE_TEMPLATE_PARM. + +1998-08-28 Mark Mitchell + + * lex.c (do_identifier): Fix thinko in previous change. + +1998-08-28 Jason Merrill + + * search.c (dfs_search, binfo_for_vtable, dfs_bfv_helper): New fns. + * decl2.c (output_vtable_inherit): Call binfo_for_vtable. + +1998-08-28 Richard Henderson + + Add support for discarding unused virtual functions. + * lang-options.h: Add -fvtable-gc. + * cp-tree.h: Add flag_vtable_gc. + * decl2.c (output_vtable_inherit): New fn. + (finish_vtable_vardecl): Call it. + * class.c (build_vtable_entry_ref): New fn. + (build_vtbl_ref): Call it. + +1998-08-28 Mark Mitchell + + * cp-tree.h (build_enumerator): Take the enumeration type as a + parameter. + * decl.c (finish_enum): Don't set the TREE_TYPE for the + enumeration constant values if we're processing_template_decls. + Don't set the type for the CONST_DECLs either; that's done in + build_enumerator. + (build_enumerator): Take the enumeration type as a + parameter. + * lex.c (do_identifier): Don't resolve enumeration constants while + processing template declarations, even if they happen to be + TEMPLATE_PARM_INDEXs. + + * parse.y (current_enum_type): New variable. + (primary): Don't allow statement-expression in local classes just + as we don't in global classes. + (structsp): Use current_enum_type. + (enum_list): Likewise. + * pt.c (tsubst_enum): Don't check for NOP_EXPRs introduced by + finish_enum; they no longer occur. + + * cp-tree.h (finish_base_specifier): New function. + * parse.y (base_class): Use it. + * semantics.c (finish_base_specifier): Define it. + + * parse.y (structsp): Warn on use of typename outside of template + declarations. + +1998-08-27 Jason Merrill + + * lex.c (handle_cp_pragma): Remove #pragma vtable. + * lang-options.h: Remove +e options. + * decl2.c (lang_decode_option): Likewise. + (import_export_vtable): Don't check write_virtuals. + (finish_vtable_vardecl, finish_file): Likewise. + * search.c (dfs_debug_mark): Likewise. + * semantics.c (begin_class_definition): Likewise. + * class.c (build_vtable, finish_vtbls, finish_struct_1): Likewise. + + * call.c (build_over_call): Check flag_elide_constructors. + * decl2.c: flag_elide_constructors defaults to 1. + * typeck.c (convert_arguments): Remove return_loc parm. + (build_function_call_real): Adjust. + + * search.c: Tear out all mi_matrix and memoize code. + (lookup_field, lookup_fnfields): Use scratch_tree_cons. + * lang-options.h: Remove documentation for -fhandle-exceptions, + -fmemoize-lookups and -fsave-memoized. + * cp-tree.h: Lose mi_matrix and memoize support. + * decl2.c: Ignore -fmemoize-lookups and -fsave-memoized. + * class.c: Lose struct class_level. + (pushclass, popclass): Lose memoize support. + * init.c (build_offset_ref): Likewise. + + Never change BINFO_INHERITANCE_CHAIN. + * init.c (emit_base_init): Change modification of + BINFO_INHERITANCE_CHAIN to an assert. + * search.c (get_base_distance_recursive): Likewise. + (get_base_distance): Likewise. + (lookup_member): Likewise. + (convert_pointer_to_single_level): Likewise. + (lookup_field): Likewise. Lose setting TREE_VIA_* on TREE_LISTs. + (lookup_fnfields): Likewise. + * tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos. + (unshare_base_binfos): Don't call propagate_binfo_offsets. + (layout_basetypes): Call propagate_binfo_offsets instead of + unshare_base_binfos. + * decl.c (xref_basetypes): Call unshare_base_binfos. * pt.c (instantiate_class_template): Likewise. + * tree.c (reverse_path): Remove 'copy' parm; always make a + temporary copy. + * class.c (build_vbase_path): Just call it. + * search.c (compute_access): Likewise. Don't re-reverse. + +1998-08-27 Mark Mitchell + + * class.c (build_vbase_path): Use reverse_path. + (finish_base_struct): Move warnings for inaccessible bases to + layout_basetypes. + (modify_one_vtable): Remove check of TREE_USED (binfo). + (fixup_vtable_deltas1): Likewise. + * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here. + (xref_tag): Remove binfos parameter. + (make_binfo): Remove chain parameter. + (reverse_path): Add copy parameter. + * decl.c (init_decl_processing): Change calls to xref_tag. + (xref_tag): Remove binfos parameter. + (xref_basetypes): Change calls to make_binfo. + * decl2.c (grok_x_components): Change calls to xref_tag. + (handle_class_head): Likewise. + * friend.c (do_friend): Likewise. + * lex.c (make_lang_type): Change calls to make_binfo. + * parse.y (structsp): Change calls to xref_tag. + (named_complex_class_head_sans_basetype): Likewise. + (named_class_head): Likewise. + * rtti.c (init_rtti_processing): Likewise. + * search.c (compute_access): Change calls to reverse_path. + (dfs_get_vbase_types): Change calls to make_binfo. + (get_vbase_types): Remove dead code. + * tree.c (unshare_base_binfos): Change calls to make_binfo. + (layout_basetypes): Warn here about inaccessible bases. + (make_binfo): Remove chain parameter. + (reverse_path): Add copy parameter. + +1998-08-27 Jason Merrill + + * class.c: #if 0 complete_type_p. + * init.c (build_java_class_ref, build_new_1): Remove unused locals. + * method.c (process_overload_item): Likewise. + * typeck.c (comp_target_types): Likewise. + + Stop sharing binfos for indirect virtual bases. + * tree.c (propagate_binfo_offsets): Unshare vbases, too. + (layout_basetypes): Likewise. + (unshare_base_binfos): Copy vbases, too. + * cp-tree.h (BINFO_VIA_PUBLIC, BINFO_BASEINIT_MARKED, + BINFO_VBASE_INIT_MARKED): Remove obsolete macros. + (BINFO_PUSHDECLS_MARKED, SET_BINFO_PUSHDECLS_MARKED, + CLEAR_BINFO_PUSHDECLS_MARKED): New macros. + * search.c (lookup_field, lookup_fnfields, lookup_member): Remove + reference to BINFO_VIA_PUBLIC. + (marked_pushdecls_p, unmarked_pushdecls_p): New fns. + (push_class_decls): Use them. + (dfs_pushdecls): Use SET_BINFO_PUSHDECLS_MARKED. + (dfs_compress_decls): Use CLEAR_BINFO_PUSHDECLS_MARKED. + +1998-08-27 Mark Mitchell + + * decl.c (build_enumerator): Set DECL_CONTEXT for the + CONST_DECLs. + +1998-08-26 Mark Mitchell + + * cp-tree.h (finish_enum): Change prototype. + * decl.c (finish_enum): Use TYPE_VALUES, rather than taking a + VALUES parameter. Don't try to compute mins/maxs if + processing_template_decl. + * parse.y (structsp): Use new calling sequence for finish_enum. + * pt.c (tsubst_enum): Likewise. Take the new type as input. + (lookup_template_class): Remove unused variables. Tweak. + Register enums on instantiation list before substituting + enumeration constants. + (tsubst_decl): Remove unused variables. + (regenerate_decl_from_template): Likewise. + + * decl.c (duplicate_decls): Don't obliterate the + DECL_TEMPLATE_INFO for a template if we're not replacing it with + anything. + + * lex.c (do_identifier): Fix typo in comment. + +Wed Aug 26 10:54:51 1998 Kaveh R. Ghazi + + * errfn.c: Remove stdarg.h/varargs.h. + * tree.c: Likewise. + +1998-08-25 Brendan Kehoe + + * pt.c (tsubst_copy): Only do typename overloading on an + IDENTIFIER_NODE that happens to look like a typename if it actually + has a type for us to use. -1998-10-23 Martin von Löwis +1998-08-25 Jason Merrill - * parse.y (condition): Convert VAR_DECL from reference to indirect - reference. + * typeck.c (comp_cv_target_types): Split out... + (comp_target_types): From here. Don't allow cv-qual changes under + a pointer if nptrs == 0. Fix OFFSET_TYPE handling. + (build_ptrmemfunc): Pass 1 to nptrs. + * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes. -1998-10-18 Jason Merrill +1998-08-25 Mark Mitchell + + * search.c (dependent_base_p): Don't compare a binfo to + current_class_type; use the TREE_TYPE of the binfo instead. + + * cp-tree.h (CLASS_TYPE_P): Revise definition. + +1998-08-25 Jason Merrill + + * decl.c (duplicate_decls): Don't complain about different + exceptions from an internal decl even if pedantic. + + * typeck.c (convert_for_assignment): Converting from pm of vbase + to derived is an error, not a sorry. + + * call.c (build_over_call): Use convert_pointer_to_real for 'this'. + * class.c (fixed_type_or_null): Rename from + resolves_to_fixed_type_p. Return the dynamic type of the + expression, if fixed, or null. + (resolves_to_fixed_type_p): Use it. Return 0 if the dynamic type + does not match the static type. + (build_vbase_path): Rename 'alias_this' to 'nonnull'. Use + resolves_to_fixed_type_p again. + +1998-08-24 Mark Mitchell + + * pt.c (tsubst_decl): Move special case code for dealing with + tricky friend templates here from ... + (regenerate_decl_from_template): Here. + +1998-08-24 Jason Merrill + + * decl.c (start_decl): Remove redundant linkage check. + +1998-08-24 Gavin Romig-Koch + + * typeck.c (c_expand_return): Handle the case that valtype + is wider than the functions return type. + +1998-08-24 Mark Mitchell + + * cp-tree.h (CLASS_TYPE_P): New macro. + * decl.c (grokdeclarator): Use it instead of IS_AGGR_TYPE. + * pt.c (process_template_parm): Undo previous change. + +1998-08-24 Benjamin Kosnik + + * cp-tree.h: Declare. + * pt.c (decl_template_parm_p): New function. + * decl.c (pushdecl): Check decls for redeclaring template parms. + (xref_tag): Make redeclaration an error, print decl. + * decl2.c (grokfield): Check field_decls for redeclaration as well. + +1998-08-24 Jason Merrill + + * parse.y (primary): Fix up the type of string constants. + +1998-08-24 Mark Mitchell + + * typeck.c (convert_for_initialization): Move check for odd uses + of NULL to avoid duplicate warnings. + +1998-08-24 Jason Merrill + + * tree.c (lvalue_type): Fix for arrays. + * typeck.c (string_conv_p): New fn. + (convert_for_assignment): Use it. + (build_unary_op): Use lvalue_type. + * call.c (standard_conversion, convert_like): Use string_conv_p. + (add_function_candidate): Use lvalue_type. + * cvt.c (convert_to_reference): Likewise. + * decl2.c (lang_decode_option): Ignore -traditional. + * decl.c (init_decl_processing): flag_writable_strings inhibits + flag_const_strings. + +1998-08-24 Andrew MacLeod + + * lang-options.h (lang_options): Add fconst-strings to the list + of valid options. + * decl2.c (lang_f_options, lang_decode_option): Likewise. + +1998-08-24 Nathan Sidwell + + * lex.c (real_yylex): Don't warn about long long constants if + we're allowing long long. + +1998-08-24 Martin von Löwis + + * decl.c (pushdecl): Use IDENTIFIER_NAMESPACE_VALUE instead of + accessing bindings directly. + + * search.c (my_tree_cons): Reimplement. + + * lang-specs.h: Remove __HONOR_STD. + * inc/exception, inc/new, inc/new.h, inc/typeinfo: Likewise. + +1998-08-23 Mark Mitchell + + * decl.c (grokdeclarator): Complain about in-class initialization + of aggregates and/or references. + * pt.c (process_template_parm): Clear IS_AGGR_TYPE for + TEMPLATE_TYPE_PARMs. + + * decl2.c (grok_array_decl): Add comment. + (mark_used): Don't instantiate an explicit instantiation. + * friend.c (make_friend_class): Remove bogus comment. Fix check + for partial specializations. + * pt.c (check_explicit_specialization): Don't + SET_DECL_EXPLICIT_INSTANTIATION here. + (mark_decl_instantiated): Or here. + (do_decl_instantiation): Do it here, instead. Add checks for + duplicate explicit instantiations, etc. Tidy. + (do_type_instantiation): Likewise. + (instantiate_decl): Improve comments. Complain about explicit + instantiations where no definition is available. + + * cp-tree.h (ansi_null_node): Remove. + * call.c (build_over_call): Warn about converting NULL to an + arithmetic type. + * cvt.c (build_expr_type_conversion): Likewise. Use + null_ptr_cst_p instead of expanding it inline. + * decl.c (ansi_null_node): Remove. + (init_decl_processing): Make null_node always have integral type. + * except.c (build_throw): Warn about converting NULL to an + arithmetic type. + * lex.c (init_parse): Remove handling of ansi_null_node. + * pt.c (type_unification_real): Don't convert NULL to void* type. + * typeck.c (build_binary_op_nodefault): Fix NULL warnings. + (convert_for_assignment): Warn about converting NULL to an + arithmetic type. + (convert_for_initialization): Likewise. + +1998-08-20 Jason Merrill + + * tree.c (search_tree, no_linkage_helper, no_linkage_check): New fn. + * pt.c (coerce_template_parms): Use no_linkage_check. + * decl.c (grokvardecl): Likewise. + (grokfndecl): Likewise. Members of anonymous types have no linkage. + + * method.c (process_overload_item): Remove useless code. + +1998-08-20 Per Bothner + + Handle new'ing of Java classes. + * init.c (build_class_classref): New function. + (build_new_1): If type is TYPE_FOR_JAVA: Call _Jv_AllocObject; + constructor does not return this; don't need to exception-protect. + + * pt.c (lookup_template_class): Copy TYPE_FOR_JAVA flag. + * decl2.c (acceptable_java_type): Handle template-derived types. + +1998-08-20 Per Bothner + + * decl2.c (import_export_vtable): Suppress vtables for Java classes. + +1998-08-20 Mark Mitchell + + * decl.c (duplicate_decls): Always merge the old and new patterns + for templates, regardless of whether or not the new one has + DECL_INITIAL. Don't throw away specializations. Merge + DECL_SAVED_TREE. + * pt.c (tsubst_decl): Use the right pattern when calculating the + complete args for a new template instance. + (do_decl_instantiation): Fix typo in comment. + (regenerate_decl_from_template): Deal with tricky friend template + case. + (instantiate_decl): Likewise. + +Thu Aug 20 09:09:45 1998 Jeffrey A Law (law@cygnus.com) + + * init.c (build_builtin_delete_call): Add missing assemble_external + call. + +1998-08-20 Jason Merrill + + * parse.y (notype_unqualified_id): Also accept ~A. + +1998-08-19 Mark Mitchell - * method.c (hack_identifier): Just return a member function. + * typeck.c (build_binary_op_nodefault): Warn on use of NULL in + arithmetic. + * except.c (build_throw): Warn when NULL is thrown, even with + -ansi. Use ansi_null_node, rather than integer_zero_node, in the + thrown expression. -1998-10-18 Martin von Löwis + * cp-tree.h (ansi_null_node): New variable. + * decl.c (ansi_null_node): New variable. + (init_decl_processing): Initialize its type. + * lex.c (init_parse): Initialize its value. Use ansi_null_node + for null_node in non-ANSI mode. + * typeck.c (build_binary_op_nodefault): Use ansi_null_node in + place of null_node to avoid spurious errors. - * decl2.c (validate_nonmember_using_decl): Fix using-directives of - std if std is ignored. +1998-08-17 Mark Mitchell -1998-10-14 Jason Merrill + * cp-tree.h (enter_scope_of): New function. + * parse.y (complex_direct_notype_declarator): Use it. + * semantics.c (enter_scope_of): New function. - * spew.c (yylex): Clear looking_for_typename if we got - 'enum { ... };'. +1998-08-17 Jason Merrill -1998-10-13 Jason Merrill + * decl.c (grokparms): No, here. - * tinfo2.cc (fast_compare): Remove. - (before): Just use strcmp. - * tinfo.cc (operator==): Just use strcmp. + * decl.c (grokdeclarator): Catch parm with pointer to array of + unknown bound here... + * method.c (process_overload_item): ...not here. -1998-10-12 Jason Merrill + * gxxint.texi: Remove obsolete documentation of overloading code. - * tinfo.cc (operator==): Always compare names. + * decl.c (finish_enum): Also set TYPE_SIZE_UNIT. + * class.c (finish_struct_bits): Likewise. -1998-10-12 Jason Merrill + * tree.c (lvalue_type): Fix for arrays. + * typeck.c (build_unary_op): Use lvalue_type. + * call.c (add_function_candidate): Likewise. + * cvt.c (convert_to_reference): Likewise. - * inc/typeinfo: Add #pragma interface. - (operator!=): Just call operator==. - * tinfo.cc: Add #pragma implementation. - (operator==): Move from inc/typeinfo and tinfo2.cc. + * decl2.c (lang_decode_option): Ignore -traditional. - * typeck2.c (my_friendly_abort): Add URL. + * init.c (build_offset_ref): Don't mess with error_mark_node. + * lex.c (do_scoped_id): Use cp_error. -1998-10-05 Martin von Löwis + * rtti.c (get_tinfo_fn): Don't mess with the context for now. - * method.c (build_decl_overload_real): Clear - numeric_output_need_bar after __. +1998-08-17 Benjamin Kosnik -1998-10-04 Jason Merrill + * decl.c (grokdeclarator): Allow anonymous types to be cv-qualified. - * decl.c (cp_finish_decl): Make statics in extern inlines and - templates common, if possible and the target doesn't support weak - symbols. +Mon Aug 17 10:40:18 1998 Jeffrey A Law (law@cygnus.com) -1998-10-03 Jason Merrill + * cp-tree.h (set_identifier_local_value): Provide prototype. - * decl2.c (merge_functions): Remove duplicates. + * decl2.c (do_namespace_alias): Remove unused variables `binding' + and `old'. - * typeck.c (build_conditional_expr): Only fold if ifexp is an - INTEGER_CST. +Fri Aug 14 16:42:27 1998 Nick Clifton -Fri Oct 2 02:07:26 1998 Mumit Khan + * Makefile.in: Rename BBISON to BISON so that it can be properly + inherited from the parent makefile. - * parse.y (nomods_initdcl0): Set up the parser stack correctly. +1998-08-13 Jason Merrill -1998-08-25 Jason Merrill + * lang-options.h: Add -finit-priority. + * decl2.c: Likewise. Check flag_init_priority instead of + USE_INIT_PRIORITY. - * decl.c (duplicate_decls): Don't complain about different - exceptions from an internal decl even if pedantic. + * decl2.c (setup_initp): New fn. + (start_objects, finish_objects, do_ctors): Handle init_priority. + (do_dtors, finish_file): Likewise. -1998-08-24 Gavin Romig-Koch +1998-08-13 Jason Merrill - * typeck.c (c_expand_return): Handle the case that valtype - is wider than the functions return type. + * pt.c (tsubst_copy): Hush warning. -1998-08-24 Martin von Löwis + * rtti.c (get_tinfo_fn): Also set DECL_IGNORED_P. - * search.c (my_tree_cons): Reimplement. +1998-08-12 Mark Mitchell -1998-08-17 Jason Merrill + * pt.c (print_template_context): Don't abort when instantiating a + synthesized method. - * decl.c (finish_enum): Also set TYPE_SIZE_UNIT. - * class.c (finish_struct_bits): Likewise. + * decl.c (grokdeclarator): Issue errors on namespace qualified + declarators in parameter lists or in class scope. -1998-08-17 Mark Mitchell +1998-08-09 Mark Mitchell * pt.c (check_explicit_specialization): Don't abort on bogus explicit instantiations. -1998-08-14 Jason Merrill +1998-08-07 Mark Mitchell + + * typeck.c (require_complete_type): Use complete_type_or_else. + (complete_type_or_else): Always return NULL_TREE on failure, as + documented. + + * pt.c (tsubst_aggr_type): Prototype. + (tsubst_decl): New function, split out from tsubst. Set + input_filename and lineno as appropriate. + (pop_tinst_level): Restore the file and line number saved in + push_tinst_level. + (instantiate_class_template): Set input_filename and lineno as + appropriate. + (tsubst): Move _DECL processing to tsubst_decl. Make sure the + context for a TYPENAME_TYPE is complete. + + * decl2.c (grokbitfield): Issue errors on bitfields declared with + function type. + (do_dtors): As in do_ctors, pretend to be a member of the same + class as a static data member while generating a call to its + destructor. - * rtti.c (get_tinfo_fn): Don't mess with the context for now. + * cvt.c (cp_convert_to_pointer): Handle NULL pointer + conversions, even in complex virtual base class hierarchies. -1998-08-13 Mumit Khan +1998-08-06 Mark Mitchell + + * cp-tree.h (ENUM_TEMPLATE_INFO): New macro. + (TYPE_TEMPLATE_INFO): Likewise. + (SET_TYPE_TEMPLATE_INFO): Likewise. + (ENUM_TI_TEMPLATE): Likewise. + (ENUM_TI_ARGS): Likewise. + (lookup_nested_type_by_name): Remove. + * decl.c (maybe_process_template_type_declaration): Handle enums. + (start_enum): Don't check for primary-template enum declarations + here. + (finish_enum): Clean up, document. Make sure template enum + constants get the correct type. + (build_enumerator): Copy initializers for template enumerations, + too. + (grok_enum_decls): Document. + * lex.c (do_identifier): Document use of LOOKUP_EXPR a bit + better. Build LOOKUP_EXPRs for local variables, even if they are + TREE_PERMANENT. + * pt.c (tsubst_enum): Remove field_chain parameter. + (template_class_depth): Include the depth of surrounding function + contexts. + (push_template_decl): Check for primary-template enum declarations + here. Deal with enumeration templates. + (lookup_template_class): Likewise. + (for_each_template_parm): Likewise. + (instantiate_class_template): Don't call tsubst_enum directly, + call tsubst instead, to instantiate enums. Deal with all + field_chain issues here, not in tsubst_enum. + (lookup_nested_type_by_name): Remove. + (tsubst_aggr_type): Revise handling of enumeration types. + (tsubst): Likewise. + (tsubst_copy): Likewise. + (tsubst_expr): Call tsubst, not tsubst_enum for TAG_DEFNs. + +1998-08-04 Mark Mitchell + + * decl.c (pushtag): Don't mangle the name of a TYPE_DECL if it + uses template parameters. + * method.c (build_template_parm_names): Use the full set of + template arguments for tsubst'ing. + (build_overload_identifier): Pass the full set of template + arguments to build_template_parm_names, not just the + innermost_args. + * pt.c (TMPL_ARGS_DEPTH): Define using + TMPL_ARGS_HAVE_MULTIPLE_LEVELS, for clarity. + (NUM_TMPL_ARGS): New macro. + (add_outermost_template_args): Deal with the case where the outer + args will be completely discarded. + (coerce_template_parms): Use the full set of template arguments + for tsubst'ing. Simplify. Add some asserts. Improve + error messages. + (lookup_template_class): Pass the full set of template arguments + to coerce_template_parms. + (tsubst): Add assertion. + (do_type_instantiation): Don't instantiate member template + classes. - * decl2.c (import_export_class): Don't use dllexport - attribute as a heuristic. + * init.c (build_offset_ref): Deal with a TEMPLATE_ID_EXPR whose + name is a LOOKUP_EXPR, rather than an IDENTIFIER_NODE. + +1998-08-03 Jason Merrill + + * method.c (set_mangled_name_for_decl): Change return type to void. + + * decl.c (lookup_name_real): A namespace-level decl takes priority + over implicit typename. Avoid doing the same lookup twice. + + * search.c (dependent_base_p): New fn. + (dfs_pushdecls, dfs_compress_decls): Use it. + + * typeck.c (get_member_function_from_ptrfunc): Don't try to handle + virtual functions if the type doesn't have any. + +1998-08-03 Mark Mitchell + + * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it + uses template parameters. + +1998-08-02 Mark Mitchell + + * cp-tree.def (LOOKUP_EXPR): Document. Remove second argument. + * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation. + * lex.c (do_identifier): Don't use a second argument, or a type, + when building LOOKUP_EXPRs. + (do_identifier): Likewise. + (do_scoped_id): Likewise. + * method.c (hack_identifier): Improve error message. + * pt.c (lookup_template_function): Don't needlessly call + copy_to_permanent or build_min. + (tsubst_copy): Remove #if 0'd code. tsubst into LOOKUP_EXPRs if + necessary. + (do_decl_instantiation): Improve error message. + * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy. + (build_min): Copy the type to the permanent obstack, too. + +1998-08-01 Jason Merrill + + * init.c (init_init_processing): Remove BI* handling. + (build_builtin_call): Remove. + (build_builtin_delete_call): New fn. + (build_delete): Use it. + +1998-07-31 Mark Mitchell + + * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): New macro. + (maybe_check_template_type): New function. + * decl.c (maybe_process_template_type_declaration): New function, + split out from pushtag Call maybe_check_template_type. + (pushtag): Use it. Use PROCESSING_REAL_TEMPLATE_DECL_P. + (xref_tag): Use PROCESSING_REAL_TEMPLATE_DECL_P. + * friend.c (do_friend): Use PROCESSING_REAL_TEMPLATE_DECL_P. + * pt.c (template_class_depth_real): Generalization of ... + (template_class_depth): Use it. + (register_specialization): Use duplicate_decls for duplicate + declarations of specializations. + (maybe_check_template_type): New function. + (push_template_decl_real): Fix comment. + (convert_nontype_argument): Likewise. + (lookup_template_class): Likewise. Avoid an infinite loop on + erroneous code. + (tsubst_friend_function): Fix comment. + (tsubst, case FUNCTION_DECL): Deal with a DECL_TI_TEMPLATE that is + an IDENTIFIER_NODE. + * semantics.c (begin_function_definition): Use + reset_specialization to note that template headers don't apply + directly to declarations after the opening curly for a function. 1998-07-29 Jason Merrill @@ -155,13 +5014,141 @@ Fri Oct 2 02:07:26 1998 Mumit Khan * decl.c (lookup_name_real): Fix typo. +1998-07-28 Mark Mitchell + + * friend.c (is_friend): Be lenient with member functions to deal + with nested friends. + 1998-07-28 Jason Merrill * class.c (finish_struct_1): Convert integer_zero_node to - ssizetype before passing it to set_rtti_entry. + ssizetype before passing it to set_rtti_entry. * typeck2.c (initializer_constant_valid_p): Allow conversion of 0 of any size to a pointer. +1998-07-27 Mark Mitchell + + * cp-tree.h (TI_USES_TEMPLATE_PARMS): Remove. + (build_template_decl_overload): Remove. + (set_mangled_name_for_decl): New function. + (innermost_args): Remove is_spec parameter. + (most_specialized, most_specialized_class): Remove declarations. + (lookup_template_class): Add entering_scope parameter. + (maybe_process_partial_specialization): New function. + (finish_template_decl): Likewise. + (finish_template_type): Likewise. + * class.c (finish_struct): Clean up processing of member template + specializations. + * decl.c (pushtag): Fix formatting. + (lookup_tag): Improve handling of pseudo-global levels. + (make_typename_type): Adjust call to lookup_template_class. + (shadow_tag): Use maybe_process_partial_specialization. + (xref_tag): Improve handling of member friends. + (start_function): Call push_nested_class before + push_template_decl. Don't call push_template_decl for + specializations. + * decl2.c (grok_x_components): Don't call xref_tag for + template instantiations. Handle UNION_TYPEs like RECORD_TYPEs. + (grokclassfn): Use set_mangled_name_for_decl. + (arg_assoc_class): Adjust call to innermost_args. + (mark_used): Don't call instantiate_decl for a TEMPLATE_DECL. + * error.c (dump_function_name): Improve printing of template + function names. + * friend.c (is_friend): Don't compare types of decls to determine + friendship, unless flag_guiding_decls. + (make_friend_class): Partial specializations cannot be friends. + (do_friend): Use set_mangled_name_for_decl. Call + push_template_decl_real instead of push_template_decl. + * method.c (build_decl_overload_real): Remove prototype. Give it + external linkage. + (build_overload_identififer): Adjust call to innermost_args. + (build_template_decl_overload): Remove. + (set_mangled_name_for_decl): New function. + * parse.y (.finish_template_type): New non-terminal. + (template_def): Use finish_template_decl. Use template_extdef + instead of extdef. + (template_extdef, template_datadef): New non-terminals, containing + only those rules for things which can be templates. + (datadef): Tidy. + (template_type, self_template_type): Use .finish_template_type. + (named_class_head): Use maybe_process_partial_specialization. + * pt.c (mangle_class_name_for_template): Remove context parameter. + (get_class_bindings): Remove outer_args parameter. + (complete_template_args): Remove. + (add_outermost_template_args): New function. + (register_specialization): Return the specialization. + (unregister_specialization): New function. + (tsubst_template_parms): Likewise. + (most_specialized, most_specialized_class): Prototype here as + static. + (original_template): Rename to most_general_template. + (tsubst_template_parms): New function. + (set_mangled_name_for_template_decl): Likewise. + (TMPL_ARGS_DEPTH): New macro. + (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Adjust. + (TMPL_ARGS_LEVEL): New macro. + (SET_TMPL_ARGS_LEVEL): Likewise. + (TMPL_ARG): Likewise. + (SET_TMPL_ARG): Likewise. + (TMPL_ARGS_DEPTH): Likewise. + (finish_member_template_decl): Use finish_template_decl. + (maybe_process_partial_specialization): New function, split out + from tsubst. + (inline_needs_template_parms): Use TMPL_PARMS_DEPTH. + (maybe_begin_member_template_processing): Use new macros. + (is_member_template): Likewise. + (is_member_template_class): Likewise. + (add_to_template_args): Likewise. Deal with multiple levels of + args. + (maybe_process_partial_specialization): New function. + (retrieve_specialization): Add consistency check. + (determine_specialization): Return full argument list. + (check_explicit_specialization): Tweak friend handling. Use full + argument lists. Simplify. + (current_template_args): Use new macros. + (push_template_decl_real): Change ill-named mainargs to specargs. + Check that a partial specialization actually specializes at least + one parameter. Improve friend handling. Modify for full + template arguments. + (classtype_mangled_name): Don't mangle the names of + specializations. + (lookup_template_class): Add entering_scope parameter. Use it to + avoid finding a template type when an instantiation is required. + Simplify. Use full template arguments. + (tsubst_friend_function): Use unregister_specialization. Use new + macros. Use full template arguments. + (tsubst_friend_class): Substitute, using tsubst_template_parms, + into the template parameters before passing them to + redeclare_class_template. + (instantiate_class_template): Simplify. Use full template + arguments. Adjust calls to get_class_bindings. Use + SET_IDENTIFIER_TYPE_VALUE where needed. Improve friend handling. + (innermost_args): Use new macros. + (tsubst_aggr_type): New function, split out from tsubst. + (tsubst): Use tsubst_aggr_type, tsubst_template_parms, new calling + conventions for lookup_template_class. Refine handling of partial + instantiations. Remove calls to complete_template_args. + Simplify. Add consistency checks. Use set_mangled_name_for_decl + and set_mangled_name_for_template_decl. + (tsubst_copy): Use tsubst_aggr_type. + (instantiate_template): Use full template arguments. + (more_specialized): Improve formatting. + (more_specialized_class): Adjust calls to get_class_bindings. + (get_bindings_real): Don't call complete_template_args. + (most_specialized): Don't overwrite input; create a new list. + (most_specialized_class): Use most_general_template. + (regenerate_decl_from_template): Use unregister_specialization. + Use full template arguments. + (instantiate_decl): Use full template arguments. + (set_mangled_name_for_template_decl): New function. + * semantics.c (begin_class_definition): Use + maybe_process_partial_specialization. + (finish_member_class_template): New function. + (finish_template_decl): Likewise. + (finish_template_type): Likewise. + (typeck.c): Don't crash after issuing a compiler_error. + * Makefile.in (CONFLICTS): Adjust; we removed a s/r conflict. + 1998-07-27 Jason Merrill * typeck2.c (build_functional_cast): Handle default-initialization. @@ -174,6 +5161,11 @@ Fri Oct 2 02:07:26 1998 Mumit Khan * tree.c (ovl_member): Fix for single function in OVL. +1998-07-27 Dave Brolley + + * c-lex.c (yylex): Fix boundary conditions in character literal and + string literal loops. + 1998-07-24 Jason Merrill * decl.c (lookup_name_real): OK, do return the from_obj value @@ -217,7 +5209,7 @@ Fri Oct 2 02:07:26 1998 Mumit Khan (finish_prevtable_vardecl): From here. * class.c (finish_struct_1): Call import_export_class if at_eof. - * decl.c (start_function): #if 0 mysterious code I wrote and have + * decl.c (start_function): #if 0 mysterious code I wrote and have forgotten why. * rtti.c (get_tinfo_fn): If this is for a class type, set DECL_CONTEXT. @@ -237,6 +5229,14 @@ Fri Oct 2 02:07:26 1998 Mumit Khan * method.c (process_overload_item): Use build_overload_value for arrays. +1998-07-20 Dave Brolley + + * lex.c (mbchar.h): #include it. + (GET_ENVIRONMENT): New macro. + (init_parse): Set character set based on LANG environment variable. + (real_yylex): Handle multibyte characters in character literals. + (real_yylex): Handle multibyte characters in string literals. + 1998-07-19 Jason Merrill * lex.c (do_identifier): Look for class value even if we don't @@ -252,7 +5252,7 @@ Fri Oct 2 02:07:26 1998 Mumit Khan * decl.c (pushtag): Don't put out debugging information for compiler-generated typedefs. - + * error.c (dump_type_real): Don't crash when presented with intQI_type_node or the like. @@ -369,7 +5369,7 @@ Fri Oct 2 02:07:26 1998 Mumit Khan (cat_namespace_levels): Ignore aliases. (duplicate_decls): Ignore duplicate aliases. * decl2.c (do_namespace_alias): Process block level namespace - aliases. Store alias with pushdecl. Remove odr errors. + aliases. Store alias with pushdecl. Remove odr errors. * parse.y (namespace_alias): New non-terminal. (extdef): Use it. @@ -405,6 +5405,12 @@ Fri Oct 2 02:07:26 1998 Mumit Khan * decl2.c (namespace_ancestor): Use CP_DECL_CONTEXT. (arg_assoc): Don't skip the first argument of a function. +Tue Jul 14 20:09:22 1998 Jeffrey A Law (law@cygnus.com) + + * search.c (my_tree_cons): Clean up. + +1998-07-14 Jason Merrill + * call.c (joust): Don't warn about "confusing" conversions to the same type. @@ -420,14 +5426,14 @@ Fri Oct 2 02:07:26 1998 Mumit Khan of namespace-qualified ids to -1, enter the namespace. * method.c (build_template_decl_overload): Expect _DECL as first - parameter. Put context temporarily into current_namespace. + parameter. Put context temporarily into current_namespace. * pt.c (check_explicit_specialization): Change caller. (tsubst): Likewise. * init.c (build_offset_ref): Call mark_used and convert_from_reference for namespace members. -Mon Jul 13 23:25:28 1998 Martin von Lvwis +Mon Jul 13 23:25:28 1998 Martin von Löwis * search.c (my_tree_cons): The bitfield is at index 2. @@ -435,7 +5441,7 @@ Mon Jul 13 17:21:01 1998 Nick Clifton * lang-options.h: Format changed to work with new --help support in gcc/toplev.c - + 1998-07-12 Martin von Löwis * decl2.c (build_expr_from_tree): Change calls of do_identifier. @@ -472,14 +5478,14 @@ Mon Jul 13 17:21:01 1998 Nick Clifton * decl.c (xref_baseypes): Change caller. * friend.c (make_friend_class): Likewise. -1998-07-12 Kriang Lerdsuwanakij +1998-07-12 Kriang Lerdsuwanakij - * typeck.c (comptypes, case TEMPLATE_TEMPLATE_PARM): Add parameter + * typeck.c (comptypes, case TEMPLATE_TEMPLATE_PARM): Add parameter comparison. - * pt.c (for_each_template_parm, case TEMPLATE_DECL): If it is a + * pt.c (for_each_template_parm, case TEMPLATE_DECL): If it is a template template parameter, record its use. - (for_each_template_parm, case TEMPLATE_TEMPLATE_PARM): Traverse + (for_each_template_parm, case TEMPLATE_TEMPLATE_PARM): Traverse its template arguments if exists. * pt.c (coerce_template_template_parms): New function equivalent @@ -493,17 +5499,17 @@ Mon Jul 13 17:21:01 1998 Nick Clifton current_class_type. Don't display error message when COMPLAIN is false. -1998-07-12 Klaus Kaempf (kkaempf@progis.de) +1998-07-12 Klaus Kaempf (kkaempf@progis.de) - * repo.c (get_base_filename): Use file_name_nondirectory. - (open_repo_file): Ditto. + * repo.c (get_base_filename): Use file_name_nondirectory. + (open_repo_file): Likewise. * cp-tree.h (file_name_nondirectory): Add prototype. 1998-07-12 Jason Merrill * friend.c (do_friend): Pull the identifier out of declarator. Use cp_error and friends. - * decl2.c (qualified_lookup_using_namespace): Fix call to + * decl2.c (qualified_lookup_using_namespace): Fix call to purpose_member. * decl.c (lookup_name_real): Don't call complete_type on a namespace. (grokvardecl): Use DECL_CLASS_SCOPE_P. @@ -511,7 +5517,7 @@ Mon Jul 13 17:21:01 1998 Nick Clifton * class.c (warn_hidden): Fix for OVERLOAD. From grahams@rcp.co.uk: * cp-tree.h (DEFARG_NODE_CHECK): New macro. - (DEFARG_LENGTH, DEFARG_POINTER): Use it. + (DEFARG_LENGTH, DEFARG_POINTER): Use it. Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com) @@ -577,7 +5583,7 @@ Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com) * decl2.c: Define them. (lang_decode_option): Handle them. * lang-options.h: Add -foptional-diags. - * class.c (finish_struct): Don't complain about multiple meanings of + * class.c (finish_struct): Don't complain about multiple meanings of name if -fno-optional-diags. * decl.c (pushdecl_class_level): Likewise. * lex.c (real_yylex): Check warn_multichar. @@ -590,8 +5596,8 @@ Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com) 1998-06-30 Benjamin Kosnik - * decl2.c (lang_decode_option): Remove warn_template_debugging. - * lang-options.h: Ditto. + * decl2.c (lang_decode_option): Remove warn_template_debugging. + * lang-options.h: Likewise. Mon Jun 29 20:17:40 1998 Kaveh R. Ghazi @@ -613,7 +5619,7 @@ Sat Jun 27 23:34:18 1998 Fred Fish Sat Jun 27 12:22:56 1998 Jeffrey A Law (law@cygnus.com) - * Make-lang.in (g++): Depend on mkstemp.o. Link in mkstemp.o + * Make-lang.in (g++): Depend on mkstemp.o. Link in mkstemp.o Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi @@ -636,7 +5642,7 @@ Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi * cp-tree.h (mark_all_runtime_matches): Add function prototype. * except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED - flag for all function decls which are in the exception table. + flag for all function decls which are in the exception table. * exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match. * decl2.c (finish_file): Call mark_all_runtime_matches to make sure code is emitted for any referenced rtti function. @@ -704,7 +5710,7 @@ Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi * exception.cc (struct cp_eh_info): Add original_value field. (__cplus_type_matcher): Perform type matching on the original exception value, and if we have a match, set the current value. - (__cp_push_exception): Set the original expcetion value. + (__cp_push_exception): Set the original exception value. 1998-06-23 Jason Merrill @@ -739,8 +5745,8 @@ Mon Jun 22 08:50:26 1998 Kaveh R. Ghazi Fri Jun 19 23:22:42 1998 Bruno Haible - * typeck2.c (pop_init_level): Warn about implicit zero initialization - of struct members. + * typeck2.c (pop_init_level): Warn about implicit zero initialization + of struct members. Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi @@ -785,7 +5791,7 @@ Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi 1998-06-16 Andrew MacLeod - * decl.c (grokvardecl): Don't build external assembler names for + * decl.c (grokvardecl): Don't build external assembler names for TYPENAMEs in other namespaces as there is no declarator. * error.c (cp_file_of, cp_line_of): Don't extract file or line number info from DECL_CONTEXT if it is NULL. @@ -821,7 +5827,7 @@ Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi (pointer_diff): Likewise. * pt.c (for_each_template_parm): Traverse the TYPE_CONTEXT for - types. + types. * search.c (get_matching_virtual): Note that member templates cannot override virtual functions. @@ -856,7 +5862,7 @@ Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi 1998-06-11 Benjamin Kosnik * friend.c (do_friend): Add support for nested classes using - member functions of the enclosing class as friends. + member functions of the enclosing class as friends. 1998-06-10 Mark Mitchell @@ -870,9 +5876,9 @@ Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi (expand_member_init): Remove much of this code; it is dead. * typeck.c (convert_arguments): Use convert_default_arg and convert_arg_for_ellipsis, rather than duplicating here. - - * call.c (convert_like): Don't fail silently if - build_user_type_conversion fails. Always return error_mark_node + + * call.c (convert_like): Don't fail silently if + build_user_type_conversion fails. Always return error_mark_node for failure. 1998-06-10 Jason Merrill @@ -931,8 +5937,8 @@ Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi 1998-06-10 Branko Cibej - * typeck.c (c_expand_return): Don't warn about void expressions on - return statements in functions returning void. + * typeck.c (c_expand_return): Don't warn about void expressions on + return statements in functions returning void. 1998-06-09 Mark Mitchell @@ -959,26 +5965,26 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * Makefile.in (decl2.o): Depend on dwarf2out.h and dwarfout.h. * cp-tree.h: Add prototype for `maybe_print_template_context' and - `maybe_make_one_only'. + `maybe_make_one_only'. * decl.c (auto_function): Remove unused variable `decl'. * decl2.c: Include dwarf2out.h and dwarfout.h. * lex.c: Remove redundant declarations of `set_float_handler' and - `asm_out_file'. + `asm_out_file'. 1998-06-08 Andrew MacLeod - * except.c (init_exception_processing): Remove NEW_EH_MODEL compile + * except.c (init_exception_processing): Remove NEW_EH_MODEL compile time flag. Call __cp_eh_info instead of __cp_exception_info. * exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag. - (__cp_exception_info): Return offset into cp_eh_info structure to + (__cp_exception_info): Return offset into cp_eh_info structure to match what use to be the start of this structure. (__cp_eh_info): New function to return a pointer to cp_eh_info struct. (__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL compile time flag. - (__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call + (__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call __cp_eh_info instead of __cp_exception_info. 1998-06-08 Jason Merrill @@ -1002,7 +6008,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * lex.c (lang_init_options): New function. (lang_init): Remove flag_exceptions == 2 hack. - + 1998-06-05 Jason Merrill * search.c (envelope_add_decl): Tweak for implicit typename. @@ -1044,7 +6050,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi (begin_only_namespace_names, end_only_namespace_names): New functions. * decl2.c (set_decl_namespace): Skip namespace aliases. (do_using_directive): Likewise. - (do_namespace_alias): Produce namespace aliases, fix alias + (do_namespace_alias): Produce namespace aliases, fix alias redeclaration. * error.c (dump_decl): Support SCOPE_REF. * parse.y (extdef): Wrap lookup with namespace_only for namespace @@ -1127,9 +6133,9 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * method.c (build_destructor_name): New fn. * decl2.c (maybe_retrofit_in_chrg): Split out... (grokclassfn): From here. Reorganize. - * decl.c (grok_ctor_properties): Make sure ctors for types with + * decl.c (grok_ctor_properties): Make sure ctors for types with vbases have the in_chrg parm. - * pt.c (instantiate_class_template): Update + * pt.c (instantiate_class_template): Update TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call grok_*_properties. (tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg. @@ -1141,7 +6147,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi 1998-05-28 Jason Merrill - * decl.c (start_decl): Always pedwarn about vacuously redeclaring + * decl.c (start_decl): Always pedwarn about vacuously redeclaring a member. (start_function): Call check_default_args. * decl2.c (grokfield): Don't call check_default_args. @@ -1170,7 +6176,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi (maybe_push_to_top_level): Clear shadowed_labels. * pt.c (instantiate_decl): Reset lineno and filename after calling - regenerate_decl_from_template. + regenerate_decl_from_template. * decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an error_mark_node. @@ -1199,7 +6205,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi 1998-05-26 Benjamin Kosnik * decl.c (start_decl): Check for DECL_LANG_SPECIFIC before - DECL_USE_TEMPLATE. + DECL_USE_TEMPLATE. 1998-05-26 Per Bothner @@ -1244,7 +6250,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * cp-tree.h (processing_template_parmlist): Declare. * decl.c (pushtag): Don't call push_template_decl when we - shouldn't. + shouldn't. * pt.c (processing_template_parmlist): New variable. (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): New macro. (complete_template_args): Use it. @@ -1289,7 +6295,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * parse.y (xcond): Move call to condition_conversion ... * semantics.c (finish_for_cond): Here. * parse.c: Regenerated. - + 1998-05-24 Jason Merrill * decl.c (push_namespace): Namespaces have type void. @@ -1308,14 +6314,14 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * tree.c (build_srcloc, build_srcloc_here): New fns. * pt.c (add_pending_template): Use build_srcloc_here. (push_tinst_level): Update last_template_error_tick before erroring. - (instantiate_decl): Restore lineno and input_filename before + (instantiate_decl): Restore lineno and input_filename before calling add_pending_template. * decl2.c (finish_file): Set up lineno and input_filename for pending templates. 1998-05-22 Jason Merrill - * decl.c (lang_print_error_function): New fn. + * decl.c (lang_print_error_function): New fn. (init_decl_processing): Set print_error_function to use it. * errfn.c (cp_thing): Don't call maybe_print_template_context here. @@ -1342,7 +6348,7 @@ Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi * pt.c (determine_specialization): Just return an error_mark_node. Also print the decl we want in error messages. If we complain, return error_mark_node. - (tsubst_friend_function): Set lineno and input_filename so + (tsubst_friend_function): Set lineno and input_filename so error messages will be useful. (instantiate_template): Just return an error_mark_node. (check_explicit_specialization): Don't mess with a returned @@ -1376,7 +6382,7 @@ Thu May 21 11:54:44 1998 Dave Brolley * cp-tree.h: (get_directive_line): Different prototype for cpplib. (GET_DIRECTIVE_LINE): Macro wrapper for get_directive_line. - * Makefile.in (CXX_OBJS): add @extra_cxx_objs@ for cpplib. + * Makefile.in (CXX_OBJS): Add @extra_cxx_objs@ for cpplib. 1998-05-21 Jason Merrill @@ -1409,11 +6415,11 @@ Thu May 21 11:54:44 1998 Dave Brolley CLASSTYPE_TAGS list, just as for ordinary member classes. (pushdecl_class_level): Use DECL_DECLARES_TYPE_P. (lookup_tag): Look for IDENTIFIER_CLASS_VALUEs, just as with - IDENTIFIER_NAMESPACE_VALUEs. + IDENTIFIER_NAMESPACE_VALUEs. * parse.y (component_decl): Move code to ... - * semantics.c (finish_member_class_template): New function. + * semantics.c (finish_member_class_template): New function. Don't put member class templates on the list of components for a - class. + class. * parse.c: Regenerated. * pt.c (classtype_mangled_name): Don't try DECL_CONTEXT on types. In fact, don't use DECL_CONTEXT at all here. @@ -1492,7 +6498,7 @@ Tue May 19 10:05:02 1998 Kaveh R. Ghazi definition. * errfn.c (cp_error): Cast function pointer `error' to (errorfn *) - in call to `cp_thing'. + in call to `cp_thing'. (cp_warning): Likewise for function pointer `warning'. * except.c (do_function_call): Remove prototype and definition. @@ -1503,10 +6509,10 @@ Tue May 19 10:05:02 1998 Kaveh R. Ghazi * parse.y: Include toplev.h. * pt.c (type_unification): Remove unused variable `arg'. - (instantiate_decl): likewise for `save_ti'. + (instantiate_decl): Likewise for `save_ti'. * tree.c (propagate_binfo_offsets): Likewise for `base_binfos'. - + Tue May 19 02:43:25 1998 Jason Merrill * init.c (build_member_call): Handle template_ids. @@ -1520,9 +6526,9 @@ Mon May 18 23:22:52 1998 Jason Merrill Mon May 18 12:28:44 1998 Mark Mitchell * parse.y (.finish_new_placement): New non-terminal. - (unary_expr, new_type_id): Use it. + (unary_expr, new_type_id): Use it. * parse.c: Regenerated. - + Mon May 18 12:20:27 1998 Brendan Kehoe * pt.c (redeclare_class_template): Say where the original definition @@ -1538,7 +6544,7 @@ Mon May 18 03:00:57 1998 Jason Merrill Mon May 18 01:43:01 1998 Martin v. Loewis - * decl.c (lookup_name_real): Don't look at IDENTIFIER_LOCAL_VALUE + * decl.c (lookup_name_real): Don't look at IDENTIFIER_LOCAL_VALUE for a type unless it is one. * class.c (finish_struct_1): Use OVL_CURRENT in error message. @@ -1548,7 +6554,7 @@ Mon May 18 01:24:08 1998 Jeffrey A Law (law@cygnus.com) * Makefile.in (program_transform_name, objdir): Define. * Makefile.in (BISON): Use bison from the build tree if it exists. - (FLEX): Similarly. + (FLEX): Likewise. Sun May 17 14:52:08 1998 Martin v. Loewis @@ -1567,7 +6573,7 @@ Sun May 17 13:53:48 1998 Mark Mitchell * parse.y (.build_new_placement): New non-terminal. (unary_expr, new_placement): Use it. * parse.c: Regenerated. - + Sun May 17 12:32:08 1998 Jason Merrill * decl.c (duplicate_decls): Use CANONICAL_TYPE_VARIANT to compare @@ -1586,7 +6592,7 @@ Fri May 15 20:28:00 1998 Jason Merrill Fri May 15 15:34:02 1998 Benjamin Kosnik - * decl.c (duplicate_decls): Clean up, add DECL_DATA_AREA bits. + * decl.c (duplicate_decls): Clean up, add DECL_DATA_AREA bits. Fri May 15 00:46:05 1998 Jason Merrill @@ -1594,20 +6600,20 @@ Fri May 15 00:46:05 1998 Jason Merrill * decl.c (start_decl): Use 'tem'. -Thu May 14 16:30:47 EDT 1998 Andrew MacLeod +Thu May 14 16:30:47 1998 Andrew MacLeod * exception.cc: Include eh-common.h. - (struct cp_eh_info): add eh_info struct with NEW_EH_MODEL. + (struct cp_eh_info): Add eh_info struct with NEW_EH_MODEL. (__cplus_type_matcher): First stab at new C++ runtime type matcher. (__cp_push_exception): Initialize eh_info struct as well. * except.c: Remove local structs and include eh-common.h. (init_exception_processing): Set language and version codes. - (call_eh_info): add presence of eh_info to runtime description of + (call_eh_info): Add presence of eh_info to runtime description of struct cp_eh_info. - (expand_end_eh_spec): call start_catch_block() and end_catch_block(). - * semantics.c (finish_try_block): call start_catch_block() and + (expand_end_eh_spec): Call start_catch_block() and end_catch_block(). + * semantics.c (finish_try_block): Call start_catch_block() and end_catch_block(). - * parse.y (function_try_block): call start_catch_block() and + * parse.y (function_try_block): Call start_catch_block() and end_catch_block(). Thu May 14 12:27:34 1998 Brendan Kehoe @@ -1620,11 +6626,11 @@ Thu May 14 12:27:34 1998 Brendan Kehoe Wed May 13 12:54:30 1998 Kaveh R. Ghazi * Makefile.in (lex.o): Depend on output.h. - + * call.c (add_function_candidate): Remove unused variable `cand'. (add_conv_candidate): Likewise. (build_builtin_candidate): Likewise. - + * cp-tree.h: Add prototype for `types_overlap_p'. * decl.c (signal_catch): Mark parameter `sig' with ATTRIBUTE_UNUSED. @@ -1659,7 +6665,7 @@ Tue May 12 21:37:49 1998 Jason Merrill DECL_NAMESPACE_SCOPE_P. (lang_decl_name): Likewise. * pt.c (tsubst_friend_function, tsubst): Likewise. - * decl.c (pushdecl, redeclaration_error_message, start_decl, + * decl.c (pushdecl, redeclaration_error_message, start_decl, cp_finish_decl, start_function): Likewise. * class.c (finish_struct_1): Likewise. * call.c (build_over_call): Likewise. @@ -1681,7 +6687,7 @@ Mon May 11 11:38:07 1998 Mark Mitchell * pt.c (tsubst): Remove duplicate check for IDENTIFIER_NODE. * call.c (add_template_candidate): Adjust for changes to - fn_type_unification. + fn_type_unification. (add_template_candidate_real): Likewise. (add_template_conv_candidate): Likewise. (build_user_type_conversion_1): Likewise. @@ -1726,11 +6732,11 @@ Mon May 11 11:38:07 1998 Mark Mitchell tsubst_template_argument_vector where appropriate. (regenerate_decl_from_template): Break out from ... (instantiate_decl): Here. - + * lex.c (yyprint): Remove TYPENAME_ELLIPSIS. * parse.h: Regenerated. * parse.c: Really regenerated. - + * cp-tree.h (finish_unary_op_expr): New function. (finish_id_expr): Likewise. (begin_new_placement): Likewise. @@ -1792,7 +6798,7 @@ Sat May 9 14:44:37 1998 Jason Merrill Fri May 8 23:32:42 1998 Martin von Loewis - * cp-tree.def (OVERLOAD): New node. + * cp-tree.def (OVERLOAD): New node. * cp-tree.h (BINDING_TYPE, SET_IDENTIFIER_GLOBAL_VALUE, SET_IDENTIFIER_NAMESPACE_VALUE): Define. (NAMESPACE_BINDING): Remove. @@ -1821,10 +6827,10 @@ Fri May 8 23:32:42 1998 Martin von Loewis * call.c (add_function_candidate): Special-case type of OVERLOAD node. (build_user_conversions_1): Iterate using OVL_NEXT for ctors, convs, fns. - (build_new_function_call): Iterate using OVL_CHAIN. + (build_new_function_call): Iterate using OVL_CHAIN. Print DECL_NAME in when reporting ambiguities. (build_object_call): Iterate using OVL_NEXT for fns, convs. - (build_new_op): Call lookup_function_nonclass. + (build_new_op): Call lookup_function_nonclass. Iterate using OVL_NEXT. (build_op_delete_call): Change detection of members. Do not wrap TREE_LIST around fields and single global functions. @@ -1842,7 +6848,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis fdecls that are OVERLOAD nodes. (validate_lhs): New function. (instantiate_type): Do not copy OVERLOAD nodes. Remove dead - code. Use DECL_NAME in error messages. Split code between global + code. Use DECL_NAME in error messages. Split code between global and member function processing. * decl.c (global_type_node): New static variable. (in_std): New global. @@ -1869,7 +6875,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis (pushtag): If no context, use current_namespace. (duplicate_decls): Don't process DECL_CHAIN. (pushdecl): Set DECL_CONTEXT to current_namespace, if it is not - already set. Never reset it to NULL_TREE. Lookup global variables + already set. Never reset it to NULL_TREE. Lookup global variables in their namespace. Push overloaded templates if they are on namespace level. (pushdecl_namespace_level): New function. @@ -1877,7 +6883,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis (pushdecl_using_decl): New function. (overloaded_globals_p): Remove. (push_overloaded_decl): Create OVERLOAD nodes, and iterate through - them. Use namespace_binding and set_namespace_value. + them. Use namespace_binding and set_namespace_value. (redeclaration_error_message): Complain if the declarations come from different namespaces. (lookup_tag): On namespace level, look in the BINDING_TYPE. @@ -1903,7 +6909,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis (grokvardecl): Add namespace parameter. (grokdeclarator): Process SCOPEs that are namespaces. For mangling, temporarily set the DECL_CONTEXT on anonymous structs. - (start_function): Check for contexts that are namespaces. + (start_function): Check for contexts that are namespaces. Set context for declarations that have not been pushed. (store_parm_decls): Check for ::main only. (finish_function): Likewise. @@ -1939,7 +6945,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis * lang-specs.h (__HONOR_STD): Define if -fnew-abi or -fhonor-std. * lex.c (identifier_type): Loop using OVL_CHAIN. (see_typename): Set looking_for_typename to 2. - (real_yylex): Likewise. + (real_yylex): Likewise. (do_identifier): Expect OVERLOAD nodes instead of TREE_LISTs. (do_scoped_id): Expect OVERLOAD nodes. Change calling convention for qualified_lookup_using_namespace. @@ -1966,7 +6972,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis Set DECL_CONTEXT to current_namespace if not set already. Ignore real contexts that are namespaces. (mangle_class_name_for_template): Skip global_namespace. - Mangle other namepaces as declarations. + Mangle other namespaces as declarations. (lookup_template_function): Set type of OVERLOAD nodes to unknown. (lookup_template_class): Push into namespace of context. If the context is a namespace, set it to global_namespace. @@ -2008,7 +7014,7 @@ Fri May 8 23:32:42 1998 Martin von Loewis * decl.c (duplicate_decls): Check for namespace bindings instead of global bindings. (pushdecl, push_overloaded_decl, lookup_tag, lookup_name_real, - lookup_name_current_level, start_decl, xref_tag, + lookup_name_current_level, start_decl, xref_tag, finish_enum): Likewise. * init.c (build_offset_ref): Likewise. * search.c (lookup_field): Likewise. @@ -2025,17 +7031,17 @@ Fri May 8 23:32:42 1998 Martin von Loewis * parse.y (make_thunk): Likewise. * pt.c (tsubst): Likewise. * tree.c (debug_binfo): Likewise. - * exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h, + * exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h, tinfo2.cc, inc/new.h: Add std qualifications. * inc/new: Wrap with namespace std if __HONOR_STD. * inc/typeinfo: Likewise. Fri May 8 00:43:50 1998 Jason Merrill - * call.c (build_user_type_conversion_1): Handle second_conv + * call.c (build_user_type_conversion_1): Handle second_conv properly for templates. -Thu May 7 17:09:25 EDT 1998 Andrew MacLeod +Thu May 7 17:09:25 1998 Andrew MacLeod * method.c (build_decl_overload_real): Set TREE_USED flag to zero for build_type_variants nodes as well. @@ -2048,7 +7054,7 @@ Wed May 6 16:49:48 1998 Jim Wilson * Makefile.in (call.o, class.o, decl.o, decl2.o, errfn.o, error.o, except.o, expr.o, friend.o, init.o, lex.o, method.o, pt.o, repo.o, - rtti.o, search.o, semantics.o, sig.o, tree.o, typeck.o, typeck2.o, + rtti.o, search.o, semantics.o, sig.o, tree.o, typeck.o, typeck2.o, xref.o): Add toplev.h dependencies. Wed May 6 16:44:58 1998 Jeffrey A Law (law@cygnus.com) @@ -2065,9 +7071,9 @@ Wed May 6 14:28:18 1998 Kaveh R. Ghazi Wed May 6 06:36:41 1998 Robert Lipe - * call.c, class.c, decl.c, decl2.c, errfn.c, error.c, except.c, - expr.c, friend.c, init.c, lex.c, method.c, pt.c, repo.c, rtti.c, - search.c, semantics.c, sig.c, tree.c, typeck.c, typeck2.c, + * call.c, class.c, decl.c, decl2.c, errfn.c, error.c, except.c, + expr.c, friend.c, init.c, lex.c, method.c, pt.c, repo.c, rtti.c, + search.c, semantics.c, sig.c, tree.c, typeck.c, typeck2.c, xref.c: Add include of toplev.h. Wed May 6 02:33:39 1998 Jason Merrill @@ -2080,9 +7086,9 @@ Tue May 5 23:54:04 1998 Jason Merrill * init.c (expand_vec_init): The initialization of each array element is a full-expression. -Tue May 5 18:24:13 EDT 1998 Andrew MacLeod +Tue May 5 18:24:13 1998 Andrew MacLeod - * method.c (build_mangled_name): Add a call to build_type_variant + * method.c (build_mangled_name): Add a call to build_type_variant to get the right type. Tue May 5 01:25:03 1998 Jason Merrill @@ -2093,7 +7099,7 @@ Tue May 5 01:25:03 1998 Jason Merrill Sun May 3 01:32:14 1998 Jason Merrill - * call.c (build_over_call): Do evaluate arg even if it has empty + * call.c (build_over_call): Do evaluate arg even if it has empty class type. * decl.c (start_function): Don't push a member function. @@ -2101,7 +7107,7 @@ Thu Apr 30 18:59:23 1998 Jim Wilson * Makefile.in (g++FAQ.info): Put -o option before input file. -Thu Apr 30 13:05:33 EDT 1998 Andrew MacLeod +Thu Apr 30 13:05:33 1998 Andrew MacLeod * gxxint.texi: Add info for squangling codes K and B. @@ -2130,7 +7136,7 @@ Sun Apr 26 12:10:18 1998 Mark Mitchell (PRIMARY_TEMPLATE_P): Use it. (push_template_decl_real): New function. (redeclare_class_template): Take new template parameters as - input. + input. (is_specialization_of): New function. (comp_template_args): Declare. * decl.c (pushtag): Handle friend template classes. @@ -2150,7 +7156,7 @@ Sun Apr 26 12:10:18 1998 Mark Mitchell with friend templates. * typeck.c (comptypes): Use comp_template_args, rather than expanding it inline. - * parse.y (component_decl): Handle a nested template type + * parse.y (component_decl): Handle a nested template type like other component type declarations. * pt.c (check_explicit_specialization): Handle overloaded @@ -2168,14 +7174,14 @@ Thu Apr 23 21:19:06 1998 Jason Merrill Enforce access control here. Emit overload warnings here. (add_warning): New fn. (joust): Add WARN parm. If not set, call add_warning instead of - printing a warning. Reenable some warnings. + printing a warning. Re-enable some warnings. (tourney): Pass it. (convert_like): Adjust. (build_new_op): Adjust. (build_new_function_call): Adjust. (build_user_type_conversion_1): Adjust. (USER_CONV_FN): Adjust. - * tree.c (build_expr_wrapper, build_expr_ptr_wrapper, + * tree.c (build_expr_wrapper, build_expr_ptr_wrapper, build_int_wrapper): New fns. Thu Apr 23 18:27:53 1998 Mark P. Mitchell @@ -2194,15 +7200,15 @@ Wed Apr 22 13:24:48 1998 Mark Mitchell the DECL_RESULTs of a member TEMPLATE_DECL, not just the TEMPLATE_DECL. - * pt.c (tsubst): Decrease the template-level of - TEMPLATE_TEMPLATE_PARMS. Likewise for the DECL_INITIAL of a - TEMPLATE_PARM_INDEX. - (template_decl_level): New function. - (unify): Make sure to record unifications for template - parameters, even when the parameters exactly match the arguments. - Combine duplicated code for TEMPLATE_TEMPLATE_PARMs and - TEMPLATE_TYPE_PARMS. Don't try to unify template parameters that - aren't from the level we're currently working on. + * pt.c (tsubst): Decrease the template-level of + TEMPLATE_TEMPLATE_PARMS. Likewise for the DECL_INITIAL of a + TEMPLATE_PARM_INDEX. + (template_decl_level): New function. + (unify): Make sure to record unifications for template + parameters, even when the parameters exactly match the arguments. + Combine duplicated code for TEMPLATE_TEMPLATE_PARMs and + TEMPLATE_TYPE_PARMS. Don't try to unify template parameters that + aren't from the level we're currently working on. Tue Apr 21 22:00:04 1998 Mark Mitchell @@ -2345,29 +7351,29 @@ Sun Apr 12 22:31:19 1998 Richard Kenner Fri Apr 10 12:16:49 1998 Benjamin Kosnik * decl.c (duplicate_decls): Don't warn for redundant decls if - friend: let add_friend take care of it. + friend: let add_friend take care of it. Thu Apr 9 02:40:48 1998 Jason Merrill * sig.c (build_signature_pointer_constructor): Don't set TREE_HAS_CONSTRUCTOR for a signature pointer. * cvt.c (ocp_convert): Don't force a temporary for internal structs. - * init.c (resolve_offset_ref): Warn about implicit & on pmfs + * init.c (resolve_offset_ref): Warn about implicit & on pmfs here, too. - * typeck.c (build_unary_op): Only allow taking the address of a + * typeck.c (build_unary_op): Only allow taking the address of a real constructor. * typeck2.c (digest_init): Simplify. (store_init_value): Don't pedwarn about using { } for pmfs. Thu Apr 9 22:16:57 1998 Per Bothner - * cp-tree.h (start_decl): Update prototype. - * decl.c (start_decl): Like the C version, new parameters - for the attributes. Call cplus_decl_attributes here, - (pushdecl): Like C version, do build_type_copy if TYPE_DECL, - (grokdeclarator): Pass NULL for new start_decl arguments. - * pt.c (tsubst_expr): Likewise. - * parse.y: Merge cplus_decl_attribute calls into start_decl calls. + * cp-tree.h (start_decl): Update prototype. + * decl.c (start_decl): Like the C version, new parameters + for the attributes. Call cplus_decl_attributes here, + (pushdecl): Like C version, do build_type_copy if TYPE_DECL, + (grokdeclarator): Pass NULL for new start_decl arguments. + * pt.c (tsubst_expr): Likewise. + * parse.y: Merge cplus_decl_attribute calls into start_decl calls. * typeck.c (common_type): Check TYPE_MAIN_VARIANT. * lex.c (build_lang_decl): Add lang_name_java. * class.c (push_lang_context): Add lang_name_java. @@ -2378,14 +7384,14 @@ Thu Apr 9 22:16:57 1998 Benjamin Kosnik * decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT. * call.c (build_scoped_method_call): Check for TREE_CODE for VOID_TYPE instead of type == void_type_node. - (build_method_call): Ditto. - * decl.c (lookup_name_real): Ditto. - (grokdeclarator): Ditto. - (start_decl): Ditto. - (grokparms): Ditto. - (start_function): Ditto. - (finish_function): Ditto. - (start_method): Ditto. + (build_method_call): Likewise. + * decl.c (lookup_name_real): Likewise. + (grokdeclarator): Likewise. + (start_decl): Likewise. + (grokparms): Likewise. + (start_function): Likewise. + (finish_function): Likewise. + (start_method): Likewise. Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com) @@ -2419,7 +7425,7 @@ Sat Apr 4 12:52:35 1998 Jeffrey A Law (law@cygnus.com) Fri Apr 3 02:22:59 1998 Jason Merrill Implement empty base optimization. - * class.c (finish_struct_1): Add vbase fields earlier. Set + * class.c (finish_struct_1): Add vbase fields earlier. Set CLASSTYPE_SIZE of an empty base to 0. Types with bases can be empty. * search.c (dfs_check_overlap, dfs_no_overlap_yet): New fns. (types_overlap_p): New fn. @@ -2456,7 +7462,7 @@ Wed Apr 1 18:22:25 1998 Jeffrey A Law (law@cygnus.com) * class.c, Make sure system.h is included just after config.h. Delete lingering stdio and errno references too. * decl.c, errfn.c, parse.y, ptree.c search.c, xref.c: Likewise. - + Wed Apr 1 15:38:36 1998 Jason Merrill * friend.c (is_friend): Fix access control for local classes. @@ -2483,7 +7489,7 @@ Tue Mar 31 13:43:57 1998 Jeffrey A Law (law@cygnus.com) Mon Mar 30 12:15:00 1998 Mark Mitchell - * pt.c (fn_type_unification): Allow incomplete unification without + * pt.c (fn_type_unification): Allow incomplete unification without an immediate error message. Mon Mar 30 08:55:42 1998 Jason Merrill @@ -2561,7 +7567,7 @@ Fri Mar 27 20:23:18 1998 Mark Mitchell * error.c (dump_decl): Be a bit more explicit with template type arguments, when verbose. - + Fri Mar 27 18:16:40 1998 Jason Merrill * inc/exception: Reorder closing braces. @@ -2574,7 +7580,7 @@ Fri Mar 27 13:22:18 1998 Mark Mitchell Thu Mar 26 11:16:30 1998 Jason Merrill - * call.c (build_over_call): Check IS_AGGR_TYPE, not + * call.c (build_over_call): Check IS_AGGR_TYPE, not TYPE_LANG_SPECIFIC. * typeck.c (convert_arguments): Likewise. @@ -2633,8 +7639,8 @@ Tue Mar 24 12:21:55 1998 Benjamin Kosnik Tue Mar 24 12:21:48 1998 Jim Wilson - * decl.c (init_decl_processing): Initialize TYPE_MAX_VALUE for - boolean_type_node to 1. + * decl.c (init_decl_processing): Initialize TYPE_MAX_VALUE for + boolean_type_node to 1. Tue Mar 24 10:23:47 1998 Mark Mitchell @@ -2673,7 +7679,7 @@ Tue Mar 24 10:23:47 1998 Mark Mitchell (fn_type_unification): Use new interfaces. (type_unification): Likewise. Remove NOP_EXPR hack. (type_unification_real): Likewise. - (unify): Likewise. Deal with unification of complex expresions. + (unify): Likewise. Deal with unification of complex expressions. Mon Mar 23 12:24:37 1998 Jason Merrill @@ -2686,7 +7692,7 @@ Mon Mar 23 12:24:37 1998 Jason Merrill * search.c (lookup_field): Do implicit typename stuff. Sun Mar 22 00:50:42 1998 Nick Clifton - Geoff Noer + Geoff Noer * Makefile.in: Various fixes for building cygwin32 native toolchains. * Make-lang.in: Likewise. @@ -2706,7 +7712,7 @@ Fri Mar 20 10:42:07 1998 Jason Merrill Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org) - * semantics.c (finish_asm_stmt): Fix combine strings. Call + * semantics.c (finish_asm_stmt): Fix combine strings. Call c_expand_asm_operands () if output_operands, input_operands or clobbers is not NULL_TREE. @@ -2714,7 +7720,7 @@ Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij * pt.c (complete_template_args): New function. (get_bindings): Deal with specializations of function templates - with return type containing parameters from outer class + with return type containing parameters from outer class templates. (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, substitute arguments and compose a new type. @@ -2730,7 +7736,7 @@ Thu Mar 19 11:51:58 1998 Jason Merrill * call.c (standard_conversion): Handle A* -> const A* properly. - * pt.c (get_bindings_real): Rename from get_bindings. Add + * pt.c (get_bindings_real): Rename from get_bindings. Add check_rettype parm. (get_bindings): Pass 1. (get_bindings_overload): Pass 0. @@ -2751,7 +7757,7 @@ Thu Mar 19 02:27:48 1998 Jason Merrill Wed Mar 18 12:41:43 1998 Jason Merrill - * decl.c (make_implicit_typename): Only change the type of a + * decl.c (make_implicit_typename): Only change the type of a TYPENAME_TYPE. Wed Mar 18 10:09:51 1998 Mark Mitchell @@ -2765,7 +7771,7 @@ Wed Mar 18 10:09:51 1998 Mark Mitchell * cp-tree.def: Add ASM_STMT tree node. * Makefile.in, Make-lang.in: Add dependencies on and for semantics.c. - + Wed Mar 18 00:24:10 1998 Jason Merrill * pt.c (push_template_decl): Only check primary templates. @@ -2773,7 +7779,7 @@ Wed Mar 18 00:24:10 1998 Jason Merrill * pt.c (check_explicit_specialization): Complain about default args in explicit specialization. - * parse.y (nomods_initdcl0): Also call cp_finish_decl for a + * parse.y (nomods_initdcl0): Also call cp_finish_decl for a constructor_declarator. Tue Mar 17 14:44:54 1998 Mark Mitchell @@ -2800,7 +7806,7 @@ Mon Mar 16 12:10:39 1998 Jason Merrill * class.c (pushclass): Only use the mi_matrix stuff #ifdef MI_MATRIX. * search.c: Likewise. - * lex.c (do_pending_defargs): Only call + * lex.c (do_pending_defargs): Only call maybe_{begin,end}_member_template_processing for FUNCTION_DECLs. * parse.y (initdcl0_innards): Move maybeasm back into initdcl0 et al. @@ -2813,9 +7819,9 @@ Mon Mar 16 10:54:21 1998 Mark Mitchell * pt.c (tsubst_copy): Deal with BIND_EXPR in a way that more closely mimics the behavior in parse.y. - (tsubst_expr): Return the resuting BLOCK when making a tsubst'ing + (tsubst_expr): Return the resulting BLOCK when making a tsubst'ing into a compound statement. - + Sun Mar 15 02:07:26 1998 Jason Merrill * cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro. @@ -2832,13 +7838,13 @@ Sun Mar 15 01:14:22 1998 Kriang Lerdsuwanakij * lex.c (do_identifier): Handle TEMPLATE_DECL that was added in the class scope to catch redefinition error. - * pt.c (reduce_template_parm_level): Also copy + * pt.c (reduce_template_parm_level): Also copy the DECL_TEMPLATE_PARMS field. Sun Mar 15 10:54:08 1998 Mark Mitchell * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a - reduced-level template type parameter. + reduced-level template type parameter. Sun Mar 15 12:26:02 1998 Manfred Hollstein @@ -2849,10 +7855,10 @@ Sun Mar 15 12:26:02 1998 Manfred Hollstein * typeck2.c (abstract_virtuals_error): Use two loops to emit abstract virtual functions and virtual functions which need a final overrider separately. - + Thu Mar 12 09:39:40 1998 Manfred Hollstein - * lang-specs.h: Properly put brackets around array elements in + * lang-specs.h: Properly put brackets around array elements in initializer. * typeck.c (build_binary_op_nodefault): Correctly place parens around @@ -2870,7 +7876,7 @@ Thu Mar 12 09:26:04 1998 Manfred Hollstein * except.c (do_unwind): #if 0 definition of unused variables fcall and next_pc. - * expr.c (extract_scalar_init): #if 0 prototype and function + * expr.c (extract_scalar_init): #if 0 prototype and function definition. * init.c (expand_aggr_init_1): Remove unused variable init_type. @@ -2914,13 +7920,13 @@ Fri Mar 6 23:27:35 1998 Jeffrey A Law (law@cygnus.com) Fri Mar 6 10:06:59 1998 Kaveh R. Ghazi - * method.c: Include "system.h" to get stdlib.h, stdio.h, - ctype.h, string.h, etc. - (issue_nrepeats): Add default case in enumeration switch. - (check_btype): Likewise. - (process_overload_item): Likewise. - - * Makefile.in (method.o): Depend on system.h. + * method.c: Include "system.h" to get stdlib.h, stdio.h, + ctype.h, string.h, etc. + (issue_nrepeats): Add default case in enumeration switch. + (check_btype): Likewise. + (process_overload_item): Likewise. + + * Makefile.in (method.o): Depend on system.h. Wed Mar 4 22:26:53 1998 Andreas Schwab @@ -2931,7 +7937,7 @@ Wed Mar 4 12:11:53 1998 Michael Tiemann * rtti.c (get_tinfo_fn_dynamic): If this function is called an FLAG_RTTI is unset, initialize type info machinery and continue with FLAG_RTTI enabled. - (get_typeid): Ditto. + (get_typeid): Likewise. Wed Mar 4 11:47:55 1998 Jason Merrill @@ -2950,7 +7956,7 @@ Tue Mar 3 01:38:17 1998 Jason Merrill some formatting quirks. * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c, - method.c, pt.c, ptree.c, typeck.c: Remove support for + method.c, pt.c, ptree.c, typeck.c: Remove support for -fno-ansi-overloading and overloading METHOD_CALL_EXPR. * class.h: Remove. * Makefile.in: Adjust. @@ -2966,7 +7972,7 @@ Mon Mar 2 12:11:06 1998 Jason Merrill (nested_name_specifier): And add it before this use. (typename_sub0): And this use. Also add use without the keyword. (typename_sub1): Likewise. - * pt.c (instantiate_class_template): Don't actually instantiate + * pt.c (instantiate_class_template): Don't actually instantiate anything if our type uses template parms. Mon Mar 2 11:04:59 1998 Jim Wilson @@ -2987,9 +7993,9 @@ Sat Feb 28 12:06:44 1998 Jason Merrill * lex.c (yyprint): Handle a PTYPENAME being a TEMPLATE_DECL. * decl.c (make_typename_type): Handle template-id where the name is a TEMPLATE_DECL. - * call.c (build_scoped_method_call): Handle member template + * call.c (build_scoped_method_call): Handle member template destructor call. - * pt.c (tsubst_copy, METHOD_CALL_EXPR): Don't assume a member + * pt.c (tsubst_copy, METHOD_CALL_EXPR): Don't assume a member destructor is represented by the type. * cp-tree.h (TYPENAME_TYPE_FULLNAME): New macro. @@ -3036,7 +8042,7 @@ Fri Feb 27 02:25:16 1998 Jason Merrill * decl.c (pushtag): Handle member templates. * method.c (do_inline_function_hair): Don't touch IDENTIFIER_GLOBAL_VALUE. - * init.c (build_offset_ref): If name isn't an identifier, just + * init.c (build_offset_ref): If name isn't an identifier, just return it. * spew.c (yylex): Handle PTYPENAME like TYPENAME. @@ -3067,43 +8073,43 @@ Wed Feb 25 00:35:33 1998 Jason Merrill Tue Feb 24 22:15:04 1998 Martin von Loewis * cp-tree.def: Add CPLUS_BINDING node. - * cp-tree.h (tree_binding): new struct - (BINDING_SCOPE, BINDING_VALUE): new macros - (current_namespace, global_namespace): declare extern - (struct lang_decl_flags): new field in_namespace - (DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): new macros - (DECL_NAMESPACE, SET_DECL_NAMESPACE): new macros - (TREE_INDIRECT_USING): new macro + * cp-tree.h (tree_binding): New struct. + (BINDING_SCOPE, BINDING_VALUE): New macros. + (current_namespace, global_namespace): Declare extern. + (struct lang_decl_flags): New field in_namespace. + (DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): New macros. + (DECL_NAMESPACE, SET_DECL_NAMESPACE): New macros. + (TREE_INDIRECT_USING): New macro. * decl2.c (current_namespace, global_namespace): Declare. The value is a NAMESPACE_DECL now, not a TREE_LIST. - (is_namespace_ancestor, namespace_ancestor):new static functions. - (add_using_namespace, ambiguous_decl): likewise. - (lookup_using_namespace): new support function for lookup_name. - (qualified_lookup_using_namespace): new support function for - do_scoped_id and lookup_namespace_name - (get_namespace_id): mark as obsolete. + (is_namespace_ancestor, namespace_ancestor): New static functions. + (add_using_namespace, ambiguous_decl): Likewise. + (lookup_using_namespace): New support function for lookup_name. + (qualified_lookup_using_namespace): New support function for + do_scoped_id and lookup_namespace_name. + (get_namespace_id): Mark as obsolete. (current_namespace_id): Likewise. (do_namespace_alias): Implement. (do_using_directive): Implement as call to add_using_namespace. - * decl.c (binding_for_name): new function. - (push_namespace, pop_namespace): implement. - (push_decl): don't install a FUNCTION_DECL in the global branch. - (lookup_namespace_name): implement using qualified lookup. + * decl.c (binding_for_name): New function. + (push_namespace, pop_namespace): Implement. + (push_decl): Don't install a FUNCTION_DECL in the global branch. + (lookup_namespace_name): Implement using qualified lookup. (lookup_name_real): For global scoping, lookup in - global_namespace. For namespace scoping, lookup in given - namespace. For unscoped lookup, iterate over namespace, + global_namespace. For namespace scoping, lookup in given + namespace. For unscoped lookup, iterate over namespace, considering using directives. - (init_decl_processing): initialize global_namespace. + (init_decl_processing): Initialize global_namespace. (grokvardecl): Build assembler name as static name for globals. (grokdeclarator): Remove old namespace mangling. (xref_tag): When installing a global binding for the tag, make sure we have an identifier. - * method.c (build_overload_nested_name): mangle namespaces. + * method.c (build_overload_nested_name): Mangle namespaces. (build_qualified_name): Likewise. (build_decl_overload_real): Likewise. - * lex.c (build_lang_decl): set namespace for new declaration to + * lex.c (build_lang_decl): Set namespace for new declaration to current_namespace. - (do_scoped_id): find global names in global or current + (do_scoped_id): Find global names in global or current namespace, or using qualified namespace lookup, depending on context. * init.c (build_member_call): When scope is namespace, use @@ -3133,7 +8139,7 @@ Tue Feb 24 01:40:24 1998 Jason Merrill * pt.c (instantiate_class_template): Don't instantiate if pedantic and the args use template parms. - * pt.c (push_tinst_level): If the instantiaton uses template parms, + * pt.c (push_tinst_level): If the instantiation uses template parms, fail silently. * decl.c (xref_basetypes): Do call complete_type for basetypes that involve template parameters. @@ -3162,7 +8168,7 @@ Mon Feb 23 02:52:29 1998 Mark Mitchell * Make-lang.in (cc1plus): Note that cc1plus depends on cp/cp-tree.h and cp/cp-tree.def. - + * cp-tree.def (TEMPLATE_CONST_PARM): Remove. (TEMPLATE_PARM_INDEX): New tree code, used to indicate a position in a template parameter list. @@ -3197,7 +8203,7 @@ Mon Feb 23 02:52:29 1998 Mark Mitchell two template functions with the same DECL_ASSEMBLER_NAME the same, since the names are not yet mangled. * error.c (dump_decl): Use TEMPLATE_PARM_INDEX instead of - TEMPLATE_CONST_PARM. + TEMPLATE_CONST_PARM. (dump_expr): Likewise. Use the TEMPLATE_PARM_DECL to get at the decl for a non-type parameter, rather than printing `'. * friend.c (is_friend): Handle TEMPLATE_DECL friends. @@ -3210,7 +8216,7 @@ Mon Feb 23 02:52:29 1998 Mark Mitchell conditionally calling end_member_template_processing. (do_pending_defargs): Likewise. (do_identifier): Use TEMPLATE_PARM_INDEX instead of - TEMPLATE_CONST_PARM. + TEMPLATE_CONST_PARM. * method.c (build_mangled_template_parm_index): New function. (build_overload_value): Use it. (build_overload_name): Likewise. @@ -3240,14 +8246,14 @@ Mon Feb 23 02:52:29 1998 Mark Mitchell template. (tsubst_copy): Tidy up slightly. Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. Handle TYPE_DECLs by tsubsting into them. - (unify): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. + (unify): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. (get_bindings): Call add_to_template_args if necessary. (instantiate_decl): Handle instantiations of friend templates. * search.c (lookup_field_1): Don't treat the TYPE_FIELDS of a TEMPLATE_TYPE_PARM as a list of fields; it's not! - * spew.c (yylex): Do a little manual constant propogation to + * spew.c (yylex): Do a little manual constant propagation to clarify the code. - + Sun Feb 22 19:53:29 1998 Jeffrey A Law (law@cygnus.com) * error.c: Include sys/types.h. @@ -3260,20 +8266,20 @@ Thu Feb 19 10:36:48 1998 Jason Merrill * typeck2.c (process_init_constructor): Sorry about non-trivial labeled initializers. - * parse.y (initlist): Reenable labeled initializers. + * parse.y (initlist): Re-enable labeled initializers. Thu Feb 19 10:15:55 1998 Kriang Lerdsuwanakij - * pt.c (coerce_template_parms) Add a new parameter, is_tmpl_parm, - all callers changed. Rely on the new parameter instead of arg + * pt.c (coerce_template_parms): Add a new parameter, is_tmpl_parm, + all callers changed. Rely on the new parameter instead of arg being a TREE_LIST when determine whether we are working inside template template parameter. Clean up is_type test. - + Thu Feb 19 10:04:12 1998 Jason Merrill * cvt.c (cp_convert_to_pointer): Preserve TREE_CONSTANT. * typeck2.c (initializer_constant_valid_p): Allow conversions - between pointers and refrerences. + between pointers and references. 1998-02-19 Brendan Kehoe @@ -3304,14 +8310,14 @@ Tue Feb 17 14:07:52 1998 Mark Mitchell (datadef): Remove redundant actions. (initdcl0, notype_initdcl0, nomods_initdcl0): Use initdcl0_innards. * parse.c: Regenerated. - + Tue Feb 17 11:54:16 1998 Jason Merrill * parse.y (simple_stmt): Use getdecls() to check for decl. Sat Feb 14 11:50:51 1998 Manfred Hollstein - * Make-lang.in (DEMANGLER_INSTALL_NAME, DEMANGLER_CROSS_NAME): New + * Make-lang.in (DEMANGLER_INSTALL_NAME, DEMANGLER_CROSS_NAME): New macros. (c++.install-common): Install c++filt properly as native or as cross variant. @@ -3327,14 +8333,14 @@ Fri Feb 13 14:06:22 1998 Mike Stump Fri Feb 13 13:24:32 1998 Jason Merrill - * parse.y (simple_stmt): If the condition isn't a declaration, + * parse.y (simple_stmt): If the condition isn't a declaration, start the controlled block after the test. Fri Feb 13 02:26:10 1998 Andreas Schwab * call.c (build_over_call): Convert builtin abs, labs and fabs to tree-codes. - * decl.c (init_decl_processing): Reenable abs, labs and fabs as + * decl.c (init_decl_processing): Re-enable abs, labs and fabs as builtins. Fri Feb 13 01:36:42 1998 Jason Merrill @@ -3363,7 +8369,7 @@ Wed Feb 11 23:28:05 1998 Mark Mitchell Wed Feb 11 16:42:04 1998 Mark Mitchell * tree.c (is_overloaded_fn): Use really_overloaded_fn. - (really_overloaded_fn): Move check here from is_overloaded_fn. + (really_overloaded_fn): Move check here from is_overloaded_fn. (get_first_fn): Use really_overloaded_fn and is_overloaded_fn. Wed Feb 11 15:54:18 1998 Mark Mitchell @@ -3402,7 +8408,7 @@ Mon Feb 9 22:23:31 1998 Mark Mitchell (uses_template_parms): Handle the DECL_INITIAL for a CONST_DECL. * typeck.c (build_component_ref): Assign the correct type to the result of build_vfn_ref. - + Tue Feb 10 23:56:46 1998 Jason Merrill * pt.c (convert_nontype_argument): Fix typo. @@ -3415,19 +8421,19 @@ Tue Feb 10 20:36:52 1998 Jason Merrill * decl.c (grokdeclarator): Use DECL_USE_TEMPLATE instead when deciding to override DECL_ASSEMBLER_NAME. -Tue Feb 10 15:30:55 EST 1998 Andrew MacLeod +Tue Feb 10 15:30:55 1998 Andrew MacLeod * decl2.c (lang_f_options): Add -fsquangle to option processing list. * cp-tree.h (flag_do_squangling): Add declaration. * lang-options.h: Add -fsquangle and -fno-squangle. * method.c: Add macros and static variables for squangling. - (build_overload_name): Rename to build_mangled_name, add logic for B - compression, and split into process_modifiers and + (build_overload_name): Rename to build_mangled_name, add logic for B + compression, and split into process_modifiers and process_overload_item. - (process_modifiers): New function, to handle constant, reference, - and pointer types. + (process_modifiers): New function, to handle constant, reference, + and pointer types. (process_overload_item): New function, handles issue of type codes. - (build_overload_name): New function, start squangling and call + (build_overload_name): New function, start squangling and call build_mangled_name. (ALLOCATE_TYPEVEC, DEALLOCATE_TYPEVEC): Remove macro and expand inline. (start_squangling): New function to initialize squangling structs. @@ -3440,7 +8446,7 @@ Tue Feb 10 15:30:55 EST 1998 Andrew MacLeod use DECL_ASSEMBLER_NAME when squangling is on. (check_btype): New function, checks for B type compression. (build_static_name, build_decl_overload_real): Initiate squangling. - (build_typename_overload, build_overload_with_type): Initiate + (build_typename_overload, build_overload_with_type): Initiate squangling Sun Feb 8 23:47:38 1998 scott snyder @@ -3476,7 +8482,7 @@ Tue Feb 3 23:50:52 1998 Mark Mitchell * cvt.c (ocp_convert): Obtain the constant values from constant decls even if the destination type is the same as the type of the - decl. + decl. * decl2.c (finish_file): Make sure that static inlines with definitions are not marked DECL_EXTERNAL before returning. @@ -3485,7 +8491,7 @@ Tue Feb 3 22:43:42 1998 Jason Merrill * decl.c: Lose arg_looking_for_template. (lookup_name_real): Likewise. - * parse.y: Lose processing_template_arg, template_arg1 + * parse.y: Lose processing_template_arg, template_arg1. (primary): Likewise. * spew.c (yylex): Set lastiddecl for PTYPENAMEs, too. @@ -3493,36 +8499,36 @@ Tue Feb 3 22:04:01 1998 Kriang Lerdsuwanakij * error.c (dump_decl): Fix type of default arguments for template template parameters and nontype template parameters. - * parse.y (template_parm): Handle invalid default template + * parse.y (template_parm): Handle invalid default template template arguments here. - * parse.y (template_parm): Use template_arg instead of PTYPENAME + * parse.y (template_parm): Use template_arg instead of PTYPENAME for default template template argument. - * pt.c (coerce_template_parms): Merge default template argument + * pt.c (coerce_template_parms): Merge default template argument codes. Can treat RECORD_TYPE as template name if it is implicitly created. Fix argument index in error message. - * typeck.c (comptypes): Merge template argument comparison codes in + * typeck.c (comptypes): Merge template argument comparison codes in TEMPLATE_TEMPLATE_PARM and RECORD_TYPE. -Tue Jan 6 01:42:44 1998 Mumit Khan +Tue Jan 6 01:42:44 1998 Mumit Khan * lex.c (file_name_nondirectory): Also check for '/'. Mon Feb 2 11:24:22 1998 Mark Mitchell * parse.y (primary): Deal with statement-expressions in - templates. + templates. * pt.c (tsubst_copy): Handle BIND_EXPR. * tree.c (mapcar): Likewise. * call.c (add_template_candidate_real): Pass extra parameter to - fn_type_unification. + fn_type_unification. * cp-tree.h (fn_type_unification): Add parameter. * pt.c (fn_type_unification): Add additional parameter to deal with static member functions. (get_bindings): Deal with static member functions. - * cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro. + * cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro. (revert_static_member_fn): Declare. * decl.c (revert_static_member_fn): Remove declaration. Change linkage from internal to external. @@ -3571,7 +8577,7 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi (grokdeclarator): Add parentheses around && within ||. Add explicit braces to avoid ambiguous `else'. (grokparms): Initialize `type' to NULL_TREE. - (xref_tag): Remove unused label `just_return'. + (xref_tag): Remove unused label `just_return'. (finish_enum): Initialize `minnode' and `maxnode' to NULL_TREE. (finish_function): Initialize `cond' and `thenclause' to NULL_TREE. (hack_incomplete_structures): Add parentheses around assignment @@ -3581,7 +8587,7 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi * error.c: Include . (dump_expr): Change the type of `i' to size_t. Remove unused - label `error'. + label `error'. * except.c (init_exception_processing): Remove unused variable `d'. (expand_throw): Likewise for `label'. @@ -3607,7 +8613,7 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi `look_for_semicolon' and `look_for_lbrac'. (cons_up_default_function): Initialize `args' to NULL_TREE. (readescape): Initialize `firstdig' to 0. - (real_yylex): Add parentheses around assignment used as truth value. + (real_yylex): Add parentheses around assignment used as truth value. * method.c: Include if we don't have . Protect declaration of `index' with autoconf macro. @@ -3628,8 +8634,8 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi * repo.c (init_repo): Add parentheses around assignment used as truth value. (finish_repo): Remove unused varable `p'. - - * search.c (get_binfo): Initiize `type' to NULL_TREE. + + * search.c (get_binfo): Initialize `type' to NULL_TREE. (get_base_distance): Likewise. (lookup_field): Initialize `rval_binfo_h', `type', `basetype_path' and `new_v' to NULL_TREE. @@ -3649,7 +8655,7 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi (hash_tree_cons): Initialize hashcode to 0. (can_free): Likewise for `size'. (cp_tree_equal): Add explicit braces to avoid ambiguous `else'. - + * typeck.c (convert_sequence): Hide prototype. (common_type): Add explicit braces to avoid ambiguous `else'. (comp_target_types): Likewise. @@ -3665,7 +8671,7 @@ Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi * xref.c (GNU_xref_decl): Initialize `cls' to 0. -Sun Feb 1 12:45:34 1998 J"orn Rennecke +Sun Feb 1 12:45:34 1998 J"orn Rennecke * decl.c (init_decl_processing): Use set_sizetype. * decl2.c (sizetype): Don't declare. @@ -3688,13 +8694,13 @@ Thu Jan 29 10:39:30 1998 Mark Mitchell Wed Jan 28 23:14:44 1998 Jason Merrill * class.c (instantiate_type): Don't just return a known type if - it's wrong. + it's wrong. Wed Jan 28 11:04:07 1998 Mark Mitchell * class.c (instantiate_type): Remove handling of FUNCTION_DECL since that code could never be reached. - + * error.c (dump_decl): Avoid aborting in the midst of printing an error message about an illegal template declaration. @@ -3703,7 +8709,7 @@ Wed Jan 28 11:04:07 1998 Mark Mitchell * pt.c (convert_nontype_argument): Allow REAL_TYPE and COMPLEX_TYPE template arguments as a g++ extension. - + * cp-tree.def (ALIGNOF_EXPR): New tree code. * decl2.c (grok_alignof): If processing_template_decl, just store the expression. @@ -3715,7 +8721,7 @@ Wed Jan 28 11:04:07 1998 Mark Mitchell * pt.c (uses_template_parms): Correctly determine whether or not a SIZEOF_EXPR/ALIGNOF_EXPR uses template parameters so that constant folding can be done. - + * cp-tree.h (grok_enum_decls): Remove type parameter. * decl.c (grok_enum_decls): Likewise. * decl2.c (grok_x_components): Call grok_enum_decls @@ -3727,7 +8733,7 @@ Wed Jan 28 11:04:07 1998 Mark Mitchell * decl.c (start_function): Make member functions of local classes in extern inline functions have comdat linkage here... (grokdeclarator): Rather than here. - + Wed Jan 28 10:55:47 1998 Jason Merrill * pt.c (convert_nontype_argument): Use decl_constant_value. @@ -3755,18 +8761,18 @@ Tue Jan 27 16:42:21 1998 Mark Mitchell (maybe_push_to_top_level): Save them. (pop_from_top_level): Restore them. (grokfndecl): Use new return value from - check_explicit_specialization. + check_explicit_specialization. (start_decl): Don't check flag_guiding_decls before pushing - decls. + decls. (cp_finish_decl): Remove previous (bogus) change. (grok_declarator): Use decl_function_context rather than - is_local_class. + is_local_class. * decl2.c (finish_file): Pass extra argument to get_bindings. - (build_expr_from_tree): Let build_x_component_ref check + (build_expr_from_tree): Let build_x_component_ref check validity of arguments rather than doing it here. * lex.c (cons_up_default_function): Remove code fooling with processing_specialization, processing_explicit_instantiation - flags, as that is now done in {maybe_push_top,pop_from}_top_level. + flags, as that is now done in {maybe_push_top,pop_from}_top_level. * method.c (build_overload_identifier): Mangle local classes in template functions correctly. * parse.y (finish_member_template_decl): Move to pt.c. @@ -3775,9 +8781,9 @@ Tue Jan 27 16:42:21 1998 Mark Mitchell (determine_specialization): Change interface. Properly look for most specialized versions of template candidates. (check_explicit_specialization): Fully process explicit - instantiations. + instantiations. (push_template_decl): Avoid looking at CLASSTYPE fields in - FUNCTION_DECLS. + FUNCTION_DECLS. (determine_overloaded_function): Remove. (convert_nontype_argument): Change name from convert_nontype_parameter. Use determine_overloaded_function @@ -3788,7 +8794,7 @@ Tue Jan 27 16:42:21 1998 Mark Mitchell (lookup_template_class): Likewise. (tsubst): Likewise. (more_specialized): Take explict template arguments as a - parameter. + parameter. (most_specialized): Likewise. (get_bindings): Likewise. Check that return types match before proclaiming a function a match. @@ -3801,7 +8807,7 @@ Tue Jan 27 16:42:21 1998 Mark Mitchell Tue Jan 27 01:44:02 1998 Jason Merrill - * expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that + * expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that return_target and call_target are equivalent. * pt.c (type_unification_real): Just accept function parms that @@ -3819,7 +8825,7 @@ Sat Jan 24 12:13:54 1998 Jason Merrill * error.c (dump_decl): Fix type default template args. (dump_type): Hand TEMPLATE_DECL off to dump_decl. -Fri Jan 23 18:34:37 1998 Mumit Khan +Fri Jan 23 18:34:37 1998 Mumit Khan * lex.c (DIR_SEPARATOR): Define to be '/' if not already defined. (file_name_nondirectory): Use. @@ -3827,10 +8833,10 @@ Fri Jan 23 18:34:37 1998 Mumit Khan Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij * pt.c (coerce_template_parms): Don't access elements of ARGLIST - that are not really present. Substitute default arguments in - template template arguments. Correctly convert TEMPLATE_DECL to + that are not really present. Substitute default arguments in + template template arguments. Correctly convert TEMPLATE_DECL to TEMPLATE_TEMPLATE_PARM. - (comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM + (comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM are no longer treated specially here. * parse.y (template_template_parm): Fix copy error. * decl.c (grokdeclarator): Warn about missing `typename' for nested @@ -3851,15 +8857,15 @@ Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij (grokdeclarator): Handle TEMPLATE_DECL. * decl2.c (constructor_name_full): Handle TEMPLATE_TEMPLATE_PARM. * error.c (dump_type): Add TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM. - (dump_type_prefix, dump_type_suffix) Handle TEMPLATE_TEMPLATE_PARM. + (dump_type_prefix, dump_type_suffix): Handle TEMPLATE_TEMPLATE_PARM. (dump_decl): Handle unnamed template type parameters. Handle template template parameters. (dump_function_name): Handle template template parameters. - * init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef): + * init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef): Handle TEMPLATE_TEMPLATE_PARM. * method.c (build_template_template_parm_names): New function. (build_template_parm_names): Handle TEMPLATE_DECL. - (build_overload_nested_name, build_overload_name): + (build_overload_nested_name, build_overload_name): Handle TEMPLATE_TEMPLATE_PARM. * parse.y (maybe_identifier): New nonterminal. (template_type_parm): Use it. @@ -3873,11 +8879,11 @@ Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij (process_template_parm): Handle template template parameters. (coerce_template_parms, comp_template_args): Likewise. (mangle_class_name_for_template, lookup_template_class): Likewise. - (uses_template_parms): Handle TEMPLATE_DECL and + (uses_template_parms): Handle TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM. (current_template_args): Handle TEMPLATE_DECL. (tsubst, tsubst_copy, unify): Handle TEMPLATE_TEMPLATE_PARM. - * search.c (dfs_walk, dfs_record_inheritance): + * search.c (dfs_walk, dfs_record_inheritance): Handle TEMPLATE_TEMPLATE_PARM. * tree.c (copy_template_template_parm): New function. (mapcar): Handle TEMPLATE_TEMPLATE_PARM. @@ -3893,16 +8899,16 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell * decl2.c (build_expr_from_tree): Issue an error message if the object in a COMPONENT_REF is a TEMPLATE_DECL. - + * typeck.c (incomplete_type_error): Handle TEMPLATE_TYPE_PARMs. - + * class.c (is_local_class): New function. * cp-tree.h (is_local_class): Declare it. (last_tree): Likewise. (begin_tree): Likewise. (end_tree): Likewise. (lookup_template_class): Change prototype. - * decl.c (cp_finish_decl): Check for NULL where necesary. + * decl.c (cp_finish_decl): Check for NULL where necessary. Consider FUNCTION_DECLS to declare objects with top-level binding, when calling make_decl_rtl. (grokdeclarator): Give members of local classes internal linkage. @@ -3922,19 +8928,19 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell * pt.c (saved_trees): New variable. (mangle_class_name_for_template): Change prototype. Use additional function context to name local classes in templates - correctly. + correctly. (classtype_mangled_name): Pass the context. (push_template_decl): Handle local classes and templates, and member functions for such classes. (convert_nontype_parameter): Fix handling of pointer-to-member - constants. + constants. (lookup_template_class): Handle local classes in templates. (tsubst): Likewise. Don't assume that template instantiations - have external linkage; pay attention to the template declaration. + have external linkage; pay attention to the template declaration. (mark_decl_instantiated): Likewise. (begin_tree): New function. (end_tree): Likewise. - + * decl.c (xref_basetypes): Don't call complete_type for basetypes that involve template parameters; that can lead to infinite recursion unnecessarily. @@ -3946,11 +8952,11 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell (build_template_decl): New function. (push_template_delc): Handle out-of-class specializations of member templates. - - * pt.c (check_explicit_specialization): Set up the template - information before registering the specialization. - (coerce_template_parms): Fix thinko. - (tsubst): Handle specializations of member templates correctly. + + * pt.c (check_explicit_specialization): Set up the template + information before registering the specialization. + (coerce_template_parms): Fix thinko. + (tsubst): Handle specializations of member templates correctly. * class.c (finish_struct_methods): Remove calls to check_explicit_specialization from here. @@ -3960,7 +8966,7 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell (begin_explicit_instantiation): Likewise. (end_explicit_instantiation): Likewise. (determine_specialization): Renamed from - determine_explicit_specialization. + determine_explicit_specialization. (comp_template_parms): New function. (processing_explicit_instantiation): New variable. * cvt.c (perform_qualification_conversions): New function. @@ -3970,7 +8976,7 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell instantiation/specialization mismatches. (start_decl): Don't call pushdecl for template specializations, since they don't affect overloading. - (start_function): Likewise + (start_function): Likewise. (grokfndecl): Call check_explicit_specialization a little later. Don't call duplicate_decls for memberm template specializations. (grokdeclarator): Don't update template_count for classes that are @@ -3981,7 +8987,7 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell * parse.y (finish_member_template_decl): New function. (component_decl_1): Use it. (fn.def2): Likewise. - (template_arg_list_opt): New nonterminal. + (template_arg_list_opt): New nonterminal. (template_type): Use it. (self_template_type): Likewise. (template_id): Likewise. @@ -4005,12 +9011,12 @@ Mon Jan 19 22:40:03 1998 Mark Mitchell (comp_template_parms): New function. (coerce_template_parms): Call convert_nontype_parameter. (tsubst): Refine handling of member templates. Use - register_specialization. + register_specialization. (instantiate_template): Use retrieve_specialization. (do_decl_instantiation): Likewise. (instantiate_decl): Likewise. (type_unification): Improve handling of explict template - arguments. + arguments. * tree.c (mapcar): Return error_mark_node, rather than aborting, on VAR_DECLS, FUNCTION_DECLS, and CONST_DECLS. * typeck.c (build_unary_op): Call determine_specialization, rather @@ -4022,7 +9028,7 @@ Mon Jan 19 13:18:51 1998 Jason Merrill Fri Jan 16 11:40:50 1998 Bruno Haible - * error.c (dump_decl): For enum tags, output the tag, not its value. + * error.c (dump_decl): For enum tags, output the tag, not its value. 1998-01-13 Brendan Kehoe @@ -4052,11 +9058,11 @@ Wed Jan 7 23:47:13 1998 Jason Merrill (expand_exception_blocks): Likewise. (alloc_eh_object): New fn. (expand_throw): Use it. Protect exception init with terminate. - * typeck.c (build_modify_expr): Remove code that ignores trivial + * typeck.c (build_modify_expr): Remove code that ignores trivial methods. Mon Dec 22 11:36:27 1997 Kaveh R. Ghazi - + * call.c (add_builtin_candidate): Add default case in enumeration switch. (build_new_op): Likewise. @@ -4087,7 +9093,7 @@ Thu Dec 18 14:51:50 1997 Mark Mitchell Thu Dec 18 14:43:19 1997 Jason Merrill - * typeck.c (unary_complex_lvalue): Ignore op0 when taking the + * typeck.c (unary_complex_lvalue): Ignore op0 when taking the address of an OFFSET_REF. * cp-tree.def: Add AGGR_INIT_EXPR. @@ -4100,10 +9106,10 @@ Thu Dec 18 14:43:19 1997 Jason Merrill Wed Dec 17 17:08:52 1997 Benjamin Kosnik * pt.c (instantiate_class_template): Don't do injection when - processing_template_decl is true, as pollutes current_binding_level - for base classes. + processing_template_decl is true, as pollutes current_binding_level + for base classes. -Wed Dec 17 21:17:39 1997 Peter Schmid +Wed Dec 17 21:17:39 1997 Peter Schmid * pt.c (maybe_fold_nontype_arg): Add prototype. @@ -4123,21 +9129,21 @@ Sun Dec 14 22:34:20 1997 Jason Merrill * cvt.c (cp_convert_to_pointer): Fix base conversion of pm's. - * pt.c (type_unification_real): Change __null to type void* with + * pt.c (type_unification_real): Change __null to type void* with a warning. Sun Dec 14 20:38:35 1997 Mark Mitchell * call.c (implicit_conversion): Don't call build_user_type_conversion_1 with a NULL expr, since it will - crash. + crash. * pt.c (unify): Don't try to unify array bounds if either array is unbounded. Fri Dec 12 16:09:14 1997 Jason Merrill - * errfn.c (cp_pedwarn, cp_pedwarn_at, cp_error_at, cp_warning_at): + * errfn.c (cp_pedwarn, cp_pedwarn_at, cp_error_at, cp_warning_at): Replace extern decls with casts. * decl.c (expand_start_early_try_stmts): Don't mess with a sequence. @@ -4150,7 +9156,7 @@ Thu Dec 11 22:18:37 1997 Jason Merrill * decl2.c (comdat_linkage): Also set DECL_COMDAT. (finish_file): Check DECL_COMDAT instead of weak|one_only. (import_export_vtable): Use make_decl_one_only instead of - comdat_linkage for win32 tweak. + comdat_linkage for win32 tweak. (import_export_decl): Likewise. * pt.c (mark_decl_instantiated): Likewise. @@ -4164,16 +9170,16 @@ Thu Dec 11 21:12:09 1997 Jason Merrill * decl.c: Likewise. Thu Dec 11 20:43:33 1997 Teemu Torma - + * decl.c (ptr_ptr_type_node): Define. (init_decl_processing): Initialize it. * cp-tree.h: Declare it. * exception.cc (__cp_exception_info): Use __get_eh_info. - (__cp_push_exception): Ditto. - (__cp_pop_exception): Ditto. + (__cp_push_exception): Likewise. + (__cp_pop_exception): Likewise. From Scott Snyder : - * except.c (expand_builtin_throw): Use get_saved_pc_ref instead of + * except.c (expand_builtin_throw): Use get_saved_pc_ref instead of saved_pc. (init_exception_processing): Removed saved_pc initialization. @@ -4186,8 +9192,8 @@ Mon Dec 8 23:17:13 1997 Jason Merrill * init.c (expand_vec_init): Don't fold a list of parameters. * decl.c (copy_args_p): Handle copy elision for types with virtual - bases. - * call.c (build_over_call): Likewise. + bases. + * call.c (build_over_call): Likewise. Sun Dec 7 22:38:12 1997 Mark Mitchell @@ -4242,8 +9248,8 @@ Fri Dec 5 01:17:34 1997 Jason Merrill Wed Dec 3 20:02:39 1997 Jason Merrill * init.c (build_new): Use a TARGET_EXPR instead of SAVE_EXPR for - alloc_expr. - * call.c (build_op_delete_call): Adjust. + alloc_expr. + * call.c (build_op_delete_call): Adjust. * except.c (expand_end_catch_block): Lose rethrow region. (expand_start_catch_block): Likewise. @@ -4252,7 +9258,7 @@ Wed Dec 3 20:02:39 1997 Jason Merrill Wed Dec 3 13:24:04 1997 Benjamin Kosnik * pt.c (tsubst): Remove tree_cons call (places redundant info into - DECL_TEMPLATE_INSTANTIATION). + DECL_TEMPLATE_INSTANTIATION). Wed Dec 3 11:44:52 1997 Jason Merrill @@ -4294,7 +9300,7 @@ Tue Dec 2 01:37:19 1997 Jason Merrill Fri Nov 28 01:58:14 1997 Jason Merrill - * pt.c (check_explicit_specialization): Complain about using a + * pt.c (check_explicit_specialization): Complain about using a template-id for a non-specialization. Fri Nov 28 12:35:19 1997 Scott Christley @@ -4304,7 +9310,7 @@ Fri Nov 28 12:35:19 1997 Scott Christley Fri Nov 28 01:56:35 1997 Bruno Haible - * error.c (dump_decl): Handle TEMPLATE_ID_EXPR. + * error.c (dump_decl): Handle TEMPLATE_ID_EXPR. Thu Nov 27 00:59:46 1997 Jason Merrill @@ -4312,9 +9318,9 @@ Thu Nov 27 00:59:46 1997 Jason Merrill handing off to convert_to_reference. * except.c: Lose Unexpected, SetTerminate, SetUnexpected, - TerminateFunctionCall. + TerminateFunctionCall. (init_exception_processing): Likewise. Terminate et al are now - the fns, not ADDR_EXPRs. + the fns, not ADDR_EXPRs. (various): Lose redundant assemble_external calls. (do_unwind): s/BuiltinReturnAddress/builtin_return_address_fndecl/. @@ -4325,7 +9331,7 @@ Thu Nov 27 00:59:46 1997 Jason Merrill * decl2.c (import_export_decl): Just set DECL_COMDAT on VAR_DECLs. * class.c: Remove static pending_hard_virtuals. - (add_virtual_function): Take pointers to pending_virtuals + (add_virtual_function): Take pointers to pending_virtuals and pending_hard_virtuals. (finish_struct_1): Pass them. Declare pending_hard_virtuals. @@ -4334,7 +9340,7 @@ Wed Nov 26 20:28:49 1997 Jason Merrill * decl2.c (import_export_vtable): If we support one_only but not weak symbols, mark instantiated template vtables one_only. (import_export_decl): Likewise for tinfo functions. - (finish_vtable_vardecl): Also write out vtables from explicitly + (finish_vtable_vardecl): Also write out vtables from explicitly instantiated template classes. * pt.c (mark_class_instantiated): Revert last change. @@ -4369,7 +9375,7 @@ Tue Nov 25 11:28:21 1997 Jason Merrill * init.c (build_new): Copy size to the saveable obstack. * init.c (build_new): Stick a CLEANUP_POINT_EXPR inside the - TRY_CATCH_EXPR for now. + TRY_CATCH_EXPR for now. Mon Nov 24 12:15:55 1997 Jason Merrill @@ -4390,14 +9396,14 @@ Fri Nov 21 12:22:07 1997 Jason Merrill (expand_end_eh_spec): Likewise. Call __check_eh_spec instead of doing everything inline. (init_exception_processing): throw_type_match now takes - const void pointers. + const void pointers. * exception.cc (__check_eh_spec): New fn. * inc/exception: Neither terminate nor unexpected return. * decl.c: Make const_ptr_type_node public. * tinfo2.cc (__throw_type_match_rtti): Take the typeinfos constly. * except.c (expand_start_catch_block): We only need the rethrow - region for non-sjlj exceptions. + region for non-sjlj exceptions. (expand_end_catch_block): Likewise. Use outer_context_label_stack. Thu Nov 20 14:40:17 1997 Jason Merrill @@ -4412,7 +9418,7 @@ Thu Nov 20 14:40:17 1997 Jason Merrill * decl.c (init_decl_processing): Update exception specs on new and delete. - * method.c (build_decl_overload_real): Don't mess with global + * method.c (build_decl_overload_real): Don't mess with global placement delete. * init.c (build_new): Check for null throw spec, not nothrow_t. @@ -4427,13 +9433,13 @@ Thu Nov 20 14:40:17 1997 Jason Merrill Wed Nov 19 18:24:14 1997 Jason Merrill - * decl.c (start_decl): Don't just complain about a mismatched + * decl.c (start_decl): Don't just complain about a mismatched scope, fix it. * decl.c (make_implicit_typename): Handle case where t is not - actually from context. + actually from context. * tree.c (get_type_decl): Lose identifier case. - * spew.c (yylex): Lose useless call to identifer_typedecl_value. + * spew.c (yylex): Lose useless call to identifier_typedecl_value. * parse.y (nonnested_type): Just use lookup_name. (complex_type_name): Just use IDENTIFIER_GLOBAL_VALUE. @@ -4448,7 +9454,7 @@ Wed Nov 19 10:39:27 1997 Jason Merrill * decl.c (make_implicit_typename): New fn. (lookup_name_real): Use it. Use current_class_type as the context. -Mon Nov 17 23:42:03 1997 Bruno Haible +Mon Nov 17 23:42:03 1997 Bruno Haible * pt.c (do_poplevel): Don't prohibit jumps into this contour. @@ -4483,7 +9489,7 @@ Thu Nov 13 01:52:36 1997 Jason Merrill Wed Nov 12 11:04:33 1997 Jason Merrill * pt.c (do_type_instantiation): Fix typo. - (mark_class_instantiated): If we support one_only but not weak + (mark_class_instantiated): If we support one_only but not weak symbols, don't mark this as known. * init.c (build_new): Handle vec delete in EH cleanup. @@ -4491,7 +9497,7 @@ Wed Nov 12 11:04:33 1997 Jason Merrill Wed Nov 12 08:11:55 1997 Benjamin Kosnik * call.c (build_method_call): Call complete_type before checking - for destructor. + for destructor. Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com) @@ -4524,32 +9530,32 @@ Tue Nov 11 02:53:44 1997 Jason Merrill Mon Nov 10 20:25:31 1997 Jason Merrill * call.c (build_new_method_call): Handle getting a - TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field - if we got template parms. + TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field + if we got template parms. * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR, - not just the args. + not just the args. * decl2.c (build_expr_from_tree): Tweak last change. * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE. (maybe_fold_nontype_arg): Split out from tsubst_copy. * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR. -Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij +Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij - * pt.c (tsubst_copy): Handle explicit template arguments in + * pt.c (tsubst_copy): Handle explicit template arguments in function calls. * typeck.c (build_x_function_call): Likewise. - * decl2.c (build_expr_from_tree): Lookup function name if it + * decl2.c (build_expr_from_tree): Lookup function name if it hasn't been done. - * pt.c (tsubst): Instantiate template functions properly when - template parameter does not appear in function arguments and return + * pt.c (tsubst): Instantiate template functions properly when + template parameter does not appear in function arguments and return type. (comp_template_args): Handle member templates required by tsubst. Mon Nov 10 20:08:38 1997 Jason Merrill * decl.c (grokdeclarator): Tweak conditions for pedwarn in - previous change. + previous change. Mon Nov 10 20:08:29 1997 Bruno Haible @@ -4570,10 +9576,10 @@ Mon Nov 10 03:04:20 1997 Jason Merrill (expand_end_catch_block): Likewise. End the region for the eh_cleanup. * exception.cc (__cp_pop_exception): Now takes two parms. Handle popping off the middle of the stack. - * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, + * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, WITH_CLEANUP_EXPR, and UNSAVE_EXPR. (build_cplus_new): Only wrap CALL_EXPRs. - * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around + * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around the constructor call. Sun Nov 9 18:00:26 1997 Richard Kenner @@ -4642,7 +9648,7 @@ Fri Oct 31 01:47:57 1997 Jason Merrill (__cp_exception_info, __uncatch_exception): New fns. (__cp_push_exception, __cp_pop_exception): New fns. * except.c: Lose saved_throw_{type,value,cleanup,in_catch}. - Lose empty_fndecl. + Lose empty_fndecl. (init_exception_processing): Likewise. __eh_pc is now external. (push_eh_info): New fn. (get_eh_{info,value,type,caught}): New fns. @@ -4670,21 +9676,21 @@ Thu Oct 23 02:01:30 1997 Jason Merrill Mon Oct 20 12:06:34 1997 Jason Merrill - * except.c (expand_exception_blocks): Call do_pending_stack_adust. + * except.c (expand_exception_blocks): Call do_pending_stack_adjust. (expand_end_catch_block): Likewise. (expand_end_eh_spec): Likewise. Mon Oct 20 11:44:20 1997 Mark Mitchell * decl.c (duplicate_decls): Handle template specializations - correctly. + correctly. * error.c (dump_function_name): Fix printing of specializations of member functions that are not member templates. * cp-tree.h (processing_specialization): Make global. * pt.c (processing_specialization): Likewise. * lex.c (cons_up_default_function): Save and restore processing_specialization to avoid confusion. - + Mon Oct 20 10:52:22 1997 Jason Merrill * decl.c (init_decl_processing): Give null_node unknown* type. @@ -4701,7 +9707,7 @@ Sun Oct 19 09:13:01 1997 Richard Kenner * Make-lang.in (g++): Include prefix.o. -Thu Oct 16 15:31:09 1997 Judy Goldberg +Thu Oct 16 15:31:09 1997 Judy Goldberg * pt.c (determine_explicit_specialization): Initialize "dummy" to keep Purify quiet. @@ -4727,19 +9733,19 @@ Tue Oct 14 12:01:00 1997 Mark Mitchell so as to avoid incorrect manglings. * method.c (build_decl_overload_real): Don't mangle return types for constructors. - + Tue Oct 14 11:46:14 1997 Jason Merrill * cp-tree.h (scratchalloc, build_scratch_list, make_scratch_vec, scratch_tree_cons): Define as macros for now. - * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, expr.c, init.c, + * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, expr.c, init.c, lex.c, method.c, parse.y, pt.c, rtti.c, search.c, tree.c, typeck.c, typeck2.c: Use them and the expression_obstack variants. Mon Oct 13 17:41:26 1997 Benjamin Kosnik * decl.c (store_return_init): Allow classes with explicit ctors to - be used with the named return values extension. + be used with the named return values extension. Fri Oct 10 12:21:11 1997 Jason Merrill @@ -4753,7 +9759,7 @@ Thu Oct 9 12:08:21 1997 Jason Merrill * call.c (build_new_method_call): Use simple constructor_name for error messages. -Wed Oct 8 22:44:42 1997 Jeffrey A Law (law@cygnus.com) +Wed Oct 8 22:44:42 1997 Jeffrey A Law * method.c (build_underscore_int): Don't use ANSI specific features. @@ -4774,9 +9780,9 @@ Tue Oct 7 22:52:10 1997 Jason Merrill Tue Oct 7 22:45:31 1997 Alexandre Oliva - * typeck.c (build_reinterpret_cast): converting a void pointer + * typeck.c (build_reinterpret_cast): Converting a void pointer to function pointer with a reinterpret_cast produces a warning - if -pedantic is issued + if -pedantic is issued. Tue Oct 7 22:43:43 1997 Bruno Haible @@ -4803,7 +9809,7 @@ Tue Oct 7 00:48:36 1997 Jason Merrill non-templates. * call.c (build_new_function_call): Fix handling of null explicit - template args. + template args. (build_new_method_call): Likewise. Mon Oct 6 23:44:34 1997 Mark Mitchell @@ -4855,7 +9861,7 @@ Tue Sep 30 00:18:26 1997 Jason Merrill -traditional and -ansi now do not mess with dollars_in_ident. -Mon Sep 29 19:57:51 1997 H.J. Lu (hjl@gnu.ai.mit.edu) +Mon Sep 29 19:57:51 1997 H.J. Lu * Makefile.in (parse.o, decl.o): Also depend on $(srcdir)/../except.h $(srcdir)/../output.h. @@ -4866,37 +9872,37 @@ Mon Sep 29 19:57:51 1997 H.J. Lu (hjl@gnu.ai.mit.edu) * call.c, cp-tree.h, decl.c, tree.c: Finish prototyping. - * expr.c (cplus_expand_expr): Make it static. + * expr.c (cplus_expand_expr): Make it static. * decl2.c, init.c, typeck.c: Include "expr.h". (expand_expr): Use proper values when calling the function. Mon Sep 29 11:05:54 1997 Alexandre Oliva - * lang-options.h: new -Wold-style-cast flag. - * cp-tree.h (warn_old_style_cast): new variable. - * decl2.c (warn_old_style_cast): ditto. - (lang_decode_option): support -Wold-style-cast. - (reparse_absdcl_as_casts): produce old-style-cast warning. + * lang-options.h: New -Wold-style-cast flag. + * cp-tree.h (warn_old_style_cast): New variable. + * decl2.c (warn_old_style_cast): Likewise. + (lang_decode_option): Support -Wold-style-cast. + (reparse_absdcl_as_casts): Produce old-style-cast warning. Mon Sep 29 09:20:53 1997 Benjamin Kosnik * decl.c (cp_finish_decl): Allow expand_aggr_init to set - TREE_USED, reset value based on already_used. + TREE_USED, reset value based on already_used. * init.c (expand_member_init): Revert change. - + Mon Sep 29 08:57:53 1997 Jason Merrill * cp-tree.h, decl.c, decl2.c, pt.c: - Lose DECL_C_STATIC and DECL_PUBLIC. Don't pretend statics are public. + Lose DECL_C_STATIC and DECL_PUBLIC. Don't pretend statics are public. * decl2.c (lang_decode_option): Add missing ;. Sat Sep 27 16:22:48 1997 Jason Merrill * friend.c (do_friend): Disable injection for all template-derived - decls. + decls. * decl2.c (lang_decode_option): Handle -fguiding-decls. * parse.y (notype_template_declarator): New nonterminal. (direct_notype_declarator): Use it. @@ -4906,112 +9912,112 @@ Sat Sep 27 16:22:48 1997 Jason Merrill Sat Sep 27 16:21:58 1997 Mark Mitchell - * call.c (add_template_candidate): Add explicit_targs parameter. - (build_scoped_method_call): Use it. - (build_overload_call_real): Likewise. - (build_user_type_conversion_1): Likewise. - (build_new_function_call): Likewise. - (build_object_call): Likewise. - (build_new_op): Likewise. - (build_new_method_call): Likewise. - (build_new_function_call): Handle TEMPLATE_ID_EXPR. - (build_new_method_call): Likewise. + * call.c (add_template_candidate): Add explicit_targs parameter. + (build_scoped_method_call): Use it. + (build_overload_call_real): Likewise. + (build_user_type_conversion_1): Likewise. + (build_new_function_call): Likewise. + (build_object_call): Likewise. + (build_new_op): Likewise. + (build_new_method_call): Likewise. + (build_new_function_call): Handle TEMPLATE_ID_EXPR. + (build_new_method_call): Likewise. - * class.c (finish_struct_methods): Add specialization pass to - determine which methods were specializing which other methods. - (instantiate_type): Handle TEMPLATE_ID_EXPR. + * class.c (finish_struct_methods): Add specialization pass to + determine which methods were specializing which other methods. + (instantiate_type): Handle TEMPLATE_ID_EXPR. - * cp-tree.def (TEMPLATE_ID_EXPR): New tree code. + * cp-tree.def (TEMPLATE_ID_EXPR): New tree code. - * cp-tree.h (name_mangling_version): New variable. + * cp-tree.h (name_mangling_version): New variable. (flag_guiding_decls): Likewise. - (build_template_decl_overload): New function. - (begin_specialization): Likewise. - (reset_specialization): Likewise. - (end_specialization): Likewise. - (determine_explicit_specialization): Likewise. - (check_explicit_specialization): Likewise. - (lookup_template_function): Likewise. - (fn_type_unification): Add explicit_targs parameter. - (type_unification): Likewise. - - * decl.c (duplicate_decls): Add smarts for explicit - specializations. - (grokdeclarator): Handle TEMPLATE_ID_EXPR, and function - specializations. - (grokfndecl): Call check_explicit_specialization. - - * decl2.c (lang_decode_option): Handle -fname-mangling-version. - (build_expr_from_tree): Handle TEMPLATE_ID_EXPR. - (check_classfn): Handle specializations. - - * error.c (dump_function_name): Print specialization arguments. - - * friend.c (do_friend): Don't call pushdecl for template - instantiations. - - * init.c (build_member_call): Handle TEMPLATE_ID_EXPR. - - * lang-options.h: Add -fname-mangling-version, -fguiding-decls, + (build_template_decl_overload): New function. + (begin_specialization): Likewise. + (reset_specialization): Likewise. + (end_specialization): Likewise. + (determine_explicit_specialization): Likewise. + (check_explicit_specialization): Likewise. + (lookup_template_function): Likewise. + (fn_type_unification): Add explicit_targs parameter. + (type_unification): Likewise. + + * decl.c (duplicate_decls): Add smarts for explicit + specializations. + (grokdeclarator): Handle TEMPLATE_ID_EXPR, and function + specializations. + (grokfndecl): Call check_explicit_specialization. + + * decl2.c (lang_decode_option): Handle -fname-mangling-version. + (build_expr_from_tree): Handle TEMPLATE_ID_EXPR. + (check_classfn): Handle specializations. + + * error.c (dump_function_name): Print specialization arguments. + + * friend.c (do_friend): Don't call pushdecl for template + instantiations. + + * init.c (build_member_call): Handle TEMPLATE_ID_EXPR. + + * lang-options.h: Add -fname-mangling-version, -fguiding-decls, and -fno-guiding-decls. - * lex.c (identifier_type): Return PFUNCNAME for template function - names. - - * method.c (build_decl_overload_real): New function. - (build_template_parm_names): New function. - (build_overload_identifier): Use it. - (build_underscore_int): New function. - (build_overload_int): Use it. Add levels for template - parameters. - (build_overload_name): Likewise. Also, handle TYPENAME_TYPEs. - (build_overload_nested_names): Handle template type parameters. - (build_template_decl_overload): New function. - - * parse.y (YYSTYPE): New ntype member. - (nested_name_specifier): Use it. - (nested_name_specifier_1): Likewise. - (PFUNCNAME): New token. - (template_id, object_template_id): New non-terminals. - (template_parm_list): Note specializations. - (template_def): Likewise. - (structsp): Likewise. - (fn.def2): Handle member template specializations. - (component_decl_1): Likewise. - (direct_notype_declarator): Handle template-ids. - (component_decl_1): Likewise. - (direct_notype_declarator): Handle template-ids. - (primary): Handle TEMPLATE_ID_EXPR, and template-ids. - - * pt.c (processing_specializations): New variable. - (template_header_count): Likewise. - (type_unification_real): New function. - (processing_explicit_specialization): Likewise. - (note_template_header): Likewise. - (is_member_template): Handle specializations. - (end_template_decl): Call reset_specialization. - (push_template_decl): Handle member template specializations. - (tsubst): Likewise. - (tsubst_copy): Handle TEMPLATE_ID_EXPR. - (instantiate_template): Handle specializations. - (instantiate_decl): Likewise. - (fn_type_unification): Handle explicit_targs. - (type_unification): Likewise. Allow incomplete unification - without an error message, if allow_incomplete. - (get_bindings): Use new calling sequence for fn_type_unification. - - * spew.c (yylex): Handle PFUNCNAME. - - * tree.c (is_overloaded_fn): Handle TEMPLATE_ID_EXPR. - (really_overloaded_fn): Likewise. - (get_first_fn): Handle function templates. - - * typeck.c (build_x_function_call): Use really_overloaded_fn. - Handle TEMPLATE_ID_EXPR. - (build_x_unary_op): Likewise. - (build_unary_op): Likewise. - (mark_addressable): Templates whose address is taken are marked - as used. + * lex.c (identifier_type): Return PFUNCNAME for template function + names. + + * method.c (build_decl_overload_real): New function. + (build_template_parm_names): New function. + (build_overload_identifier): Use it. + (build_underscore_int): New function. + (build_overload_int): Use it. Add levels for template + parameters. + (build_overload_name): Likewise. Also, handle TYPENAME_TYPEs. + (build_overload_nested_names): Handle template type parameters. + (build_template_decl_overload): New function. + + * parse.y (YYSTYPE): New ntype member. + (nested_name_specifier): Use it. + (nested_name_specifier_1): Likewise. + (PFUNCNAME): New token. + (template_id, object_template_id): New non-terminals. + (template_parm_list): Note specializations. + (template_def): Likewise. + (structsp): Likewise. + (fn.def2): Handle member template specializations. + (component_decl_1): Likewise. + (direct_notype_declarator): Handle template-ids. + (component_decl_1): Likewise. + (direct_notype_declarator): Handle template-ids. + (primary): Handle TEMPLATE_ID_EXPR, and template-ids. + + * pt.c (processing_specializations): New variable. + (template_header_count): Likewise. + (type_unification_real): New function. + (processing_explicit_specialization): Likewise. + (note_template_header): Likewise. + (is_member_template): Handle specializations. + (end_template_decl): Call reset_specialization. + (push_template_decl): Handle member template specializations. + (tsubst): Likewise. + (tsubst_copy): Handle TEMPLATE_ID_EXPR. + (instantiate_template): Handle specializations. + (instantiate_decl): Likewise. + (fn_type_unification): Handle explicit_targs. + (type_unification): Likewise. Allow incomplete unification + without an error message, if allow_incomplete. + (get_bindings): Use new calling sequence for fn_type_unification. + + * spew.c (yylex): Handle PFUNCNAME. + + * tree.c (is_overloaded_fn): Handle TEMPLATE_ID_EXPR. + (really_overloaded_fn): Likewise. + (get_first_fn): Handle function templates. + + * typeck.c (build_x_function_call): Use really_overloaded_fn. + Handle TEMPLATE_ID_EXPR. + (build_x_unary_op): Likewise. + (build_unary_op): Likewise. + (mark_addressable): Templates whose address is taken are marked + as used. 1997-09-25 Andreas Schwab @@ -5041,7 +10047,7 @@ Thu Sep 25 11:11:13 1997 Jason Merrill Rvalue conversions were removed in London. * call.c (is_subseq): Don't consider lvalue transformations. (build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK. - (joust): Reenable ?: kludge. + (joust): Re-enable ?: kludge. 1997-09-22 Brendan Kehoe @@ -5077,12 +10083,12 @@ Wed Sep 17 10:31:25 1997 Jason Merrill Tue Sep 16 14:06:56 1997 Jason Merrill * call.c (build_new_op): Give better error for syntactically - correct, but semantically invalid, use of undeclared template. + correct, but semantically invalid, use of undeclared template. * call.c (compare_qual): Handle pmfs. * decl.c (store_parm_decls): last_parm_cleanup_insn is the insn - after the exception spec. + after the exception spec. Mon Sep 15 11:52:13 1997 Jason Merrill @@ -5118,9 +10124,9 @@ Thu Sep 11 10:08:45 1997 Mark Mitchell * pt.c (coerce_template_parms): Avoid looking at the TYPE_LANG_DECL portion of a typename type, since there won't be - one. + one. (tsubst): Do constant folding as necessary to make sure that - arguments passed to lookup_template_class really are constants. + arguments passed to lookup_template_class really are constants. Wed Sep 10 11:21:55 1997 Jason Merrill @@ -5137,9 +10143,9 @@ Tue Sep 9 19:49:38 1997 Jason Merrill Tue Sep 9 17:57:25 1997 Mark Mitchell * error.c (dump_decl): Avoid crashing when presented with a - uninitialized constant, as can occur with a template parameter. + uninitialized constant, as can occur with a template parameter. (dump_expr): Make sure that there are enough levels of - current_template_parms before we start diving through them. + current_template_parms before we start diving through them. 1997-09-09 Brendan Kehoe @@ -5148,7 +10154,7 @@ Tue Sep 9 17:57:25 1997 Mark Mitchell Tue Sep 9 09:36:39 1997 Benjamin Kosnik - * except.c (expand_throw): Call build_delete for all + * except.c (expand_throw): Call build_delete for all exception types, not just objects with destructors. Mon Sep 8 02:33:20 1997 Jody Goldberg @@ -5156,7 +10162,7 @@ Mon Sep 8 02:33:20 1997 Jody Goldberg * decl.c (current_local_enum): Remove static. * pt.c (tsubst_enum): Save and restore value of current_local_enum in case template is expanded in enum decl. - (instantiate_class_template) : Use new tsubst_enum signature. + (instantiate_class_template): Use new tsubst_enum signature. (tsubst_expr): Likewise. Mon Sep 8 01:21:43 1997 Mark Mitchell @@ -5168,7 +10174,7 @@ Mon Sep 8 01:21:43 1997 Mark Mitchell member templates using the same parameter names can be declared. (end_member_template_processing): Pop the binding level. (push_template_decl): Mark member templates as static when - appropriate. + appropriate. * lex.c (do_pending_inlines): Pass the function, not its template arguments, to begin_member_template_processing. @@ -5176,17 +10182,17 @@ Mon Sep 8 01:21:43 1997 Mark Mitchell (do_pending_defargs): Likewise. * error.c (dump_expr): Obtain the correct declaration for a - TEMPLATE_CONST_PARM. + TEMPLATE_CONST_PARM. * call.c (add_template_conv_candidate): New function. (build_object_call): Handle member templates, as done in the other build_ functions. - + Sat Sep 6 10:20:27 1997 Mark Mitchell * decl.c (replace_defag): Undo previous change. * lex.c (do_pending_defargs): Deal with member templates. - + * pt.c (is_member_template): Avoid crashing when passed a non-function argument. @@ -5206,24 +10212,24 @@ Fri Sep 5 01:37:17 1997 Mark Mitchell * pt.c (push_template_decl): Likewise. (classtype_mangled_name): Likewise. (lookup_template_class): Likewise. - + * cp-tree.h (DECL_NTPARMS): Change name from DECL_NT_PARMS to DECL_NTPARMS to conform to usage elsewhere. * call.c (add_template_candidate): Likewise. * class.c (instantiate_type): Likewise. * pt.c (instantiate_template): Likewise. (get_bindings): Likewise. - + * class.c (grow_method): Use DECL_FUNCTION_TEMPLATE_P instead of is_member_template. * pt.c (unify): Undo changes to allow multiple levels of template - parameters. + parameters. (type_unification): Likewise. (fn_type_unification): Likewise. (get_class_bindings): Likewise. * cp-tree.h (Likewise). - + * decl.c (replace_defarg): Check that the type of the default parameter does not invlove a template type before complaining about the initialization. @@ -5232,13 +10238,13 @@ Fri Sep 5 01:37:17 1997 Mark Mitchell member templates correctly. * pt.c (is_member_template): Deal with class specializations - correctly. + correctly. (tsubst): Handle "partial instantiation" of member templates - correctly. + correctly. Wed Sep 3 12:30:24 1997 Mark Mitchell - * pt.c (type_unification): Change calling squence to allow for + * pt.c (type_unification): Change calling sequence to allow for multiple levels of template parameters. (tsubst_expr): Likewise. (tsubst): Likewise. @@ -5252,7 +10258,7 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell * decl.c (grokdeclarator): Use it. * decl2.c (finish_file): Use it. * method.c (build_overload_identifier): Use it. - + * call.c (add_template_candidate): Add additional parameter for the function return type. Call fn_type_unification istead of type_unification. @@ -5260,12 +10266,12 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell (build_new_function_call): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. - + * class.c (grow_method): Don't give an error message indicating - that two member templates with the same name are ambiguous. + that two member templates with the same name are ambiguous. (finish_struct): Treat member template functions just like member - functions. - + functions. + * cp-tree.h (check_member_template): Add declaration. (begin_member_template_processing): Likewise. (end_member_template_processing): Likewise. @@ -5278,31 +10284,31 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell (get_bindings): Likewise. * decl.c (decls_match): Handle multiple levels of template - parameters. + parameters. (pushdecl): Handle template type params just like other type - declarations. + declarations. (push_class_level_binding): Return immediately if the class_binding_level is NULL. (grokfndecl): If check_classfn() returns a member_template, use the result of the template, not the template itself. - + * decl2.c (check_member_template): New function. Check to see that the entity declared to be a member template can be one. (check_classfn): Allow redeclaration of member template functions with different types; the new functions can be specializations or explicit instantiations. - + * error.c (dump_decl): Handle multiple levels of template - parameters. - (dump_function_decl): Update to handle function templates. + parameters. + (dump_function_decl): Update to handle function templates. * lex.c (do_pending_inlines): Set up template parameter context for member templates. (process_next_inline): Likewise. - * method. (build_overload_identifier): Adjust for multiple levels + * method.c (build_overload_identifier): Adjust for multiple levels of template parameters. - + * parse.y (fn.def2): Add member templates. (component_decl_1): Likewise. @@ -5313,7 +10319,7 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell (current_template_parms): Return a vector of all the template parms, not just the innermost level of parms. (push_template_decl): Deal with the possibility of member - templates. + templates. (lookup_template_class): Likewise. (uses_template_parms): Likewise. (tsubst): Modify processing to TEMPLATE_TYPE_PARM and @@ -5323,7 +10329,7 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell (do_decl_instantiation): Handle member templates. * search.c (lookup_fnfields_1): Handle member template conversion - operators. + operators. * tree.c (cp_tree_equal): Check the levels, as well as the indices, of TEMPLATE_CONST_PARMs. @@ -5331,12 +10337,12 @@ Wed Sep 3 12:30:24 1997 Mark Mitchell * typeck.c (comptypes): Check the levels, as well as the indices, fo TEMPLATE_TYPE_PARMs. (build_x_function_call): Treat member templates like member - functions. - + functions. + Wed Sep 3 11:09:25 1997 Jason Merrill * typeck.c (c_expand_return): Always convert_for_initialization - before checking for returning a pointer to local. + before checking for returning a pointer to local. * pt.c (type_unification): If strict and the function parm doesn't use template parms, just compare types. @@ -5349,7 +10355,7 @@ Wed Sep 3 10:35:49 1997 Klaus Espenlaub * typeck.c (convert_arguments): Don't arbitrarily choose the first - of a set of overloaded functions. + of a set of overloaded functions. Tue Sep 2 12:09:13 1997 Jason Merrill @@ -5360,12 +10366,12 @@ Tue Sep 2 12:09:13 1997 Jason Merrill (build_overload_identifier): Pass it. * decl.c (duplicate_decls): Don't bash a previous template - definition with a redeclaration. + definition with a redeclaration. * pt.c (unify): float doesn't match double. * pt.c (do_type_instantiation): Handle getting a _TYPE or a - TYPE_DECL. Handle getting non-template types. + TYPE_DECL. Handle getting non-template types. * parse.y (explicit_instantiation): Use typespec instead of aggr template_type. @@ -5373,7 +10379,7 @@ Tue Sep 2 10:27:08 1997 Richard Henderson * typeck.c (build_ptrmemfunc1): Clean up ptr->int cast warnings. -Mon Sep 1 13:19:04 1997 Eugene Mamchits +Mon Sep 1 13:19:04 1997 Eugene Mamchits * call.c (add_builtin_candidate): Add missing TREE_TYPE. (compare_ics): Likewise. @@ -5381,8 +10387,8 @@ Mon Sep 1 13:19:04 1997 Eugene Mamchits Mon Sep 1 13:19:04 1997 Jason Merrill * call.c (joust): Warn about choosing one conversion op over - another because of 'this' argument when the other return type is - better. + another because of 'this' argument when the other return type is + better. (source_type): New fn. * call.c (build_new_op): Strip leading REF_BIND from first operand @@ -5395,7 +10401,7 @@ Thu Aug 28 09:45:23 1997 Jason Merrill * call.c (null_ptr_cst_p): Remove support for (void*)0. -Wed Aug 27 02:03:34 1997 Jeffrey A Law (law@cygnus.com) +Wed Aug 27 02:03:34 1997 Jeffrey A Law * typeck.c (expand_target_expr): Make definition match declaration. @@ -5415,7 +10421,7 @@ Sat Aug 23 18:02:59 1997 Mark Mitchell * error.c (type_as_string): Put const/volatile on template type parameters where appropriate. -Sat Aug 23 17:47:22 1997 Jeffrey A Law (law@cygnus.com) +Sat Aug 23 17:47:22 1997 Jeffrey A Law * call.c (strictly_better): Make arguments unsigned ints. @@ -5423,7 +10429,7 @@ Thu Aug 21 18:48:44 1997 Jason Merrill * lex.c (real_yylex): Refer to __complex instead of complex. -Thu Aug 21 22:25:46 1997 J"orn Rennecke +Thu Aug 21 22:25:46 1997 J"orn Rennecke * lex.c (real_yylex): Don't use getc directly. @@ -5435,10 +10441,10 @@ Wed Aug 20 03:13:36 1997 H.J. Lu (hjl@gnu.ai.mit.edu) * parse.y, pt.c: Include "except.h". * call.c, class.c, class.h, cp-tree.h, cvt.c, decl.c, decl2.c, - error.c, except.c, expr.c, friend.c, g++spec.c, init.c, input.c, - lex.c, lex.h, method.c, parse.y, pt.c, repo.c, rtti.c, search.c, - sig.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c: Finish - prototyping. + error.c, except.c, expr.c, friend.c, g++spec.c, init.c, input.c, + lex.c, lex.h, method.c, parse.y, pt.c, repo.c, rtti.c, search.c, + sig.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c: Finish + prototyping. Wed Aug 20 01:34:40 1997 Jason Merrill @@ -5461,7 +10467,7 @@ Tue Aug 19 02:26:07 1997 Jason Merrill * repo.c (finish_repo): Don't crash on no args. * parse.y (named_complex_class_head_sans_basetype): Handle - explicit global scope. + explicit global scope. * decl2.c (handle_class_head): New fn. * pt.c (unify): Add CONST_DECL case. @@ -5494,13 +10500,13 @@ Wed Aug 13 10:46:19 1997 H.J. Lu (hjl@gnu.ai.mit.edu) Tue Aug 12 20:13:57 1997 Jason Merrill - * parse.y: Don't clear the inlines from their obstack until they've + * parse.y: Don't clear the inlines from their obstack until they've all been processed. * decl.c (duplicate_decls): Don't complain about exception - specification mismatch if flag_exceptions is off. + specification mismatch if flag_exceptions is off. -Mon Aug 11 15:01:56 1997 Marc Lehmann +Mon Aug 11 15:01:56 1997 Marc Lehmann * Make-lang.in (c++.distclean): Remove g++.c on make distclean. @@ -5508,10 +10514,10 @@ Sun Aug 10 12:06:09 1997 Paul Eggert * cp-tree.h: Replace STDIO_PROTO with PROTO in include files. * cvt.c, error.c, except.c, expr.c, friend.c, init.c, rtti.c: - Include before include files that formerly used STDIO_PROTO. + Include before include files that formerly used STDIO_PROTO. * decl.c, g++spec.c, lex.c, method.c, repo.c: - Include "config.h" first, as per autoconf manual. + Include "config.h" first, as per autoconf manual. Fri Aug 8 11:47:48 1997 Jason Merrill @@ -5523,13 +10529,13 @@ Fri Aug 8 11:47:48 1997 Jason Merrill * decl2.c (lang_decode_option): Handle -fhandle-exceptions. * lang-options.h: Add -fhandle-exceptions. - * class.c (build_vtable): vtables are artificial. + * class.c (build_vtable): Vtables are artificial. (prepare_fresh_vtable): Likewise. Wed Aug 6 11:02:36 1997 Jason Merrill * cvt.c (ocp_convert): After converting to the target type, set - LOOKUP_NO_CONVERSION. + LOOKUP_NO_CONVERSION. * call.c (joust): Warn about potentially confusing promotion rules with -Wsign-promo. @@ -5607,18 +10613,18 @@ Fri Jul 18 17:56:08 1997 Jason Merrill Thu Jul 17 18:06:30 1997 Jason Merrill * method.c (build_overload_nested_name): Use static_labelno - instead of var_labelno. + instead of var_labelno. (build_qualified_name): New fn. (build_overload_name): Split out from here. (build_static_name): Use build_qualified_name. - * decl.c (cp_finish_decl): Statics in extern inline functions + * decl.c (cp_finish_decl): Statics in extern inline functions have comdat linkage. (start_function): Initialize static_labelno. Thu Jul 17 11:20:17 1997 Benjamin Kosnik - * class.c (finish_struct_methods): add check of warn_ctor_dtor_privacy - before "all member functions in class [] are private" + * class.c (finish_struct_methods): Add check of warn_ctor_dtor_privacy + before "all member functions in class [] are private". Wed Jul 16 23:47:08 1997 Jason Merrill @@ -5632,7 +10638,7 @@ Wed Jul 16 12:34:29 1997 Benjamin Kosnik Mon Jul 14 03:23:46 1997 Jason Merrill * typeck.c (get_member_function_from_ptrfunc): Promote index - before saving it. + before saving it. Sun Jul 13 00:11:52 1997 Jason Merrill @@ -5686,7 +10692,7 @@ Wed Jul 9 13:44:12 1997 Jason Merrill Wed Jul 9 13:04:38 1997 Geoffrey Noer - * decl.c (init_decl_processing): fix Jun 30 patch -- move + * decl.c (init_decl_processing): Fix Jun 30 patch -- move ifndef for Cygwin32 to include SIGSEGV. Thu Jul 3 01:44:05 1997 Jason Merrill @@ -5697,17 +10703,17 @@ Thu Jul 3 01:44:05 1997 Jason Merrill * rtti.c (build_dynamic_cast): Call complete_type on the types. * decl.c (grokfndecl): If the function we chose doesn't actually - match, die. + match, die. * decl2.c (grokclassfn): Don't specify 'const int' for the - artificial destructor parm. + artificial destructor parm. - * pt.c (type_unification): If we are called recursively, nothing + * pt.c (type_unification): If we are called recursively, nothing decays. Mon Jun 30 17:53:21 1997 Geoffrey Noer - * decl.c (init_decl_processing): Stop trying to catch signals + * decl.c (init_decl_processing): Stop trying to catch signals other than SIGABRT since the Cygwin32 library doesn't support them correctly yet. This fixes a situation in which g++ causes a hang on SIGSEGVs and other such signals in our Win32-hosted @@ -5719,11 +10725,11 @@ Mon Jun 30 14:50:01 1997 Jason Merrill Fri Jun 27 15:18:49 1997 Jason Merrill - * typeck2.c (store_init_value): Always return the value if our + * typeck2.c (store_init_value): Always return the value if our type needs constructing. * method.c (hack_identifier): Convert class statics from - reference, too. + reference, too. Thu Jun 26 11:44:46 1997 Jason Merrill @@ -5741,7 +10747,7 @@ Thu Jun 19 12:28:43 1997 Brendan Kehoe Tue Jun 17 18:35:57 1997 Mike Stump * except.c (expand_builtin_throw): Add support - -fno-sjlj-exceptions -fPIC exception handling on the SPARC. + -fno-sjlj-exceptions -fPIC exception handling on the SPARC. Mon Jun 16 01:24:37 1997 Jason Merrill @@ -5749,7 +10755,7 @@ Mon Jun 16 01:24:37 1997 Jason Merrill * cp-tree.h (TI_SPEC_INFO): New macro. (CLASSTYPE_TI_SPEC_INFO): New macro. - * pt.c (push_template_decl): Correctly determine # of template parms + * pt.c (push_template_decl): Correctly determine # of template parms for partial specs. * call.c (compare_ics): Really fix 'this' conversions. @@ -5758,20 +10764,20 @@ Mon Jun 16 01:24:37 1997 Jason Merrill non-template fn. * pt.c (push_template_decl): Complain about mismatch in # of - template parms between a class template and a member template. + template parms between a class template and a member template. Sun Jun 15 02:38:20 1997 Jason Merrill * method.c (synthesize_method): You can't call - function_cannot_inline_p after finish_function. + function_cannot_inline_p after finish_function. * decl.c (finish_function): Turn on flag_inline_functions and turn - off DECL_INLINE before handing a synthesized method to the - backend. + off DECL_INLINE before handing a synthesized method to the + backend. Thu Jun 12 17:35:28 1997 Jason Merrill * method.c (synthesize_method): Remove July 30 change to never set - DECL_INLINE if at_eof. + DECL_INLINE if at_eof. Thu Jun 12 15:25:08 1997 Mike Stump @@ -5811,22 +10817,22 @@ Tue Jun 10 00:22:09 1997 Jason Merrill Mon Jun 9 14:25:30 1997 Mike Stump * Makefile.in, Make-lang.in: Protect C-ls with a comment - character, idea from Paul Eggert . + character, idea from Paul Eggert . Mon Jun 9 01:52:03 1997 Jason Merrill * typeck.c (c_expand_return): Be more persistent in looking for - returned temps. + returned temps. * cvt.c (build_up_reference): Use NOP_EXPR for switching from - pointer to reference. + pointer to reference. * class.c (build_vbase_path): Don't do anything if PATH has no steps. Sun Jun 8 03:07:05 1997 Jason Merrill * init.c (build_member_call, build_offset_ref): - Use do_scoped_id instead of do_identifier. + Use do_scoped_id instead of do_identifier. * cvt.c (convert): Remove bogosity. @@ -5840,13 +10846,13 @@ Fri Jun 6 17:36:39 1997 Jason Merrill * cvt.c (build_up_reference): Call get_binfo to get access control. * decl2.c (import_export_decl): If we don't support weaks, leave - statics undefined. + statics undefined. Fri Jun 6 15:55:49 1997 Mike Stump * except.c (expand_builtin_throw): Add support for machines that - cannot access globals after throw's epilogue when - -fno-sjlj-exceptions is used. + cannot access globals after throw's epilogue when + -fno-sjlj-exceptions is used. Thu Jun 5 16:28:43 1997 Jason Merrill @@ -5863,14 +10869,14 @@ Thu Jun 5 16:28:43 1997 Jason Merrill Tue Jun 3 18:08:23 1997 Jason Merrill * search.c (push_class_decls): A name which ambiguously refers to - several instantiations of the same template just refers to the - template. + several instantiations of the same template just refers to the + template. Tue Jun 3 12:30:40 1997 Benjamin Kosnik - * decl.c (build_enumerator): fix problem with unsigned long + * decl.c (build_enumerator): Fix problem with unsigned long enumerated values being smashed to ints, causing overflow - when computing next enumerated value. (for enum values around + when computing next enumerated value (for enum values around MAX_VAL). Mon Jun 2 17:40:56 1997 Jason Merrill @@ -6003,7 +11009,7 @@ Wed May 14 19:08:28 1997 Mike Stump (struct cp_function): Add last_parm_cleanup_insn. (push_cp_function_context): Likewise. (pop_cp_function_context): Likewise. - + Tue May 13 15:51:20 1997 Jason Merrill * pt.c (tsubst_copy): Handle BIT_NOT_EXPR. @@ -6056,13 +11062,13 @@ Wed Apr 23 18:06:50 1997 Jason Merrill * typeck.c (c_expand_return): Don't complain about returning void to void in an artificial function. - * method.c (make_thunk): Change settings of READONLY/VOLATILE, + * method.c (make_thunk): Change settings of READONLY/VOLATILE, don't set DECL_RESULT, set DECL_ARTIFICIAL. - (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC. + (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC. Wed Apr 23 14:43:06 1997 Mike Stump - * init.c (init_decl_processing): Add supoprt for setjmp/longjmp based + * init.c (init_decl_processing): Add support for setjmp/longjmp based exception handling. * except.c (init_exception_processing): Likewise. (expand_end_catch_block): Likewise. @@ -6080,7 +11086,7 @@ Wed Apr 23 14:43:06 1997 Mike Stump (store_parm_decls): Likewise. (cplus_expand_expr_stmt): Likewise. * decl2.c (finish_file): Likewise. - + * Make-lang.in (exception.o): Ok to compile with -O now. * decl.c (maybe_build_cleanup_1): We no longer have to unsave, as @@ -6088,7 +11094,7 @@ Wed Apr 23 14:43:06 1997 Mike Stump * decl2.c (lang_f_options): Remove support for short temps. * lang-options.h: Likewise. - + Wed Apr 23 04:12:06 1997 Jason Merrill * tree.c (varargs_function_p): New fn. @@ -6154,7 +11160,7 @@ Wed Apr 2 12:51:36 1997 Mike Stump * exception.cc (__default_unexpected): Call terminate by default, so that if the user overrides terminate, the correct function will be called. - + Wed Mar 19 14:14:45 1997 Mike Stump * parse.y (left_curly): Avoid trying to use any fields of @@ -6382,7 +11388,7 @@ Tue Feb 11 13:50:48 1997 Mike Stump avoid lossing on systems that require one (ones that define malloc in xm.h). -Mon Feb 10 22:51:13 1997 Bruno Haible +Mon Feb 10 22:51:13 1997 Bruno Haible * decl2.c (max_tinst_depth): New variable. (lang_decode_option): Parse "-ftemplate-depth-NN" command line @@ -6551,7 +11557,7 @@ Thu Jan 23 16:39:06 1997 Jason Merrill Tue Jan 21 18:32:04 1997 Mike Stump - * cvt.c (cp_convert): Pedwarn enum to pointer conversions. + * cvt.c (cp_convert): pedwarn enum to pointer conversions. Mon Jan 20 17:59:51 1997 Jason Merrill @@ -6675,7 +11681,7 @@ Fri Dec 27 10:31:40 1996 Paul Eggert * Make-lang.in (g++spec.o): Don't use $< with an explicit target; this isn't portable to some versions of `make' (e.g. Solaris 2.5.1). -Tue Dec 24 10:24:03 1996 Jeffrey A Law (law@cygnus.com) +Tue Dec 24 10:24:03 1996 Jeffrey A Law * decl.c (grokvardecl): Avoid ANSI style initialization. @@ -6720,7 +11726,7 @@ Sat Dec 7 17:20:22 1996 Jason Merrill * cp-tree.h (TYPE_MAIN_DECL): Use TYPE_STUB_DECL. * *.c: Use TYPE_MAIN_DECL instead of TYPE_NAME where appropriate. - + Fri Dec 6 14:40:09 1996 Jason Merrill * decl.c (grokdeclarator): When giving an anonymous struct a name, @@ -6866,7 +11872,7 @@ Wed Nov 13 12:32:07 1996 Jason Merrill Wed Nov 13 11:51:20 1996 Brendan Kehoe * g++.c (main): Also set PEXECUTE_SEARCH, to make the invocation - of GCC be path-relative. + of GCC be path-relative. Wed Nov 13 11:27:16 1996 Michael Meissner @@ -6881,7 +11887,7 @@ Wed Nov 13 07:53:38 1996 Brendan Kehoe Wed Nov 13 02:00:26 1996 Jason Merrill - * init.c (expand_default_init): Avoid calling constructors to + * init.c (expand_default_init): Avoid calling constructors to initialize reference temps. * cvt.c (convert_to_reference): Fix. @@ -6974,7 +11980,7 @@ Fri Nov 8 17:38:44 1996 Jason Merrill * decl2.c (finish_file): Don't emit debug info. * decl.c (pushdecl): Lose obsolete code. (grokdeclarator): Still do the long long thing after complaining. - * search.c (note_debug_info_needed): Don't do anything if we're in a + * search.c (note_debug_info_needed): Don't do anything if we're in a template. * method.c (synthesize_method): For non-local classes, push_to_top_level first. @@ -7038,7 +12044,7 @@ Thu Oct 31 17:08:49 1996 Jason Merrill similar code in build_up_ref. * cvt.c (build_up_reference): Drastically simplify. -Mon Oct 28 12:45:05 1996 Jeffrey A Law (law@cygnus.com) +Mon Oct 28 12:45:05 1996 Jeffrey A Law * typeck.c (signed_or_unsigned_type): If the given type already as the correct signedness, then just return it. @@ -7163,7 +12169,7 @@ Fri Sep 27 16:40:30 1996 Jason Merrill * decl2.c (build_expr_from_tree): Use it. * cp-tree.h: Declare it. - * decl.c (start_decl): variable-sized arrays cannot be initialized. + * decl.c (start_decl): Variable-sized arrays cannot be initialized. * error.c (dump_type_suffix): Handle variable arrays. Fri Sep 27 13:14:05 1996 Brendan Kehoe @@ -7187,7 +12193,7 @@ Thu Sep 26 10:59:00 1996 Jason Merrill calling them. (get_tinfo_fn_dynamic): Extracted from build_typeid. * tinfo2.cc (__dynamic_cast): Adjust. - + * rtti.c (build_typeid): Use resolves_to_fixed_type_p. (build_x_typeid): Likewise. @@ -7266,7 +12272,7 @@ Sun Sep 22 05:31:22 1996 Jason Merrill * typeck2.c (store_init_value): Oops. - * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}: + * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}: New files for C++ lang-support library. * Make-lang.in (CXX_EXTRA_HEADERS): Define. (CXX_LIB2FUNCS): Define. @@ -7391,7 +12397,7 @@ Wed Sep 4 17:16:09 1996 Bob Manson * init.c (perform_member_init): Use add_partial_entry () instead of directly manipulating lists. - (emit_base_init): Ditto. + (emit_base_init): Likewise. Wed Sep 4 12:14:36 1996 Mike Stump @@ -7482,7 +12488,7 @@ Fri Aug 30 10:01:55 1996 Mike Stump to start_function. * parse.y (datadef): Remove non-winning optimization. (decl): Likewise. - (fndef): Remove ambiguous error productions uncovered by grammer + (fndef): Remove ambiguous error productions uncovered by grammar fixing. (constructor_declarator): Add exception_specification_opt here. (component_constructor_declarator): Likewise. @@ -7512,7 +12518,7 @@ Wed Aug 28 01:40:30 1996 Jason Merrill * call.c (joust): Extend the previous change to all comparisons. - * decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and + * decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and NO_LINKAGE_HEURISTICS. * decl2.c (finish_file): Emit any statics that weren't already. @@ -7547,7 +12553,7 @@ Tue Aug 27 13:12:21 1996 Jason Merrill Tue Aug 27 13:14:58 1996 Bob Manson * rtti.c (build_dynamic_cast): Don't try to dereference exprtype - too early. Make sure we explode if exprtype turns out to be a + too early. Make sure we explode if exprtype turns out to be a NULL_TREE when it shouldn't be. Tue Aug 27 10:56:21 1996 Mike Stump @@ -7561,7 +12567,7 @@ Tue Aug 27 10:56:21 1996 Mike Stump * lex.c (cons_up_default_function): Likewise. * parse.y: Likewise. * pt.c (tsubst): Likewise. - + Mon Aug 26 17:40:03 1996 Mike Stump * decl2.c (groktypefield): Remove unused code. @@ -7573,11 +12579,11 @@ Mon Aug 26 17:00:33 1996 Mike Stump Change type_quals into cv_qualifiers. Change nonempty_type_quals into nonempty_cv_qualifiers. * hash.h: Rebuild. - + * lex.c (make_pointer_declarator): Change type_quals into cv_qualifiers. (make_reference_declarator): Likewise. - + Thu Aug 22 01:09:22 1996 Jason Merrill * decl.c (start_function): Only check interface_* for templates @@ -7594,7 +12600,7 @@ Wed Aug 21 00:13:15 1996 Jason Merrill * call.c (build_new_method_call): Add missing args to cp_error. - * tree.c (error_type): Dont print reference-to-array. + * tree.c (error_type): Don't print reference-to-array. * typeck.c (convert_for_assignment): Don't say contravariance for removing const. @@ -7810,7 +12816,7 @@ Sun Aug 4 15:29:11 1996 Jason Merrill (build_conditional_expr): If both operands are TARGET_EXPRs, wrap the COND_EXPR in a TARGET_EXPR so they use the same slot. - * cvt.c (build_up_reference): Propagate INDIRECT_BIND to + * cvt.c (build_up_reference): Propagate INDIRECT_BIND to recursive calls. * typeck.c (complete_type): Propagate TYPE_NEEDS_{CONSTRUCTING,DESTRUCTOR}. @@ -7907,7 +12913,7 @@ Thu Aug 1 15:18:00 1996 Brendan Kehoe Thu Aug 1 11:53:51 1996 Bob Manson - * pt.c (instantiate_class_template): Call complete_type. Also, if + * pt.c (instantiate_class_template): Call complete_type. Also, if we're at the end of the file and we just instantiated a template class with a vtable, call finish_prevtable_vardecl. @@ -8063,12 +13069,12 @@ Tue Jul 23 12:46:30 1996 Jason Merrill * cvt.c (implicit_conversion): Do const-ref case first. (add_conv_candidate, build_object_call, op_error): New fns. (ptr_complete_ob, TYPE_PTROB_P): void is not an object type. - ({add,build}_builtin_candidate{,s}, print_z_candidates): Display + ({add,build}_builtin_candidate{,s}, print_z_candidates): Display builtin candidates. (build_new_op): Handle CALL_EXPR. Don't try to decay void. - Fall back on preincrement handling. Use op_error. + Fall back on preincrement handling. Use op_error. Handle warn_synth. - (convert_like): Pass INDIRECT_BIND. Don't try to do anything with + (convert_like): Pass INDIRECT_BIND. Don't try to do anything with an error_mark_node. (build_over_call): Handle PROMOTE_PROTOTYPES and ellipsis promotions properly. @@ -8087,7 +13093,7 @@ Mon Jul 22 12:18:54 1996 Jason Merrill * g++.c (main): Don't link with -lg++. NEW_OVER changes: - * cvt.c (convert_to_reference): Don't use convert_from_refeence on + * cvt.c (convert_to_reference): Don't use convert_from_reference on result of build_type_conversion. (cp_convert): Only call build_method_call for ctors if build_type_conversion failed. @@ -8095,7 +13101,7 @@ Mon Jul 22 12:18:54 1996 Jason Merrill (TYPE_PTR{,OB,MEM}_P): New macros. ({add,build}_builtin_candidate{,s}): New functions. (print_z_candidates): Handle builtins. - (build_user_type_conversion_1): Don't use conversion fns for + (build_user_type_conversion_1): Don't use conversion fns for converting to a base type. (build_user_type_conversion_1): Set ICS_USER_FLAG on AMBIG_CONVs. (build_user_type_conversion): Use convert_from_reference. @@ -8417,7 +13423,7 @@ Fri Jun 7 10:37:33 1996 Mike Stump lifetime of the temporary, don't try it again. * typeck.c (c_expand_return): Don't try and convert the return value twice when we want a reference, once is enough. - + Tue Jun 4 15:41:45 1996 Jason Merrill * pt.c (tsubst_expr, case DECL_STMT): Don't pass @@ -8494,8 +13500,8 @@ Thu May 23 12:13:08 1996 Bob Manson and cant_synth_asn_ref. (finish_base_struct): Remove the code that tries to conditionalize synthesis of copy constructors & assignment operators based on - access permissions. Instead, let it fail when it tries to - synthesize the copy constructor. This will give meaningful error + access permissions. Instead, let it fail when it tries to + synthesize the copy constructor. This will give meaningful error messages instead of silently generating code to perform a bitcopy. Wed May 22 11:45:19 1996 Bob Manson @@ -8514,7 +13520,7 @@ Wed May 22 11:45:19 1996 Bob Manson (init_decl_processing): Use NULL instead of NULL_TREE to initialize named_label_uses. (finish_function): Likewise. - + (start_decl): Complain about defining a static data member in a different type from which it was declared. @@ -8794,11 +13800,11 @@ Wed Apr 24 15:41:15 1996 Bob Manson definition of flagged_type_tree is found before it is used. * lex.c: Likewise. * parse.y: Added the ftype member to the type union, and changed a - number of rules to use it instead of ttype. Added calls to + number of rules to use it instead of ttype. Added calls to check_for_new_type() as appropriate. * typeck2.c (check_for_new_type): New function for checking if a newly defined type appears in the specified tree. - * cp-tree.h: Add new type flagged_type_tree. Add a prototype + * cp-tree.h: Add new type flagged_type_tree. Add a prototype for check_for_new_type(). Wed Apr 24 00:36:21 1996 Jason Merrill @@ -8923,7 +13929,7 @@ Sun Apr 14 11:34:39 1996 Jason Merrill Fri Apr 12 09:08:27 1996 Bob Manson * call.c (build_method_call): Remember the original basetype we - were called with. Give an error message instead of trying + were called with. Give an error message instead of trying (incorrectly) to call a non-static member function through a non-inherited class. @@ -9052,7 +14058,7 @@ Sat Apr 6 13:56:27 1996 Jason Merrill Fri Apr 5 17:02:09 1996 Jason Merrill RTTI rewrite to initialize nodes as needed, not require that - users #include , complete functionality and reduce wasted + users #include , complete functionality and reduce wasted space. * rtti.c (init_rtti_processing): New fn. (build_typeid): The vtable entry is now a function. @@ -9152,11 +14158,11 @@ Sat Mar 30 12:14:33 1996 Brendan Kehoe Fri Mar 29 15:51:36 1996 Bob Manson - * class.c (base_info, finish_base_struct): Replace + * class.c (base_info, finish_base_struct): Replace needs_virtual_dtor with base_has_virtual. (finish_struct_1): Remove the old code that tried to make default - destructors virtual. Use base_has_virtual when checking if we need + destructors virtual. Use base_has_virtual when checking if we need to add a vtable entry for the rtti code. Fri Mar 29 14:02:36 1996 Jason Merrill @@ -9269,7 +14275,7 @@ Fri Mar 22 17:57:55 1996 Mike Stump Fri Mar 22 13:48:29 1996 Jason Merrill * decl.c (grokdeclarator): Call bad_specifiers for typedefs. Also - give an error if initialized. Pedwarn about nested type with the + give an error if initialized. pedwarn about nested type with the same name as its enclosing class. * pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT. @@ -9500,7 +14506,7 @@ Wed Mar 13 14:03:34 1996 Jason Merrill Tue Mar 12 14:36:02 1996 Jason Merrill - * init.c (build_new): Pedwarn about init and array new. + * init.c (build_new): pedwarn about init and array new. (expand_vec_init): Handle lists, use convert_for_initialization. * typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION @@ -9622,7 +14628,7 @@ Mon Mar 4 20:03:33 1996 Jason Merrill * error.c (dump_expr): Support LOOKUP_EXPR and actually do something for CAST_EXPR. - + Mon Feb 19 14:49:18 1996 Rusty Russell * cvt.c (cp_convert): Warn about implicit conversion of the @@ -9892,7 +14898,7 @@ Thu Feb 22 15:30:12 1996 Brendan Kehoe (repo_compile_flags, repo_template_declared, repo_template_defined, repo_class_defined, repo_inline_used, repo_vtable_used, repo_tinfo_used): #if 0 unused fns. - (repo_get_id, repo_vtable_used): Declare as static. + (repo_get_id, repo_vtable_used): Declare as static. * cp-tree.h (mark_{decl,class}_instantiated, finish_repo): Add prototypes. @@ -9921,7 +14927,7 @@ Thu Feb 22 13:24:15 1996 Brendan Kehoe (init_lex): Don't set it. (init_parse): Add decl before use. (reduce_count): Only define #ifdef GATHER_STATISTICS && REDUCE_LENGTH. - (current_unit_{name, language}): Delete unused vars. + (current_unit_{name, language}): Delete unused vars. (check_newline): Don't bother setting them, just accept the #pragma. * cp-tree.h (init_repo, peek_yylex): Add prototypes. (current_unit_{name, language}): Delete decls. @@ -10045,7 +15051,7 @@ Thu Feb 22 00:54:22 1996 Jason Merrill Wed Feb 21 16:57:33 1996 Brendan Kehoe - * init.c (expand_recursive_init{,_1}): Delete decls. + * init.c (expand_recursive_init{,_1}): Delete decls. (sort_member_init): Delete unused var INIT. (emit_base_init): Delete unused var X. (build_offset_ref): Delete unused var CNAME. @@ -10081,7 +15087,7 @@ Wed Feb 21 16:57:33 1996 Brendan Kehoe * class.c (n_*): Wrap with #ifdef GATHER_STATISTICS. - * class.c (get_vtable_entry): Diable unused function. + * class.c (get_vtable_entry): Disable unused function. (doing_hard_virtuals): Delete unused static global var. (finish_struct_1): Don't init DOING_HARD_VIRTUALS. (prepare_fresh_vtable): Delete unused vars PATH and RESULT. @@ -10112,7 +15118,7 @@ Wed Feb 21 16:57:33 1996 Brendan Kehoe (grokparms): Delete unused var SAW_VOID. (start_function): Delete unused var OLDDECL. (cplus_expand_expr_stmt): Delete unused var - REMOVE_IMPLICIT_IMMEDIATELY. + REMOVE_IMPLICIT_IMMEDIATELY. * cp-tree.h (pushdecl_nonclass_level): Fix prototype. @@ -10127,7 +15133,7 @@ Wed Feb 21 00:06:17 1996 Jason Merrill (tsubst_expr): Set lineno from TREE_COMPLEXITY in stmt nodes. * parse.y: Use do_pushlevel and do_poplevel. * cp-tree.h: Declare do_poplevel. - + * cp-tree.h: Declare at_eof. * decl.c (cp_finish_decl): Pass it to rest_of_decl_compilation. * decl2.c (import_export_decl): Renamed from import_export_inline. @@ -10744,7 +15750,7 @@ Tue Dec 19 22:36:56 1995 Jason Merrill Mon Dec 18 15:51:33 1995 Jason Merrill * cp-tree.h, decl2.c (flag_weak): New flag to control the use of - weak symbols. + weak symbols. * lang-options.h: Add -f{no-,}weak. * decl.c (init_decl_processing): If the target does not support weak symbols, don't use them. @@ -10771,7 +15777,7 @@ Thu Dec 14 14:16:26 1995 Mike Stump copy constructors well. The compiler would do bitwise copying, instead of ctor calling in some cases. -Wed Dec 13 17:05:54 PST 1995 Paul Eggert +Wed Dec 13 17:05:54 1995 Paul Eggert * g++.c (my_strerror): Return "cannot access" if errno is 0. (pfatal_with_name, perror_exec): Don't assume that @@ -10782,7 +15788,7 @@ Wed Dec 13 17:05:54 PST 1995 Paul Eggert Wed Dec 13 16:22:38 1995 Jason Merrill Lose CLASSTYPE_METHODS/DECL_NEXT_METHOD chain; make - TYPE_METHODS/TREE_CHAIN mean what they used to. + TYPE_METHODS/TREE_CHAIN mean what they used to. * decl2.c (constructor_name_full): Refer to CLASSTYPE_METHOD_VEC instead of TYPE_METHODS. * decl.c (duplicate_decls): Lose references to DECL_NEXT_METHOD. @@ -10823,7 +15829,7 @@ Mon Dec 11 18:56:14 1995 Mike Stump * decl2.c (build_cleanup): New routine, taken from finish_file. (finish_file): Use build_cleanup instead, and don't put function local statics in global dtor list. - + Wed Dec 6 14:34:29 1995 Mike Stump * except.c (expand_throw): Ensure that we have cleanups, if we try @@ -10862,7 +15868,7 @@ Wed Dec 6 11:48:21 1995 Mike Stump * class.c (build_vfn_ref): Remove building_cleanup logic, as we now use UNSAVE_EXPRs. - typeck.c (get_member_function_from_ptrfunc): Remove remnants of + * typeck.c (get_member_function_from_ptrfunc): Remove remnants of building_cleanup logic, as we now use UNSAVE_EXPRs. * cp-tree.h (unsave_expr): Declare it. * decl.c (building_cleanup): Remove. @@ -10956,11 +15962,11 @@ Fri Nov 10 09:18:09 1995 Brendan Kehoe Mon Nov 6 18:36:13 1995 Brendan Kehoe * call.c (build_method_call): Make sure instance has a - TYPE_LANG_SPECIFIC node before we dive into it. + TYPE_LANG_SPECIFIC node before we dive into it. Sat Nov 4 20:01:52 1995 Jason Molenda - * method.c (make_thunk): use TREE_SET_CODE to set thunk's tree code. + * method.c (make_thunk): Use TREE_SET_CODE to set thunk's tree code. Thu Nov 2 17:56:57 1995 Mike Stump @@ -10995,7 +16001,7 @@ Tue Oct 31 11:56:55 1995 Jason Merrill (emit_thunk): Don't call assemble_external. (make_thunk): Create thunk as a FUNCTION_DECL so that it gets the right mode and ENCODE_SECTION_INFO works. - + * parse.y: Use mark_used. Pass operator names to do_identifier. * lex.c (do_identifier): Handle operator names. diff --git a/contrib/gcc/cp/Make-lang.in b/contrib/gcc/cp/Make-lang.in index be02cf1..d5d4e4d 100644 --- a/contrib/gcc/cp/Make-lang.in +++ b/contrib/gcc/cp/Make-lang.in @@ -1,5 +1,5 @@ # Top level makefile fragment for GNU C++. -# Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. #This file is part of GNU CC. @@ -75,43 +75,38 @@ C++ c++: cc1plus$(exeext) # Tell GNU make to ignore these if they exist. .PHONY: C++ c++ -g++.c: $(srcdir)/gcc.c - -rm -f $@ - $(LN_S) $(srcdir)/gcc.c $@ - g++spec.o: $(srcdir)/cp/g++spec.c $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/cp/g++spec.c -# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added. -# It'd be nice if we could find an easier way to do this---rather than have -# to track changes to the toplevel gcc Makefile as well. -# We depend on g++.c last, to make it obvious where it came from. -g++.o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) g++.c \ - system.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(DRIVER_DEFINES) \ - -DLANG_SPECIFIC_DRIVER \ - -c g++.c +$(INTL_TARGETS): $(srcdir)/cp/parse.c +$(srcdir)/cp/parse.c: $(srcdir)/cp/parse.y + @cp_srcdir=`sed -n 's/^srcdir[ ]*=[ ]*//p' cp/Makefile` && \ + echo "cd cp && $(MAKE) $$cp_srcdir/parse.c" && \ + cd cp && \ + $(MAKE) $(SUBDIR_FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) \ + $$cp_srcdir/parse.c # Create the compiler driver for g++. -g++$(exeext): g++.o g++spec.o version.o choose-temp.o pexecute.o prefix.o mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ g++.o g++spec.o prefix.o \ - version.o choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS) +GXX_OBJS = gcc.o g++spec.o intl.o prefix.o version.o +g++$(exeext): $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ + $(GXX_OBJS) $(EXTRA_GCC_OBJS) $(LIBS) # Create a version of the g++ driver which calls the cross-compiler. g++-cross$(exeext): g++$(exeext) -rm -f g++-cross$(exeext) cp g++$(exeext) g++-cross$(exeext) -cxxmain.o: cplus-dem.c demangle.h +cxxmain.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H) rm -f cxxmain.c - $(LN_S) $(srcdir)/cplus-dem.c cxxmain.c + $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cxxmain.c $(CC) -c -DMAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DVERSION=\"$(version)\" cxxmain.c -$(DEMANGLER_PROG): cxxmain.o underscore.o getopt.o getopt1.o $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) $(LIBS) -o $@ \ - cxxmain.o underscore.o getopt.o getopt1.o +# Apparently OpenVM needs the -o to be at the beginning of the link line. +$(DEMANGLER_PROG): cxxmain.o underscore.o $(LIBDEPS) + $(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) \ + cxxmain.o underscore.o $(LIBS) CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \ $(srcdir)/cp/except.c $(srcdir)/cp/input.c $(srcdir)/cp/pt.c \ @@ -125,7 +120,7 @@ CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \ $(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \ - $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def + $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def hash.o cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext) # # Build hooks: @@ -140,40 +135,40 @@ c++.dvi: # C++ language-support library pieces for libgcc. tinfo.o: cc1plus$(exeext) $(srcdir)/cp/tinfo.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/tinfo.cc tinfo2.o: cc1plus$(exeext) $(srcdir)/cp/tinfo2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/tinfo2.cc exception.o: cc1plus$(exeext) $(srcdir)/cp/exception.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c -fexceptions $(srcdir)/cp/exception.cc new.o: cc1plus$(exeext) $(srcdir)/cp/new.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new.cc opnew.o: cc1plus$(exeext) $(srcdir)/cp/new1.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new1.cc -DL_op_new -o opnew.o opnewnt.o: cc1plus$(exeext) $(srcdir)/cp/new1.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new1.cc -DL_op_newnt -o opnewnt.o opvnew.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_vnew -o opvnew.o opvnewnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_vnewnt -o opvnewnt.o opdel.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_delete -o opdel.o opdelnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_delnt -o opdelnt.o opvdel.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_vdel -o opvdel.o opvdelnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) \ + $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ -c $(srcdir)/cp/new2.cc -DL_op_vdelnt -o opvdelnt.o # We want to update cplib2.txt if any of the source files change... @@ -187,8 +182,11 @@ cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready mv -f cplib2.new cplib2.txt # Or if it would be different. -cplib2.ready: $(GCC_PASSES) $(LANGUAGES) $(LIBGCC2_DEPS) stmp-int-hdrs - @if [ -r cplib2.txt ]; then \ +# Don't try to do write if `.' is not writable; +# in that case, we're installing from someone else's directory. +# But go ahead and fail if that directory hasn't been properly built. +cplib2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs + @if [ -r cplib2.txt -a -w . ]; then \ case " $(LANGUAGES) " in \ *" "[cC]"++ "*) \ echo $(CXX_LIB2FUNCS) > cplib2.new;; \ @@ -246,13 +244,13 @@ c++.install-info: c++.install-man: $(srcdir)/cp/g++.1 -if [ -f cc1plus$(exeext) ] ; then \ if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(mandir)/$(GXX_CROSS_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(mandir)/$(GXX_CROSS_NAME)$(manext); \ - chmod a-x $(mandir)/$(GXX_CROSS_NAME)$(manext); \ + rm -f $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ + $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ + chmod a-x $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ else \ - rm -f $(mandir)/$(GXX_INSTALL_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(mandir)/$(GXX_INSTALL_NAME)$(manext); \ - chmod a-x $(mandir)/$(GXX_INSTALL_NAME)$(manext); \ + rm -f $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ + $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ + chmod a-x $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ fi; \ else true; fi @@ -263,8 +261,8 @@ c++.uninstall: -rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext) -rm -rf $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext) -rm -rf $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext) - -rm -rf $(mandir)/$(GXX_INSTALL_NAME)$(manext) - -rm -rf $(mandir)/$(GXX_CROSS_NAME)$(manext) + -rm -rf $(man1dir)/$(GXX_INSTALL_NAME)$(manext) + -rm -rf $(man1dir)/$(GXX_CROSS_NAME)$(manext) # # Clean hooks: # A lot of the ancillary files are deleted by the main makefile. @@ -277,7 +275,6 @@ c++.clean: c++.distclean: -rm -f cp/config.status cp/Makefile -rm -f cp/parse.output - -rm -f g++.c c++.extraclean: c++.maintainer-clean: -rm -f cp/parse.c cp/parse.h diff --git a/contrib/gcc/cp/Makefile.in b/contrib/gcc/cp/Makefile.in index 8d7098d..1a5b32c 100644 --- a/contrib/gcc/cp/Makefile.in +++ b/contrib/gcc/cp/Makefile.in @@ -1,5 +1,5 @@ # Makefile for GNU C++ compiler. -# Copyright (C) 1987, 88, 90-5, 1998 Free Software Foundation, Inc. +# Copyright (C) 1987, 88, 90-5, 1998, 1999 Free Software Foundation, Inc. #This file is part of GNU CC. @@ -34,6 +34,10 @@ # Suppress smart makes who think they know how to automake Yacc files .y.c: +# It defines the c++ interface name. It should be changed when the +# c++ interface is changed. +INTERFACE = 2 + # Variables that exist for you to override. # See below for how to change them for certain systems. @@ -55,7 +59,7 @@ X_CPPFLAGS = T_CPPFLAGS = CC = @CC@ -BBISON = `if [ -f ../../bison/bison ] ; then echo ../../bison/bison -L $(srcdir)/../../bison/ ; else echo bison ; fi` +BISON = `if [ -f ../../bison/bison ] ; then echo ../../bison/bison -L $(srcdir)/../../bison/ ; else echo bison ; fi` BISONFLAGS = LEX = `if [ -f ../../flex/flex ] ; then echo ../../flex/flex ; else echo flex ; fi` LEXFLAGS = @@ -101,6 +105,12 @@ VPATH = @srcdir@ # Additional system libraries to link with. CLIB= + +# Top build directory, relative to here. +top_builddir = .. + +# Internationalization library. +INTLLIBS = @INTLLIBS@ # Change this to a null string if obstacks are installed in the # system library. @@ -150,13 +160,14 @@ SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi` # How to link with both our special library facilities # and the system's installed libraries. -LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB) +LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) \ + $(INTLLIBS) $(CLIB) # Specify the directories to be searched for header files. # Both . and srcdir are used, in that order, # so that tm.h and config.h will be found in the compilation # subdirectory rather than in the source directory. -INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config +INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)/../../include # Always use -I$(srcdir)/config when compiling. .c.o: @@ -184,9 +195,8 @@ OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o compiler: ../cc1plus$(exeext) -../cc1plus$(exeext): $(P) $(CXX_OBJS) $(OBJDEPS) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ \ - $(CXX_OBJS) $(OBJS) $(LIBS) +../cc1plus$(exeext): $(P) $(OBJDEPS) $(CXX_OBJS) $(LIBDEPS) + $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(CXX_OBJS) $(LIBS) Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure cd ..; $(SHELL) config.status @@ -215,7 +225,7 @@ parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \ `echo $(PARSE_C) | sed 's,^\./,,'` -CONFLICTS = expect 26 shift/reduce conflicts and 42 reduce/reduce conflicts. +CONFLICTS = expect 30 shift/reduce conflicts and 42 reduce/reduce conflicts. $(PARSE_H) : $(PARSE_C) $(PARSE_C) : $(srcdir)/parse.y @echo $(CONFLICTS) @@ -231,33 +241,35 @@ $(PARSE_C) : $(srcdir)/parse.y # cp $(PARSE_C) y.tab.c # touch stamp-parse -# hash.h really depends on $(srcdir)/gxx.gperf. -# But this would screw things for people that don't have gperf, -# if gxx.gpref got touched, say. -# Thus you have to remove hash.h to force it to be re-made. -$(srcdir)/hash.h: - gperf -p -j1 -g -o -t -N is_reserved_word '-k1,4,7,$$' \ - $(srcdir)/gxx.gperf >$(srcdir)/hash.h +# We used to try to protect people from having to rerun gperf. But, +# the C front-end already requires this if c-parse.gperf is changed, +# so we should be consistent. +$(srcdir)/hash.h: $(srcdir)/gxx.gperf + gperf -L C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word \ + '-k1,4,7,$$' $(srcdir)/gxx.gperf >$(srcdir)/hash.h -spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) \ - $(PARSE_H) $(srcdir)/../flags.h lex.h $(srcdir)/../system.h +spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \ + lex.h $(srcdir)/../system.h $(srcdir)/../toplev.h lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \ $(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \ $(srcdir)/../c-pragma.h $(srcdir)/../system.h $(srcdir)/../toplev.h \ - $(srcdir)/../output.h + $(srcdir)/../output.h $(srcdir)/../mbchar.h decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \ - $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h + $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \ + $(srcdir)/../hash.h decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \ $(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \ - $(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h + $(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \ + $(srcdir)/../../include/splay-tree.h $(srcdir)/../varray.h typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ $(srcdir)/../system.h $(srcdir)/../toplev.h typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h + $(srcdir)/../system.h $(srcdir)/../toplev.h \ + $(srcdir)/../../include/splay-tree.h call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ $(srcdir)/../system.h $(srcdir)/../toplev.h friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ @@ -266,9 +278,11 @@ init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h method.o : method.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \ $(srcdir)/../toplev.h -cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h +cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \ + $(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \ - $(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h + $(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h \ + $(srcdir)/../varray.h tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ $(srcdir)/../system.h $(srcdir)/../toplev.h ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h @@ -308,32 +322,3 @@ TAGS: force .PHONY: TAGS force: - -g++FAQ.info: $(srcdir)/g++FAQ.texi - $(MAKEINFO) --no-split -o ./g++FAQ.info $(srcdir)/g++FAQ.texi - -# Preprocess the texi file so that the final document will have -# hyperlinks. -# It would be nice if texi2html could do something like this itself. - -# Assumption 1: the FAQ puts all http: and ftp: links in a @file{...}. -# Assumption 2: newsgroups are like @file{comp.foo} -# Assumption 3: email addresses match the regexp shown. - -g++FAQ.html: $(srcdir)/g++FAQ.texi - mkdir work - sed -e 's?@file{\([fth]*p://[^}]*\)}?@strong{\1}?' \ - -e 's?@file{\(comp\.[-a-z+.]*\)}?\1?' \ - -e 's?@file{\(gnu\.[-a-z+.]*\)}?\1?' \ - -e 's?\([.+a-zA-Z0-9-]*@@[.a-zA-Z0-9-]*[a-zA-Z0-9]\)?\1?' \ - $(srcdir)/g++FAQ.texi > work/g++FAQ.texi - cd work; texi2html g++FAQ.texi - mv work/*.html . - rm -r work - -# Make plain-text form. - -g++FAQ.txt: $(srcdir)/g++FAQ.texi - $(MAKEINFO) --no-split --no-headers -o - $(srcdir)/g++FAQ.texi |\ - sed '/^Concept Index/,$$d' > g++FAQ.txt - diff --git a/contrib/gcc/cp/NEWS b/contrib/gcc/cp/NEWS index 9cb7d5b..1a242ab 100644 --- a/contrib/gcc/cp/NEWS +++ b/contrib/gcc/cp/NEWS @@ -1,3 +1,39 @@ +*** Changes in GCC 2.95: + +* Messages about non-conformant code that we can still handle ("pedwarns") + are now errors by default, rather than warnings. This can be reverted + with -fpermissive, and is overridden by -pedantic or -pedantic-errors. + +* String constants are now of type `const char[n]', rather than `char[n]'. + This can be reverted with -fno-const-strings. + +* References to functions are now supported. + +* Lookup of class members during class definition now works in all cases. + +* In overload resolution, type conversion operators are now properly + treated as always coming from the most derived class. + +* C9x-style restricted pointers are supported, using the `__restrict' + keyword. + +* You can now use -fno-implicit-inline-templates to suppress writing out + implicit instantiations of inline templates. Normally we do write them + out, even with -fno-implicit-templates, so that optimization doesn't + affect which instantiations are needed. + +* -fstrict-prototype now also suppresses implicit declarations. + +* Many obsolete options have been removed: -fall-virtual, -fmemoize-lookups, + -fsave-memoized, +e?, -fenum-int-equivalence, -fno-nonnull-objects. + +* Unused virtual functions can be discarded on some targets by specifying + -ffunction-sections -fvtable-gc to the compiler and --gc-sections to the + linker. Unfortunately, this only works on Linux if you're linking + statically. + +* Lots of bugs stomped. + *** Changes in EGCS 1.1: * Namespaces are fully supported. The library has not yet been converted diff --git a/contrib/gcc/cp/call.c b/contrib/gcc/cp/call.c index e65898e..094a345 100644 --- a/contrib/gcc/cp/call.c +++ b/contrib/gcc/cp/call.c @@ -1,5 +1,5 @@ /* Functions related to invoking methods and overloaded functions. - Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) and modified by Brendan Kehoe (brendan@cygnus.com). @@ -49,7 +49,7 @@ static int compare_ics PROTO((tree, tree)); static tree build_over_call PROTO((struct z_candidate *, tree, int)); static tree convert_like PROTO((tree, tree)); static void op_error PROTO((enum tree_code, enum tree_code, tree, tree, - tree, char *)); + tree, const char *)); static tree build_object_call PROTO((tree, tree)); static tree resolve_args PROTO((tree)); static struct z_candidate * build_user_type_conversion_1 @@ -87,22 +87,22 @@ static tree strip_top_quals PROTO((tree)); static tree non_reference PROTO((tree)); static tree build_conv PROTO((enum tree_code, tree, tree)); static int is_subseq PROTO((tree, tree)); -static int is_properly_derived_from PROTO((tree, tree)); static int maybe_handle_ref_bind PROTO((tree*, tree*)); static void maybe_handle_implicit_object PROTO((tree*)); +static struct z_candidate * add_candidate PROTO((struct z_candidate *, + tree, tree, int)); +static tree source_type PROTO((tree)); +static void add_warning PROTO((struct z_candidate *, struct z_candidate *)); tree build_vfield_ref (datum, type) tree datum, type; { tree rval; - int old_assume_nonnull_objects = flag_assume_nonnull_objects; if (datum == error_mark_node) return error_mark_node; - /* Vtable references are always made from non-null objects. */ - flag_assume_nonnull_objects = 1; if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) datum = convert_from_reference (datum); @@ -111,7 +111,6 @@ build_vfield_ref (datum, type) datum, CLASSTYPE_VFIELD (type)); else rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), NULL_TREE, 0); - flag_assume_nonnull_objects = old_assume_nonnull_objects; return rval; } @@ -128,91 +127,40 @@ build_field_call (basetype_path, instance_ptr, name, parms) if (name == ctor_identifier || name == dtor_identifier) return NULL_TREE; - if (instance_ptr == current_class_ptr) - { - /* Check to see if we really have a reference to an instance variable - with `operator()()' overloaded. */ - field = IDENTIFIER_CLASS_VALUE (name); - - if (field == NULL_TREE) - { - cp_error ("`this' has no member named `%D'", name); - return error_mark_node; - } - - if (TREE_CODE (field) == FIELD_DECL) - { - /* If it's a field, try overloading operator (), - or calling if the field is a pointer-to-function. */ - instance = build_component_ref_1 (current_class_ref, field, 0); - if (instance == error_mark_node) - return error_mark_node; - - if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance))) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE); - - if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) - return build_function_call (instance, parms); - else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) - return build_function_call (instance, expr_tree_cons (NULL_TREE, current_class_ptr, parms)); - } - } - return NULL_TREE; - } + /* Speed up the common case. */ + if (instance_ptr == current_class_ptr + && IDENTIFIER_CLASS_VALUE (name) == NULL_TREE) + return NULL_TREE; - /* Check to see if this is not really a reference to an instance variable - with `operator()()' overloaded. */ field = lookup_field (basetype_path, name, 1, 0); - /* This can happen if the reference was ambiguous or for access - violations. */ - if (field == error_mark_node) - return error_mark_node; + if (field == error_mark_node || field == NULL_TREE) + return field; - if (field && TREE_CODE (field) == FIELD_DECL) + if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL) { - tree basetype; - tree ftype = TREE_TYPE (field); + /* 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_PTR); + instance = build_component_ref_1 (instance, field, 0); - if (TREE_CODE (ftype) == REFERENCE_TYPE) - ftype = TREE_TYPE (ftype); + if (instance == error_mark_node) + return error_mark_node; - if (TYPE_LANG_SPECIFIC (ftype)) + 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)) == POINTER_TYPE) { - /* Make the next search for this field very short. */ - basetype = DECL_FIELD_CONTEXT (field); - instance_ptr = convert_pointer_to (basetype, instance_ptr); - - instance = build_indirect_ref (instance_ptr, NULL_PTR); - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, - build_component_ref_1 (instance, field, 0), - parms, NULL_TREE); + if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) + return build_function_call (instance, parms); + else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) + == METHOD_TYPE) + return build_function_call + (instance, expr_tree_cons (NULL_TREE, instance_ptr, parms)); } - if (TREE_CODE (ftype) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (ftype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (ftype)) == METHOD_TYPE) - { - /* This is a member which is a pointer to function. */ - tree ref - = build_component_ref_1 (build_indirect_ref (instance_ptr, - NULL_PTR), - field, LOOKUP_COMPLAIN); - if (ref == error_mark_node) - return error_mark_node; - return build_function_call (ref, parms); - } - } - else if (TREE_CODE (ftype) == METHOD_TYPE) - { - error ("invalid call via pointer-to-member function"); - return error_mark_node; - } - else - return NULL_TREE; } + return NULL_TREE; } @@ -350,6 +298,10 @@ check_dtor_name (basetype, name) { name = TREE_OPERAND (name, 0); + /* Just accept something we've already complained about. */ + if (name == error_mark_node) + return 1; + if (TREE_CODE (name) == TYPE_DECL) name = TREE_TYPE (name); else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') @@ -551,6 +503,9 @@ build_call (function, result_type, parms) if (decl && DECL_CONSTRUCTOR_P (decl)) is_constructor = 1; + if (decl) + my_friendly_assert (TREE_USED (decl), 990125); + /* Don't pass empty class objects by value. This is useful for tags in STL, which are used to control overload resolution. We don't need to handle other cases of copying empty classes. */ @@ -628,10 +583,15 @@ build_method_call (instance, name, parms, basetype_path, flags) { /* 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_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) + if (TREE_CODE (name) == BIT_NOT_EXPR) { - tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0); + 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); } @@ -639,29 +599,6 @@ build_method_call (instance, name, parms, basetype_path, flags) return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE); } - /* This is the logic that magically deletes the second argument to - operator delete, if it is not needed. */ - if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2) - { - tree save_last = TREE_CHAIN (parms); - - /* get rid of unneeded argument */ - TREE_CHAIN (parms) = NULL_TREE; - if (build_method_call (instance, name, parms, basetype_path, - (LOOKUP_SPECULATIVELY|flags) & ~LOOKUP_COMPLAIN)) - { - /* If it finds a match, return it. */ - return build_method_call (instance, name, parms, basetype_path, flags); - } - /* If it doesn't work, two argument delete must work */ - TREE_CHAIN (parms) = save_last; - } - /* We already know whether it's needed or not for vec delete. */ - else if (name == ansi_opname[(int) VEC_DELETE_EXPR] - && TYPE_LANG_SPECIFIC (TREE_TYPE (instance)) - && ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance))) - TREE_CHAIN (parms) = NULL_TREE; - if (TREE_CODE (name) == BIT_NOT_EXPR) { if (parms) @@ -806,6 +743,15 @@ standard_conversion (to, from, expr) to = strip_top_quals (to); from = strip_top_quals (from); + if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) + && expr && type_unknown_p (expr)) + { + expr = instantiate_type (to, expr, 0); + if (expr == error_mark_node) + return NULL_TREE; + from = TREE_TYPE (expr); + } + fcode = TREE_CODE (from); tcode = TREE_CODE (to); @@ -839,16 +785,15 @@ standard_conversion (to, from, expr) enum tree_code ufcode = TREE_CODE (TREE_TYPE (from)); enum tree_code utcode = TREE_CODE (TREE_TYPE (to)); - if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (from)), - TYPE_MAIN_VARIANT (TREE_TYPE (to)), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)), + TYPE_MAIN_VARIANT (TREE_TYPE (to)))) ; else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE && ufcode != FUNCTION_TYPE) { from = build_pointer_type - (cp_build_type_variant (void_type_node, - TYPE_READONLY (TREE_TYPE (from)), - TYPE_VOLATILE (TREE_TYPE (from)))); + (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) @@ -857,9 +802,9 @@ standard_conversion (to, from, expr) tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); if (DERIVED_FROM_P (fbase, tbase) - && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to))), - 1))) + && (same_type_p + (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), + TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to)))))) { from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from))); from = build_pointer_type (from); @@ -871,18 +816,21 @@ standard_conversion (to, from, expr) { if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))) { - from = cp_build_type_variant (TREE_TYPE (to), - TYPE_READONLY (TREE_TYPE (from)), - TYPE_VOLATILE (TREE_TYPE (from))); + from = + cp_build_qualified_type (TREE_TYPE (to), + CP_TYPE_QUALS (TREE_TYPE (from))); from = build_pointer_type (from); conv = build_conv (PTR_CONV, from, conv); } } - if (comptypes (from, to, 1)) + if (same_type_p (from, to)) /* OK */; else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from))) 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))) { conv = build_conv (PTR_CONV, to, conv); @@ -901,15 +849,13 @@ standard_conversion (to, from, expr) tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); if (! DERIVED_FROM_P (fbase, tbase) - || ! comptypes (TREE_TYPE (fromfn), TREE_TYPE (tofn), 1) + || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), - TREE_CHAIN (TYPE_ARG_TYPES (tofn)), 1) - || TYPE_READONLY (fbase) != TYPE_READONLY (tbase) - || TYPE_VOLATILE (fbase) != TYPE_VOLATILE (tbase)) + TREE_CHAIN (TYPE_ARG_TYPES (tofn))) + || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase)) return 0; - from = cp_build_type_variant (tbase, TYPE_READONLY (fbase), - TYPE_VOLATILE (fbase)); + 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_ptrmemfunc_type (build_pointer_type (from)); @@ -971,24 +917,30 @@ reference_binding (rto, rfrom, expr, flags) tree from = rfrom; int related; + if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) + { + expr = instantiate_type (to, expr, 0); + if (expr == error_mark_node) + return NULL_TREE; + from = TREE_TYPE (expr); + } + if (TREE_CODE (from) == REFERENCE_TYPE) from = TREE_TYPE (from); else if (! expr || ! real_lvalue_p (expr)) lvalue = 0; - related = (comptypes (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from), 1) + related = (same_type_p (TYPE_MAIN_VARIANT (to), + TYPE_MAIN_VARIANT (from)) || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) && DERIVED_FROM_P (to, from))); - if (lvalue && related - && TYPE_READONLY (to) >= TYPE_READONLY (from) - && TYPE_VOLATILE (to) >= TYPE_VOLATILE (from)) + if (lvalue && related && at_least_as_qualified_p (to, from)) { conv = build1 (IDENTITY_CONV, from, expr); - if (comptypes (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (to), + TYPE_MAIN_VARIANT (from))) conv = build_conv (REF_BIND, rto, conv); else { @@ -1012,14 +964,12 @@ reference_binding (rto, rfrom, expr, flags) TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0); } if (conv - && ((! (TYPE_READONLY (to) && ! TYPE_VOLATILE (to) + && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to) && (flags & LOOKUP_NO_TEMP_BIND) == 0)) /* If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cv-qualification than, cv2; otherwise, the program is ill-formed. */ - || (related - && (TYPE_READONLY (to) < TYPE_READONLY (from) - || TYPE_VOLATILE (to) < TYPE_VOLATILE (from))))) + || (related && !at_least_as_qualified_p (to, from)))) ICS_BAD_FLAG (conv) = 1; } @@ -1039,14 +989,6 @@ implicit_conversion (to, from, expr, flags) tree conv; struct z_candidate *cand; - if (expr && type_unknown_p (expr)) - { - expr = instantiate_type (to, expr, 0); - if (expr == error_mark_node) - return 0; - from = TREE_TYPE (expr); - } - if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, flags); else @@ -1056,7 +998,7 @@ implicit_conversion (to, from, expr, flags) ; else if (expr != NULL_TREE && (IS_AGGR_TYPE (non_reference (from)) - || IS_AGGR_TYPE (non_reference (to))) + || IS_AGGR_TYPE (non_reference (to))) && (flags & LOOKUP_NO_CONVERSION) == 0) { cand = build_user_type_conversion_1 @@ -1071,8 +1013,7 @@ implicit_conversion (to, from, expr, flags) (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING); if (cand) { - if (! TYPE_READONLY (TREE_TYPE (to)) - || TYPE_VOLATILE (TREE_TYPE (to))) + if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to))) ICS_BAD_FLAG (cand->second_conv) = 1; if (!conv || (ICS_BAD_FLAG (conv) > ICS_BAD_FLAG (cand->second_conv))) @@ -1121,42 +1062,92 @@ add_function_candidate (candidates, fn, arglist, flags) tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); int i, len; tree convs; - tree parmnode = parmlist; - tree argnode = arglist; + tree parmnode, argnode; int viable = 1; /* The `this' and `in_chrg' arguments to constructors are not considered in overload resolution. */ if (DECL_CONSTRUCTOR_P (fn)) { - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); + parmlist = TREE_CHAIN (parmlist); + arglist = TREE_CHAIN (arglist); if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) { - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); + parmlist = TREE_CHAIN (parmlist); + arglist = TREE_CHAIN (arglist); } } - len = list_length (argnode); + len = list_length (arglist); convs = make_scratch_vec (len); + /* 13.3.2 - Viable functions [over.match.viable] + First, to be a viable function, a candidate function shall have enough + parameters to agree in number with the arguments in the list. + + We need to check this first; otherwise, checking the ICSes might cause + us to produce an ill-formed template instantiation. */ + + parmnode = parmlist; + for (i = 0; i < len; ++i) + { + if (parmnode == NULL_TREE || parmnode == void_list_node) + break; + parmnode = TREE_CHAIN (parmnode); + } + + if (i < len && parmnode) + viable = 0; + + /* Make sure there are default args for the rest of the parms. */ + else for (; parmnode && parmnode != void_list_node; + parmnode = TREE_CHAIN (parmnode)) + if (! TREE_PURPOSE (parmnode)) + { + viable = 0; + break; + } + + if (! viable) + goto out; + + /* Second, for F to be a viable function, there shall exist for each + argument an implicit conversion sequence that converts that argument + to the corresponding parameter of F. */ + + parmnode = parmlist; + argnode = arglist; + for (i = 0; i < len; ++i) { tree arg = TREE_VALUE (argnode); - tree argtype = TREE_TYPE (arg); + tree argtype = lvalue_type (arg); tree t; - /* An overloaded function does not have an argument type */ - if (TREE_CODE (arg) == OVERLOAD) - argtype = unknown_type_node; - argtype = cp_build_type_variant - (argtype, TREE_READONLY (arg), TREE_THIS_VOLATILE (arg)); - if (parmnode == void_list_node) break; - else if (parmnode) - t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags); + + if (parmnode) + { + tree parmtype = TREE_VALUE (parmnode); + + /* [over.match.funcs] For conversion functions, the function is + considered to be a member of the class of the implicit object + argument for the purpose of defining the type of the implicit + object parameter. + + Since build_over_call ignores the ICS for the `this' parameter, + we can just change the parm type. */ + if (DECL_CONV_FN_P (fn) && i == 0) + { + parmtype + = build_qualified_type (TREE_TYPE (argtype), + TYPE_QUALS (TREE_TYPE (parmtype))); + parmtype = build_pointer_type (parmtype); + } + + t = implicit_conversion (parmtype, argtype, arg, flags); + } else { t = build1 (IDENTITY_CONV, argtype, arg); @@ -1169,7 +1160,10 @@ add_function_candidate (candidates, fn, arglist, flags) TREE_VEC_ELT (convs, i) = t; if (! t) - break; + { + viable = 0; + break; + } if (ICS_BAD_FLAG (t)) viable = -1; @@ -1179,25 +1173,20 @@ add_function_candidate (candidates, fn, arglist, flags) argnode = TREE_CHAIN (argnode); } - if (i < len) - viable = 0; - - /* Make sure there are default args for the rest of the parms. */ - for (; parmnode && parmnode != void_list_node; - parmnode = TREE_CHAIN (parmnode)) - if (! TREE_PURPOSE (parmnode)) - { - viable = 0; - break; - } - + out: return add_candidate (candidates, fn, convs, viable); } /* Create an overload candidate for the conversion function FN which will be invoked for expression OBJ, producing a pointer-to-function which will in turn be called with the argument list ARGLIST, and add it to - CANDIDATES. FLAGS is passed on to implicit_conversion. */ + CANDIDATES. FLAGS is passed on to implicit_conversion. + + Actually, we don't really care about FN; we care about the type it + converts to. There may be multiple conversion functions that will + convert to that type, and we rely on build_user_type_conversion_1 to + choose the best one; so when we create our candidate, we record the type + instead of the function. */ static struct z_candidate * add_conv_candidate (candidates, fn, obj, arglist) @@ -1213,6 +1202,10 @@ add_conv_candidate (candidates, fn, obj, arglist) int viable = 1; int flags = LOOKUP_NORMAL; + /* Don't bother looking up the same type twice. */ + if (candidates && candidates->fn == totype) + return candidates; + for (i = 0; i < len; ++i) { tree arg = i == 0 ? obj : TREE_VALUE (argnode); @@ -1257,7 +1250,7 @@ add_conv_candidate (candidates, fn, obj, arglist) break; } - return add_candidate (candidates, fn, convs, viable); + return add_candidate (candidates, totype, convs, viable); } static struct z_candidate * @@ -1803,7 +1796,7 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) ; else if (IS_AGGR_TYPE (argtypes[i])) { - tree convs = lookup_conversions (argtypes[i]); + tree convs; if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) return candidates; @@ -1825,11 +1818,11 @@ add_builtin_candidates (candidates, code, code2, fnname, args, flags) for (; convs; convs = TREE_CHAIN (convs)) { - type = TREE_TYPE (TREE_TYPE (TREE_VALUE (convs))); + type = TREE_TYPE (TREE_TYPE (OVL_CURRENT (TREE_VALUE (convs)))); if (i == 0 && ref1 && (TREE_CODE (type) != REFERENCE_TYPE - || TYPE_READONLY (TREE_TYPE (type)))) + || CP_TYPE_CONST_P (TREE_TYPE (type)))) continue; if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE) @@ -1911,7 +1904,7 @@ add_template_candidate_real (candidates, tmpl, explicit_targs, tree fn; i = fn_type_unification (tmpl, explicit_targs, targs, arglist, - return_type, strict, NULL_TREE); + return_type, strict); if (i != 0) return candidates; @@ -2020,7 +2013,7 @@ static void print_z_candidates (candidates) struct z_candidate *candidates; { - char *str = "candidates are:"; + const char *str = "candidates are:"; for (; candidates; candidates = candidates->next) { if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE) @@ -2038,8 +2031,10 @@ print_z_candidates (candidates) cp_error ("%s %D(%T) ", str, candidates->fn, TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0))); } + else if (TYPE_P (candidates->fn)) + cp_error ("%s %T ", str, candidates->fn); else - cp_error_at ("%s %+D%s", str, candidates->fn, + cp_error_at ("%s %+#D%s", str, candidates->fn, candidates->viable == -1 ? " " : ""); str = " "; } @@ -2123,7 +2118,7 @@ build_user_type_conversion_1 (totype, expr, flags) if (TREE_CODE (totype) == REFERENCE_TYPE) convflags |= LOOKUP_NO_TEMP_BIND; - if (TREE_CODE (fns) != TEMPLATE_DECL) + if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL) ics = implicit_conversion (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags); else @@ -2293,6 +2288,8 @@ build_new_function_call (fn, args) for (t1 = fn; t1; t1 = OVL_CHAIN (t1)) { tree t = OVL_FUNCTION (t1); + struct z_candidate *old_candidates = candidates; + if (TREE_CODE (t) == TEMPLATE_DECL) { templates = scratch_tree_cons (NULL_TREE, t, templates); @@ -2303,6 +2300,9 @@ build_new_function_call (fn, args) else if (! template_only) candidates = add_function_candidate (candidates, t, args, LOOKUP_NORMAL); + + if (candidates != old_candidates) + candidates->basetype_path = DECL_REAL_CONTEXT (t); } if (! any_viable (candidates)) @@ -2349,7 +2349,6 @@ build_object_call (obj, args) struct z_candidate *candidates = 0, *cand; tree fns, convs, mem_args = NULL_TREE; tree type = TREE_TYPE (obj); - tree templates = NULL_TREE; if (TYPE_PTRMEMFUNC_P (type)) { @@ -2379,7 +2378,6 @@ build_object_call (obj, args) tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) { - templates = scratch_tree_cons (NULL_TREE, fn, templates); candidates = add_template_candidate (candidates, fn, NULL_TREE, mem_args, NULL_TREE, @@ -2400,16 +2398,15 @@ build_object_call (obj, args) { tree fns = TREE_VALUE (convs); tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))); - tree fn; - if (TREE_CODE (totype) == POINTER_TYPE + if ((TREE_CODE (totype) == POINTER_TYPE + || TREE_CODE (totype) == REFERENCE_TYPE) && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) - for (; fns; fns = OVL_NEXT (fn)) + for (; fns; fns = OVL_NEXT (fns)) { - fn = OVL_CURRENT (fn); + tree fn = OVL_CURRENT (fns); if (TREE_CODE (fn) == TEMPLATE_DECL) { - templates = scratch_tree_cons (NULL_TREE, fn, templates); candidates = add_template_conv_candidate (candidates, fn, obj, @@ -2441,7 +2438,11 @@ build_object_call (obj, args) return error_mark_node; } - if (DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR]) + /* Since cand->fn will be a type, not a function, for a conversion + function, we must be careful not to unconditionally look at + DECL_NAME here. */ + if (TREE_CODE (cand->fn) == FUNCTION_DECL + && DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR]) return build_over_call (cand, mem_args, LOOKUP_NORMAL); obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj); @@ -2454,9 +2455,9 @@ static void op_error (code, code2, arg1, arg2, arg3, problem) enum tree_code code, code2; tree arg1, arg2, arg3; - char *problem; + const char *problem; { - char * opname + const char * opname = (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]); switch (code) @@ -2520,73 +2521,10 @@ build_new_op (code, flags, arg1, arg2, arg3) { case NEW_EXPR: case VEC_NEW_EXPR: - { - tree rval; - - arglist = scratch_tree_cons (NULL_TREE, arg2, arg3); - if (flags & LOOKUP_GLOBAL) - return build_new_function_call - (lookup_function_nonclass (fnname, arglist), arglist); - - /* FIXME */ - rval = build_method_call - (build_indirect_ref (build1 (NOP_EXPR, arg1, error_mark_node), - "new"), - fnname, arglist, NULL_TREE, flags); - if (rval == error_mark_node) - /* User might declare fancy operator new, but invoke it - like standard one. */ - return rval; - - TREE_TYPE (rval) = arg1; - return rval; - } - case VEC_DELETE_EXPR: case DELETE_EXPR: - { - tree rval; - - if (flags & LOOKUP_GLOBAL) - { - arglist = build_scratch_list (NULL_TREE, arg1); - return build_new_function_call - (lookup_function_nonclass (fnname, arglist), arglist); - } - - arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2)); - - arg1 = TREE_TYPE (arg1); - - /* This handles the case where we're trying to delete - X (*a)[10]; - a=new X[5][10]; - delete[] a; */ - - if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE) - { - /* Strip off the pointer and the array. */ - arg1 = TREE_TYPE (TREE_TYPE (arg1)); - - while (TREE_CODE (arg1) == ARRAY_TYPE) - arg1 = (TREE_TYPE (arg1)); - - arg1 = build_pointer_type (arg1); - } - - /* FIXME */ - rval = build_method_call - (build_indirect_ref (build1 (NOP_EXPR, arg1, - error_mark_node), - NULL_PTR), - fnname, arglist, NULL_TREE, flags); -#if 0 - /* This can happen when operator delete is protected. */ - my_friendly_assert (rval != error_mark_node, 250); - TREE_TYPE (rval) = void_type_node; -#endif - return rval; - } + /* Use build_op_new_call and build_op_delete_call instead. */ + my_friendly_abort (981018); case CALL_EXPR: return build_object_call (arg1, arg2); @@ -2798,8 +2736,7 @@ build_new_op (code, flags, arg1, arg2, arg3) case LE_EXPR: case EQ_EXPR: case NE_EXPR: - if (flag_int_enum_equivalence == 0 - && TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE + if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))) @@ -2820,9 +2757,19 @@ build_new_op (code, flags, arg1, arg2, arg3) conv = TREE_OPERAND (conv, 0); arg1 = convert_like (conv, arg1); if (arg2) - arg2 = convert_like (TREE_VEC_ELT (cand->convs, 1), arg2); + { + conv = TREE_VEC_ELT (cand->convs, 1); + if (TREE_CODE (conv) == REF_BIND) + conv = TREE_OPERAND (conv, 0); + arg2 = convert_like (conv, arg2); + } if (arg3) - arg3 = convert_like (TREE_VEC_ELT (cand->convs, 2), arg3); + { + conv = TREE_VEC_ELT (cand->convs, 2); + if (TREE_CODE (conv) == REF_BIND) + conv = TREE_OPERAND (conv, 0); + arg3 = convert_like (conv, arg3); + } builtin: switch (code) @@ -2906,10 +2853,8 @@ build_op_new_call (code, type, args, flags) if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL) && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR)))) { - tree dummy = build1 (NOP_EXPR, build_pointer_type (type), - error_mark_node); - dummy = build_indirect_ref (dummy, "new"); - return build_method_call (dummy, fnname, args, NULL_TREE, flags); + return build_method_call (build_dummy_object (type), + fnname, args, NULL_TREE, flags); } else return build_new_function_call @@ -2988,12 +2933,7 @@ build_op_delete_call (code, addr, size, flags, placement) if (type != TYPE_MAIN_VARIANT (type)) addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr); - /* instantiate_type will always return a plain function; pretend it's - overloaded. */ - if (TREE_CODE (fns) == FUNCTION_DECL) - fns = scratch_ovl_cons (fns, NULL_TREE); - - fn = instantiate_type (fntype, fns, 0); + fn = instantiate_type (fntype, fns, 2); if (fn != error_mark_node) { @@ -3013,11 +2953,11 @@ build_op_delete_call (code, addr, size, flags, placement) tree_cons (NULL_TREE, sizetype, void_list_node)); fntype = build_function_type (void_type_node, argtypes); - fn = instantiate_type (fntype, fns, 0); + fn = instantiate_type (fntype, fns, 2); if (fn != error_mark_node) { - if (TREE_CODE (fns) == TREE_LIST) + if (BASELINK_P (fns)) /* Member functions. */ enforce_access (TREE_PURPOSE (fns), fn); return build_function_call @@ -3036,28 +2976,30 @@ build_op_delete_call (code, addr, size, flags, placement) } /* If the current scope isn't allowed to access DECL along - BASETYPE_PATH, give an error. */ + BASETYPE_PATH, give an error. The most derived class in + BASETYPE_PATH is the one used to qualify DECL. */ -void +int enforce_access (basetype_path, decl) - tree basetype_path, decl; + tree basetype_path; + tree decl; { - tree access = compute_access (basetype_path, decl); + int accessible; - if (access == access_private_node) - { - cp_error_at ("`%+#D' is %s", decl, - TREE_PRIVATE (decl) ? "private" - : "from private base class"); - error ("within this context"); - } - else if (access == access_protected_node) + accessible = accessible_p (basetype_path, decl); + if (!accessible) { - cp_error_at ("`%+#D' %s", decl, - TREE_PROTECTED (decl) ? "is protected" - : "has protected accessibility"); - error ("within this context"); + if (TREE_PRIVATE (decl)) + cp_error_at ("`%+#D' is private", decl); + else if (TREE_PROTECTED (decl)) + cp_error_at ("`%+#D' is protected", decl); + else + cp_error_at ("`%+#D' is inaccessible", decl); + cp_error ("within this context"); + return 0; } + + return 1; } /* Perform the conversions in CONVS on the expression EXPR. */ @@ -3156,7 +3098,7 @@ convert_like (convs, expr) destination type takes a pointer argument. */ if (TYPE_SIZE (TREE_TYPE (expr)) == 0) { - if (comptypes (TREE_TYPE (expr), TREE_TYPE (convs), 1)) + if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs))) incomplete_type_error (expr, TREE_TYPE (expr)); else cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'", @@ -3178,6 +3120,11 @@ convert_like (convs, expr) case LVALUE_CONV: return decay_conversion (expr); + case QUAL_CONV: + /* Warn about deprecated conversion if appropriate. */ + string_conv_p (TREE_TYPE (convs), expr, 1); + break; + default: break; } @@ -3205,17 +3152,47 @@ convert_arg_to_ellipsis (arg) /* Convert `short' and `char' to full-size `int'. */ arg = default_conversion (arg); + arg = require_complete_type (arg); + return arg; } /* ARG is a default argument expression being passed to a parameter of - the indicated TYPE. Do any required conversions. Return the - converted value. */ + the indicated TYPE, which is a parameter to FN. Do any required + conversions. Return the converted value. */ tree -convert_default_arg (type, arg) - tree type, arg; +convert_default_arg (type, arg, fn) + tree type; + tree arg; + tree fn; { + if (fn && DECL_TEMPLATE_INFO (fn)) + { + /* This default argument came from a template. Instantiate the + default argument here, not in tsubst. In the case of + something like: + + template + struct S { + static T t(); + void f(T = t()); + }; + + we must be careful to do name lookup in the scope of S, + rather than in the current class. */ + if (DECL_CLASS_SCOPE_P (fn)) + pushclass (DECL_REAL_CONTEXT (fn), 2); + + arg = tsubst_expr (arg, DECL_TI_ARGS (fn), /*complain=*/1, NULL_TREE); + + if (DECL_CLASS_SCOPE_P (fn)) + popclass (); + + /* Make sure the default argument is reasonable. */ + arg = check_default_argument (type, arg); + } + arg = break_out_target_exprs (arg); if (TREE_CODE (arg) == CONSTRUCTOR) @@ -3289,21 +3266,23 @@ build_over_call (cand, args, flags) { tree parmtype = TREE_VALUE (parm); tree argtype = TREE_TYPE (TREE_VALUE (arg)); + tree t; if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i))) - { - int dv = (TYPE_VOLATILE (TREE_TYPE (parmtype)) - < TYPE_VOLATILE (TREE_TYPE (argtype))); - int dc = (TYPE_READONLY (TREE_TYPE (parmtype)) - < TYPE_READONLY (TREE_TYPE (argtype))); - char *p = (dv && dc ? "const and volatile" - : dc ? "const" : dv ? "volatile" : ""); - - cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards %s", - TREE_TYPE (argtype), fn, p); - } - converted_args = expr_tree_cons - (NULL_TREE, convert_force (TREE_VALUE (parm), TREE_VALUE (arg), CONV_C_CAST), - converted_args); + cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers", + TREE_TYPE (argtype), fn); + + /* [class.mfct.nonstatic]: If a nonstatic member function of a class + X is called for an object that is not of type X, or of a type + derived from X, the behavior is undefined. + + So we can assume that anything passed as 'this' is non-null, and + optimize accordingly. */ + if (TREE_CODE (parmtype) == POINTER_TYPE) + t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg)); + else + /* This happens with signatures. */ + t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST); + converted_args = expr_tree_cons (NULL_TREE, t, converted_args); parm = TREE_CHAIN (parm); arg = TREE_CHAIN (arg); ++i; @@ -3337,7 +3316,14 @@ build_over_call (cand, args, flags) "argument passing", fn, i - is_method); } else - val = convert_like (conv, TREE_VALUE (arg)); + { + /* Issue warnings about peculiar, but legal, uses of NULL. */ + if (ARITHMETIC_TYPE_P (TREE_VALUE (parm)) + && TREE_VALUE (arg) == null_node) + cp_warning ("converting NULL to non-pointer type"); + + val = convert_like (conv, TREE_VALUE (arg)); + } #ifdef PROMOTE_PROTOTYPES if ((TREE_CODE (type) == INTEGER_TYPE @@ -3350,34 +3336,12 @@ build_over_call (cand, args, flags) /* Default arguments */ for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm)) - { - tree arg = TREE_PURPOSE (parm); - - if (DECL_TEMPLATE_INFO (fn)) - { - /* This came from a template. Instantiate the default arg here, - not in tsubst. In the case of something like: - - template - struct S { - static T t(); - void f(T = t()); - }; - - we must be careful to do name lookup in the scope of - S, rather than in the current class. */ - if (DECL_CLASS_SCOPE_P (fn)) - pushclass (DECL_REAL_CONTEXT (fn), 2); - - arg = tsubst_expr (arg, DECL_TI_ARGS (fn), NULL_TREE); - - if (DECL_CLASS_SCOPE_P (fn)) - popclass (1); - } - converted_args = expr_tree_cons - (NULL_TREE, convert_default_arg (TREE_VALUE (parm), arg), - converted_args); - } + converted_args + = expr_tree_cons (NULL_TREE, + convert_default_arg (TREE_VALUE (parm), + TREE_PURPOSE (parm), + fn), + converted_args); /* Ellipsis */ for (; arg; arg = TREE_CHAIN (arg)) @@ -3388,10 +3352,17 @@ build_over_call (cand, args, flags) converted_args = nreverse (converted_args); + if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn))) + check_function_format (DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn), + converted_args); + /* Avoid actually calling copy constructors and copy assignment operators, if possible. */ - if (DECL_CONSTRUCTOR_P (fn) - && TREE_VEC_LENGTH (convs) == 1 + + if (! flag_elide_constructors) + /* Do things the hard way. */; + else if (DECL_CONSTRUCTOR_P (fn) + && TREE_VEC_LENGTH (convs) == 1 && copy_args_p (fn)) { tree targ; @@ -3409,8 +3380,8 @@ build_over_call (cand, args, flags) if (TREE_CODE (targ) == ADDR_EXPR) { targ = TREE_OPERAND (targ, 0); - if (! comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), - TYPE_MAIN_VARIANT (TREE_TYPE (targ)), 1)) + if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), + TYPE_MAIN_VARIANT (TREE_TYPE (targ)))) targ = NULL_TREE; } else @@ -3437,8 +3408,7 @@ build_over_call (cand, args, flags) return arg; else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) { - val = build (VAR_DECL, DECL_CONTEXT (fn)); - layout_decl (val, 0); + val = build_decl (VAR_DECL, NULL_TREE, DECL_CONTEXT (fn)); val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0); TREE_SIDE_EFFECTS (val) = 1; return val; @@ -3447,20 +3417,34 @@ build_over_call (cand, args, flags) else if (! real_lvalue_p (arg) || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) { + tree address; tree to = stabilize_reference (build_indirect_ref (TREE_VALUE (args), 0)); - /* Don't copy the padding byte; it might not have been allocated - if to is a base subobject. */ - if (is_empty_class (DECL_CLASS_CONTEXT (fn))) - return build_unary_op - (ADDR_EXPR, build (COMPOUND_EXPR, TREE_TYPE (to), - cp_convert (void_type_node, arg), to), - 0); - - val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg); + /* If we're initializing an empty class, then we actually + have to use a MODIFY_EXPR rather than an INIT_EXPR. The + reason is that the dummy padding member in the target may + not actually be allocated if TO is a base class + subobject. Since we've set TYPE_NONCOPIED_PARTS on the + padding, a MODIFY_EXPR will preserve its value, which is + the right thing to do if it's not really padding at all. + + It's not safe to just throw away the ARG if we're looking + at an empty class because the ARG might contain a + TARGET_EXPR which wants to be bound to TO. If it is not, + expand_expr will assign a dummy slot for the TARGET_EXPR, + and we will call a destructor for it, which is wrong, + because we will also destroy TO, but will never have + constructed it. */ + val = build (is_empty_class (DECL_CLASS_CONTEXT (fn)) + ? MODIFY_EXPR : INIT_EXPR, + DECL_CONTEXT (fn), to, arg); TREE_SIDE_EFFECTS (val) = 1; - return build_unary_op (ADDR_EXPR, val, 0); + 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; } } else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR] @@ -3472,12 +3456,6 @@ build_over_call (cand, args, flags) arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0); - /* Don't copy the padding byte; it might not have been allocated - if to is a base subobject. */ - if (is_empty_class (DECL_CLASS_CONTEXT (fn))) - return build (COMPOUND_EXPR, TREE_TYPE (to), - cp_convert (void_type_node, arg), to); - val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg); TREE_SIDE_EFFECTS (val) = 1; return val; @@ -3524,7 +3502,7 @@ build_over_call (cand, args, flags) } fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args); - if (TREE_TYPE (fn) == void_type_node) + if (TREE_CODE (TREE_TYPE (fn)) == VOID_TYPE) return fn; fn = require_complete_type (fn); if (IS_AGGR_TYPE (TREE_TYPE (fn))) @@ -3549,8 +3527,16 @@ build_new_method_call (instance, name, args, basetype_path, flags) { explicit_targs = TREE_OPERAND (name, 1); name = TREE_OPERAND (name, 0); - if (TREE_CODE (name) == TEMPLATE_DECL) + if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd') name = DECL_NAME (name); + else + { + if (TREE_CODE (name) == COMPONENT_REF) + name = TREE_OPERAND (name, 1); + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (OVL_CURRENT (name)); + } + template_only = 1; } @@ -3572,7 +3558,7 @@ build_new_method_call (instance, name, args, basetype_path, flags) instance = resolve_offset_ref (instance); if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) instance = convert_from_reference (instance); - basetype = TREE_TYPE (instance); + basetype = TYPE_MAIN_VARIANT (TREE_TYPE (instance)); /* XXX this should be handled before we get here. */ if (! IS_AGGR_TYPE (basetype) @@ -3672,8 +3658,12 @@ build_new_method_call (instance, name, args, basetype_path, flags) /* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */ if (flags & LOOKUP_SPECULATIVELY) return NULL_TREE; - cp_error ("no matching function for call to `%T::%D (%A)%V'", basetype, - pretty_name, user_args, TREE_TYPE (TREE_TYPE (instance_ptr))); + if (TYPE_SIZE (basetype) == 0) + incomplete_type_error (instance_ptr, basetype); + else + cp_error ("no matching function for call to `%T::%D (%A)%V'", + basetype, pretty_name, user_args, + TREE_TYPE (TREE_TYPE (instance_ptr))); print_z_candidates (candidates); return error_mark_node; } @@ -3692,12 +3682,14 @@ build_new_method_call (instance, name, args, basetype_path, flags) && instance == current_class_ref && DECL_CONSTRUCTOR_P (current_function_decl) && ! (flags & LOOKUP_NONVIRTUAL) - && value_member (cand->fn, get_abstract_virtuals (basetype))) + && value_member (cand->fn, CLASSTYPE_ABSTRACT_VIRTUALS (basetype))) cp_error ("abstract virtual `%#D' called from constructor", cand->fn); if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE - && TREE_CODE (instance_ptr) == NOP_EXPR - && TREE_OPERAND (instance_ptr, 0) == error_mark_node) - cp_error ("cannot call member function `%D' without object", cand->fn); + && is_dummy_object (instance_ptr)) + { + cp_error ("cannot call member function `%D' without object", cand->fn); + return error_mark_node; + } if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL) && ((instance == current_class_ref && (dtor_label || ctor_label)) @@ -3750,9 +3742,9 @@ is_subseq (ics1, ics2) ics2 = TREE_OPERAND (ics2, 0); if (TREE_CODE (ics2) == TREE_CODE (ics1) - && comptypes (TREE_TYPE (ics2), TREE_TYPE (ics1), 1) - && comptypes (TREE_TYPE (TREE_OPERAND (ics2, 0)), - TREE_TYPE (TREE_OPERAND (ics1, 0)), 1)) + && 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; } } @@ -3760,7 +3752,7 @@ is_subseq (ics1, ics2) /* Returns non-zero iff DERIVED is derived from BASE. The inputs may be any _TYPE nodes. */ -static int +int is_properly_derived_from (derived, base) tree derived; tree base; @@ -3771,8 +3763,8 @@ is_properly_derived_from (derived, base) /* We only allow proper derivation here. The DERIVED_FROM_P macro considers every class derived from itself. */ - return (!comptypes (TYPE_MAIN_VARIANT (derived), - TYPE_MAIN_VARIANT (base), 1) + return (!same_type_p (TYPE_MAIN_VARIANT (derived), + TYPE_MAIN_VARIANT (base)) && DERIVED_FROM_P (base, derived)); } @@ -3879,9 +3871,9 @@ compare_ics (ics1, ics2) tree to_type1; tree to_type2; tree deref_from_type1 = NULL_TREE; - tree deref_from_type2; - tree deref_to_type1; - tree deref_to_type2; + tree deref_from_type2 = NULL_TREE; + tree deref_to_type1 = NULL_TREE; + tree deref_to_type2 = NULL_TREE; /* REF_BINDING is non-zero if the result of the conversion sequence is a reference type. In that case TARGET_TYPE is the @@ -3985,7 +3977,7 @@ compare_ics (ics1, ics2) from_type2 = TREE_TYPE (from_type2); } - if (comptypes (from_type1, from_type2, 1)) + if (same_type_p (from_type1, from_type2)) { if (is_subseq (ics1, ics2)) return 1; @@ -4085,7 +4077,7 @@ compare_ics (ics1, ics2) else if (TREE_CODE (deref_to_type1) == VOID_TYPE || TREE_CODE (deref_to_type2) == VOID_TYPE) { - if (comptypes (deref_from_type1, deref_from_type2, 1)) + if (same_type_p (deref_from_type1, deref_from_type2)) { if (TREE_CODE (deref_to_type2) == VOID_TYPE) { @@ -4112,7 +4104,7 @@ compare_ics (ics1, ics2) --conversion of B* to A* is better than conversion of C* to A* */ - if (comptypes (deref_from_type1, deref_from_type2, 1)) + if (same_type_p (deref_from_type1, deref_from_type2)) { if (is_properly_derived_from (deref_to_type1, deref_to_type2)) @@ -4121,7 +4113,7 @@ compare_ics (ics1, ics2) deref_to_type1)) return -1; } - else if (comptypes (deref_to_type1, deref_to_type2, 1)) + else if (same_type_p (deref_to_type1, deref_to_type2)) { if (is_properly_derived_from (deref_from_type2, deref_from_type1)) @@ -4133,7 +4125,7 @@ compare_ics (ics1, ics2) } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1)) - && comptypes (from_type1, from_type2, 1)) + && same_type_p (from_type1, from_type2)) { /* [over.ics.rank] @@ -4152,7 +4144,7 @@ compare_ics (ics1, ics2) } } else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1)) - && comptypes (to_type1, to_type2, 1)) + && same_type_p (to_type1, to_type2)) { /* [over.ics.rank] @@ -4179,7 +4171,7 @@ compare_ics (ics1, ics2) qualification signature of type T2 */ if (TREE_CODE (ics1) == QUAL_CONV && TREE_CODE (ics2) == QUAL_CONV - && comptypes (from_type1, from_type2, 1)) + && same_type_p (from_type1, from_type2)) return comp_cv_qual_signature (to_type1, to_type2); /* [over.ics.rank] @@ -4191,8 +4183,8 @@ compare_ics (ics1, ics2) which the reference initialized by S1 refers */ if (ref_binding1 && ref_binding2 - && comptypes (TYPE_MAIN_VARIANT (to_type1), - TYPE_MAIN_VARIANT (to_type2), 1)) + && same_type_p (TYPE_MAIN_VARIANT (to_type1), + TYPE_MAIN_VARIANT (to_type2))) return comp_cv_qualification (target_type2, target_type1); /* Neither conversion sequence is better than the other. */ @@ -4250,6 +4242,11 @@ joust (cand1, cand2, warn) if (cand1->viable < cand2->viable) return -1; + /* If we have two pseudo-candidates for conversions to the same type, + arbitrarily pick one. */ + if (TYPE_P (cand1->fn) && cand1->fn == cand2->fn) + return 1; + /* a viable function F1 is defined to be a better function than another viable function F2 if for all arguments i, ICSi(F1) is not a worse conversion sequence than @@ -4335,8 +4332,8 @@ joust (cand1, cand2, warn) != DECL_CONSTRUCTOR_P (cand2->fn)) /* Don't warn if the two conv ops convert to the same type... */ || (! DECL_CONSTRUCTOR_P (cand1->fn) - && ! comptypes (TREE_TYPE (cand1->second_conv), - TREE_TYPE (cand2->second_conv), 1)))) + && ! 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) @@ -4392,8 +4389,8 @@ joust (cand1, cand2, warn) && TREE_CODE (cand1->fn) == IDENTIFIER_NODE) { for (i = 0; i < len; ++i) - if (! comptypes (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), - TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)), 1)) + if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), + TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)))) break; if (i == TREE_VEC_LENGTH (cand1->convs)) return 1; @@ -4408,7 +4405,7 @@ joust (cand1, cand2, warn) tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1))); tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2))); - if (comptypes (t1, t2, 1)) + if (same_type_p (t1, t2)) { if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND) return 1; diff --git a/contrib/gcc/cp/class.c b/contrib/gcc/cp/class.c index 8a61bf8..400c67d 100644 --- a/contrib/gcc/cp/class.c +++ b/contrib/gcc/cp/class.c @@ -1,5 +1,5 @@ /* Functions related to building classes and their related objects. - Copyright (C) 1987, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -30,66 +30,71 @@ Boston, MA 02111-1307, USA. */ #include "rtl.h" #include "output.h" #include "toplev.h" +#include "splay-tree.h" #include "obstack.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free -extern struct obstack permanent_obstack; - /* This is how we tell when two virtual member functions are really the same. */ #define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL)) extern void set_class_shadows PROTO ((tree)); -/* Way of stacking class types. */ -static tree *current_class_base, *current_class_stack; -static int current_class_stacksize; +/* The number of nested classes being processed. If we are not in the + scope of any class, this is zero. */ + int current_class_depth; -struct class_level -{ - /* The previous class level. */ - struct class_level *level_chain; - - /* The class instance variable, as a PARM_DECL. */ - tree decl; - /* The class instance variable, as an object. */ - tree object; - /* The virtual function table pointer - for the class instance variable. */ - tree vtable_decl; - - /* Name of the current class. */ +/* In order to deal with nested classes, we keep a stack of classes. + The topmost entry is the innermost class, and is the entry at index + CURRENT_CLASS_DEPTH */ + +typedef struct class_stack_node { + /* The name of the class. */ tree name; - /* Type of the current class. */ + + /* The _TYPE node for the class. */ tree type; - /* Flags for this class level. */ - int this_is_variable; - int memoized_lookups; - int save_memoized; - int unused; -}; + /* The access specifier pending for new declarations in the scope of + this class. */ + tree access; + + /* If were defining TYPE, the names used in this class. */ + splay_tree names_used; +}* class_stack_node_t; -/* The current_class_ptr is the pointer to the current class. - current_class_ref is the actual current class. */ +/* The stack itself. This is an 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; + +/* When we're processing a member function, current_class_ptr is the + PARM_DECL for the `this' pointer. The current_class_ref is an + expression for `*this'. */ tree current_class_ptr, current_class_ref; /* The following two can be derived from the previous one */ tree current_class_name; /* IDENTIFIER_NODE: name of current class */ tree current_class_type; /* _TYPE: the type of the current class */ +tree current_access_specifier; tree previous_class_type; /* _TYPE: the previous type that was a class */ -tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list +tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list when leaving an outermost class scope. */ +/* The obstack on which the cached class declarations are kept. */ +static struct obstack class_cache_obstack; +/* The first object allocated on that obstack. We can use + obstack_free with tis value to free the entire obstack. */ +char *class_cache_firstobj; + struct base_info; static tree get_vfield_name PROTO((tree)); static void finish_struct_anon PROTO((tree)); static tree build_vbase_pointer PROTO((tree, tree)); -static int complete_type_p PROTO((tree)); static tree build_vtable_entry PROTO((tree, tree)); static tree get_vtable_name PROTO((tree)); static tree get_derived_offset PROTO((tree, tree)); @@ -99,7 +104,6 @@ static tree build_vtable PROTO((tree, tree)); static void prepare_fresh_vtable PROTO((tree, tree)); static void fixup_vtable_deltas1 PROTO((tree, tree)); static void fixup_vtable_deltas PROTO((tree, int, tree)); -static void grow_method PROTO((tree, tree *)); static void finish_vtbls PROTO((tree, int, tree)); static void modify_vtable_entry PROTO((tree, tree, tree)); static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT)); @@ -115,7 +119,6 @@ static void merge_overrides PROTO((tree, tree, int, tree)); static void override_one_vtable PROTO((tree, tree, tree)); static void mark_overriders PROTO((tree, tree)); static void check_for_override PROTO((tree, tree)); -static tree maybe_fixup_vptrs PROTO((tree, tree, tree)); static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree)); static tree get_class_offset PROTO((tree, tree, tree, tree)); static void modify_one_vtable PROTO((tree, tree, tree, tree)); @@ -124,8 +127,16 @@ static void modify_all_direct_vtables PROTO((tree, int, tree, tree, tree)); static void modify_all_indirect_vtables PROTO((tree, int, int, tree, tree, tree)); -static void build_class_init_list PROTO((tree)); static int finish_base_struct PROTO((tree, struct base_info *)); +static void finish_struct_methods PROTO((tree)); +static void maybe_warn_about_overly_private_class PROTO ((tree)); +static tree make_method_vec PROTO((int)); +static void free_method_vec PROTO((tree)); +static tree add_implicitly_declared_members PROTO((tree, int, int, int)); +static tree fixed_type_or_null PROTO((tree, int *)); +static tree resolve_address_of_overloaded_function PROTO((tree, tree, int, + int, tree)); +static void build_vtable_entry_ref PROTO((tree, tree, tree)); /* Way of stacking language names. */ tree *current_lang_base, *current_lang_stack; @@ -170,12 +181,12 @@ build_vbase_pointer (exp, type) tree exp, type; { char *name; + FORMAT_VBASE_NAME (name, type); - name = (char *) alloca (TYPE_NAME_LENGTH (type) + sizeof (VBASE_NAME) + 1); - sprintf (name, VBASE_NAME_FORMAT, TYPE_NAME_STRING (type)); return build_component_ref (exp, get_identifier (name), NULL_TREE, 0); } +#if 0 /* Is the type of the EXPR, the complete type of the object? If we are going to be wrong, we must be conservative, and return 0. */ @@ -221,6 +232,7 @@ complete_type_p (expr) } return 0; } +#endif /* Build multi-level access to EXPR using hierarchy path PATH. CODE is PLUS_EXPR if we are going with the grain, @@ -229,17 +241,17 @@ complete_type_p (expr) TYPE is the type we want this path to have on exit. - ALIAS_THIS is non-zero if EXPR in an expression involving `this'. */ + NONNULL is non-zero if we know (for any reason) that EXPR is + not, in fact, zero. */ tree -build_vbase_path (code, type, expr, path, alias_this) +build_vbase_path (code, type, expr, path, nonnull) enum tree_code code; tree type, expr, path; - int alias_this; + int nonnull; { register int changed = 0; tree last = NULL_TREE, last_virtual = NULL_TREE; - int nonnull = 0; int fixed_type_p; tree null_expr = 0, nonnull_expr; tree basetype; @@ -248,40 +260,23 @@ build_vbase_path (code, type, expr, path, alias_this) if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE) return build1 (NOP_EXPR, type, expr); - if (nonnull == 0 && (alias_this && flag_this_is_variable <= 0)) - nonnull = 1; + /* If -fthis-is-variable, we might have set nonnull incorrectly. We + don't care enough to get this right, so just clear it. */ + if (flag_this_is_variable > 0) + nonnull = 0; -#if 0 - /* We need additional logic to convert back to the unconverted type - (the static type of the complete object), and then convert back - to the type we want. Until that is done, or until we can - recognize when that is, we cannot do the short cut logic. (mrs) */ + /* We could do better if we had additional logic to convert back to the + unconverted type (the static type of the complete object), and then + convert back to the type we want. Until that is done, we only optimize + if the complete type is the same type as expr has. */ fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); -#else - /* Do this, until we can undo any previous conversions. See net35.C - for a testcase. */ - fixed_type_p = complete_type_p (expr); -#endif if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) expr = save_expr (expr); nonnull_expr = expr; if (BINFO_INHERITANCE_CHAIN (path)) - { - tree reverse_path = NULL_TREE; - - push_expression_obstack (); - while (path) - { - tree r = copy_node (path); - BINFO_INHERITANCE_CHAIN (r) = reverse_path; - reverse_path = r; - path = BINFO_INHERITANCE_CHAIN (path); - } - path = reverse_path; - pop_obstacks (); - } + path = reverse_path (path); basetype = BINFO_TYPE (path); @@ -308,8 +303,7 @@ build_vbase_path (code, type, expr, path, alias_this) ind = build_indirect_ref (nonnull_expr, NULL_PTR); nonnull_expr = build_vbase_pointer (ind, last_virtual); if (nonnull == 0 - && (TREE_CODE (type) == POINTER_TYPE - || !flag_assume_nonnull_objects) + && TREE_CODE (type) == POINTER_TYPE && null_expr == NULL_TREE) { null_expr = build1 (NOP_EXPR, build_pointer_type (last_virtual), integer_zero_node); @@ -382,12 +376,7 @@ build_vbase_path (code, type, expr, path, alias_this) expr = build1 (NOP_EXPR, type, expr); #endif - /* For multiple inheritance: if `this' can be set by any - function, then it could be 0 on entry to any function. - Preserve such zeroness here. Otherwise, only in the - case of constructors need we worry, and in those cases, - it will be zero, or initialized to some valid value to - which we may add. */ + /* If expr might be 0, we need to preserve that zeroness. */ if (nonnull == 0) { if (null_expr) @@ -475,6 +464,36 @@ build_vtable_entry (delta, pfn) } } +/* We want to give the assembler the vtable identifier as well as + the offset to the function pointer. So we generate + + __asm__ __volatile__ (".vtable_entry %c0, %c1" + : : "s"(&class_vtable), + "i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */ + +static void +build_vtable_entry_ref (basetype, vtbl, idx) + tree basetype, vtbl, idx; +{ + static char asm_stmt[] = ".vtable_entry %c0, %c1"; + tree s, i, i2; + + s = build_unary_op (ADDR_EXPR, TYPE_BINFO_VTABLE (basetype), 0); + s = build_tree_list (build_string (1, "s"), s); + + i = build_array_ref (vtbl, idx); + if (!flag_vtable_thunks) + i = build_component_ref (i, pfn_identifier, vtable_entry_type, 0); + i = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i, 0)); + i2 = build_array_ref (vtbl, build_int_2(0,0)); + i2 = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i2, 0)); + i = build_binary_op (MINUS_EXPR, i, i2); + i = build_tree_list (build_string (1, "i"), i); + + expand_asm_operands (build_string (sizeof(asm_stmt)-1, asm_stmt), + NULL_TREE, chainon (s, i), NULL_TREE, 1, NULL, 0); +} + /* Given an object INSTANCE, return an expression which yields the virtual function vtable element corresponding to INDEX. There are many special cases for INSTANCE which we take care of here, mainly @@ -491,8 +510,7 @@ build_vtbl_ref (instance, idx) basetype = TREE_TYPE (basetype); if (instance == current_class_ref) - vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), - NULL_PTR); + vtbl = build_vfield_ref (instance, basetype); else { if (optimize) @@ -532,10 +550,14 @@ build_vtbl_ref (instance, idx) || TREE_CODE (instance) == VAR_DECL)) vtbl = TYPE_BINFO_VTABLE (basetype); else - vtbl = build_indirect_ref (build_vfield_ref (instance, basetype), - NULL_PTR); + vtbl = build_vfield_ref (instance, basetype); } + assemble_external (vtbl); + + if (flag_vtable_gc) + build_vtable_entry_ref (basetype, vtbl, idx); + aref = build_array_ref (vtbl, idx); return aref; @@ -585,7 +607,7 @@ get_vtable_name (type) tree type_id = build_typename_overload (type); char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + IDENTIFIER_LENGTH (type_id) + 2); - char *ptr = IDENTIFIER_POINTER (type_id); + const char *ptr = IDENTIFIER_POINTER (type_id); int i; for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; #if 0 @@ -647,6 +669,9 @@ set_rtti_entry (virtuals, offset, type) { tree vfn; + if (CLASSTYPE_COM_INTERFACE (type)) + return; + if (flag_rtti) vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type)); else @@ -685,7 +710,7 @@ build_vtable (binfo, type) tree offset; virtuals = copy_list (BINFO_VIRTUALS (binfo)); - decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo))); + decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo))); /* Now do rtti stuff. */ offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); @@ -695,7 +720,7 @@ build_vtable (binfo, type) else { virtuals = NULL_TREE; - decl = build_decl (VAR_DECL, name, void_type_node); + decl = build_lang_decl (VAR_DECL, name, void_type_node); } #ifdef GATHER_STATISTICS @@ -724,9 +749,7 @@ build_vtable (binfo, type) DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), DECL_ALIGN (decl)); - /* Why is this conditional? (mrs) */ - if (binfo && write_virtuals >= 0) - DECL_VIRTUAL_P (decl) = 1; + DECL_VIRTUAL_P (decl) = 1; DECL_CONTEXT (decl) = type; binfo = TYPE_BINFO (type); @@ -847,7 +870,7 @@ prepare_fresh_vtable (binfo, for_type) buf2 = new_buf2; } - new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); + new_decl = build_lang_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); /* Remember which class this vtable is really for. */ DECL_CONTEXT (new_decl) = for_type; @@ -1013,10 +1036,14 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) CLASSTYPE_RTTI (t) = t; /* If we are using thunks, use two slots at the front, one - for the offset pointer, one for the tdesc pointer. */ - if (*has_virtual == 0 && flag_vtable_thunks) + for the offset pointer, one for the tdesc pointer. + For ARM-style vtables, use the same slot for both. */ + if (*has_virtual == 0 && ! CLASSTYPE_COM_INTERFACE (t)) { - *has_virtual = 1; + if (flag_vtable_thunks) + *has_virtual = 2; + else + *has_virtual = 1; } /* Build a new INT_CST for this DECL_VINDEX. */ @@ -1024,7 +1051,7 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) static tree index_table[256]; tree idx; /* We skip a slot for the offset/tdesc entry. */ - int i = ++(*has_virtual); + int i = (*has_virtual)++; if (i >= 256 || index_table[i] == 0) { @@ -1058,122 +1085,230 @@ add_virtual_function (pv, phv, has_virtual, fndecl, t) struct obstack class_obstack; extern struct obstack *current_obstack; -/* Add method METHOD to class TYPE. This is used when a method - has been defined which did not initially appear in the class definition, - and helps cut down on spurious error messages. +/* These are method vectors that were too small for the number of + methods in some class, and so were abandoned. */ +static tree free_method_vecs; + +/* Returns a method vector with enough room for N methods. N should + be a power of two. */ + +static tree +make_method_vec (n) + int n; +{ + tree new_vec; + tree* t; + + for (t = &free_method_vecs; *t; t = &(TREE_CHAIN (*t))) + /* Note that we don't use >= n here because we don't want to + allocate a very large vector where it isn't needed. */ + if (TREE_VEC_LENGTH (*t) == n) + { + new_vec = *t; + *t = TREE_CHAIN (new_vec); + TREE_CHAIN (new_vec) = NULL_TREE; + bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree)); + return new_vec; + } + + new_vec = make_tree_vec (n); + return new_vec; +} + +/* Free the method vector VEC. */ + +static void +free_method_vec (vec) + tree vec; +{ + TREE_CHAIN (vec) = free_method_vecs; + free_method_vecs = vec; +} + +/* Add method METHOD to class TYPE. - FIELDS is the entry in the METHOD_VEC vector entry of the class type where - the method should be added. */ + If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of + the class type where the method should be added. */ void add_method (type, fields, method) tree type, *fields, method; { - push_obstacks (&permanent_obstack, &permanent_obstack); + push_obstacks_nochange (); + end_temporary_allocation (); + /* Setting the DECL_CONTEXT and DECL_CLASS_CONTEXT here is probably + redundant. */ + DECL_CONTEXT (method) = type; + DECL_CLASS_CONTEXT (method) = type; + if (fields && *fields) - *fields = build_overload (method, *fields); - else if (CLASSTYPE_METHOD_VEC (type) == 0) - { - tree method_vec = make_node (TREE_VEC); - if (TYPE_IDENTIFIER (type) == DECL_NAME (method)) - { - /* ??? Is it possible for there to have been enough room in the - current chunk for the tree_vec structure but not a tree_vec - plus a tree*? Will this work in that case? */ - obstack_free (current_obstack, method_vec); - obstack_blank (current_obstack, sizeof (struct tree_vec) + sizeof (tree *)); - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method))) - TREE_VEC_ELT (method_vec, 1) = method; - else - TREE_VEC_ELT (method_vec, 0) = method; - TREE_VEC_LENGTH (method_vec) = 2; - } - else - { - /* ??? Is it possible for there to have been enough room in the - current chunk for the tree_vec structure but not a tree_vec - plus a tree*? Will this work in that case? */ - obstack_free (current_obstack, method_vec); - obstack_blank (current_obstack, sizeof (struct tree_vec) + 2*sizeof (tree *)); - TREE_VEC_ELT (method_vec, 2) = method; - TREE_VEC_LENGTH (method_vec) = 3; - obstack_finish (current_obstack); - } - CLASSTYPE_METHOD_VEC (type) = method_vec; - } - else - { - tree method_vec = CLASSTYPE_METHOD_VEC (type); - int len = TREE_VEC_LENGTH (method_vec); - - /* Adding a new ctor or dtor. This is easy because our - METHOD_VEC always has a slot for such entries. */ - if (TYPE_IDENTIFIER (type) == DECL_NAME (method)) - { - int idx = !!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)); - /* TREE_VEC_ELT (method_vec, idx) = method; */ - if (method != TREE_VEC_ELT (method_vec, idx)) - TREE_VEC_ELT (method_vec, idx) = - build_overload (method, TREE_VEC_ELT (method_vec, idx)); - } + *fields = build_overload (method, *fields); + else + { + int len; + int slot; + tree method_vec; + + if (!CLASSTYPE_METHOD_VEC (type)) + /* Make a new method vector. We start with 8 entries. We must + allocate at least two (for constructors and destructors), and + we're going to end up with an assignment operator at some + point as well. + + We could use a TREE_LIST for now, and convert it to a + TREE_VEC in finish_struct, but we would probably waste more + memory making the links in the list than we would by + over-allocating the size of the vector here. Furthermore, + we would complicate all the code that expects this to be a + vector. We keep a free list of vectors that we outgrew so + that we don't really waste any memory. */ + CLASSTYPE_METHOD_VEC (type) = make_method_vec (8); + + method_vec = CLASSTYPE_METHOD_VEC (type); + len = TREE_VEC_LENGTH (method_vec); + + if (DECL_NAME (method) == constructor_name (type)) + /* A new constructor or destructor. Constructors go in + slot 0; destructors go in slot 1. */ + slot = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0; else { - /* This is trickier. We try to extend the TREE_VEC in-place, - but if that does not work, we copy all its data to a new - TREE_VEC that's large enough. */ - struct obstack *ob = &class_obstack; - tree *end = (tree *)obstack_next_free (ob); - - if (end != TREE_VEC_END (method_vec)) + /* See if we already have an entry with this name. */ + for (slot = 2; slot < len; ++slot) + if (!TREE_VEC_ELT (method_vec, slot) + || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, + slot))) + == DECL_NAME (method))) + break; + + if (slot == len) { - ob = current_obstack; - TREE_VEC_LENGTH (method_vec) += 1; - TREE_VEC_ELT (method_vec, len) = NULL_TREE; - method_vec = copy_node (method_vec); - TREE_VEC_LENGTH (method_vec) -= 1; + /* We need a bigger method vector. */ + tree new_vec = make_method_vec (2 * len); + bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0), + (PTR) &TREE_VEC_ELT (new_vec, 0), + len * sizeof (tree)); + free_method_vec (method_vec); + len = 2 * len; + method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec; } - else + + if (DECL_CONV_FN_P (method) && !TREE_VEC_ELT (method_vec, slot)) { - tree tmp_vec = (tree) obstack_base (ob); - if (obstack_room (ob) < sizeof (tree)) + /* Type conversion operators have to come before + ordinary methods; add_conversions depends on this to + speed up looking for conversion operators. So, if + necessary, we slide some of the vector elements up. + In theory, this makes this algorithm O(N^2) but we + don't expect many conversion operators. */ + for (slot = 2; slot < len; ++slot) { - obstack_blank (ob, sizeof (struct tree_common) - + tree_code_length[(int) TREE_VEC] - * sizeof (char *) - + len * sizeof (tree)); - tmp_vec = (tree) obstack_base (ob); - bcopy ((char *) method_vec, (char *) tmp_vec, - (sizeof (struct tree_common) - + tree_code_length[(int) TREE_VEC] * sizeof (char *) - + (len-1) * sizeof (tree))); - method_vec = tmp_vec; + tree fn = TREE_VEC_ELT (method_vec, slot); + + if (!fn) + /* There are no more entries in the vector, so we + can insert the new conversion operator here. */ + break; + + if (!DECL_CONV_FN_P (OVL_CURRENT (fn))) + /* We can insert the new function right at the + SLOTth position. */ + break; } + + if (!TREE_VEC_ELT (method_vec, slot)) + /* There is nothing in the Ith slot, so we can avoid + moving anything. */ + ; else - obstack_blank (ob, sizeof (tree)); + { + /* We know the last slot in the vector is empty + because we know that at this point there's room + for a new function. */ + bcopy ((PTR) &TREE_VEC_ELT (method_vec, slot), + (PTR) &TREE_VEC_ELT (method_vec, slot + 1), + (len - slot - 1) * sizeof (tree)); + TREE_VEC_ELT (method_vec, slot) = NULL_TREE; + } } + } + + if (template_class_depth (type)) + /* TYPE is a template class. Don't issue any errors now; wait + until instantiation time to complain. */ + ; + else + { + tree fns; - obstack_finish (ob); - TREE_VEC_ELT (method_vec, len) = method; - TREE_VEC_LENGTH (method_vec) = len + 1; - CLASSTYPE_METHOD_VEC (type) = method_vec; - - if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type)) + /* Check to see if we've already got this method. */ + for (fns = TREE_VEC_ELT (method_vec, slot); + fns; + fns = OVL_NEXT (fns)) { - /* ??? May be better to know whether these can be extended? */ - tree baselink_vec = CLASSTYPE_BASELINK_VEC (type); + tree fn = OVL_CURRENT (fns); + + if (TREE_CODE (fn) != TREE_CODE (method)) + continue; + + if (TREE_CODE (method) != TEMPLATE_DECL) + { + /* [over.load] Member function declarations with the + same name and the same parameter types cannot be + overloaded if any of them is a static member + function declaration. */ + if (DECL_STATIC_FUNCTION_P (fn) + != DECL_STATIC_FUNCTION_P (method)) + { + tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn)); + tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method)); + + if (! DECL_STATIC_FUNCTION_P (fn)) + parms1 = TREE_CHAIN (parms1); + else + parms2 = TREE_CHAIN (parms2); + + if (compparms (parms1, parms2)) + cp_error ("`%#D' and `%#D' cannot be overloaded", + fn, method); + } + + /* Since this is an ordinary function in a + non-template class, it's mangled name can be used + as a unique identifier. This technique is only + an optimization; we would get the same results if + we just used decls_match here. */ + if (DECL_ASSEMBLER_NAME (fn) + != DECL_ASSEMBLER_NAME (method)) + continue; + } + else if (!decls_match (fn, method)) + continue; - TREE_VEC_LENGTH (baselink_vec) += 1; - CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec); - TREE_VEC_LENGTH (baselink_vec) -= 1; + /* There has already been a declaration of this method + or member template. */ + cp_error_at ("`%D' has already been declared in `%T'", + method, type); - TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0; + /* We don't call duplicate_decls here to merge the + declarations because that will confuse things if the + methods have inline definitions. In particular, we + will crash while processing the definitions. */ + return; } } - } - DECL_CONTEXT (method) = type; - DECL_CLASS_CONTEXT (method) = type; + /* Actually insert the new method. */ + TREE_VEC_ELT (method_vec, slot) + = build_overload (method, TREE_VEC_ELT (method_vec, slot)); + + /* Add the new binding. */ + if (!DECL_CONSTRUCTOR_P (method) + && !DECL_DESTRUCTOR_P (method)) + push_class_level_binding (DECL_NAME (method), + TREE_VEC_ELT (method_vec, slot)); + } pop_obstacks (); } @@ -1240,7 +1375,7 @@ delete_duplicate_fields_1 (field, fields) else if (DECL_DECLARES_TYPE_P (field) && DECL_DECLARES_TYPE_P (x)) { - if (comptypes (TREE_TYPE (field), TREE_TYPE (x), 1)) + if (same_type_p (TREE_TYPE (field), TREE_TYPE (x))) continue; cp_error_at ("duplicate nested type `%D'", x); } @@ -1310,7 +1445,6 @@ alter_access (t, binfo, fdecl, access) else { enforce_access (binfo, fdecl); - DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); return 1; } @@ -1318,10 +1452,9 @@ alter_access (t, binfo, fdecl, access) } /* Process the USING_DECL, which is a member of T. The METHOD_VEC, if - non-NULL, is the methods of T. The FIELDS are the fields of T. - Returns 1 if the USING_DECL was valid, 0 otherwise. */ + non-NULL, is the methods of T. The FIELDS are the fields of T. */ -void +static void handle_using_decl (using_decl, t, method_vec, fields) tree using_decl; tree t; @@ -1346,8 +1479,11 @@ handle_using_decl (using_decl, t, method_vec, fields) if (name == constructor_name (ctype) || name == constructor_name_full (ctype)) - cp_error_at ("using-declaration for constructor", using_decl); - + { + cp_error_at ("using-declaration for constructor", using_decl); + return; + } + fdecl = lookup_member (binfo, name, 0, 0); if (!fdecl) @@ -1372,7 +1508,7 @@ handle_using_decl (using_decl, t, method_vec, fields) name = DECL_NAME (fdecl); n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - for (i = 2; i < n_methods; i++) + for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++) if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) == name) { @@ -1408,174 +1544,11 @@ handle_using_decl (using_decl, t, method_vec, fields) else alter_access (t, binfo, fdecl, access); } - -/* If FOR_TYPE needs to reinitialize virtual function table pointers - for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST. - Returns BASE_INIT_LIST appropriately modified. */ - -static tree -maybe_fixup_vptrs (for_type, binfo, base_init_list) - tree for_type, binfo, base_init_list; -{ - /* Now reinitialize any slots that don't fall under our virtual - function table pointer. */ - tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)); - while (vfields) - { - tree basetype = VF_NORMAL_VALUE (vfields) - ? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields)) - : VF_BASETYPE_VALUE (vfields); - - tree base_binfo = get_binfo (basetype, for_type, 0); - /* Punt until this is implemented. */ - if (1 /* BINFO_MODIFIED (base_binfo) */) - { - tree base_offset = get_vfield_offset (base_binfo); - if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type))) - && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo))) - base_init_list = tree_cons (error_mark_node, base_binfo, - base_init_list); - } - vfields = TREE_CHAIN (vfields); - } - return base_init_list; -} - -/* If TYPE does not have a constructor, then the compiler must - manually deal with all of the initialization this type requires. - - If a base initializer exists only to fill in the virtual function - table pointer, then we mark that fact with the TREE_VIRTUAL bit. - This way, we avoid multiple initializations of the same field by - each virtual function table up the class hierarchy. - - Virtual base class pointers are not initialized here. They are - initialized only at the "top level" of object creation. If we - initialized them here, we would have to skip a lot of work. */ - -static void -build_class_init_list (type) - tree type; -{ - tree base_init_list = NULL_TREE; - tree member_init_list = NULL_TREE; - - /* Since we build member_init_list and base_init_list using - tree_cons, backwards fields the all through work. */ - tree x; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x)) - { - if (TREE_CODE (x) != FIELD_DECL) - continue; - - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x)) - || DECL_INITIAL (x) != NULL_TREE) - member_init_list = tree_cons (x, type, member_init_list); - } - member_init_list = nreverse (member_init_list); - - /* We will end up doing this last. Need special marker - to avoid infinite regress. */ - if (TYPE_VIRTUAL_P (type)) - { - base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type)); - if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0) - TREE_VALUE (base_init_list) = NULL_TREE; - TREE_ADDRESSABLE (base_init_list) = 1; - } - - /* Each base class which needs to have initialization - of some kind gets to make such requests known here. */ - for (i = n_baseclasses-1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree blist; - - /* Don't initialize virtual baseclasses this way. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo))) - { - /* ...and the last shall come first... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - continue; - } - - if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE) - /* Nothing to initialize. */ - continue; - - /* ...ditto... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - - /* This is normally true for single inheritance. - The win is we can shrink the chain of initializations - to be done by only converting to the actual type - we are interested in. */ - if (TREE_VALUE (blist) - && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC - && tree_int_cst_equal (BINFO_OFFSET (base_binfo), - BINFO_OFFSET (TREE_VALUE (blist)))) - { - if (base_init_list) - { - /* Does it do more than just fill in a - virtual function table pointer? */ - if (! TREE_ADDRESSABLE (blist)) - base_init_list = build_tree_list (blist, base_init_list); - /* Can we get by just with the virtual function table - pointer that it fills in? */ - else if (TREE_ADDRESSABLE (base_init_list) - && TREE_VALUE (base_init_list) == 0) - base_init_list = blist; - /* Maybe, but it is not obvious as the previous case. */ - else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type)) - { - tree last = tree_last (base_init_list); - while (TREE_VALUE (last) - && TREE_CODE (TREE_VALUE (last)) == TREE_LIST) - last = tree_last (TREE_VALUE (last)); - if (TREE_VALUE (last) == 0) - base_init_list = build_tree_list (blist, base_init_list); - } - } - else - base_init_list = blist; - } - else - { - /* The function expand_aggr_init knows how to do the - initialization of `basetype' without getting - an explicit `blist'. */ - if (base_init_list) - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - else - base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo)); - } - } - - if (base_init_list) - { - if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = - build_tree_list (base_init_list, member_init_list); - else - CLASSTYPE_BASE_INIT_LIST (type) = base_init_list; - } - else if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = member_init_list; -} struct base_info { int has_virtual; int max_has_virtual; - int n_ancestors; tree vfield; tree vfields; tree rtti; @@ -1658,7 +1631,6 @@ finish_base_struct (t, b) && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) b->no_const_asn_ref = 1; - b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype); TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); @@ -1668,8 +1640,20 @@ finish_base_struct (t, b) TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); - if (! TREE_VIA_VIRTUAL (base_binfo)) - CLASSTYPE_N_SUPERCLASSES (t) += 1; + if (CLASSTYPE_COM_INTERFACE (basetype)) + { + CLASSTYPE_COM_INTERFACE (t) = 1; + if (i > 0) + cp_error + ("COM interface type `%T' must be the leftmost base class", + basetype); + } + else if (CLASSTYPE_COM_INTERFACE (t)) + { + cp_error ("COM interface type `%T' with non-COM base class `%T'", + t, basetype); + CLASSTYPE_COM_INTERFACE (t) = 0; + } if (TYPE_VIRTUAL_P (basetype)) { @@ -1766,35 +1750,6 @@ finish_base_struct (t, b) } } - /* This comment said "Must come after offsets are fixed for all bases." - Well, now this happens before the offsets are fixed, but it seems to - work fine. Guess we'll see... */ - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - if (get_base_distance (basetype, t, 0, (tree*)0) == -2) - { - cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", - basetype, t); - } - } - { - tree v = get_vbase_types (t); - - for (; v; v = TREE_CHAIN (v)) - { - tree basetype = BINFO_TYPE (v); - if (get_base_distance (basetype, t, 0, (tree*)0) == -2) - { - if (extra_warnings) - cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", - basetype, t); - } - } - } - { tree vfields; /* Find the base class with the largest number of virtual functions. */ @@ -1854,24 +1809,15 @@ finish_struct_bits (t, max_has_virtual) if (n_baseclasses && max_has_virtual) { - /* Done by `finish_struct' for classes without baseclasses. */ - int might_have_abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (t) != 0; - tree binfos = TYPE_BINFO_BASETYPES (t); - for (i = n_baseclasses-1; i >= 0; i--) - { - might_have_abstract_virtuals - |= (CLASSTYPE_ABSTRACT_VIRTUALS (BINFO_TYPE (TREE_VEC_ELT (binfos, i))) != 0); - if (might_have_abstract_virtuals) - break; - } - if (might_have_abstract_virtuals) - { - /* We use error_mark_node from override_one_vtable to signal - an artificial abstract. */ - if (CLASSTYPE_ABSTRACT_VIRTUALS (t) == error_mark_node) - CLASSTYPE_ABSTRACT_VIRTUALS (t) = NULL_TREE; - CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t); - } + /* For a class w/o baseclasses, `finish_struct' has set + CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly + for a class who's base classes do not have vtables. When neither + of these is true, we might have removed abstract virtuals (by + providing a definition), added some (by declaring new ones), or + redeclared ones from a base class. We need to recalculate what's + really an abstract virtual at this point (by looking in the + vtables). */ + CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t); } if (n_baseclasses) @@ -1886,8 +1832,6 @@ finish_struct_bits (t, max_has_virtual) basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype); - if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t)) - CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1; } } @@ -1913,39 +1857,157 @@ finish_struct_bits (t, max_has_virtual) } } -/* Add FNDECL to the method_vec growing on the class_obstack. Used by - finish_struct_methods. Note, FNDECL cannot be a constructor or - destructor, those cases are handled by the caller. */ +/* Issue warnings about T having private constructors, but no friends, + and so forth. + + HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or + static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any + non-private static member functions. */ static void -grow_method (fndecl, method_vec_ptr) - tree fndecl; - tree *method_vec_ptr; +maybe_warn_about_overly_private_class (t) + tree t; { - tree method_vec = (tree)obstack_base (&class_obstack); + int has_member_fn = 0; + int has_nonprivate_method = 0; + tree fn; + + if (!warn_ctor_dtor_privacy + /* If the class has friends, those entities might create and + access instances, so we should not warn. */ + || (CLASSTYPE_FRIEND_CLASSES (t) + || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) + /* We will have warned when the template was declared; there's + no need to warn on every instantiation. */ + || CLASSTYPE_TEMPLATE_INSTANTIATION (t)) + /* There's no reason to even consider warning about this + class. */ + return; + + /* We only issue one warning, if more than one applies, because + otherwise, on code like: + + class A { + // Oops - forgot `public:' + A(); + A(const A&); + ~A(); + }; + + we warn several times about essentially the same problem. */ + + /* Check to see if all (non-constructor, non-destructor) member + functions are private. (Since there are no friends or + non-private statics, we can't ever call any of the private member + functions.) */ + for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) + /* We're not interested in compiler-generated methods; they don't + provide any way to call private members. */ + if (!DECL_ARTIFICIAL (fn)) + { + if (!TREE_PRIVATE (fn)) + { + if (DECL_STATIC_FUNCTION_P (fn)) + /* A non-private static member function is just like a + friend; it can create and invoke private member + functions, and be accessed without a class + instance. */ + return; + + has_nonprivate_method = 1; + break; + } + else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) + has_member_fn = 1; + } + + if (!has_nonprivate_method && has_member_fn) + { + /* There are no non-private methods, and there's at least one + private member function that isn't a constructor or + destructor. (If all the private members are + constructors/destructors we want to use the code below that + 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))) + { + has_nonprivate_method = 1; + break; + } + if (!has_nonprivate_method) + { + cp_warning ("all member functions in class `%T' are private", t); + return; + } + } - /* Start off past the constructors and destructor. */ - tree *testp = &TREE_VEC_ELT (method_vec, 2); + /* 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)) + { + tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1); - while (testp < (tree *) obstack_next_free (&class_obstack) - && (*testp == NULL_TREE || DECL_NAME (OVL_CURRENT (*testp)) != DECL_NAME (fndecl))) - testp++; + if (TREE_PRIVATE (dtor)) + { + cp_warning ("`%#T' only defines a private destructor and has no friends", + t); + return; + } + } - if (testp < (tree *) obstack_next_free (&class_obstack)) - *testp = build_overload (fndecl, *testp); - else + if (TYPE_HAS_CONSTRUCTOR (t)) { - obstack_ptr_grow (&class_obstack, fndecl); - *method_vec_ptr = (tree)obstack_base (&class_obstack); + int nonprivate_ctor = 0; + + /* If a non-template class does not define a copy + constructor, one is defined for it, enabling it to avoid + this warning. For a template class, this does not + happen, and so we would normally get a warning on: + + template class C { private: C(); }; + + To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All + complete non-template or fully instantiated classes have this + flag set. */ + if (!TYPE_HAS_INIT_REF (t)) + nonprivate_ctor = 1; + else + for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); + fn; + fn = OVL_NEXT (fn)) + { + tree ctor = OVL_CURRENT (fn); + /* Ideally, we wouldn't count copy constructors (or, in + fact, any constructor that takes an argument of the + class type as a parameter) because such things cannot + be used to construct an instance of the class unless + you already have one. But, for now at least, we're + more generous. */ + if (! TREE_PRIVATE (ctor)) + { + nonprivate_ctor = 1; + break; + } + } + + if (nonprivate_ctor == 0) + { + cp_warning ("`%#T' only defines private constructors and has no friends", + t); + return; + } } } + /* Warn about duplicate methods in fn_fields. Also compact method lists so that lookup can be made faster. - Algorithm: Outer loop builds lists by method name. Inner loop - checks for redundant method names within a list. - Data Structure: List of method lists. The outer list is a TREE_LIST, whose TREE_PURPOSE field is the field name and the TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs. TREE_CHAIN @@ -1961,35 +2023,20 @@ grow_method (fndecl, method_vec_ptr) We also link each field which has shares a name with its baseclass to the head of the list of fields for that base class. This allows us to reduce search time in places like `build_method_call' to - consider only reasonably likely functions. */ + consider only reasonably likely functions. */ -tree -finish_struct_methods (t, fn_fields, nonprivate_method) +static void +finish_struct_methods (t) tree t; - tree fn_fields; - int nonprivate_method; { - tree method_vec; - tree save_fn_fields = fn_fields; + tree fn_fields; + tree method_vec = CLASSTYPE_METHOD_VEC (t); tree ctor_name = constructor_name (t); - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - - /* Now prepare to gather fn_fields into vector. */ - struct obstack *ambient_obstack = current_obstack; - current_obstack = &class_obstack; - method_vec = make_tree_vec (2); - current_obstack = ambient_obstack; - - /* Now make this a live vector. */ - obstack_free (&class_obstack, method_vec); - - /* Save room for constructors and destructors. */ - obstack_blank (&class_obstack, sizeof (struct tree_vec) + sizeof (struct tree *)); /* First fill in entry 0 with the constructors, entry 1 with destructors, and the next few with type conversion operators (if any). */ - - for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields)) + for (fn_fields = TYPE_METHODS (t); fn_fields; + fn_fields = TREE_CHAIN (fn_fields)) { tree fn_name = DECL_NAME (fn_fields); @@ -2020,32 +2067,8 @@ finish_struct_methods (t, fn_fields, nonprivate_method) TYPE_HAS_NONPUBLIC_CTOR (t) = 2; } } - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fn_fields))) - { - /* Destructors go in slot 1. */ - TREE_VEC_ELT (method_vec, 1) = - build_overload (fn_fields, TREE_VEC_ELT (method_vec, 1)); - } - else - { - /* Constructors go in slot 0. */ - TREE_VEC_ELT (method_vec, 0) = - build_overload (fn_fields, TREE_VEC_ELT (method_vec, 0)); - } - } - else if (IDENTIFIER_TYPENAME_P (fn_name)) - grow_method (fn_fields, &method_vec); - } - - fn_fields = save_fn_fields; - for (; fn_fields; fn_fields = TREE_CHAIN (fn_fields)) - { - tree fn_name = DECL_NAME (fn_fields); - - if (fn_name == ctor_name || IDENTIFIER_TYPENAME_P (fn_name)) - continue; - - if (fn_name == ansi_opname[(int) MODIFY_EXPR]) + } + else if (fn_name == ansi_opname[(int) MODIFY_EXPR]) { tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields)); @@ -2057,76 +2080,17 @@ finish_struct_methods (t, fn_fields, nonprivate_method) TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2; } } - - grow_method (fn_fields, &method_vec); } - TREE_VEC_LENGTH (method_vec) = (tree *)obstack_next_free (&class_obstack) - - (&TREE_VEC_ELT (method_vec, 0)); - obstack_finish (&class_obstack); - CLASSTYPE_METHOD_VEC (t) = method_vec; - - if (nonprivate_method == 0 - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE) - { - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - for (i = 0; i < n_baseclasses; i++) - if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i)) - || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i))) - { - nonprivate_method = 1; - break; - } - if (nonprivate_method == 0 - && warn_ctor_dtor_privacy) - cp_warning ("all member functions in class `%T' are private", t); - } - - /* Warn if all destructors are private (in which case this class is - effectively unusable. */ - if (TYPE_HAS_DESTRUCTOR (t)) - { - tree dtor = TREE_VEC_ELT (method_vec, 1); - - /* Wild parse errors can cause this to happen. */ - if (dtor == NULL_TREE) - TYPE_HAS_DESTRUCTOR (t) = 0; - else if (TREE_PRIVATE (dtor) - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE - && warn_ctor_dtor_privacy) - cp_warning ("`%#T' only defines a private destructor and has no friends", - t); - } - - /* Now for each member function (except for constructors and - destructors), compute where member functions of the same - name reside in base classes. */ - if (n_baseclasses != 0 - && TREE_VEC_LENGTH (method_vec) > 2) - { - int len = TREE_VEC_LENGTH (method_vec); - tree baselink_vec = make_tree_vec (len); - int any_links = 0; - tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - for (i = 2; i < len; i++) - { - TREE_VEC_ELT (baselink_vec, i) - = get_baselinks (baselink_binfo, t, - DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i)))); - if (TREE_VEC_ELT (baselink_vec, i) != 0) - any_links = 1; - } - if (any_links != 0) - CLASSTYPE_BASELINK_VEC (t) = baselink_vec; - else - obstack_free (current_obstack, baselink_vec); - } - - return method_vec; -} + if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1)) + /* We thought there was a destructor, but there wasn't. Some + parse errors cause this anomalous situation. */ + TYPE_HAS_DESTRUCTOR (t) = 0; + + /* Issue warnings about private constructors and such. If there are + no methods, then some public defaults are generated. */ + maybe_warn_about_overly_private_class (t); +} /* Emit error when a duplicate definition of a type is seen. Patch up. */ @@ -2164,18 +2128,14 @@ duplicate_tag_error (t) if (TYPE_LANG_SPECIFIC (t)) { - tree as_list = CLASSTYPE_AS_LIST (t); tree binfo = TYPE_BINFO (t); - tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t); int interface_only = CLASSTYPE_INTERFACE_ONLY (t); int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t); bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type)); BINFO_BASETYPES(binfo) = NULL_TREE; - CLASSTYPE_AS_LIST (t) = as_list; TYPE_BINFO (t) = binfo; - CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list; CLASSTYPE_INTERFACE_ONLY (t) = interface_only; SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); TYPE_REDEFINED (t) = 1; @@ -2209,8 +2169,7 @@ finish_vtbls (binfo, do_self, t) decl = BINFO_VTABLE (binfo); context = DECL_CONTEXT (decl); DECL_CONTEXT (decl) = 0; - if (write_virtuals >= 0 - && DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo)) + if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo)) DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, BINFO_VIRTUALS (binfo)); cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); @@ -2255,9 +2214,9 @@ overrides (fndecl, base_fndecl) #endif types = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl)); - if ((TYPE_READONLY (TREE_TYPE (TREE_VALUE (base_types))) - == TYPE_READONLY (TREE_TYPE (TREE_VALUE (types)))) - && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types), 3)) + if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types))) + == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types)))) + && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types))) return 1; } return 0; @@ -2347,11 +2306,14 @@ get_class_offset (context, t, binfo, fndecl) /* Skip RTTI information at the front of the virtual list. */ unsigned HOST_WIDE_INT -skip_rtti_stuff (virtuals) - tree *virtuals; +skip_rtti_stuff (virtuals, t) + tree *virtuals, t; { int n; + if (CLASSTYPE_COM_INTERFACE (t)) + return 0; + n = 0; if (*virtuals) { @@ -2393,7 +2355,7 @@ modify_one_vtable (binfo, t, fndecl, pfn) if (fndecl == NULL_TREE) return; - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, t); while (virtuals) { @@ -2421,10 +2383,6 @@ modify_one_vtable (binfo, t, fndecl, pfn) BINFO_OFFSET (binfo)); this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); - /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (binfo)) - my_friendly_assert (0, 999); - if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. @@ -2491,7 +2449,7 @@ fixup_vtable_deltas1 (binfo, t) tree virtuals = BINFO_VIRTUALS (binfo); unsigned HOST_WIDE_INT n; - n = skip_rtti_stuff (&virtuals); + n = skip_rtti_stuff (&virtuals, t); while (virtuals) { @@ -2524,9 +2482,6 @@ fixup_vtable_deltas1 (binfo, t) if (! tree_int_cst_equal (this_offset, delta)) { /* Make sure we can modify the derived association with immunity. */ - if (TREE_USED (binfo)) - my_friendly_assert (0, 999); - if (binfo == TYPE_BINFO (t)) { /* In this case, it is *type*'s vtable we are modifying. @@ -2667,8 +2622,8 @@ override_one_vtable (binfo, old, t) if (BINFO_NEW_VTABLE_MARKED (binfo)) choose = NEITHER; - skip_rtti_stuff (&virtuals); - skip_rtti_stuff (&old_virtuals); + skip_rtti_stuff (&virtuals, t); + skip_rtti_stuff (&old_virtuals, t); while (virtuals) { @@ -2729,13 +2684,11 @@ override_one_vtable (binfo, old, t) } { /* This MUST be overridden, or the class is ill-formed. */ - /* For now, we just make it abstract. */ tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); tree vfn; fndecl = copy_node (fndecl); copy_lang_decl (fndecl); - DECL_ABSTRACT_VIRTUAL_P (fndecl) = 1; DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1; /* Make sure we search for it later. */ if (! CLASSTYPE_ABSTRACT_VIRTUALS (t)) @@ -2832,18 +2785,18 @@ get_basefndecls (fndecl, t) /* Mark the functions that have been hidden with their overriders. Since we start out with all functions already marked with a hider, - no need to mark functions that are just hidden. */ + no need to mark functions that are just hidden. + + Subroutine of warn_hidden. */ static void mark_overriders (fndecl, base_fndecls) tree fndecl, base_fndecls; { - while (base_fndecls) + for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls)) { - if (overrides (TREE_VALUE (base_fndecls), fndecl)) + if (overrides (fndecl, TREE_VALUE (base_fndecls))) TREE_PURPOSE (base_fndecls) = fndecl; - - base_fndecls = TREE_CHAIN (base_fndecls); } } @@ -2858,17 +2811,18 @@ check_for_override (decl, ctype) tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype)); int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; int virtualp = DECL_VIRTUAL_P (decl); + int found_overriden_fn = 0; for (i = 0; i < n_baselinks; i++) { tree base_binfo = TREE_VEC_ELT (binfos, i); - if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo)) - || flag_all_virtual == 1) + if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))) { tree tmp = get_matching_virtual (base_binfo, decl, DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))); - if (tmp) + + if (tmp && !found_overriden_fn) { /* If this function overrides some virtual in some base class, then the function itself is also necessarily @@ -2889,26 +2843,15 @@ check_for_override (decl, ctype) } virtualp = 1; -#if 0 /* The signature of an overriding function is not changed. */ - { - /* The argument types may have changed... */ - tree type = TREE_TYPE (decl); - tree argtypes = TYPE_ARG_TYPES (type); - tree base_variant = TREE_TYPE (TREE_VALUE (argtypes)); - tree raises = TYPE_RAISES_EXCEPTIONS (type); - - argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))), - TREE_CHAIN (argtypes)); - /* But the return type has not. */ - type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes); - if (raises) - type = build_exception_variant (type, raises); - TREE_TYPE (decl) = type; - } -#endif DECL_VINDEX (decl) = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl)); - break; + + /* We now know that DECL overrides something, + which is all that is important. But, we must + continue to iterate through all the base-classes + in order to allow get_matching_virtual to check for + various illegal overrides. */ + found_overriden_fn = 1; } } } @@ -2932,7 +2875,7 @@ warn_hidden (t) int i; /* We go through each separately named virtual function. */ - for (i = 2; i < n_methods; ++i) + for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) { tree fns = TREE_VEC_ELT (method_vec, i); tree fndecl; @@ -2941,8 +2884,15 @@ warn_hidden (t) tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - fndecl = OVL_CURRENT (fns); - if (DECL_VINDEX (fndecl) == NULL_TREE) + /* First see if we have any virtual functions in this batch. */ + for (; fns; fns = OVL_NEXT (fns)) + { + fndecl = OVL_CURRENT (fns); + if (DECL_VINDEX (fndecl)) + break; + } + + if (fns == NULL_TREE) continue; /* First we get a list of all possible functions that might be @@ -2957,38 +2907,28 @@ warn_hidden (t) } fns = OVL_NEXT (fns); - if (fns) - fndecl = OVL_CURRENT (fns); - else - fndecl = NULL_TREE; /* ...then mark up all the base functions with overriders, preferring overriders to hiders. */ if (base_fndecls) - while (fndecl) + for (; fns; fns = OVL_NEXT (fns)) { - mark_overriders (fndecl, base_fndecls); - - fns = OVL_NEXT (fns); - if (fns) - fndecl = OVL_CURRENT (fns); - else - fndecl = NULL_TREE; + fndecl = OVL_CURRENT (fns); + if (DECL_VINDEX (fndecl)) + mark_overriders (fndecl, base_fndecls); } /* Now give a warning for all base functions without overriders, as they are hidden. */ - while (base_fndecls) + for (; base_fndecls; base_fndecls = TREE_CHAIN (base_fndecls)) { - if (! overrides (TREE_VALUE (base_fndecls), - TREE_PURPOSE (base_fndecls))) + if (! overrides (TREE_PURPOSE (base_fndecls), + TREE_VALUE (base_fndecls))) { /* Here we know it is a hider, and no overrider exists. */ cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls)); } - - base_fndecls = TREE_CHAIN (base_fndecls); } } } @@ -3014,9 +2954,20 @@ finish_struct_anon (t) tree* uelt = &TYPE_FIELDS (TREE_TYPE (field)); for (; *uelt; uelt = &TREE_CHAIN (*uelt)) { - if (TREE_CODE (*uelt) != FIELD_DECL) + if (DECL_ARTIFICIAL (*uelt)) continue; + if (DECL_NAME (*uelt) == constructor_name (t)) + cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class", + *uelt); + + if (TREE_CODE (*uelt) != FIELD_DECL) + { + cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members", + *uelt); + continue; + } + if (TREE_PRIVATE (*uelt)) cp_pedwarn_at ("private member `%#D' in anonymous union", *uelt); @@ -3033,6 +2984,90 @@ finish_struct_anon (t) extern int interface_only, interface_unknown; +/* Create default constructors, assignment operators, and so forth for + the type indicated by T, if they are needed. + CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and + CANT_HAVE_ASSIGNMENT are nonzero if, for whatever reason, the class + cannot have a default constructor, copy constructor taking a const + reference argument, or an assignment operator, respectively. If a + virtual destructor is created, its DECL is returned; otherwise the + return value is NULL_TREE. */ + +static tree +add_implicitly_declared_members (t, cant_have_default_ctor, + cant_have_const_cctor, + cant_have_assignment) + tree t; + int cant_have_default_ctor; + int cant_have_const_cctor; + int cant_have_assignment; +{ + tree default_fn; + tree implicit_fns = NULL_TREE; + tree name = TYPE_IDENTIFIER (t); + tree virtual_dtor = NULL_TREE; + tree *f; + + /* Destructor. */ + if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t) + && !IS_SIGNATURE (t)) + { + default_fn = cons_up_default_function (t, name, 0); + check_for_override (default_fn, t); + + /* If we couldn't make it work, then pretend we didn't need it. */ + if (default_fn == void_type_node) + TYPE_NEEDS_DESTRUCTOR (t) = 0; + else + { + TREE_CHAIN (default_fn) = implicit_fns; + implicit_fns = default_fn; + + if (DECL_VINDEX (default_fn)) + virtual_dtor = default_fn; + } + } + TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); + + /* Default constructor. */ + if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor + && ! IS_SIGNATURE (t)) + { + default_fn = cons_up_default_function (t, name, 2); + TREE_CHAIN (default_fn) = implicit_fns; + implicit_fns = default_fn; + } + + /* Copy constructor. */ + if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) + { + /* ARM 12.18: You get either X(X&) or X(const X&), but + not both. --Chip */ + default_fn = cons_up_default_function (t, name, + 3 + cant_have_const_cctor); + TREE_CHAIN (default_fn) = implicit_fns; + implicit_fns = default_fn; + } + + /* Assignment operator. */ + if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) + { + default_fn = cons_up_default_function (t, name, + 5 + cant_have_assignment); + TREE_CHAIN (default_fn) = implicit_fns; + implicit_fns = default_fn; + } + + /* Now, hook all of the new functions on to TYPE_METHODS, + and add them to the CLASSTYPE_METHOD_VEC. */ + for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) + add_method (t, 0, *f); + *f = TYPE_METHODS (t); + TYPE_METHODS (t) = implicit_fns; + + return virtual_dtor; +} + /* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration (or C++ class declaration). @@ -3058,54 +3093,17 @@ extern int interface_only, interface_unknown; inheritance. Additional virtual function tables have different DELTAs, which tell how to adjust `this' to point to the right thing. - LIST_OF_FIELDLISTS is just that. The elements of the list are - TREE_LIST elements, whose TREE_PURPOSE field tells what access - the list has, and the TREE_VALUE slot gives the actual fields. - - ATTRIBUTES is the set of decl attributes to be applied, if any. - - If flag_all_virtual == 1, then we lay all functions into - the virtual function table, as though they were declared - virtual. Constructors do not lay down in the virtual function table. - - If flag_all_virtual == 2, then we lay all functions into - the virtual function table, such that virtual functions - occupy a space by themselves, and then all functions - of the class occupy a space by themselves. This is illustrated - in the following diagram: - - class A; class B : A; - - Class A's vtbl: Class B's vtbl: - -------------------------------------------------------------------- - | A's virtual functions| | B's virtual functions | - | | | (may inherit some from A). | - -------------------------------------------------------------------- - | All of A's functions | | All of A's functions | - | (such as a->A::f). | | (such as b->A::f) | - -------------------------------------------------------------------- - | B's new virtual functions | - | (not defined in A.) | - ------------------------------- - | All of B's functions | - | (such as b->B::f) | - ------------------------------- - - this allows the program to make references to any function, virtual - or otherwise in a type-consistent manner. */ + ATTRIBUTES is the set of decl attributes to be applied, if any. */ -tree +void finish_struct_1 (t, warn_anon) tree t; int warn_anon; { int old; - tree name = TYPE_IDENTIFIER (t); enum tree_code code = TREE_CODE (t); tree fields = TYPE_FIELDS (t); - tree fn_fields = TYPE_METHODS (t); tree x, last_x, method_vec; - int all_virtual; int has_virtual; int max_has_virtual; tree pending_virtuals = NULL_TREE; @@ -3113,9 +3111,11 @@ finish_struct_1 (t, warn_anon) tree abstract_virtuals = NULL_TREE; tree vfield; tree vfields; + tree virtual_dtor; int cant_have_default_ctor; int cant_have_const_ctor; int no_const_asn_ref; + int has_mutable = 0; /* The index of the first base class which has virtual functions. Only applied to non-virtual baseclasses. */ @@ -3125,11 +3125,11 @@ finish_struct_1 (t, warn_anon) int any_default_members = 0; int const_sans_init = 0; int ref_sans_init = 0; - int nonprivate_method = 0; tree access_decls = NULL_TREE; int aggregate = 1; int empty = 1; int has_pointers = 0; + tree inline_friends; if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) pedwarn ("anonymous class type not used to declare any objects"); @@ -3140,8 +3140,8 @@ finish_struct_1 (t, warn_anon) cp_error ("redefinition of `%#T'", t); else my_friendly_abort (172); - popclass (0); - return t; + popclass (); + return; } GNU_xref_decl (current_function_decl, t); @@ -3185,7 +3185,6 @@ finish_struct_1 (t, warn_anon) CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index; has_virtual = base_info.has_virtual; max_has_virtual = base_info.max_has_virtual; - CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors; vfield = base_info.vfield; vfields = base_info.vfields; CLASSTYPE_RTTI (t) = base_info.rtti; @@ -3223,25 +3222,14 @@ finish_struct_1 (t, warn_anon) CLASSTYPE_VFIELDS (t) = vfields; CLASSTYPE_VFIELD (t) = vfield; - if (IS_SIGNATURE (t)) - all_virtual = 0; - else if (flag_all_virtual == 1) - all_virtual = 1; - else - all_virtual = 0; - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) { GNU_xref_member (current_class_name, x); - nonprivate_method |= ! TREE_PRIVATE (x); - /* If this was an evil function, don't keep it in class. */ if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) continue; - DECL_CLASS_CONTEXT (x) = t; - /* Do both of these, even though they're in the same union; if the insn `r' member and the size `i' member are different sizes, as on the alpha, the larger of the two @@ -3255,8 +3243,7 @@ finish_struct_1 (t, warn_anon) /* The name of the field is the original field name Save this in auxiliary field for later overloading. */ - if (DECL_VINDEX (x) - || (all_virtual == 1 && ! DECL_CONSTRUCTOR_P (x))) + if (DECL_VINDEX (x)) { add_virtual_function (&pending_virtuals, &pending_hard_virtuals, &has_virtual, x, t); @@ -3281,7 +3268,11 @@ finish_struct_1 (t, warn_anon) if (TREE_CODE (x) == FIELD_DECL) { DECL_PACKED (x) |= TYPE_PACKED (t); - empty = 0; + + if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) + /* A zero-width bitfield doesn't do the trick. */; + else + empty = 0; } if (TREE_CODE (x) == USING_DECL) @@ -3387,8 +3378,11 @@ finish_struct_1 (t, warn_anon) if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE) has_pointers = 1; + if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x))) + has_mutable = 1; + /* If any field is const, the structure type is pseudo-const. */ - if (TREE_READONLY (x)) + if (CP_TYPE_CONST_P (TREE_TYPE (x))) { C_TYPE_FIELDS_READONLY (t) = 1; if (DECL_INITIAL (x) == NULL_TREE) @@ -3426,12 +3420,10 @@ finish_struct_1 (t, warn_anon) } } - /* We set DECL_BIT_FIELD tentatively in grokbitfield. - If the type and width are valid, we'll keep it set. - Otherwise, the flag is cleared. */ - if (DECL_BIT_FIELD (x)) + /* We set DECL_C_BIT_FIELD in grokbitfield. + If the type and width are valid, we'll also set DECL_BIT_FIELD. */ + if (DECL_C_BIT_FIELD (x)) { - DECL_BIT_FIELD (x) = 0; /* Invalid bit-field size done by grokfield. */ /* Detect invalid bit-field type. */ if (DECL_INITIAL (x) @@ -3499,23 +3491,24 @@ finish_struct_1 (t, warn_anon) x, TREE_TYPE (x)); } - if (DECL_INITIAL (x) == NULL_TREE) - ; - else if (width == 0) + if (DECL_INITIAL (x)) { + DECL_INITIAL (x) = NULL_TREE; + DECL_FIELD_SIZE (x) = width; + DECL_BIT_FIELD (x) = 1; + + if (width == 0) + { #ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), EMPTY_FIELD_BOUNDARY); + DECL_ALIGN (x) = MAX (DECL_ALIGN (x), + EMPTY_FIELD_BOUNDARY); #endif #ifdef PCC_BITFIELD_TYPE_MATTERS - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); + if (PCC_BITFIELD_TYPE_MATTERS) + DECL_ALIGN (x) = MAX (DECL_ALIGN (x), + TYPE_ALIGN (TREE_TYPE (x))); #endif - } - else - { - DECL_INITIAL (x) = NULL_TREE; - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; + } } } else @@ -3543,7 +3536,7 @@ finish_struct_1 (t, warn_anon) if (code == UNION_TYPE) { - char *fie = NULL; + const char *fie = NULL; if (TYPE_NEEDS_CONSTRUCTING (type)) fie = "constructor"; else if (TYPE_NEEDS_DESTRUCTOR (type)) @@ -3604,36 +3597,7 @@ finish_struct_1 (t, warn_anon) CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init; CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init; CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals; - - /* Synthesize any needed methods. Note that methods will be synthesized - for anonymous unions; grok_x_components undoes that. */ - - if (! fn_fields) - nonprivate_method = 1; - - if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t) - && !IS_SIGNATURE (t)) - { - /* Here we must cons up a destructor on the fly. */ - tree dtor = cons_up_default_function (t, name, 0); - check_for_override (dtor, t); - - /* If we couldn't make it work, then pretend we didn't need it. */ - if (dtor == void_type_node) - TYPE_NEEDS_DESTRUCTOR (t) = 0; - else - { - /* Link dtor onto end of fn_fields. */ - - TREE_CHAIN (dtor) = fn_fields; - fn_fields = dtor; - - if (DECL_VINDEX (dtor)) - add_virtual_function (&pending_virtuals, &pending_hard_virtuals, - &has_virtual, dtor, t); - nonprivate_method = 1; - } - } + CLASSTYPE_HAS_MUTABLE (t) = has_mutable; /* Effective C++ rule 11. */ if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t) @@ -3650,9 +3614,9 @@ finish_struct_1 (t, warn_anon) else if (! TYPE_HAS_ASSIGN_REF (t)) cp_warning (" but does not override `operator=(const %T&)'", t); } - - TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); - + + /* Do some bookkeeping that will guide the generation of implicitly + declared member functions. */ TYPE_HAS_COMPLEX_INIT_REF (t) |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) || has_virtual || any_default_members); @@ -3662,68 +3626,24 @@ finish_struct_1 (t, warn_anon) if (! IS_SIGNATURE (t)) CLASSTYPE_NON_AGGREGATE (t) = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t); - - /* ARM $12.1: A default constructor will be generated for a class X - only if no constructor has been declared for class X. So we - check TYPE_HAS_CONSTRUCTOR also, to make sure we don't generate - one if they declared a constructor in this class. */ - if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor - && ! IS_SIGNATURE (t)) - { - tree default_fn = cons_up_default_function (t, name, 2); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - } - - /* Create default copy constructor, if needed. */ - if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) - { - /* ARM 12.18: You get either X(X&) or X(const X&), but - not both. --Chip */ - tree default_fn = cons_up_default_function (t, name, - 3 + cant_have_const_ctor); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - } - - TYPE_HAS_REAL_ASSIGNMENT (t) |= TYPE_HAS_ASSIGNMENT (t); TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t); - if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) - { - tree default_fn = cons_up_default_function (t, name, - 5 + no_const_asn_ref); - TREE_CHAIN (default_fn) = fn_fields; - fn_fields = default_fn; - } + /* Synthesize any needed methods. Note that methods will be synthesized + for anonymous unions; grok_x_components undoes that. */ + virtual_dtor + = add_implicitly_declared_members (t, cant_have_default_ctor, + cant_have_const_ctor, + no_const_asn_ref); + if (virtual_dtor) + add_virtual_function (&pending_virtuals, &pending_hard_virtuals, + &has_virtual, virtual_dtor, t); - if (fn_fields) + if (TYPE_METHODS (t)) { - TYPE_METHODS (t) = fn_fields; - method_vec = finish_struct_methods (t, fn_fields, nonprivate_method); - - if (TYPE_HAS_CONSTRUCTOR (t) - && CLASSTYPE_FRIEND_CLASSES (t) == NULL_TREE - && DECL_FRIENDLIST (TYPE_MAIN_DECL (t)) == NULL_TREE) - { - int nonprivate_ctor = 0; - tree ctor; - - for (ctor = TREE_VEC_ELT (method_vec, 0); - ctor; - ctor = OVL_NEXT (ctor)) - if (! TREE_PRIVATE (OVL_CURRENT (ctor))) - { - nonprivate_ctor = 1; - break; - } - - if (nonprivate_ctor == 0 && warn_ctor_dtor_privacy) - cp_warning ("`%#T' only defines private constructors and has no friends", - t); - } + finish_struct_methods (t); + method_vec = CLASSTYPE_METHOD_VEC (t); } else { @@ -3741,10 +3661,27 @@ finish_struct_1 (t, warn_anon) if (vfield == NULL_TREE && has_virtual) { - /* We build this decl with ptr_type_node, and - change the type when we know what it should be. */ + /* We build this decl with vtbl_ptr_type_node, which is a + `vtable_entry_type*'. It might seem more precise to use + `vtable_entry_type (*)[N]' where N is the number of firtual + functions. However, that would require the vtable pointer in + base classes to have a different type than the vtable pointer + in derived classes. We could make that happen, but that + still wouldn't solve all the problems. In particular, the + 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 + class constructor was inlined, we could generate bad code for + setting up the vtable pointer. + + Therefore, we use one type for all vtable pointers. We still + use a type-correct type; it's just doesn't indicate the array + bounds. That's better than using `void*' or some such; it's + cleaner, and it let's the alias analysis code know that these + stores cannot alias stores to void*! */ vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), - ptr_type_node); + vtbl_ptr_type_node); /* If you change any of the below, take a look at all the other VFIELD_BASEs and VTABLE_BASEs in the code, and change them too. */ @@ -3776,57 +3713,17 @@ finish_struct_1 (t, warn_anon) fields = vfield; #endif empty = 0; - vfields = chainon (vfields, CLASSTYPE_AS_LIST (t)); + vfields = chainon (vfields, build_tree_list (NULL_TREE, t)); } /* Now DECL_INITIAL is null on all members except for zero-width bit-fields. - And they have already done their work. C++: maybe we will support default field initialization some day... */ - /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fields && DECL_BIT_FIELD (fields) - && DECL_INITIAL (fields)) - fields = TREE_CHAIN (fields); - /* Delete all such fields from the rest of the fields. */ - for (x = fields; x;) - { - if (TREE_CHAIN (x) && DECL_BIT_FIELD (TREE_CHAIN (x)) - && DECL_INITIAL (TREE_CHAIN (x))) - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - else - x = TREE_CHAIN (x); - } /* Delete all duplicate fields from the fields */ delete_duplicate_fields (fields); - /* Catch function/field name conflict. We don't need to do this for a - signature, since it can only contain the fields constructed in - append_signature_fields. */ - if (! IS_SIGNATURE (t)) - { - int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - for (x = fields; x; x = TREE_CHAIN (x)) - { - tree name = DECL_NAME (x); - int i = 2; - - if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)) - continue; - - for (; i < n_methods; ++i) - if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) - == name) - { - cp_error_at ("data member `%#D' conflicts with", x); - cp_error_at ("function member `%#D'", - OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); - break; - } - } - } - - /* Now we have the final fieldlist for the data fields. Record it, + /* Now we have the nearly final fieldlist for the data fields. Record it, then lay out the structure or union (including the fields). */ TYPE_FIELDS (t) = fields; @@ -3840,6 +3737,13 @@ finish_struct_1 (t, warn_anon) if (DECL_SIZE (x) != integer_zero_node) empty = 0; } + + /* CLASSTYPE_INLINE_FRIENDS is really TYPE_NONCOPIED_PARTS. Thus, + we have to save this before we start modifying + TYPE_NONCOPIED_PARTS. */ + inline_friends = CLASSTYPE_INLINE_FRIENDS (t); + CLASSTYPE_INLINE_FRIENDS (t) = NULL_TREE; + if (empty) { /* C++: do not let empty structures exist. */ @@ -3847,7 +3751,11 @@ finish_struct_1 (t, warn_anon) (FIELD_DECL, NULL_TREE, char_type_node); TREE_CHAIN (decl) = fields; TYPE_FIELDS (t) = decl; + TYPE_NONCOPIED_PARTS (t) + = tree_cons (NULL_TREE, decl, TYPE_NONCOPIED_PARTS (t)); + TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1; } + if (n_baseclasses) TYPE_FIELDS (t) = chainon (last_x, TYPE_FIELDS (t)); @@ -3880,15 +3788,31 @@ finish_struct_1 (t, warn_anon) if (n_baseclasses) /* layout_basetypes will remove the base subobject fields. */ max_has_virtual = layout_basetypes (t, max_has_virtual); - else if (empty) + if (empty) TYPE_FIELDS (t) = fields; + my_friendly_assert (TYPE_FIELDS (t) == fields, 981117); + + /* Delete all zero-width bit-fields from the front of the fieldlist */ + while (fields && DECL_C_BIT_FIELD (fields) + && DECL_INITIAL (fields)) + fields = TREE_CHAIN (fields); + /* Delete all such fields from the rest of the fields. */ + for (x = fields; x;) + { + if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x)) + && DECL_INITIAL (TREE_CHAIN (x))) + TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); + else + x = TREE_CHAIN (x); + } + TYPE_FIELDS (t) = fields; + if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree vbases; vbases = CLASSTYPE_VBASECLASSES (t); - CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases); { /* Now fixup overrides of all functions in vtables from all @@ -3983,15 +3907,18 @@ finish_struct_1 (t, warn_anon) /* We must enter these virtuals into the table. */ if (first_vfn_base_index < 0) { - /* The second slot is for the tdesc pointer when thunks are used. */ - if (flag_vtable_thunks) - pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); + if (! CLASSTYPE_COM_INTERFACE (t)) + { + /* The second slot is for the tdesc pointer when thunks are used. */ + if (flag_vtable_thunks) + pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); - /* The first slot is for the rtti offset. */ - pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); + /* The first slot is for the rtti offset. */ + pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); - set_rtti_entry (pending_virtuals, - convert (ssizetype, integer_zero_node), t); + set_rtti_entry (pending_virtuals, + convert (ssizetype, integer_zero_node), t); + } build_vtable (NULL_TREE, t); } else @@ -4040,46 +3967,22 @@ finish_struct_1 (t, warn_anon) else if (has_virtual) { TYPE_BINFO_VIRTUALS (t) = pending_virtuals; - if (write_virtuals >= 0) - DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1; + DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1; } } /* Now lay out the virtual function table. */ if (has_virtual) { - tree atype, itype; - - if (TREE_TYPE (vfield) == ptr_type_node) - { - /* We must create a pointer to this table because - the one inherited from base class does not exist. - We will fill in the type when we know what it - should really be. Use `size_int' so values are memoized - in common cases. */ - itype = build_index_type (size_int (has_virtual)); - atype = build_array_type (vtable_entry_type, itype); - layout_type (atype); - TREE_TYPE (vfield) = build_pointer_type (atype); - } - else - { - atype = TREE_TYPE (TREE_TYPE (vfield)); + /* Use size_int so values are memoized in common cases. */ + tree itype = build_index_type (size_int (has_virtual)); + tree atype = build_cplus_array_type (vtable_entry_type, itype); - if (has_virtual != TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (atype)))) - { - /* We must extend (or create) the boundaries on this array, - because we picked up virtual functions from multiple - base classes. */ - itype = build_index_type (size_int (has_virtual)); - atype = build_array_type (vtable_entry_type, itype); - layout_type (atype); - vfield = copy_node (vfield); - TREE_TYPE (vfield) = build_pointer_type (atype); - } - } + layout_type (atype); CLASSTYPE_VFIELD (t) = vfield; + + /* We may have to grow the vtable. */ if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) { TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; @@ -4123,15 +4026,10 @@ finish_struct_1 (t, warn_anon) TREE_ADDRESSABLE (vfields) = 1; vfields = TREE_CHAIN (vfields); } - if (any_default_members != 0) - build_class_init_list (t); } - else if (TYPE_NEEDS_CONSTRUCTING (t)) - build_class_init_list (t); /* Write out inline function definitions. */ - do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); - CLASSTYPE_INLINE_FRIENDS (t) = 0; + do_inline_function_hair (t, inline_friends); if (CLASSTYPE_VSIZE (t) != 0) { @@ -4158,7 +4056,9 @@ finish_struct_1 (t, warn_anon) /* In addition to this one, all the other vfields should be listed. */ /* Before that can be done, we have to have FIELD_DECLs for them, and a place to find them. */ - TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield); + TYPE_NONCOPIED_PARTS (t) + = tree_cons (default_conversion (TYPE_BINFO_VTABLE (t)), + vfield, TYPE_NONCOPIED_PARTS (t)); if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE) @@ -4207,14 +4107,9 @@ finish_struct_1 (t, warn_anon) references between translation units. */ if (CLASSTYPE_METHOD_VEC (t)) { - extern tree pending_vtables; - /* Don't output full info about any type which does not have its implementation defined here. */ - if (TYPE_VIRTUAL_P (t) && write_virtuals == 2) - TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) - = (value_member (TYPE_IDENTIFIER (t), pending_vtables) == 0); - else if (CLASSTYPE_INTERFACE_ONLY (t)) + if (CLASSTYPE_INTERFACE_ONLY (t)) TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; #if 0 /* XXX do something about this. */ @@ -4230,23 +4125,50 @@ finish_struct_1 (t, warn_anon) /* Finish debugging output for this type. */ rest_of_type_compilation (t, toplevel_bindings_p ()); - return t; + return; +} + +/* When T was built up, the member declarations were added in reverse + order. Rearrange them to declaration order. */ + +void +unreverse_member_declarations (t) + tree t; +{ + tree next; + tree prev; + tree x; + + /* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in + reverse order. Put them in declaration order now. */ + TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); + CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); + + /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in + reverse order, so we can't just use nreverse. */ + prev = NULL_TREE; + for (x = TYPE_FIELDS (t); + x && TREE_CODE (x) != TYPE_DECL; + x = next) + { + next = TREE_CHAIN (x); + TREE_CHAIN (x) = prev; + prev = x; + } + if (prev) + { + TREE_CHAIN (TYPE_FIELDS (t)) = x; + if (prev) + TYPE_FIELDS (t) = prev; + } } tree -finish_struct (t, list_of_fieldlists, attributes, warn_anon) - tree t, list_of_fieldlists, attributes; +finish_struct (t, attributes, warn_anon) + tree t, attributes; int warn_anon; { - tree fields = NULL_TREE; - tree *tail = &TYPE_METHODS (t); - tree specializations = NULL_TREE; - tree *specialization_tail = &specializations; tree name = TYPE_NAME (t); - tree x, last_x = NULL_TREE; - tree access; - tree dummy = NULL_TREE; - tree next_x = NULL_TREE; if (TREE_CODE (name) == TYPE_DECL) { @@ -4260,263 +4182,64 @@ finish_struct (t, list_of_fieldlists, attributes, warn_anon) will fill in the right line number. (mrs) */ if (DECL_SOURCE_LINE (name)) DECL_SOURCE_LINE (name) = lineno; - CLASSTYPE_SOURCE_LINE (t) = lineno; name = DECL_NAME (name); } /* Append the fields we need for constructing signature tables. */ if (IS_SIGNATURE (t)) - append_signature_fields (list_of_fieldlists); + append_signature_fields (t); - /* Move our self-reference declaration to the end of the field list so - any real field with the same name takes precedence. */ - if (list_of_fieldlists - && TREE_VALUE (list_of_fieldlists) - && DECL_ARTIFICIAL (TREE_VALUE (list_of_fieldlists))) - { - dummy = TREE_VALUE (list_of_fieldlists); - list_of_fieldlists = TREE_CHAIN (list_of_fieldlists); - } + /* Now that we've got all the field declarations, reverse everything + as necessary. */ + unreverse_member_declarations (t); - if (last_x && list_of_fieldlists) - TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists); + cplus_decl_attributes (t, attributes, NULL_TREE); - while (list_of_fieldlists) + if (processing_template_decl) { - access = TREE_PURPOSE (list_of_fieldlists); - - /* For signatures, we made all methods `public' in the parser and - reported an error if a access specifier was used. */ - if (access == access_default_node) + tree d = getdecls (); + for (; d; d = TREE_CHAIN (d)) { - if (CLASSTYPE_DECLARED_CLASS (t) == 0) - access = access_public_node; - else - access = access_private_node; + /* If this is the decl for the class or one of the template + parms, we've seen all the injected decls. */ + if ((TREE_CODE (d) == TYPE_DECL + && (TREE_TYPE (d) == t + || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM + || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM)) + || TREE_CODE (d) == CONST_DECL) + break; + /* Don't inject cache decls. */ + else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) + continue; + DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) + = tree_cons (NULL_TREE, d, + DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))); } + finish_struct_methods (t); + TYPE_SIZE (t) = integer_zero_node; + } + else + finish_struct_1 (t, warn_anon); - for (x = TREE_VALUE (list_of_fieldlists); x; x = next_x) - { - next_x = TREE_CHAIN (x); + TYPE_BEING_DEFINED (t) = 0; - TREE_PRIVATE (x) = access == access_private_node; - TREE_PROTECTED (x) = access == access_protected_node; - - if (TREE_CODE (x) == TEMPLATE_DECL) - { - TREE_PRIVATE (DECL_RESULT (x)) = TREE_PRIVATE (x); - TREE_PROTECTED (DECL_RESULT (x)) = TREE_PROTECTED (x); - } - - /* A name N used in a class S shall refer to the same declaration - in its context and when re-evaluated in the completed scope of S. - - Enums, types and static vars have already been checked. */ - if (TREE_CODE (x) != TYPE_DECL && TREE_CODE (x) != USING_DECL - && ! (TREE_CODE (x) == TEMPLATE_DECL - && TREE_CODE (DECL_RESULT (x)) == TYPE_DECL) - && TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL) - { - tree name = DECL_NAME (x); - tree icv; - - /* Don't get confused by access decls. */ - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - icv = IDENTIFIER_CLASS_VALUE (name); - else - icv = NULL_TREE; - - if (icv - && flag_optional_diags - /* Don't complain about constructors. */ - && name != constructor_name (current_class_type) - /* Or inherited names. */ - && id_in_current_class (name) - /* Or shadowed tags. */ - && !(TREE_CODE (icv) == TYPE_DECL - && DECL_CONTEXT (icv) == t)) - { - cp_pedwarn_at ("declaration of identifier `%D' as `%+#D'", - name, x); - cp_pedwarn_at ("conflicts with other use in class as `%#D'", - icv); - } - } - - if (TREE_CODE (x) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (x)) - { - DECL_CLASS_CONTEXT (x) = t; - - if (last_x) - TREE_CHAIN (last_x) = next_x; - - if (DECL_TEMPLATE_SPECIALIZATION (x)) - /* We don't enter the specialization into the class - method vector since specializations don't affect - overloading. Instead we keep track of the - specializations, and process them after the method - vector is complete. */ - { - *specialization_tail = x; - specialization_tail = &TREE_CHAIN (x); - TREE_CHAIN (x) = NULL_TREE; - continue; - } - - /* Link x onto end of TYPE_METHODS. */ - *tail = x; - tail = &TREE_CHAIN (x); - continue; - } - - if (TREE_CODE (x) != TYPE_DECL) - DECL_FIELD_CONTEXT (x) = t; - - if (! fields) - fields = x; - last_x = x; - } - list_of_fieldlists = TREE_CHAIN (list_of_fieldlists); - /* link the tail while we have it! */ - if (last_x) - { - TREE_CHAIN (last_x) = NULL_TREE; - - if (list_of_fieldlists - && TREE_VALUE (list_of_fieldlists) - && TREE_CODE (TREE_VALUE (list_of_fieldlists)) != FUNCTION_DECL) - TREE_CHAIN (last_x) = TREE_VALUE (list_of_fieldlists); - } - } - - /* Now add the tags, if any, to the list of TYPE_DECLs - defined for this type. */ - if (CLASSTYPE_TAGS (t) || dummy) - { - /* The list of tags was built up in pushtag in reverse order; we need - to fix that so that enumerators will be processed in forward order - in template instantiation. */ - CLASSTYPE_TAGS (t) = x = nreverse (CLASSTYPE_TAGS (t)); - while (x) - { - tree tag_type = TREE_VALUE (x); - tree tag = TYPE_MAIN_DECL (TREE_VALUE (x)); - - if (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type)) - && CLASSTYPE_IS_TEMPLATE (tag_type)) - tag = CLASSTYPE_TI_TEMPLATE (tag_type); - - TREE_NONLOCAL_FLAG (tag_type) = 0; - x = TREE_CHAIN (x); - last_x = chainon (last_x, tag); - } - if (dummy) - last_x = chainon (last_x, dummy); - if (fields == NULL_TREE) - fields = last_x; - CLASSTYPE_LOCAL_TYPEDECLS (t) = 1; - } - - *tail = NULL_TREE; - TYPE_FIELDS (t) = fields; - - cplus_decl_attributes (t, attributes, NULL_TREE); - - if (processing_template_decl) - { - tree d = getdecls (); - for (; d; d = TREE_CHAIN (d)) - { - /* If this is the decl for the class or one of the template - parms, we've seen all the injected decls. */ - if ((TREE_CODE (d) == TYPE_DECL - && (TREE_TYPE (d) == t - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM)) - || TREE_CODE (d) == CONST_DECL) - break; - /* Don't inject cache decls. */ - else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) - continue; - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) - = tree_cons (NULL_TREE, d, - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))); - } - CLASSTYPE_METHOD_VEC (t) - = finish_struct_methods (t, TYPE_METHODS (t), 1); - TYPE_SIZE (t) = integer_zero_node; - } - else - t = finish_struct_1 (t, warn_anon); - - TYPE_BEING_DEFINED (t) = 0; - - /* Now, figure out which member templates we're specializing. */ - for (x = specializations; x != NULL_TREE; x = TREE_CHAIN (x)) - { - tree spec_args; - tree fn; - int pending_specialization; - - if (uses_template_parms (t)) - /* If t is a template class, and x is a specialization, then x - is itself really a template. Due to the vagaries of the - parser, however, we will have a handle to a function - declaration, rather than the template declaration, at this - point. */ - { - my_friendly_assert (DECL_TEMPLATE_INFO (x) != NULL_TREE, 0); - my_friendly_assert (DECL_TI_TEMPLATE (x) != NULL_TREE, 0); - fn = DECL_TI_TEMPLATE (x); - } - else - fn = x; - - /* We want the specialization arguments, which will be the - innermost ones. */ - if (DECL_TI_ARGS (fn) && TREE_CODE (DECL_TI_ARGS (fn)) == TREE_VEC) - spec_args - = TREE_VEC_ELT (DECL_TI_ARGS (fn), 0); - else - spec_args = DECL_TI_ARGS (fn); - - pending_specialization - = TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn)); - check_explicit_specialization - (lookup_template_function (DECL_NAME (fn), spec_args), - fn, 0, 1 | (8 * pending_specialization)); - TI_PENDING_SPECIALIZATION_FLAG (DECL_TEMPLATE_INFO (fn)) = 0; - - /* Now, the assembler name will be correct for fn, so we - make its RTL. */ - DECL_RTL (fn) = 0; - make_decl_rtl (fn, NULL_PTR, 1); - - if (x != fn) - { - DECL_RTL (x) = 0; - make_decl_rtl (x, NULL_PTR, 1); - } - } - - if (current_class_type) - popclass (0); - else - error ("trying to finish struct, but kicked out due to previous parse errors."); + if (current_class_type) + popclass (); + else + error ("trying to finish struct, but kicked out due to previous parse errors."); return t; } -/* Return non-zero if the effective type of INSTANCE is static. +/* Return the dynamic type of INSTANCE, if known. Used to determine whether the virtual function table is needed or not. *NONNULL is set iff INSTANCE can be known to be nonnull, regardless of our knowledge of its type. */ -int -resolves_to_fixed_type_p (instance, nonnull) +static tree +fixed_type_or_null (instance, nonnull) tree instance; int *nonnull; { @@ -4534,9 +4257,9 @@ resolves_to_fixed_type_p (instance, nonnull) { if (nonnull) *nonnull = 1; - return 1; + return TREE_TYPE (instance); } - return 0; + return NULL_TREE; case SAVE_EXPR: /* This is a call to a constructor, hence it's never zero. */ @@ -4544,33 +4267,33 @@ resolves_to_fixed_type_p (instance, nonnull) { if (nonnull) *nonnull = 1; - return 1; + return TREE_TYPE (instance); } - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); + return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case RTL_EXPR: - return 0; + return NULL_TREE; case PLUS_EXPR: case MINUS_EXPR: if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST) /* Propagate nonnull. */ - resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); + fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR) - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); - return 0; + return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); + return NULL_TREE; case NOP_EXPR: case CONVERT_EXPR: - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); + return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case ADDR_EXPR: if (nonnull) *nonnull = 1; - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 0), nonnull); + return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); case COMPONENT_REF: - return resolves_to_fixed_type_p (TREE_OPERAND (instance, 1), nonnull); + return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull); case VAR_DECL: case FIELD_DECL: @@ -4579,7 +4302,7 @@ resolves_to_fixed_type_p (instance, nonnull) { if (nonnull) *nonnull = 1; - return 1; + return TREE_TYPE (TREE_TYPE (instance)); } /* fall through... */ case TARGET_EXPR: @@ -4588,37 +4311,65 @@ resolves_to_fixed_type_p (instance, nonnull) { if (nonnull) *nonnull = 1; - return 1; + return TREE_TYPE (instance); } else if (nonnull) { if (instance == current_class_ptr && flag_this_is_variable <= 0) { - /* Some people still use `this = 0' inside destructors. */ - *nonnull = ! DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (current_function_decl)); - /* In a constructor, we know our type. */ + /* Normally, 'this' must be non-null. */ + if (flag_this_is_variable == 0) + *nonnull = 1; + + /* <0 means we're in a constructor and we know our type. */ if (flag_this_is_variable < 0) - return 1; + return TREE_TYPE (TREE_TYPE (instance)); } else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) /* Reference variables should be references to objects. */ *nonnull = 1; } - return 0; + return NULL_TREE; default: - return 0; + return NULL_TREE; } } + +/* Return non-zero if the dynamic type of INSTANCE is known, and equivalent + to the static type. We also handle the case where INSTANCE is really + a pointer. + + Used to determine whether the virtual function table is needed + or not. + + *NONNULL is set iff INSTANCE can be known to be nonnull, regardless + of our knowledge of its type. */ + +int +resolves_to_fixed_type_p (instance, nonnull) + tree instance; + int *nonnull; +{ + tree t = TREE_TYPE (instance); + tree fixed = fixed_type_or_null (instance, nonnull); + if (fixed == NULL_TREE) + return 0; + if (POINTER_TYPE_P (t)) + t = TREE_TYPE (t); + return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed)); +} + void init_class_processing () { current_class_depth = 0; - current_class_stacksize = 10; - current_class_base = (tree *)xmalloc(current_class_stacksize * sizeof (tree)); - current_class_stack = current_class_base; + current_class_stack_size = 10; + current_class_stack + = (class_stack_node_t) xmalloc (current_class_stack_size + * sizeof (struct class_stack_node)); current_lang_stacksize = 10; current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree)); @@ -4680,34 +4431,56 @@ pushclass (type, modify) int modify; { type = TYPE_MAIN_VARIANT (type); - push_memoized_context (type, modify); - current_class_depth++; - *current_class_stack++ = current_class_name; - *current_class_stack++ = current_class_type; - if (current_class_stack >= current_class_base + current_class_stacksize) + /* Make sure there is enough room for the new entry on the stack. */ + if (current_class_depth + 1 >= current_class_stack_size) { - current_class_base - = (tree *)xrealloc (current_class_base, - sizeof (tree) * (current_class_stacksize + 10)); - current_class_stack = current_class_base + current_class_stacksize; - current_class_stacksize += 10; + 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)); } + /* Insert a new entry on the class stack. */ + current_class_stack[current_class_depth].name = current_class_name; + current_class_stack[current_class_depth].type = current_class_type; + current_class_stack[current_class_depth].access = current_access_specifier; + current_class_stack[current_class_depth].names_used = 0; + current_class_depth++; + + /* Now set up the new type. */ current_class_name = TYPE_NAME (type); if (TREE_CODE (current_class_name) == TYPE_DECL) current_class_name = DECL_NAME (current_class_name); current_class_type = type; + /* By default, things in classes are private, while things in + structures or unions are public. */ + current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type) + ? access_private_node + : access_public_node); + if (previous_class_type != NULL_TREE - && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE) + && (type != previous_class_type + || TYPE_SIZE (previous_class_type) == NULL_TREE) && current_class_depth == 1) { /* Forcibly remove any old class remnants. */ - popclass (-1); - previous_class_type = NULL_TREE; + invalidate_class_lookup_cache (); + + /* Now, free the obstack on which we cached all the values. */ + if (class_cache_firstobj) + obstack_free (&class_cache_obstack, class_cache_firstobj); + class_cache_firstobj + = (char*) obstack_finish (&class_cache_obstack); } + /* If we're about to enter a nested class, clear + IDENTIFIER_CLASS_VALUE for the enclosing classes. */ + if (modify && current_class_depth > 1) + clear_identifier_class_values (); + pushlevel_class (); #if 0 @@ -4717,122 +4490,70 @@ pushclass (type, modify) if (modify) { - tree tags; - tree this_fndecl = current_function_decl; - - if (current_function_decl - && DECL_CONTEXT (current_function_decl) - && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL) - current_function_decl = DECL_CONTEXT (current_function_decl); - else - current_function_decl = NULL_TREE; - if (type != previous_class_type || current_class_depth > 1) - { -#ifdef MI_MATRIX - build_mi_matrix (type); - push_class_decls (type); - free_mi_matrix (); -#else - push_class_decls (type); -#endif - } + push_class_decls (type); else { tree item; - /* Hooray, we successfully cached; let's just install the - cached class_shadowed list, and walk through it to get the - IDENTIFIER_TYPE_VALUEs correct. */ + /* 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 = IDENTIFIER_CLASS_VALUE (id); + 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); } - for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) - { - tree tag_type = TREE_VALUE (tags); + storetags (CLASSTYPE_TAGS (type)); + } +} - TREE_NONLOCAL_FLAG (tag_type) = 1; - if (! TREE_PURPOSE (tags)) - continue; - if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type)) - && CLASSTYPE_IS_TEMPLATE (tag_type))) - pushtag (TREE_PURPOSE (tags), tag_type, 0); - else - pushdecl_class_level (CLASSTYPE_TI_TEMPLATE (tag_type)); - } +/* When we exit a toplevel class scope, we save the + IDENTIFIER_CLASS_VALUEs so that we can restore them quickly if we + reenter the class. Here, we've entered some other class, so we + must invalidate our cache. */ - current_function_decl = this_fndecl; - } +void +invalidate_class_lookup_cache () +{ + tree t; + + /* This code can be seen as a cache miss. When we've cached a + class' scope's bindings and we can't use them, we need to reset + them. This is it! */ + for (t = previous_class_values; t; t = TREE_CHAIN (t)) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; + + previous_class_type = NULL_TREE; } /* Get out of the current class scope. If we were in a class scope - previously, that is the one popped to. The flag MODIFY tells whether - the current scope declarations needs to be modified as a result of - popping to the previous scope. 0 is used for class definitions. */ + previously, that is the one popped to. */ void -popclass (modify) - int modify; +popclass () { - if (modify < 0) - { - /* Back this old class out completely. */ - tree tags = CLASSTYPE_TAGS (previous_class_type); - tree t; - - /* This code can be seen as a cache miss. When we've cached a - class' scope's bindings and we can't use them, we need to reset - them. This is it! */ - for (t = previous_class_values; t; t = TREE_CHAIN (t)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } - goto ret; - } - - if (modify) - { - /* Just remove from this class what didn't make - it into IDENTIFIER_CLASS_VALUE. */ - tree tags = CLASSTYPE_TAGS (current_class_type); - - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } - } - - /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition, - since not all class decls make it there currently. */ - poplevel_class (! modify); - + poplevel (1, 0, 0); /* Since poplevel_class does the popping of class decls nowadays, - this really only frees the obstack used for these decls. - That's why it had to be moved down here. */ - if (modify) - pop_class_decls (); + this really only frees the obstack used for these decls. */ + pop_class_decls (); current_class_depth--; - current_class_type = *--current_class_stack; - current_class_name = *--current_class_stack; - - pop_memoized_context (modify); - - ret: - ; + current_class_name = current_class_stack[current_class_depth].name; + current_class_type = current_class_stack[current_class_depth].type; + current_access_specifier = current_class_stack[current_class_depth].access; + if (current_class_stack[current_class_depth].names_used) + splay_tree_delete (current_class_stack[current_class_depth].names_used); } /* Returns 1 if current_class_type is either T or a nested type of T. */ @@ -4845,7 +4566,7 @@ currently_open_class (t) if (t == current_class_type) return 1; for (i = 0; i < current_class_depth; ++i) - if (current_class_stack [-i*2 - 1] == t) + if (current_class_stack [i].type == t) return 1; return 0; } @@ -4864,16 +4585,16 @@ push_nested_class (type, modify) { tree context; - my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711); - + /* A namespace might be passed in error cases, like A::B:C. */ if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type) + || TREE_CODE (type) == NAMESPACE_DECL || TREE_CODE (type) == TEMPLATE_TYPE_PARM || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) return; context = DECL_CONTEXT (TYPE_MAIN_DECL (type)); - if (context && TREE_CODE (context) == RECORD_TYPE) + if (context && CLASS_TYPE_P (context)) push_nested_class (context, 2); pushclass (type, modify); } @@ -4881,14 +4602,13 @@ push_nested_class (type, modify) /* Undoes a push_nested_class call. MODIFY is passed on to popclass. */ void -pop_nested_class (modify) - int modify; +pop_nested_class () { tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type)); - popclass (modify); - if (context && TREE_CODE (context) == RECORD_TYPE) - pop_nested_class (modify); + popclass (); + if (context && CLASS_TYPE_P (context)) + pop_nested_class (); } /* Set global variables CURRENT_LANG_NAME to appropriate value @@ -4908,11 +4628,28 @@ push_lang_context (name) current_lang_stacksize += 10; } - if (name == lang_name_cplusplus || name == lang_name_java) + if (name == lang_name_cplusplus) { strict_prototype = strict_prototypes_lang_cplusplus; current_lang_name = name; } + else if (name == lang_name_java) + { + strict_prototype = strict_prototypes_lang_cplusplus; + current_lang_name = name; + /* DECL_IGNORED_P is initially set for these types, to avoid clutter. + (See record_builtin_java_type in decl.c.) However, that causes + incorrect debug entries if these types are actually used. + So we re-enable debug output after extern "Java". */ + DECL_IGNORED_P (java_byte_type_node) = 0; + DECL_IGNORED_P (java_short_type_node) = 0; + DECL_IGNORED_P (java_int_type_node) = 0; + DECL_IGNORED_P (java_long_type_node) = 0; + DECL_IGNORED_P (java_float_type_node) = 0; + DECL_IGNORED_P (java_double_type_node) = 0; + DECL_IGNORED_P (java_char_type_node) = 0; + DECL_IGNORED_P (java_boolean_type_node) = 0; + } else if (name == lang_name_c) { strict_prototype = strict_prototypes_lang_c; @@ -4937,46 +4674,273 @@ pop_lang_context () /* Type instantiation routines. */ +/* 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 + non-zero. If TEMPLATE_ONLY, the name of the overloaded function + was a template-id, and EXPLICIT_TARGS are the explicitly provided + template arguments. */ + static tree -validate_lhs (lhstype, complain) - tree lhstype; +resolve_address_of_overloaded_function (target_type, + overload, + complain, + template_only, + explicit_targs) + tree target_type; + tree overload; int complain; + int template_only; + tree explicit_targs; { - if (TYPE_PTRMEMFUNC_P (lhstype)) - lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); + /* Here's what the standard says: + + [over.over] + + If the name is a function template, template argument deduction + is done, and if the argument deduction succeeds, the deduced + arguments are used to generate a single template function, which + is added to the set of overloaded functions considered. + + Non-member functions and static member functions match targets of + type "pointer-to-function" or "reference-to-function." Nonstatic + member functions match targets of type "pointer-to-member + function;" the function type of the pointer to member is used to + select the member function from the set of overloaded member + functions. If a nonstatic member function is selected, the + reference to the overloaded function name is required to have the + form of a pointer to member as described in 5.3.1. + + If more than one function is selected, any template functions in + the set are eliminated if the set also contains a non-template + function, and any given template function is eliminated if the + set contains a second template function that is more specialized + than the first according to the partial ordering rules 14.5.5.2. + After such eliminations, if any, there shall remain exactly one + selected function. */ + + int is_ptrmem = 0; + int is_reference = 0; + /* We store the matches in a TREE_LIST rooted here. The functions + are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy + interoperability with most_specialized_instantiation. */ + tree matches = NULL_TREE; + tree fn; + + /* By the time we get here, we should be seeing only real + pointer-to-member types, not the internal POINTER_TYPE to + METHOD_TYPE representation. */ + my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE + && (TREE_CODE (TREE_TYPE (target_type)) + == METHOD_TYPE)), 0); + + /* Check that the TARGET_TYPE is reasonable. */ + if (TYPE_PTRFN_P (target_type)) + /* This is OK. */ + ; + else if (TYPE_PTRMEMFUNC_P (target_type)) + /* This is OK, too. */ + is_ptrmem = 1; + else if (TREE_CODE (target_type) == FUNCTION_TYPE) + { + /* This is OK, too. This comes from a conversion to reference + type. */ + target_type = build_reference_type (target_type); + is_reference = 1; + } + else + { + if (complain) + cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'", + DECL_NAME (OVL_FUNCTION (overload)), target_type); + return error_mark_node; + } + + /* If we can find a non-template function that matches, we can just + use it. There's no point in generating template instantiations + if we're just going to throw them out anyhow. But, of course, we + can only do this when we don't *need* a template function. */ + if (!template_only) + { + tree fns; - if (TREE_CODE (lhstype) == POINTER_TYPE) + for (fns = overload; fns; fns = OVL_CHAIN (fns)) + { + tree fn = OVL_FUNCTION (fns); + tree fntype; + + if (TREE_CODE (fn) == TEMPLATE_DECL) + /* We're not looking for templates just yet. */ + continue; + + if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) + != is_ptrmem) + /* We're looking for a non-static member, and this isn't + one, or vice versa. */ + continue; + + /* See if there's a match. */ + fntype = TREE_TYPE (fn); + if (is_ptrmem) + fntype = build_ptrmemfunc_type (build_pointer_type (fntype)); + else if (!is_reference) + fntype = build_pointer_type (fntype); + + if (can_convert_arg (target_type, fntype, fn)) + matches = scratch_tree_cons (fn, NULL_TREE, matches); + } + } + + /* Now, if we've already got a match (or matches), there's no need + to proceed to the template functions. But, if we don't have a + match we need to look at them, too. */ + if (!matches) { - if (TREE_CODE (TREE_TYPE (lhstype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) - lhstype = TREE_TYPE (lhstype); + tree target_fn_type; + tree target_arg_types; + tree fns; + + if (is_ptrmem) + target_fn_type + = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type)); else + target_fn_type = TREE_TYPE (target_type); + target_arg_types = TYPE_ARG_TYPES (target_fn_type); + + for (fns = overload; fns; fns = OVL_CHAIN (fns)) { - if (complain) - error ("invalid type combination for overload"); - return error_mark_node; + tree fn = OVL_FUNCTION (fns); + tree instantiation; + tree instantiation_type; + tree targs; + + if (TREE_CODE (fn) != TEMPLATE_DECL) + /* We're only looking for templates. */ + continue; + + if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) + != is_ptrmem) + /* We're not looking for a non-static member, and this is + one, or vice versa. */ + continue; + + /* Try to do argument deduction. */ + targs = make_scratch_vec (DECL_NTPARMS (fn)); + if (fn_type_unification (fn, explicit_targs, targs, + target_arg_types, NULL_TREE, + DEDUCE_EXACT) != 0) + /* Argument deduction failed. */ + continue; + + /* Instantiate the template. */ + instantiation = instantiate_template (fn, targs); + if (instantiation == error_mark_node) + /* Instantiation failed. */ + continue; + + /* See if there's a match. */ + instantiation_type = TREE_TYPE (instantiation); + if (is_ptrmem) + instantiation_type = + build_ptrmemfunc_type (build_pointer_type (instantiation_type)); + else if (!is_reference) + instantiation_type = build_pointer_type (instantiation_type); + if (can_convert_arg (target_type, instantiation_type, instantiation)) + matches = scratch_tree_cons (instantiation, fn, matches); } + + /* Now, remove all but the most specialized of the matches. */ + if (matches) + { + tree match = most_specialized_instantiation (matches, + explicit_targs); + + if (match != error_mark_node) + matches = scratch_tree_cons (match, NULL_TREE, NULL_TREE); + } + } + + /* Now we should have exactly one function in MATCHES. */ + if (matches == NULL_TREE) + { + /* There were *no* matches. */ + if (complain) + { + cp_error ("no matches converting function `%D' to type `%#T'", + DECL_NAME (OVL_FUNCTION (overload)), + target_type); + + /* print_candidates expects a chain with the functions in + TREE_VALUE slots, so we cons one up here (we're losing anyway, + so why be clever?). */ + for (; overload; overload = OVL_NEXT (overload)) + matches = scratch_tree_cons (NULL_TREE, OVL_CURRENT (overload), + matches); + + print_candidates (matches); + } + return error_mark_node; + } + else if (TREE_CHAIN (matches)) + { + /* There were too many matches. */ + + if (complain) + { + tree match; + + cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous", + DECL_NAME (OVL_FUNCTION (overload)), + target_type); + + /* Since print_candidates expects the functions in the + TREE_VALUE slot, we flip them here. */ + for (match = matches; match; match = TREE_CHAIN (match)) + TREE_VALUE (match) = TREE_PURPOSE (match); + + print_candidates (matches); + } + + return error_mark_node; + } + + /* Good, exactly one match. Now, convert it to the correct type. */ + fn = TREE_PURPOSE (matches); + + mark_used (fn); + + if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type)) + return build_unary_op (ADDR_EXPR, fn, 0); + else + { + /* The target must be a REFERENCE_TYPE. Above, build_unary_op + will mark the function as addressed, but here we must do it + explicitly. */ + mark_addressable (fn); + + return fn; } - return lhstype; } /* 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. If only complain is COMPLAIN is set. If we are + error_mark_node. We only complain is COMPLAIN is set. If we are not complaining, never modify rhs, as overload resolution wants to try many possible instantiations, in hopes that at least one will work. - This function is used in build_modify_expr, convert_arguments, - build_c_cast, and compute_conversion_costs. */ + FLAGS is a bitmask, as we see at the top of the function. + + For non-recursive calls, LHSTYPE should be a function, pointer to + function, or a pointer to member function. */ tree -instantiate_type (lhstype, rhs, complain) +instantiate_type (lhstype, rhs, flags) tree lhstype, rhs; - int complain; + int flags; { - tree explicit_targs = NULL_TREE; - int template_only = 0; + int complain = (flags & 1); + int strict = (flags & 2) ? COMPARE_NO_ATTRIBUTES : COMPARE_STRICT; if (TREE_CODE (lhstype) == UNKNOWN_TYPE) { @@ -4987,7 +4951,7 @@ instantiate_type (lhstype, rhs, complain) if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs))) { - if (comptypes (lhstype, TREE_TYPE (rhs), 1)) + if (comptypes (lhstype, TREE_TYPE (rhs), strict)) return rhs; if (complain) cp_error ("argument of type `%T' does not match `%T'", @@ -5021,7 +4985,7 @@ instantiate_type (lhstype, rhs, complain) tree new_rhs; new_rhs = instantiate_type (build_pointer_type (lhstype), - TREE_OPERAND (rhs, 0), complain); + TREE_OPERAND (rhs, 0), flags); if (new_rhs == error_mark_node) return error_mark_node; @@ -5033,312 +4997,71 @@ instantiate_type (lhstype, rhs, complain) case NOP_EXPR: rhs = copy_node (TREE_OPERAND (rhs, 0)); TREE_TYPE (rhs) = unknown_type_node; - return instantiate_type (lhstype, rhs, complain); + return instantiate_type (lhstype, rhs, flags); case COMPONENT_REF: { tree field = TREE_OPERAND (rhs, 1); - if (TREE_CODE (field) == TREE_LIST) - { - tree function = instantiate_type (lhstype, field, complain); - if (function == error_mark_node) - return error_mark_node; - my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 185); - if (DECL_VINDEX (function)) - { - tree base = TREE_OPERAND (rhs, 0); - tree base_ptr = build_unary_op (ADDR_EXPR, base, 0); - if (base_ptr == error_mark_node) - return error_mark_node; - base_ptr = convert_pointer_to (DECL_CONTEXT (function), base_ptr); - if (base_ptr == error_mark_node) - return error_mark_node; - return build_vfn_ref (&base_ptr, base, DECL_VINDEX (function)); - } - mark_used (function); - return function; - } - - /* I could not trigger this code. MvL */ - my_friendly_abort (980326); -#if 0 - my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 178); - my_friendly_assert (!(TREE_CODE (TREE_TYPE (field)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (field)) == METHOD_TYPE), - 179); - - TREE_TYPE (rhs) = lhstype; - /* First look for an exact match */ + tree r; - while (field && TREE_TYPE (field) != lhstype) - field = DECL_CHAIN (field); - if (field) - { - TREE_OPERAND (rhs, 1) = field; - mark_used (field); - return rhs; - } + r = instantiate_type (lhstype, field, flags); - /* No exact match found, look for a compatible function. */ - field = TREE_OPERAND (rhs, 1); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = DECL_CHAIN (field); - if (field) + if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)) { - TREE_OPERAND (rhs, 1) = field; - field = DECL_CHAIN (field); - while (field && ! comptypes (lhstype, TREE_TYPE (field), 0)) - field = DECL_CHAIN (field); - if (field) + if (complain) { - if (complain) - error ("ambiguous overload for COMPONENT_REF requested"); - return error_mark_node; + tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype); + + if (TREE_CODE (field) == OVERLOAD) + field = OVL_FUNCTION (field); + if (TREE_CODE (field) == FUNCTION_DECL) + { + cp_pedwarn ("object-dependent reference `%E' can only be used in a call", + DECL_NAME (field)); + cp_pedwarn (" to form a pointer to member function, say `&%T::%E'", + t, DECL_NAME (field)); + } + else + cp_pedwarn ("object-dependent reference can only be used in a call"); } + return r; } - else - { - if (complain) - error ("no appropriate overload exists for COMPONENT_REF"); - return error_mark_node; - } -#endif - return rhs; + + return r; } case OFFSET_REF: + rhs = TREE_OPERAND (rhs, 1); + if (BASELINK_P (rhs)) + return instantiate_type (lhstype, TREE_VALUE (rhs), flags); + /* This can happen if we are forming a pointer-to-member for a member template. */ - rhs = TREE_OPERAND (rhs, 1); my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0); - + /* Fall through. */ case TEMPLATE_ID_EXPR: - { - explicit_targs = TREE_OPERAND (rhs, 1); - template_only = 1; - rhs = TREE_OPERAND (rhs, 0); - } - /* fall through */ - my_friendly_assert (TREE_CODE (rhs) == OVERLOAD, 980401); + return + resolve_address_of_overloaded_function (lhstype, + TREE_OPERAND (rhs, 0), + complain, + /*template_only=*/1, + TREE_OPERAND (rhs, 1)); case OVERLOAD: - { - tree elem, elems; - - /* Check that the LHSTYPE and the RHS are reasonable. */ - lhstype = validate_lhs (lhstype, complain); - if (lhstype == error_mark_node) - return lhstype; - - if (TREE_CODE (lhstype) != FUNCTION_TYPE - && TREE_CODE (lhstype) != METHOD_TYPE) - { - if (complain) - cp_error("cannot resolve overloaded function `%D' " - "based on non-function type", - DECL_NAME (OVL_FUNCTION (rhs))); - return error_mark_node; - } - - /* Look for an exact match, by searching through the - overloaded functions. */ - if (template_only) - /* If we're processing a template-id, only a template - function can match, so we don't look through the - overloaded functions. */ - ; - else for (elems = rhs; elems; elems = OVL_CHAIN (elems)) - { - elem = OVL_FUNCTION (elems); - if (comptypes (lhstype, TREE_TYPE (elem), 1)) - { - mark_used (elem); - return elem; - } - } - - /* No overloaded function was an exact match. See if we can - instantiate some template to match. */ - { - tree save_elem = 0; - elems = rhs; - if (TREE_CODE (elems) == TREE_LIST) - elems = TREE_VALUE (rhs); - for (; elems; elems = OVL_NEXT (elems)) - if (TREE_CODE (elem = OVL_CURRENT (elems)) == TEMPLATE_DECL) - { - int n = DECL_NTPARMS (elem); - tree t = make_scratch_vec (n); - int i; - i = type_unification - (DECL_INNERMOST_TEMPLATE_PARMS (elem), t, - TYPE_ARG_TYPES (TREE_TYPE (elem)), - TYPE_ARG_TYPES (lhstype), explicit_targs, DEDUCE_EXACT, 1); - if (i == 0) - { - if (save_elem) - { - cp_error ("ambiguous template instantiation converting to `%#T'", lhstype); - return error_mark_node; - } - save_elem = instantiate_template (elem, t); - /* Check the return type. */ - if (! comptypes (TREE_TYPE (lhstype), - TREE_TYPE (TREE_TYPE (save_elem)), 1)) - save_elem = 0; - } - } - if (save_elem) - { - mark_used (save_elem); - return save_elem; - } - } - - /* There's no exact match, and no templates can be - instantiated to match. The last thing we try is to see if - some ordinary overloaded function is close enough. If - we're only looking for template functions, we don't do - this. */ - if (!template_only) - { - for (elems = rhs; elems; elems = OVL_NEXT (elems)) - { - elem = OVL_CURRENT (elems); - if (comp_target_types (lhstype, TREE_TYPE (elem), 1) > 0) - break; - } - if (elems) - { - tree save_elem = elem; - for (elems = OVL_CHAIN (elems); elems; - elems = OVL_CHAIN (elems)) - { - elem = OVL_FUNCTION (elems); - if (comp_target_types (lhstype, TREE_TYPE (elem), 0) > 0) - break; - } - if (elems) - { - if (complain) - { - cp_error - ("cannot resolve overload to target type `%#T'", - lhstype); - cp_error_at (" ambiguity between `%#D'", save_elem); - cp_error_at (" and `%#D', at least", elem); - } - return error_mark_node; - } - mark_used (save_elem); - return save_elem; - } - } - - /* We failed to find a match. */ - if (complain) - { - cp_error ("cannot resolve overload to target type `%#T'", lhstype); - cp_error - (" because no suitable overload of function `%D' exists", - DECL_NAME (OVL_FUNCTION (rhs))); - } - return error_mark_node; - } + return + resolve_address_of_overloaded_function (lhstype, + rhs, + complain, + /*template_only=*/0, + /*explicit_targs=*/NULL_TREE); case TREE_LIST: - { - tree elem, baselink, name = NULL_TREE; + /* Now we should have a baselink. */ + my_friendly_assert (BASELINK_P (rhs), 990412); - if (TREE_PURPOSE (rhs) == error_mark_node) - { - /* Make sure we don't drop the non-local flag, as the old code - would rely on it. */ - int nl = TREE_NONLOCAL_FLAG (rhs); - /* We don't need the type of this node. */ - rhs = TREE_VALUE (rhs); - my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331); - } - - /* Now we should have a baselink. */ - my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC, - 980331); - /* First look for an exact match. Search member functions. - May have to undo what `default_conversion' might do to - lhstype. */ - - lhstype = validate_lhs (lhstype, complain); - if (lhstype == error_mark_node) - return lhstype; - - my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181); - my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL - || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD, - 182); - - for (baselink = rhs; baselink; - baselink = next_baselink (baselink)) - { - elem = TREE_VALUE (baselink); - while (elem) - if (comptypes (lhstype, TREE_TYPE (OVL_CURRENT (elem)), 1)) - { - mark_used (OVL_CURRENT (elem)); - return OVL_CURRENT (elem); - } - else - elem = OVL_NEXT (elem); - } - - /* No exact match found, look for a compatible method. */ - for (baselink = rhs; baselink; - baselink = next_baselink (baselink)) - { - elem = TREE_VALUE (baselink); - for (; elem; elem = OVL_NEXT (elem)) - if (comp_target_types (lhstype, - TREE_TYPE (OVL_CURRENT (elem)), 1) > 0) - break; - if (elem) - { - tree save_elem = OVL_CURRENT (elem); - for (elem = OVL_NEXT (elem); elem; elem = OVL_NEXT (elem)) - if (comp_target_types (lhstype, - TREE_TYPE (OVL_CURRENT (elem)), 0) > 0) - break; - if (elem) - { - if (complain) - error ("ambiguous overload for overloaded method requested"); - return error_mark_node; - } - mark_used (save_elem); - return save_elem; - } - name = rhs; - while (TREE_CODE (name) == TREE_LIST) - name = TREE_VALUE (name); - name = DECL_NAME (OVL_CURRENT (name)); -#if 0 - if (TREE_CODE (lhstype) == FUNCTION_TYPE && globals < 0) - { - /* Try to instantiate from non-member functions. */ - rhs = lookup_name_nonclass (name); - if (rhs && TREE_CODE (rhs) == TREE_LIST) - { - /* This code seems to be missing a `return'. */ - my_friendly_abort (4); - instantiate_type (lhstype, rhs, complain); - } - } -#endif - } - if (complain) - cp_error ("no compatible member functions named `%D'", name); - return error_mark_node; - } + return instantiate_type (lhstype, TREE_VALUE (rhs), flags); case CALL_EXPR: /* This is too hard for now. */ @@ -5349,11 +5072,11 @@ instantiate_type (lhstype, rhs, complain) case MINUS_EXPR: case COMPOUND_EXPR: TREE_OPERAND (rhs, 0) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); + = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); if (TREE_OPERAND (rhs, 0) == error_mark_node) return error_mark_node; TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); + = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; @@ -5421,11 +5144,11 @@ instantiate_type (lhstype, rhs, complain) return error_mark_node; } TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); + = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; TREE_OPERAND (rhs, 2) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain); + = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), flags); if (TREE_OPERAND (rhs, 2) == error_mark_node) return error_mark_node; @@ -5434,7 +5157,7 @@ instantiate_type (lhstype, rhs, complain) case MODIFY_EXPR: TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); + = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), flags); if (TREE_OPERAND (rhs, 1) == error_mark_node) return error_mark_node; @@ -5442,30 +5165,7 @@ instantiate_type (lhstype, rhs, complain) return rhs; case ADDR_EXPR: - if (TYPE_PTRMEMFUNC_P (lhstype)) - lhstype = TYPE_PTRMEMFUNC_FN_TYPE (lhstype); - else if (TREE_CODE (lhstype) != POINTER_TYPE) - { - if (complain) - error ("type for resolving address of overloaded function must be pointer type"); - return error_mark_node; - } - { - tree fn = instantiate_type (TREE_TYPE (lhstype), TREE_OPERAND (rhs, 0), complain); - if (fn == error_mark_node) - return error_mark_node; - mark_addressable (fn); - TREE_TYPE (rhs) = lhstype; - TREE_OPERAND (rhs, 0) = fn; - TREE_CONSTANT (rhs) = staticp (fn); - if (TREE_CODE (lhstype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (lhstype)) == METHOD_TYPE) - { - build_ptrmemfunc_type (lhstype); - rhs = build_ptrmemfunc (lhstype, rhs, 0); - } - } - return rhs; + return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), flags); case ENTRY_VALUE_EXPR: my_friendly_abort (184); @@ -5524,16 +5224,24 @@ print_class_statistics () } /* Push an obstack which is sufficiently long-lived to hold such class - decls that may be cached in the previous_class_values list. For now, let's - use the permanent obstack, later we may create a dedicated obstack just - for this purpose. The effect is undone by pop_obstacks. */ + decls that may be cached in the previous_class_values list. The + effect is undone by pop_obstacks. */ void -maybe_push_cache_obstack () +push_cache_obstack () { + static int cache_obstack_initialized; + + if (!cache_obstack_initialized) + { + gcc_obstack_init (&class_cache_obstack); + class_cache_firstobj + = (char*) obstack_finish (&class_cache_obstack); + cache_obstack_initialized = 1; + } + push_obstacks_nochange (); - if (current_class_depth == 1) - current_obstack = &permanent_obstack; + current_obstack = &class_cache_obstack; } /* Build a dummy reference to ourselves so Derived::Base (and A::A) works, @@ -5542,19 +5250,22 @@ maybe_push_cache_obstack () into the scope of the class itself. For purposes of access checking, the inserted class name is treated as if it were a public member name. */ -tree +void build_self_reference () { tree name = constructor_name (current_class_type); tree value = build_lang_decl (TYPE_DECL, name, current_class_type); + tree saved_cas; + DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type; - CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; DECL_ARTIFICIAL (value) = 1; - pushdecl_class_level (value); - return value; + saved_cas = current_access_specifier; + current_access_specifier = access_public_node; + finish_member_declaration (value); + current_access_specifier = saved_cas; } /* Returns 1 if TYPE contains only padding bytes. */ @@ -5581,3 +5292,110 @@ is_empty_class (type) t = TREE_CHAIN (t); return (t == NULL_TREE); } + +/* Find the enclosing class of the given NODE. NODE can be a *_DECL or + a *_TYPE node. NODE can also be a local class. */ + +tree +get_enclosing_class (type) + tree type; +{ + tree node = type; + + while (node && TREE_CODE (node) != NAMESPACE_DECL) + { + switch (TREE_CODE_CLASS (TREE_CODE (node))) + { + case 'd': + node = DECL_CONTEXT (node); + break; + + case 't': + if (node != type) + return node; + node = TYPE_CONTEXT (node); + break; + + default: + my_friendly_abort (0); + } + } + 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 (get_binfo (base, type, 0)) + 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; +{ + splay_tree names_used; + + /* If we're not defining a class, there's nothing to do. */ + if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type)) + return; + + /* If there's already a binding for this NAME, then we don't have + anything to worry about. */ + if (IDENTIFIER_CLASS_VALUE (name)) + return; + + if (!current_class_stack[current_class_depth - 1].names_used) + current_class_stack[current_class_depth - 1].names_used + = splay_tree_new (splay_tree_compare_pointers, 0, 0); + names_used = current_class_stack[current_class_depth - 1].names_used; + + splay_tree_insert (names_used, + (splay_tree_key) name, + (splay_tree_value) decl); +} + +/* Note that NAME was declared (as DECL) in the current class. Check + to see that the declaration is legal. */ + +void +note_name_declared_in_class (name, decl) + tree name; + tree decl; +{ + splay_tree names_used; + splay_tree_node n; + + /* Look to see if we ever used this name. */ + names_used + = current_class_stack[current_class_depth - 1].names_used; + if (!names_used) + return; + + n = splay_tree_lookup (names_used, (splay_tree_key) name); + if (n) + { + /* [basic.scope.class] + + A name N used in a class S shall refer to the same declaration + in its context and when re-evaluated in the completed scope of + S. */ + cp_error ("declaration of `%#D'", decl); + cp_error_at ("changes meaning of `%s' from `%+#D'", + IDENTIFIER_POINTER (DECL_NAME (decl)), + (tree) n->value); + } +} diff --git a/contrib/gcc/cp/config-lang.in b/contrib/gcc/cp/config-lang.in index 9b39d51..dd31af4 100644 --- a/contrib/gcc/cp/config-lang.in +++ b/contrib/gcc/cp/config-lang.in @@ -1,5 +1,5 @@ # Top level configure fragment for GNU C++. -# Copyright (C) 1994, 1995 Free Software Foundation, Inc. +# Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc. #This file is part of GNU CC. diff --git a/contrib/gcc/cp/cp-tree.def b/contrib/gcc/cp/cp-tree.def index dbbdb66..70801fc 100644 --- a/contrib/gcc/cp/cp-tree.def +++ b/contrib/gcc/cp/cp-tree.def @@ -1,7 +1,7 @@ /* 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 Free Software Foundation, Inc. + Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -29,6 +29,11 @@ Boston, MA 02111-1307, USA. */ just won't work for us. */ 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', 1) + /* For NEW_EXPR, operand 0 is the placement list. Operand 1 is the new-declarator. Operand 2 is the initializer. */ @@ -138,9 +143,18 @@ DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0) The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */ DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0) -/* A type designated by 'typename T::t'. */ +/* A type designated by `typename T::t'. TYPE_CONTEXT is `T', + TYPE_NAME is an IDENTIFIER_NODE for `t'. If the type was named via + template-id, TYPENAME_TYPE_FULLNAME will hold the TEMPLATE_ID_EXPR. + If TREE_TYPE is present, this type was generated by the implicit + typename extension, and the TREE_TYPE is a _TYPE from a baseclass + of `T'. */ DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0) +/* A type designated by `__typeof (expr)'. TYPE_FIELDS is the + expression in question. */ +DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0) + /* A thunk is a stub function. Thunks are used to implement multiple inheritance: @@ -158,17 +172,16 @@ DEFTREECODE (USING_DECL, "using_decl", 'd', 0) /* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */ DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2) -/* A template-id, like foo. The first operand is the template. - The second is the list of explicitly specified arguments. The - template will be a FUNCTION_DECL, TEMPLATE_DECL, or a list of - overloaded functions and templates if the template-id refers to - a global template. If the template-id refers to a member template, - the template may be an IDENTIFIER_NODE. */ +/* A template-id, like foo. 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. */ DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) -/* An association between namespace and entity. Parameters are the - scope and the (non-type) value. - TREE_TYPE indicates the type bound to the name. */ +/* An association between name and entity. Parameters are the scope + and the (non-type) value. TREE_TYPE indicates the type bound to + the name. */ DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2) /* A list-like node for chaining overloading candidates. TREE_TYPE is @@ -182,9 +195,14 @@ DEFTREECODE (WRAPPER, "wrapper", 'x', 1) /* A node to remember a source position. */ DEFTREECODE (SRCLOC, "srcloc", 'x', 2) +/* 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) + /* A whole bunch of tree codes for the initial, superficial parsing of templates. */ -DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 2) DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3) DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1) DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1) diff --git a/contrib/gcc/cp/cp-tree.h b/contrib/gcc/cp/cp-tree.h index 7572921..7d64307 100644 --- a/contrib/gcc/cp/cp-tree.h +++ b/contrib/gcc/cp/cp-tree.h @@ -1,5 +1,5 @@ /* Definitions for C++ parsing and type checking. - Copyright (C) 1987, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -22,38 +22,37 @@ Boston, MA 02111-1307, USA. */ #ifndef _CP_TREE_H #define _CP_TREE_H -#include "gansidecl.h" - /* Usage of TREE_LANG_FLAG_?: - 0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE). - BINFO_MARKED (BINFO nodes). - TI_USES_TEMPLATE_PARMS. + 0: BINFO_MARKED (BINFO nodes). COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). NEW_EXPR_USE_GLOBAL (in NEW_EXPR). DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). TREE_NEGATED_INT (in INTEGER_CST). - (TREE_MANGLED) (in IDENTIFIER_NODE) (commented-out). - 1: IDENTIFIER_VIRTUAL_P. + TREE_INDIRECT_USING (in NAMESPACE_DECL). + IDENTIFIER_MARKED (used by search routines). + LOCAL_BINDING_P (in CPLUS_BINDING) + 1: IDENTIFIER_VIRTUAL_P. TI_PENDING_TEMPLATE_FLAG. - TI_PENDING_SPECIALIZATION_FLAG. TEMPLATE_PARMS_FOR_INLINE. DELETE_EXPR_USE_VEC (in DELETE_EXPR). (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). TYPE_USES_COMPLEX_INHERITANCE (in _TYPE). C_DECLARED_LABEL_FLAG. + INHERITED_VALUE_BINDING_P (in CPLUS_BINDING) + BASELINK_P (in TREE_LIST) 2: IDENTIFIER_OPNAME_P. + BINFO_VBASE_MARKED. BINFO_FIELDS_MARKED. TYPE_VIRTUAL_P. - PARM_DECL_EXPR (in SAVE_EXPR). 3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE). BINFO_VTABLE_PATH_MARKED. + BINFO_PUSHDECLS_MARKED. (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). 4: BINFO_NEW_VTABLE_MARKED. TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, or FIELD_DECL). - 5: BINFO_VIA_PUBLIC. - BINFO_VBASE_INIT_MARKED. + 5: Not used. 6: Not used. Usage of TYPE_LANG_FLAG_?: @@ -67,13 +66,31 @@ Boston, MA 02111-1307, USA. */ Usage of DECL_LANG_FLAG_?: 0: DECL_ERROR_REPORTED (in VAR_DECL). + DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). + DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). 3: DECL_IN_AGGR_P. 4: DECL_MAYBE_TEMPLATE. 5: DECL_INTERFACE_KNOWN. 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). + + Usage of language-independent fields in a language-dependent manner: + + TYPE_ALIAS_SET + This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so + forth as a substitute for the mark bits provided in `lang_type'. + At present, only the six low-order bits are used. + + TYPE_BINFO + For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO. + For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME. + For a TEMPLATE_TEMPLATE_PARM, this is + TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. + + DECL_SAVED_INSNS/DECL_FIELD_SIZE + For a static VAR_DECL, this is DECL_INIT_PRIORITY. */ /* Language-dependent contents of an identifier. */ @@ -81,7 +98,8 @@ Boston, MA 02111-1307, USA. */ struct lang_identifier { struct tree_identifier ignore; - tree namespace_bindings, local_value; + tree namespace_bindings; + tree bindings; tree class_value; tree class_template_info; struct lang_id2 *x; @@ -90,7 +108,7 @@ struct lang_identifier struct lang_id2 { tree label_value, implicit_decl; - tree type_desc, as_list, error_locus; + tree error_locus; }; typedef struct @@ -110,15 +128,34 @@ typedef struct tree decl; } template_parm_index; -/* For a binding between a name and an entity, defines the scope - where the binding is declared. Currently always points to a - namespace declaration. */ -#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope) +typedef struct ptrmem_cst +{ + char common[sizeof (struct tree_common)]; + tree member; +}* 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) TREE_LANG_FLAG_0(NODE) + +/* Nonzero if BINDING_VALUE is from a base class of the class which is + currently being defined. */ +#define INHERITED_VALUE_BINDING_P(NODE) TREE_LANG_FLAG_1(NODE) + +/* 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) (((struct tree_binding*)NODE)->scope.scope) + /* This is the declaration bound to the name. Possible values: variable, overloaded function, namespace, template, enumerator. */ #define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value) + /* If name is bound to a type, this is the type (struct, union, enum). */ #define BINDING_TYPE(NODE) TREE_TYPE(NODE) + #define IDENTIFIER_GLOBAL_VALUE(NODE) \ namespace_binding (NODE, global_namespace) #define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \ @@ -131,7 +168,10 @@ typedef struct struct tree_binding { char common[sizeof (struct tree_common)]; - tree scope; + union { + tree scope; + struct binding_level *level; + } scope; tree value; }; @@ -154,6 +194,14 @@ struct tree_overload tree function; }; +/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO + indicating a particular base class, and whose TREE_VALUE is a + (possibly overloaded) function from that base class. */ +#define BASELINK_P(NODE) \ + (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE))) +#define SET_BASELINK_P(NODE) \ + (TREE_LANG_FLAG_1 ((NODE)) = 1) + #define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr) #define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i) @@ -183,13 +231,43 @@ struct tree_srcloc #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ (((struct lang_identifier *)(NODE))->namespace_bindings) -#define IDENTIFIER_CLASS_VALUE(NODE) \ - (((struct lang_identifier *)(NODE))->class_value) -#define IDENTIFIER_LOCAL_VALUE(NODE) \ - (((struct lang_identifier *)(NODE))->local_value) #define IDENTIFIER_TEMPLATE(NODE) \ (((struct lang_identifier *)(NODE))->class_template_info) +/* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the + identifier. It's TREE_CHAIN is the next outermost binding. Each + BINDING_VALUE 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. */ +#define IDENTIFIER_BINDING(NODE) \ + (((struct lang_identifier*) (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)) \ + : NULL_TREE) + +/* 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 + IDENTIFIER_BINDINGs list, so any time that this is non-NULL so is + IDENTIFIER_BINDING. */ +#define IDENTIFIER_CLASS_VALUE(NODE) \ + (((struct lang_identifier *) (NODE))->class_value) + +/* The amount of time used by the file whose special "time identifier" + is NODE, represented as an INTEGER_CST. See get_time_identifier. */ +#define TIME_IDENTIFIER_TIME(NODE) IDENTIFIER_BINDING(NODE) + +/* For a "time identifier" this is a INTEGER_CST. The + TREE_INT_CST_LOW is 1 if the corresponding file is "interface only". + The TRE_INT_CST_HIGH is 1 if it is "interface unknown". */ +#define TIME_IDENTIFIER_FILEINFO(NODE) IDENTIFIER_CLASS_VALUE (NODE) + /* TREE_TYPE only indicates on local and class scope the current type. For namespace scope, the presence of a type in any namespace is indicated with global_type_node, and the real type behind must @@ -216,14 +294,6 @@ struct tree_srcloc #define SET_IDENTIFIER_IMPLICIT_DECL(NODE,VALUE) \ SET_LANG_ID(NODE, VALUE, implicit_decl) -#define IDENTIFIER_AS_DESC(NODE) LANG_ID_FIELD(type_desc, NODE) -#define SET_IDENTIFIER_AS_DESC(NODE,DESC) \ - SET_LANG_ID(NODE, DESC, type_desc) - -#define IDENTIFIER_AS_LIST(NODE) LANG_ID_FIELD(as_list, NODE) -#define SET_IDENTIFIER_AS_LIST(NODE,LIST) \ - SET_LANG_ID(NODE, LIST, as_list) - #define IDENTIFIER_ERROR_LOCUS(NODE) LANG_ID_FIELD(error_locus, NODE) #define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE) \ SET_LANG_ID(NODE, VALUE, error_locus) @@ -234,10 +304,12 @@ struct tree_srcloc /* Nonzero if this identifier is the prefix for a mangled C++ operator name. */ #define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2(NODE) -#define IDENTIFIER_TYPENAME_P(NODE) \ - (! strncmp (IDENTIFIER_POINTER (NODE), \ - IDENTIFIER_POINTER (ansi_opname[(int) TYPE_EXPR]), \ - IDENTIFIER_LENGTH (ansi_opname[(int) TYPE_EXPR]))) +/* Nonzero if this identifier is the name of a type-conversion + operator. */ +#define IDENTIFIER_TYPENAME_P(NODE) \ + (! strncmp (IDENTIFIER_POINTER (NODE), \ + OPERATOR_TYPENAME_FORMAT, \ + strlen (OPERATOR_TYPENAME_FORMAT))) /* Nonzero means reject anything that ANSI standard C forbids. */ extern int pedantic; @@ -278,7 +350,9 @@ extern tree intQI_type_node, unsigned_intQI_type_node; extern tree intHI_type_node, unsigned_intHI_type_node; extern tree intSI_type_node, unsigned_intSI_type_node; extern tree intDI_type_node, unsigned_intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 extern tree intTI_type_node, unsigned_intTI_type_node; +#endif extern tree java_byte_type_node; extern tree java_short_type_node; @@ -321,10 +395,6 @@ extern int flag_gnu_xref; extern int flag_gnu_binutils; -/* Nonzero means ignore `#ident' directives. */ - -extern int flag_no_ident; - /* Nonzero means warn about implicit declarations. */ extern int warn_implicit; @@ -343,9 +413,13 @@ extern int warn_ctor_dtor_privacy; extern int warn_return_type; -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ +/* Nonzero means give string constants the type `const char *', as mandated + by the standard. */ + +extern int flag_const_strings; + +/* Nonzero means warn about deprecated conversion from string constant to + `char *'. */ extern int warn_write_strings; @@ -472,6 +546,22 @@ extern int flag_do_squangling; /* Nonzero if we want to issue diagnostics that the standard says are not required. */ extern int flag_optional_diags; + +/* Nonzero means do not consider empty argument prototype to mean function + takes no arguments. */ +extern int flag_strict_prototype; + +/* 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. */ +extern int flag_permissive; + +/* Nonzero if we want to obey access control semantics. */ + +extern int flag_access_control; + /* C++ language-specific tree codes. */ #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, @@ -495,7 +585,26 @@ enum languages { lang_c, lang_cplusplus, lang_java }; /* The _DECL for this _TYPE. */ #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) -#define IS_AGGR_TYPE(t) (TYPE_LANG_FLAG_5 (t)) +/* Nonzero if T is a class (or struct or union) type. Also nonzero + for template type parameters and typename types. Despite its name, + this macro has nothing to do with the definition of aggregate given + in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */ +#define IS_AGGR_TYPE(t) \ + (TREE_CODE (t) == TEMPLATE_TYPE_PARM \ + || TREE_CODE (t) == TYPENAME_TYPE \ + || TREE_CODE (t) == TYPEOF_TYPE \ + || TYPE_LANG_FLAG_5 (t)) + +/* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or + union type. */ +#define SET_IS_AGGR_TYPE(T, VAL) \ + (TYPE_LANG_FLAG_5 (T) = (VAL)) + +/* Nonzero if T is a class type. Zero for template type parameters, + typename types, and so forth. */ +#define CLASS_TYPE_P(t) \ + (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) \ @@ -509,6 +618,32 @@ enum languages { lang_c, lang_cplusplus, lang_java }; /* True if this a "Java" type, defined in 'extern "Java"'. */ #define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3(NODE) +/* The type qualifiers for this type, including the qualifiers on the + elements for an array type. */ +#define CP_TYPE_QUALS(NODE) \ + ((TREE_CODE (NODE) != ARRAY_TYPE) \ + ? TYPE_QUALS (NODE) : cp_type_quals (NODE)) + +/* Nonzero if this type is const-qualified. */ +#define CP_TYPE_CONST_P(NODE) \ + ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_CONST) != 0) + +/* Nonzero if this type is volatile-qualified. */ +#define CP_TYPE_VOLATILE_P(NODE) \ + ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_VOLATILE) != 0) + +/* Nonzero if this type is restrict-qualified. */ +#define CP_TYPE_RESTRICT_P(NODE) \ + ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_RESTRICT) != 0) + +/* Nonzero if this type is const-qualified, but not + volatile-qualified. Other qualifiers are ignored. This macro is + used to test whether or not it is OK to bind an rvalue to a + reference. */ +#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \ + ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \ + == TYPE_QUAL_CONST) + #define DELTA_FROM_VTABLE_ENTRY(ENTRY) \ (!flag_vtable_thunks ? \ TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \ @@ -537,23 +672,31 @@ enum languages { lang_c, lang_cplusplus, lang_java }; #define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0) #define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1) -/* Statistics show that while the GNU C++ compiler may generate - thousands of different types during a compilation run, it - generates relatively few (tens) of classtypes. Because of this, - it is not costly to store a generous amount of information - in classtype nodes. This struct must fill out to a multiple of 4 bytes. */ +/* This structure provides additional information above and beyond + what is provide in the ordinary tree_type. In the past, we used it + for the types of class types, template parameters types, typename + types, and so forth. However, there can be many (tens to hundreds + of thousands) of template parameter types in a compilation, and + there's no need for this additional information in that case. + Therefore, we now use this data structure only for class types. + + In the past, it was thought that there would be relatively few + class types. However, in the presence of heavy use of templates, + many (i.e., thousands) of classes can easily be generated. + Therefore, we should endeavor to keep the size of this structure to + a minimum. */ struct lang_type { struct { unsigned has_type_conversion : 1; unsigned has_init_ref : 1; - unsigned has_assignment : 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; + unsigned anon_union : 1; unsigned has_nonpublic_ctor : 2; unsigned has_nonpublic_assign_ref : 2; @@ -565,63 +708,54 @@ struct lang_type unsigned has_call_overloaded : 1; unsigned has_array_ref_overloaded : 1; unsigned has_arrow_overloaded : 1; - unsigned local_typedecls : 1; unsigned interface_only : 1; unsigned interface_unknown : 1; - unsigned needs_virtual_reinit : 1; + + unsigned marks: 6; unsigned vec_delete_takes_size : 1; unsigned declared_class : 1; + unsigned being_defined : 1; unsigned redefined : 1; - unsigned marked : 1; - unsigned marked2 : 1; - unsigned marked3 : 1; - - unsigned marked4 : 1; - unsigned marked5 : 1; - unsigned marked6 : 1; unsigned debug_requested : 1; unsigned use_template : 2; unsigned got_semicolon : 1; unsigned ptrmemfunc_flag : 1; - unsigned is_signature : 1; + unsigned is_signature_pointer : 1; unsigned is_signature_reference : 1; unsigned has_opaque_typedecls : 1; unsigned sigtable_has_been_generated : 1; unsigned was_anonymous : 1; - unsigned has_real_assignment : 1; unsigned has_real_assign_ref : 1; - unsigned has_const_init_ref : 1; unsigned has_complex_init_ref : 1; + unsigned has_complex_assign_ref : 1; unsigned has_abstract_assign_ref : 1; unsigned non_aggregate : 1; + unsigned is_partial_instantiation : 1; + unsigned has_mutable : 1; + unsigned com_interface : 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! */ /* The MIPS compiler gets it wrong if this struct also does not fill out to a multiple of 4 bytes. Add a member `dummy' with new bits if you go over the edge. */ - unsigned dummy : 11; + unsigned dummy : 10; } type_flags; -#ifdef MI_MATRIX - int cid; -#endif - int n_ancestors; - int n_vancestors; int vsize; - int max_depth; int vfield_parent; - union tree_node *baselink_vec; union tree_node *vfields; union tree_node *vbases; union tree_node *tags; - char *memoized_table_entry; union tree_node *search_slot; @@ -630,17 +764,9 @@ struct lang_type union tree_node *size; - union tree_node *base_init_list; union tree_node *abstract_virtuals; - union tree_node *as_list; - union tree_node *id_as_list; - union tree_node *binfo_as_list; union tree_node *friend_classes; -#ifdef MI_MATRIX - char *mi_matrix; -#endif - union tree_node *rtti; union tree_node *methods; @@ -648,14 +774,10 @@ struct lang_type union tree_node *signature; union tree_node *signature_pointer_to; union tree_node *signature_reference_to; - union tree_node *template_info; - - int linenum; + tree befriending_classes; }; -#define CLASSTYPE_SOURCE_LINE(NODE) (TYPE_LANG_SPECIFIC(NODE)->linenum) - /* Indicates whether or not (and how) a template was expanded for this class. 0=no information yet/non-template class 1=implicit template instantiation @@ -669,13 +791,6 @@ struct lang_type /* List of friends which were defined inline in this class definition. */ #define CLASSTYPE_INLINE_FRIENDS(NODE) (TYPE_NONCOPIED_PARTS (NODE)) -/* Nonzero for _CLASSTYPE means that the _CLASSTYPE either has - a special meaning for the assignment operator ("operator="), - or one of its fields (or base members) has a special meaning - defined. */ -#define TYPE_HAS_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assignment) -#define TYPE_HAS_REAL_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assignment) - /* Nonzero for _CLASSTYPE means that operator new and delete are defined, respectively. */ #define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) @@ -690,9 +805,6 @@ struct lang_type (TYPE_NEEDS_DESTRUCTOR (NODE) \ || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE))) -/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */ -#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE)) - /* Nonzero means that this _CLASSTYPE node defines ways of converting itself to other types. */ #define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion) @@ -751,7 +863,7 @@ struct lang_type signature reference type. */ #define SIGNATURE_REFERENCE_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_reference_to) -/* The is the VAR_DECL that contains NODE's rtti. */ +/* The is the basetype that contains NODE's rtti. */ #define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti) /* Nonzero means that this _CLASSTYPE node overloads operator(). */ @@ -773,7 +885,12 @@ struct lang_type hierarchy, then we can use more efficient search techniques. */ #define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE)) -/* List of lists of member functions defined in this class. */ +/* Vector member functions defined in this class. Each element is + either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. All + functions with the same name end up in the same slot. The first + two elements are for constructors, and destructors, respectively. + These are followed by ordinary member functions. There may be + empty entries at the end of the vector. */ #define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods) /* The first type conversion operator in the class (the others can be @@ -784,30 +901,46 @@ struct lang_type ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \ : NULL_TREE; -/* Pointer from any member function to the head of the list of - member functions of the type that member function belongs to. */ -#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec) - /* Mark bits for depth-first and breath-first searches. */ -#define CLASSTYPE_MARKED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked) -#define CLASSTYPE_MARKED2(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked2) -#define CLASSTYPE_MARKED3(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked3) -#define CLASSTYPE_MARKED4(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked4) -#define CLASSTYPE_MARKED5(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked5) -#define CLASSTYPE_MARKED6(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.marked6) + +/* Get the value of the Nth mark bit. */ +#define CLASSTYPE_MARKED_N(NODE, N) \ + (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \ + : TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0) + +/* Set the Nth mark bit. */ +#define SET_CLASSTYPE_MARKED_N(NODE, N) \ + (CLASS_TYPE_P (NODE) \ + ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks |= (1 << (N))) \ + : (TYPE_ALIAS_SET (NODE) |= (1 << (N)))) + +/* Clear the Nth mark bit. */ +#define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \ + (CLASS_TYPE_P (NODE) \ + ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks &= ~(1 << (N))) \ + : (TYPE_ALIAS_SET (NODE) &= ~(1 << (N)))) + +/* Get the value of the mark bits. */ +#define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N(NODE, 0) +#define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N(NODE, 1) +#define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N(NODE, 2) +#define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N(NODE, 3) +#define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N(NODE, 4) +#define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N(NODE, 5) + /* Macros to modify the above flags */ -#define SET_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED(NODE) (CLASSTYPE_MARKED(NODE) = 0) -#define SET_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED2(NODE) (CLASSTYPE_MARKED2(NODE) = 0) -#define SET_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED3(NODE) (CLASSTYPE_MARKED3(NODE) = 0) -#define SET_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED4(NODE) (CLASSTYPE_MARKED4(NODE) = 0) -#define SET_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED5(NODE) (CLASSTYPE_MARKED5(NODE) = 0) -#define SET_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 1) -#define CLEAR_CLASSTYPE_MARKED6(NODE) (CLASSTYPE_MARKED6(NODE) = 0) +#define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0) +#define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0) +#define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1) +#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1) +#define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2) +#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2) +#define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3) +#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3) +#define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4) +#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4) +#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5) +#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5) /* A list of the nested tag-types (class, struct, union, or enum) found within this class. The TREE_PURPOSE of each node is the name @@ -838,42 +971,15 @@ struct lang_type #define CLASSTYPE_N_BASECLASSES(NODE) \ (TYPE_BINFO_BASETYPES (NODE) ? TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0) -/* Memoize the number of super classes (base classes) tha this node - has. That way we can know immediately (albeit conservatively how - large a multiple-inheritance matrix we need to build to find - derivation information. */ -#define CLASSTYPE_N_SUPERCLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->n_ancestors) -#define CLASSTYPE_N_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->n_vancestors) - -/* Record how deep the inheritance is for this class so `void*' conversions - are less favorable than a conversion to the most base type. */ -#define CLASSTYPE_MAX_DEPTH(NODE) (TYPE_LANG_SPECIFIC(NODE)->max_depth) - /* Used for keeping search-specific information. Any search routine which uses this must define what exactly this slot is used for. */ #define CLASSTYPE_SEARCH_SLOT(NODE) (TYPE_LANG_SPECIFIC(NODE)->search_slot) -/* Entry for keeping memoization tables for this type to - hopefully speed up search routines. Since it is a pointer, - it can mean almost anything. */ -#define CLASSTYPE_MTABLE_ENTRY(NODE) (TYPE_LANG_SPECIFIC(NODE)->memoized_table_entry) - /* These are the size, mode and alignment of the type without its virtual base classes, for when we use this type as a base itself. */ #define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size) #define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align) -/* A cons list of structure elements which either have constructors - to be called, or virtual function table pointers which - need initializing. Depending on what is being initialized, - the TREE_PURPOSE and TREE_VALUE fields have different meanings: - - Member initialization: - Base class construction: - Base class initialization: - Whole type: . */ -#define CLASSTYPE_BASE_INIT_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->base_init_list) - /* A cons list of virtual functions which cannot be inherited by derived classes. When deriving from this type, the derived class must provide its own definition for each of these functions. */ @@ -892,9 +998,6 @@ struct lang_type the virtual function table will be written out. */ #define CLASSTYPE_VTABLE_NEEDS_WRITING(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.vtable_needs_writing) -/* Nonzero means that this type defines its own local type declarations. */ -#define CLASSTYPE_LOCAL_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.local_typedecls) - /* Nonzero means that this type has an X() constructor. */ #define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_default_ctor) @@ -906,26 +1009,22 @@ struct lang_type /* Ditto, for operator=. */ #define TYPE_HAS_NONPUBLIC_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_assign_ref) -/* Many routines need to cons up a list of basetypes for access - checking. This field contains a TREE_LIST node whose TREE_VALUE - is the main variant of the type, and whose TREE_VIA_PUBLIC - and TREE_VIA_VIRTUAL bits are correctly set. */ -#define CLASSTYPE_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->as_list) -/* Same, but cache a list whose value is the name of this type. */ -#define CLASSTYPE_ID_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->id_as_list) -/* Same, but cache a list whose value is the binfo of this type. */ -#define CLASSTYPE_BINFO_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->binfo_as_list) - -/* A list of class types with which this type is a friend. The +/* Nonzero means that this type contains a mutable member */ +#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable) +#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) + +/* Nonzero means that this type is meant for communication via COM. */ +#define CLASSTYPE_COM_INTERFACE(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->type_flags.com_interface) + +/* A list of class types of which this type is a friend. The TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the case of a template friend. */ #define CLASSTYPE_FRIEND_CLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->friend_classes) -#ifdef MI_MATRIX -/* Keep an inheritance lattice around so we can quickly tell whether - a type is derived from another or not. */ -#define CLASSTYPE_MI_MATRIX(NODE) (TYPE_LANG_SPECIFIC(NODE)->mi_matrix) -#endif +/* A list of the classes which grant friendship to this class. */ +#define CLASSTYPE_BEFRIENDING_CLASSES(NODE) \ + (TYPE_LANG_SPECIFIC (NODE)->befriending_classes) /* Say whether this node was declared as a "class" or a "struct". */ #define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class) @@ -952,17 +1051,20 @@ struct lang_type /* Additional macros for inheritance information. */ -/* When following an binfo-specific chain, this is the cumulative - via-public flag. */ -#define BINFO_VIA_PUBLIC(NODE) TREE_LANG_FLAG_5 (NODE) +/* 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. In addition, shared + versions of each of the virtual class BINFOs are stored in + CLASSTYPE_VBASECLASSES. -#ifdef MI_MATRIX -/* When building a matrix to determine by a single lookup - whether one class is derived from another or not, - this field is the index of the class in the table. */ -#define CLASSTYPE_CID(NODE) (TYPE_LANG_SPECIFIC(NODE)->cid) -#define BINFO_CID(NODE) CLASSTYPE_CID(BINFO_TYPE(NODE)) -#endif + 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_VIAR_PRIVATE, which is unused. + + The TREE_CHAIN is for scratch space in search.c. */ /* Nonzero means marked by DFS or BFS search, including searches by `get_binfo' and `get_base_distance'. */ @@ -972,12 +1074,6 @@ struct lang_type #define SET_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=1)) #define CLEAR_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=0)) -/* Nonzero means marked in building initialization list. */ -#define BINFO_BASEINIT_MARKED(NODE) CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) -/* Modifier macros */ -#define SET_BINFO_BASEINIT_MARKED(NODE) SET_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) -#define CLEAR_BINFO_BASEINIT_MARKED(NODE) CLEAR_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) - /* Nonzero means marked in search through virtual inheritance hierarchy. */ #define BINFO_VBASE_MARKED(NODE) CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) /* Modifier macros */ @@ -1002,11 +1098,13 @@ struct lang_type #define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1)) #define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0)) -/* Nonzero means this class has initialized its virtual baseclasses. */ -#define BINFO_VBASE_INIT_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED5(BINFO_TYPE(NODE)):TREE_LANG_FLAG_5(NODE)) -#define SET_BINFO_VBASE_INIT_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED5(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_5(NODE)=1)) -#define CLEAR_BINFO_VBASE_INIT_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED5(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_5(NODE)=0)) +/* 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) + +/* Used by various search routines. */ +#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) /* Accessor macros for the vfield slots in structures. */ @@ -1027,12 +1125,28 @@ struct lang_type #define TREE_PARMLIST(NODE) ((NODE)->common.unsigned_flag) /* overloaded! */ /* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that - this type can raise. */ + this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE + will be NULL_TREE to indicate a throw specification of `(...)', or, + equivalently, no throw specification. */ #define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE) +/* For FUNCTION_TYPE or METHOD_TYPE, return 1 iff it is declared `throw()'. */ +#define TYPE_NOTHROW_P(NODE) \ + (TYPE_RAISES_EXCEPTIONS (NODE) \ + && TREE_VALUE (TYPE_RAISES_EXCEPTIONS (NODE)) == NULL_TREE) + /* The binding level associated with the namespace. */ #define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) + +/* If a DECL has DECL_LANG_SPECIFIC, it is either a lang_decl_flags or + a lang_decl (which has lang_decl_flags as its initial prefix). A + FUNCTION_DECL, NAMESPACE_DECL, TYPE_DECL, or USING_DECL may have a + full lang_decl. A FIELD_DECL, or a static data member VAR_DECL, + will have only lang_decl_flags. Thus, one should only access the + members of lang_decl that are not in lang_decl_flags for DECLs that + are not FIELD_DECLs or VAR_DECLs. */ + struct lang_decl_flags { #ifdef ONLY_INT_FIELDS @@ -1043,8 +1157,6 @@ struct lang_decl_flags unsigned operator_attr : 1; unsigned constructor_attr : 1; - unsigned returns_first_arg : 1; - unsigned preserves_first_arg : 1; unsigned friend_attr : 1; unsigned static_function : 1; unsigned const_memfunc : 1; @@ -1061,9 +1173,10 @@ struct lang_decl_flags unsigned nonconverting : 1; unsigned declared_inline : 1; unsigned not_really_extern : 1; - unsigned comdat : 1; unsigned needs_final_overrider : 1; - unsigned dummy : 3; + unsigned bitfield : 1; + unsigned defined_in_class : 1; + unsigned dummy : 4; tree access; tree context; @@ -1077,6 +1190,7 @@ struct lang_decl struct lang_decl_flags decl_flags; tree main_decl_variant; + tree befriending_classes; struct pending_inline *pending_inline_info; }; @@ -1098,26 +1212,34 @@ struct lang_decl /* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ #define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr) -#define DECL_DESTRUCTOR_P(NODE) (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME(NODE))) + +/* There ought to be a better way to find out whether or not something is + a destructor. */ +#define DECL_DESTRUCTOR_P(NODE) \ + (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (NODE)) \ + && DECL_LANGUAGE (NODE) == lang_cplusplus) + +#define DECL_CONV_FN_P(NODE) \ + (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE))) /* For FUNCTION_DECLs: nonzero means that this function is a constructor for an object with virtual baseclasses. */ #define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) +/* Non-zero for a FUNCTION_DECL that declares a type-info function. */ +#define DECL_TINFO_FN_P(NODE) \ + (TREE_CODE (NODE) == FUNCTION_DECL \ + && DECL_ARTIFICIAL (NODE) \ + && DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) + +/* Mark NODE as a type-info function. */ +#define SET_DECL_TINFO_FN_P(NODE) \ + (DECL_LANG_SPECIFIC((NODE))->decl_flags.mutable_flag = 1) + /* For FUNCTION_DECLs: nonzero means that this function is a default implementation of a signature method. */ #define IS_DEFAULT_IMPLEMENTATION(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_default_implementation) -/* For FUNCTION_DECLs: nonzero means that the constructor - is known to return a non-zero `this' unchanged. */ -#define DECL_RETURNS_FIRST_ARG(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.returns_first_arg) - -/* Nonzero for FUNCTION_DECL means that this constructor is known to - not make any assignment to `this', and therefore can be trusted - to return it unchanged. Otherwise, we must re-assign `current_class_ptr' - after performing base initializations. */ -#define DECL_PRESERVES_THIS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.preserves_first_arg) - /* Nonzero for _DECL means that this decl appears in (or will appear in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for detecting circularity in case members are multiply defined. In the @@ -1125,11 +1247,20 @@ struct lang_decl should be allocated. */ #define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE)) +/* Nonzero if the DECL was defined in the class definition itself, + rather than outside the class. */ +#define DECL_DEFINED_IN_CLASS_P(DECL) \ + (DECL_LANG_SPECIFIC (DECL)->decl_flags.defined_in_class) + /* Nonzero for FUNCTION_DECL means that this decl is just a friend declaration, and should not be added to the list of member functions for this class. */ #define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.friend_attr) +/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ +#define DECL_BEFRIENDING_CLASSES(NODE) \ + (DECL_LANG_SPECIFIC(NODE)->befriending_classes) + /* Nonzero for FUNCTION_DECL means that this decl is a static member function. */ #define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function) @@ -1158,6 +1289,12 @@ struct lang_decl has `this' as volatile X *const. */ #define DECL_VOLATILE_MEMFUNC_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.volatile_memfunc) +/* Nonzero for a DECL means that this member is a non-static member. */ +#define DECL_NONSTATIC_MEMBER_P(NODE) \ + ((TREE_CODE (NODE) == FUNCTION_DECL \ + && DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE)) \ + || TREE_CODE (NODE) == FIELD_DECL) + /* Nonzero for _DECL means that this member object type is mutable. */ #define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) @@ -1190,6 +1327,10 @@ struct lang_decl (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) #define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) +/* For a virtual function, the base where we find its vtable entry. + For a non-virtual function, the base where it is defined. */ +#define DECL_VIRTUAL_CONTEXT(NODE) DECL_CONTEXT (NODE) + /* 1 iff NODE has namespace scope, including the global namespace. */ #define DECL_NAMESPACE_SCOPE_P(NODE) \ (DECL_CONTEXT (NODE) == NULL_TREE \ @@ -1200,6 +1341,11 @@ struct lang_decl (DECL_CONTEXT (NODE) \ && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (NODE))) == 't') +/* 1 iff NODE is function-local. */ +#define DECL_FUNCTION_SCOPE_P(NODE) \ + (DECL_CONTEXT (NODE) \ + && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) + /* For a NAMESPACE_DECL: the list of using namespace directives The PURPOSE is the used namespace, the value is the namespace that is the common ancestor. */ @@ -1215,6 +1361,11 @@ struct lang_decl #define ORIGINAL_NAMESPACE(NODE) \ (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) +/* In a non-local VAR_DECL with static storage duration, this is the + initialization priority. If this value is zero, the NODE will be + initialized at the DEFAULT_INIT_PRIORITY. */ +#define DECL_INIT_PRIORITY(NODE) (DECL_FIELD_SIZE ((NODE))) + /* In a TREE_LIST concatenating using directives, indicate indirekt directives */ #define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0) @@ -1246,23 +1397,86 @@ struct lang_decl /* For a VAR_DECL or FUNCTION_DECL: template-specific information. */ #define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info) + +/* Template information for a RECORD_TYPE or UNION_TYPE. */ #define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) + +/* Template information for an ENUMERAL_TYPE. Although an enumeration may + not be a primary template, it may be declared within the scope of a + primary template and the enumeration constants may depend on + non-type template parameters. */ +#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) + +/* Template information for a template template parameter. */ +#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) + +/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ +#define TYPE_TEMPLATE_INFO(NODE) \ + (TREE_CODE (NODE) == ENUMERAL_TYPE \ + ? ENUM_TEMPLATE_INFO (NODE) : \ + (TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \ + ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ + : CLASSTYPE_TEMPLATE_INFO (NODE))) + +/* Set the template information for an ENUMERAL_, RECORD_, or + UNION_TYPE to VAL. */ +#define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \ + (TREE_CODE (NODE) == ENUMERAL_TYPE \ + ? (ENUM_TEMPLATE_INFO (NODE) = VAL) \ + : (CLASSTYPE_TEMPLATE_INFO (NODE) = VAL)) + #define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE)) #define TI_ARGS(NODE) (TREE_VALUE (NODE)) #define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE)) -#define TI_USES_TEMPLATE_PARMS(NODE) TREE_LANG_FLAG_0 (NODE) #define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) -/* TI_PENDING_SPECIALIZATION_FLAG on a template-info node indicates - that the template is a specialization of a member template, but - that we don't yet know which one. */ -#define TI_PENDING_SPECIALIZATION_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) + +/* The TEMPLATE_DECL instantiated or specialized by NODE. This + TEMPLATE_DECL will be the immediate parent, not the most general + template. For example, in: + + template struct S { template void f(U); } + + the FUNCTION_DECL for S::f will have, as its + DECL_TI_TEMPLATE, `template S::f'. + + 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 or IDENTIFIER_NODE indicating the name of the template + and any explicit template arguments provided. For example, in: + + template struct S { friend void f(int, double); } + + the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the + DECL_TI_ARGS will be {int}. */ #define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) + +/* The template arguments used to obtain this decl from the most + general form of DECL_TI_TEMPLATE. For the example given for + DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}. These + are always the full set of arguments required to instantiate this + declaration from the most general template specialized here. */ #define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE)) #define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE)) +#define ENUM_TI_TEMPLATE(NODE) \ + TI_TEMPLATE (ENUM_TEMPLATE_INFO (NODE)) +#define ENUM_TI_ARGS(NODE) \ + TI_ARGS (ENUM_TEMPLATE_INFO (NODE)) + +/* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ +#define TYPE_TI_TEMPLATE(NODE) \ + (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE))) + +/* Like DECL_TI_ARGS, , but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ +#define TYPE_TI_ARGS(NODE) \ + (TI_ARGS (TYPE_TEMPLATE_INFO (NODE))) + #define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE) +/* Nonzero if the NODE corresponds to the template parameters for a + member template, whose inline definition is being processed after + the class definition is complete. */ #define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) #define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) @@ -1281,7 +1495,15 @@ struct lang_decl && !CLASSTYPE_USE_TEMPLATE (NODE) \ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) -#define TYPENAME_TYPE_FULLNAME(NODE) CLASSTYPE_SIZE (NODE) +/* The name used by the user to name the typename type. Typically, + this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the + corresponding TYPE_DECL. However, this may also be a + TEMPLATE_ID_EXPR if we had something like `typename X::Y'. */ +#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE) + +/* Nonzero if NODE is an implicit typename. */ +#define IMPLICIT_TYPENAME_P(NODE) \ + (TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE)) /* Nonzero in INTEGER_CST means that this int is negative by dint of using a twos-complement negated operand. */ @@ -1302,7 +1524,7 @@ struct lang_decl /* Nonzero in IDENTIFIER_NODE means that this name is not the name the user gave; it's a DECL_NESTED_TYPENAME. Someone may want to set this on mangled function names, too, but it isn't currently. */ -#define TREE_MANGLED(NODE) (TREE_LANG_FLAG_0 (NODE)) +#define TREE_MANGLED(NODE) (FOO) #endif #if 0 /* UNUSED */ @@ -1338,6 +1560,12 @@ extern int flag_new_for_scope; /* Record whether a typedef for type `int' was actually `signed int'. */ #define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) +/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ +#define DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield) +#define SET_DECL_C_BIT_FIELD(NODE) \ + (DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield = 1) + /* Nonzero if the type T promotes to itself. ANSI C states explicitly the list of types that promote; in particular, short promotes to int even if they have the same width. */ @@ -1377,8 +1605,9 @@ extern int flag_new_for_scope; has been duly initialized in its constructor. */ #define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE)) -#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \ - && CONSTRUCTOR_ELTS (NODE) == NULL_TREE) +#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \ + && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \ + && ! TREE_HAS_CONSTRUCTOR (NODE)) #if 0 /* Indicates that a NON_LVALUE_EXPR came from a C++ reference. @@ -1442,8 +1671,63 @@ extern int flag_new_for_scope; /* Nonzero for _TYPE node means that this type is a pointer to member function type. */ -#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) -#define TYPE_PTRMEMFUNC_FLAG(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) +#define TYPE_PTRMEMFUNC_P(NODE) \ + (TREE_CODE(NODE) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (NODE)) +#define TYPE_PTRMEMFUNC_FLAG(NODE) \ + (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) + +/* A pointer-to-function member type looks like: + + struct { + short __delta; + short __index; + union { + P __pfn; + short __delta2; + } __pfn_or_delta2; + }; + + where P is a POINTER_TYPE to a METHOD_TYPE appropriate for the + pointer to member. The fields are used as follows: + + If __INDEX is -1, then the function to call is non-virtual, and + is located at the address given by __PFN. + + If __INDEX is zero, then this a NULL pointer-to-member. + + Otherwise, the function to call is virtual. Then, __DELTA2 gives + the offset from an instance of the object to the virtual function + table, and __INDEX - 1 is the index into the vtable to use to + find the function. + + The value to use for the THIS parameter is the address of the + object plus __DELTA. + + For example, given: + + struct B1 { + int i; + }; + + struct B2 { + double d; + void f(); + }; + + struct S : public B1, B2 {}; + + the pointer-to-member for `&S::f' looks like: + + { 4, -1, { &f__2B2 } }; + + The `4' means that given an `S*' you have to add 4 bytes to get to + the address of the `B2*'. Then, the -1 indicates that this is a + non-virtual function. Of course, `&f__2B2' is the name of that + function. + + (Of course, the exactl values may differ depending on the mangling + scheme, sizes of types, and such.). */ + /* Get the POINTER_TYPE to the METHOD_TYPE associated with this pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, before using this macro. */ @@ -1458,8 +1742,19 @@ extern int flag_new_for_scope; #define TYPE_GET_PTRMEMFUNC_TYPE(NODE) ((tree)TYPE_LANG_SPECIFIC(NODE)) #define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) (TYPE_LANG_SPECIFIC(NODE) = ((struct lang_type *)(void*)(VALUE))) /* These are to get the delta2 and pfn fields from a TYPE_PTRMEMFUNC_P. */ -#define DELTA2_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), delta2_identifier, NULL_TREE, 0)) -#define PFN_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), pfn_identifier, NULL_TREE, 0)) +#define DELTA2_FROM_PTRMEMFUNC(NODE) delta2_from_ptrmemfunc ((NODE)) +#define PFN_FROM_PTRMEMFUNC(NODE) pfn_from_ptrmemfunc ((NODE)) + +/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for + `X'. */ +#define PTRMEM_CST_CLASS(NODE) \ + (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \ + ? TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (NODE))) \ + : TYPE_PTRMEMFUNC_OBJECT_TYPE (TREE_TYPE (NODE))) + +/* For a pointer-to-member constant `X::Y' this is the _DECL for + `Y'. */ +#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t) NODE)->member) /* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was specified in its declaration. */ @@ -1469,19 +1764,20 @@ extern int flag_new_for_scope; specified in its declaration. */ #define DECL_THIS_STATIC(NODE) (DECL_LANG_FLAG_6(NODE)) -/* Nonzero for SAVE_EXPR if used to initialize a PARM_DECL. */ -#define PARM_DECL_EXPR(NODE) (TREE_LANG_FLAG_2(NODE)) - /* Nonzero in FUNCTION_DECL means it is really an operator. Just used to communicate formatting information to dbxout.c. */ #define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr) #define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0) -/* Nonzero if TYPE is an anonymous union type. */ -#define ANON_UNION_TYPE_P(TYPE) \ - (TREE_CODE (TYPE) == UNION_TYPE \ - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TYPE))) +/* Nonzero if TYPE is an anonymous union type. We have to use a flag for + this because "A union for which objects or pointers are declared is not + an anonymous union" [class.union]. */ +#define ANON_UNION_TYPE_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE) \ + && TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union) +#define SET_ANON_UNION_TYPE_P(NODE) \ + (TYPE_LANG_SPECIFIC (NODE)->type_flags.anon_union = 1) #define UNKNOWN_TYPE LANG_TYPE @@ -1515,9 +1811,15 @@ extern int flag_new_for_scope; the TREE_PUROSE will be the class type, and the TREE_VALUE will be NULL_TREE. */ #define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE)) +#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) +#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) -/* The DECL_ACCESS is used to record under which context - special access rules apply. */ +/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of + each node is a type; the TREE_VALUE is the access granted for this + DECL in that type. The DECL_ACCESS is set by access declarations. + For example, if a member that would normally be public in a + derived class is made protected, then the derived class and the + protected_access_node will appear in the DECL_ACCESS for the node. */ #define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access) /* C++: all of these are overloaded! @@ -1528,32 +1830,88 @@ extern int flag_new_for_scope; /* Accessor macros for C++ template decl nodes. */ /* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node - indicates the level of the template parameters, with 1 being the - outermost set of template parameters. The TREE_VALUE is a vector, - whose elements are the template parameters at each level. Each - element in the vector is a 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 DECL_INITIAL (for a PARM_DECL) or as - the TREE_TYPE (for a TYPE_DECL). */ + is a INT_CST whose TREE_INT_CST_HIGH indicates the level of the + template parameters, with 1 being the outermost set of template + parameters. The TREE_VALUE is a vector, whose elements are the + template parameters at each level. Each element in the vector is a + 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 + DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a + TYPE_DECL). */ #define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS(NODE) #define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \ INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE)) #define DECL_NTPARMS(NODE) \ TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) -/* For class templates. */ -#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) /* For function, method, class-data templates. */ #define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE) +/* For a static member variable template, the + DECL_TEMPLATE_INSTANTIATIONS list contains the explicitly and + implicitly generated instantiations of the variable. There are no + partial instantiations of static member variables, so all of these + will be full instantiations. + + For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds + all instantiations and specializations of the class type, including + partial instantiations and partial specializations. + + In both cases, the TREE_PURPOSE of each node contains the arguments + used; the TREE_VALUE contains the generated variable. The template + arguments are always complete. For example, given: + + template struct S1 { + template struct S2 {}; + template struct S2 {}; + }; + + the record for the partial specialization will contain, as its + argument list, { {T}, {U*} }, and will be on the + DECL_TEMPLATE_INSTANTIATIONS list for `template template + struct S1::S2'. + + This list is not used for function templates. */ #define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE) +/* For a function template, the DECL_TEMPLATE_SPECIALIZATIONS lists + contains all instantiations and specializations of the function, + including partial instantiations. For a partial instantiation + which is a specialization, this list holds only full + specializations of the template that are instantiations of the + partial instantiation. For example, given: + + template struct S { + template void f(U); + template <> void f(T); + }; + + the `S::f(int)' function will appear on the + DECL_TEMPLATE_SPECIALIZATIONS list for both `template + template void S::f(U)' and `template void + S::f(T)'. In the latter case, however, it will have only the + innermost set of arguments (T, in this case). The DECL_TI_TEMPLATE + for the function declaration will point at the specialization, not + the fully general template. + + For a class template, this list contains the partial + specializations of this template. (Full specializations are not + recorded on this list.) The TREE_PURPOSE holds the innermost + arguments used in the partial specialization (e.g., for `template + struct S' this will be `T*'.) The TREE_VALUE + holds the innermost template parameters for the specialization + (e.g., `T' in the example above.) The TREE_TYPE is the _TYPE node + for the partial specialization. + + This list is not used for static variable templates. */ +#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) #define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) -/* Nonzero for TEMPLATE_DECL nodes that represents template template - parameters */ +/* Nonzero for a DECL which is actually a template parameter. */ +#define DECL_TEMPLATE_PARM_P(NODE) \ + DECL_LANG_FLAG_0 (NODE) + #define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ - (TREE_CODE (NODE) == TEMPLATE_DECL && TREE_TYPE (NODE) \ - && TREE_CODE (TREE_TYPE (NODE)) == TEMPLATE_TEMPLATE_PARM) + (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) #define DECL_FUNCTION_TEMPLATE_P(NODE) \ (TREE_CODE (NODE) == TEMPLATE_DECL \ @@ -1616,8 +1974,36 @@ extern int flag_new_for_scope; #define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ (CLASSTYPE_USE_TEMPLATE(NODE) = 3) +/* Non-zero if DECL is a friend function which is an instantiation + from the point of view of the compiler, but not from the point of + view of the language. For example given: + template struct S { friend void f(T) {}; }; + the declaration of `void f(int)' generated when S is + instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be + a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION. */ +#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ + (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) + +/* Non-zero 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) \ + (TYPE_LANG_SPECIFIC (TYPE)->type_flags.is_partial_instantiation) + +/* Non-zero iff we are currently processing a declaration for an + entity with its own template parameter list, and which is not a + full specialization. */ +#define PROCESSING_REAL_TEMPLATE_DECL_P() \ + (processing_template_decl > template_class_depth (current_class_type)) + /* This function may be a guiding decl for a template. */ #define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE) + +/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been + instantiated, i.e. its definition has been generated from the + pattern given in the the template. */ +#define DECL_TEMPLATE_INSTANTIATED(NODE) DECL_LANG_FLAG_1(NODE) + /* We know what we're doing with this decl now. */ #define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE) @@ -1636,10 +2022,6 @@ extern int flag_new_for_scope; #define DECL_REALLY_EXTERN(NODE) \ (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) -/* Used to tell cp_finish_decl that it should approximate comdat linkage - as best it can for this decl. */ -#define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat) - #define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i) /* ...and for unexpanded-parameterized-type nodes. */ @@ -1710,6 +2092,11 @@ extern int warn_overloaded_virtual; /* Nonzero means warn about use of multicharacter literals. */ extern int warn_multichar; +/* Non-zero means warn if a non-templatized friend function is + declared in a templatized class. This behavior is warned about with + flag_guiding_decls in do_friend. */ +extern int warn_nontemplate_friend; + /* in c-common.c */ extern void declare_function_name PROTO((void)); extern void decl_attributes PROTO((tree, tree, tree)); @@ -1719,7 +2106,7 @@ extern void check_function_format PROTO((tree, tree, 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 PROTO((enum tree_code)); -extern tree cp_build_type_variant PROTO((tree, int, int)); +extern tree cp_build_qualified_type PROTO((tree, int)); extern tree canonical_type_variant PROTO((tree)); extern void c_expand_expr_stmt PROTO((tree)); /* Validate the expression after `case' and apply default promotions. */ @@ -1730,6 +2117,8 @@ extern void constant_expression_warning PROTO((tree)); extern tree convert_and_check PROTO((tree, tree)); extern void overflow_warning PROTO((tree)); extern void unsigned_conversion_warning PROTO((tree, tree)); +extern void c_apply_type_quals_to_decl PROTO((int, tree)); + /* Read the rest of the current #-directive line. */ #if USE_CPPLIB extern char *get_directive_line PROTO((void)); @@ -1789,8 +2178,10 @@ extern tree opaque_type_node, signature_type_node; #define vfunc_ptr_type_node \ (flag_vtable_thunks ? vtable_entry_type : ptr_type_node) -/* Array type `(void *)[]' */ +/* The type of a vtbl, i.e., an array of vtable entries. */ extern tree vtbl_type_node; +/* The type of a class vtbl pointer, i.e., a pointer to a vtable entry. */ +extern tree vtbl_ptr_type_node; extern tree delta_type_node; extern tree std_node; @@ -1801,6 +2192,12 @@ extern tree boolean_type_node, boolean_true_node, boolean_false_node; extern tree null_node; +extern tree anonymous_namespace_name; + +/* The FUNCTION_DECL for the default `::operator delete'. */ + +extern tree global_delete_fndecl; + /* in pt.c */ /* These values are used for the `STRICT' parameter to type_unfication and @@ -1832,6 +2229,13 @@ extern int minimal_parse_mode; extern void maybe_print_template_context PROTO ((void)); /* in class.c */ + +/* When parsing a class definition, the access specifier most recently + given by the user, or, if no access specifier was given, the + default value appropriate for the kind of class (i.e., struct, + class, or union). */ +extern tree current_access_specifier; + extern tree current_class_name; extern tree current_class_type; extern tree current_class_ptr; @@ -1842,6 +2246,9 @@ extern int current_class_depth; extern tree current_lang_name; extern tree lang_name_cplusplus, lang_name_c, lang_name_java; +/* The low-water mark on the class-cache obstack. */ +extern char *class_cache_firstobj; + /* Points to the name of that function. May not be the DECL_NAME of CURRENT_FUNCTION_DECL due to overloading */ extern tree original_function_name; @@ -1858,12 +2265,6 @@ extern int current_function_parms_stored; #define OPERATOR_ASSIGN_FORMAT "__a%s" #define OPERATOR_FORMAT "__%s" #define OPERATOR_TYPENAME_FORMAT "__op" -#define OPERATOR_TYPENAME_P(ID_NODE) \ - (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ - && IDENTIFIER_POINTER (ID_NODE)[1] == '_' \ - && IDENTIFIER_POINTER (ID_NODE)[2] == 'o' \ - && IDENTIFIER_POINTER (ID_NODE)[3] == 'p') - /* Cannot use '$' up front, because this confuses gdb (names beginning with '$' are gdb-local identifiers). @@ -1986,9 +2387,9 @@ extern int current_function_parms_stored; #define SIGNATURE_OPTR_NAME "__optr" #define SIGNATURE_SPTR_NAME "__sptr" #define SIGNATURE_POINTER_NAME "__sp_" -#define SIGNATURE_POINTER_NAME_FORMAT "__%s%ssp_%s" +#define SIGNATURE_POINTER_NAME_FORMAT "__%s%s%ssp_%s" #define SIGNATURE_REFERENCE_NAME "__sr_" -#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%ssr_%s" +#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%s%ssr_%s" #define SIGTABLE_PTR_TYPE "__sigtbl_ptr_type" #define SIGTABLE_NAME_FORMAT "__st_%s_%s" @@ -2028,6 +2429,14 @@ extern int current_function_parms_stored; && IDENTIFIER_POINTER (ID_NODE)[1] <= '9') #endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ +/* Store the vbase pointer field name for type TYPE into pointer BUF. */ +#define FORMAT_VBASE_NAME(BUF,TYPE) do { \ + char *wbuf = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (TYPE) \ + + sizeof (VBASE_NAME) + 1); \ + sprintf (wbuf, VBASE_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (TYPE)); \ + (BUF) = wbuf; \ +} while (0) + /* Returns non-zero iff ID_NODE is an IDENTIFIER_NODE whose name is `main'. */ #define MAIN_NAME_P(ID_NODE) \ @@ -2037,7 +2446,7 @@ extern int current_function_parms_stored; `main'. */ #define DECL_MAIN_P(NODE) \ (TREE_CODE (NODE) == FUNCTION_DECL \ - && DECL_CONTEXT (NODE) == NULL_TREE \ + && DECL_LANGUAGE (NODE) == lang_c \ && DECL_NAME (NODE) != NULL_TREE \ && MAIN_NAME_P (DECL_NAME (NODE))) @@ -2077,24 +2486,11 @@ struct pending_inline /* in method.c */ extern struct pending_inline *pending_inlines; -/* 1 for -fall-virtual: make every member function (except - constructors) lay down in the virtual function table. - Calls can then either go through the virtual function table or not, - depending on whether we know what function will actually be called. */ - -extern int flag_all_virtual; - /* Positive values means that we cannot make optimizing assumptions about `this'. Negative values means we know `this' to be of static type. */ extern int flag_this_is_variable; -/* Controls whether enums and ints freely convert. - 1 means with complete freedom. - 0 means enums can convert to ints, but not vice-versa. */ - -extern int flag_int_enum_equivalence; - /* Nonzero means generate 'rtti' that give run-time type information. */ extern int flag_rtti; @@ -2138,7 +2534,6 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; /* The following two can be derived from the previous one */ extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */ -extern tree current_class_type; /* _TYPE: the type of the current class */ /* Some macros for char-based bitfields. */ #define B_SET(a,x) (a[x>>3] |= (1 << (x&7))) @@ -2233,11 +2628,47 @@ extern tree current_class_type; /* _TYPE: the type of the current class */ #define WANT_ENUM 4 /* enumerated types */ #define WANT_POINTER 8 /* pointer types */ #define WANT_NULL 16 /* null pointer constant */ - #define WANT_ARITH (WANT_INT | WANT_FLOAT) -#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) -#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) +/* Used with comptypes, and related functions, to guide type + comparison. */ + +#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 enmeration + types as the same as integer types + of the same width. */ +#define COMPARE_REDECLARATION 4 /* The comparsion 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, + regardless of the current scope. */ +#define PUSH_LOCAL 1 /* Push the DECL into the current + scope. */ +#define PUSH_USING 2 /* We are pushing this DECL as the + result of a using declaration. */ + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual + sense of `same'. */ +#define same_type_p(type1, type2) \ + comptypes ((type1), (type2), COMPARE_STRICT) + +/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2 + is derived from TYPE1, or if TYPE2 is a pointer (reference) to a + class derived from the type pointed to (referred to) by TYPE1. */ +#define same_or_base_type_p(type1, type2) \ + comptypes ((type1), (type2), COMPARE_BASE) /* These macros are used to access a TEMPLATE_PARM_INDEX. */ #define TEMPLATE_PARM_IDX(NODE) (((template_parm_index*) NODE)->index) @@ -2283,9 +2714,10 @@ extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int)); extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree)); extern int can_convert PROTO((tree, tree)); extern int can_convert_arg PROTO((tree, tree, tree)); -extern void enforce_access PROTO((tree, tree)); -extern tree convert_default_arg PROTO((tree, tree)); +extern int enforce_access PROTO((tree, tree)); +extern tree convert_default_arg PROTO((tree, tree, tree)); extern tree convert_arg_to_ellipsis PROTO((tree)); +extern int is_properly_derived_from PROTO((tree, tree)); /* in class.c */ extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int)); @@ -2295,24 +2727,29 @@ extern void add_method PROTO((tree, tree *, tree)); extern int currently_open_class PROTO((tree)); extern tree get_vfield_offset PROTO((tree)); extern void duplicate_tag_error PROTO((tree)); -extern tree finish_struct PROTO((tree, tree, tree, int)); -extern tree finish_struct_1 PROTO((tree, int)); -extern tree finish_struct_methods PROTO((tree, tree, int)); +extern tree finish_struct PROTO((tree, tree, int)); +extern void finish_struct_1 PROTO((tree, int)); extern int resolves_to_fixed_type_p PROTO((tree, int *)); extern void init_class_processing PROTO((void)); extern int is_empty_class PROTO((tree)); extern void pushclass PROTO((tree, int)); -extern void popclass PROTO((int)); +extern void popclass PROTO((void)); extern void push_nested_class PROTO((tree, int)); -extern void pop_nested_class PROTO((int)); +extern void pop_nested_class PROTO((void)); extern void push_lang_context PROTO((tree)); extern void pop_lang_context PROTO((void)); extern tree instantiate_type PROTO((tree, tree, int)); extern void print_class_statistics PROTO((void)); -extern void maybe_push_cache_obstack PROTO((void)); -extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *)); -extern tree build_self_reference PROTO((void)); +extern void push_cache_obstack PROTO((void)); +extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *, tree)); +extern void build_self_reference PROTO((void)); extern void warn_hidden PROTO((tree)); +extern tree get_enclosing_class PROTO((tree)); +int is_base_of_enclosing_class PROTO((tree, tree)); +extern void unreverse_member_declarations PROTO((tree)); +extern void invalidate_class_lookup_cache PROTO((void)); +extern void maybe_note_name_used_in_class PROTO((tree, tree)); +extern void note_name_declared_in_class PROTO((tree, tree)); /* in cvt.c */ extern tree convert_to_reference PROTO((tree, tree, int, int, tree)); @@ -2323,15 +2760,17 @@ extern tree ocp_convert PROTO((tree, tree, int, int)); extern tree cp_convert PROTO((tree, tree)); extern tree convert PROTO((tree, tree)); extern tree convert_force PROTO((tree, tree, int)); -extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int)); +extern tree build_type_conversion PROTO((tree, tree, int)); extern tree build_expr_type_conversion PROTO((int, tree, int)); extern tree type_promotes_to PROTO((tree)); extern tree perform_qualification_conversions PROTO((tree, tree)); /* decl.c */ /* resume_binding_level */ +extern void set_identifier_local_value PROTO((tree, tree)); extern int global_bindings_p PROTO((void)); extern int toplevel_bindings_p PROTO((void)); +extern int namespace_bindings_p PROTO((void)); extern void keep_next_level PROTO((void)); extern int kept_level_p PROTO((void)); extern void declare_parm_level PROTO((void)); @@ -2348,7 +2787,6 @@ extern void insert_block PROTO((tree)); extern void add_block_current_level PROTO((tree)); extern void set_block PROTO((tree)); extern void pushlevel_class PROTO((void)); -extern tree poplevel_class PROTO((int)); extern void print_binding_stack PROTO((void)); extern void print_binding_level PROTO((struct binding_level *)); extern void push_namespace PROTO((tree)); @@ -2358,7 +2796,6 @@ extern void push_to_top_level PROTO((void)); extern void pop_from_top_level PROTO((void)); extern tree identifier_type_value PROTO((tree)); extern void set_identifier_type_value PROTO((tree, tree)); -extern void set_identifier_local_value PROTO((tree, tree)); extern void pop_everything PROTO((void)); extern void pushtag PROTO((tree, tree, int)); extern tree make_anon_name PROTO((void)); @@ -2367,7 +2804,7 @@ extern int decls_match PROTO((tree, tree)); extern int duplicate_decls PROTO((tree, tree)); extern tree pushdecl PROTO((tree)); extern tree pushdecl_top_level PROTO((tree)); -extern tree pushdecl_class_level PROTO((tree)); +extern void pushdecl_class_level PROTO((tree)); #if 0 extern void pushdecl_nonclass_level PROTO((tree)); #endif @@ -2375,14 +2812,13 @@ extern tree pushdecl_namespace_level PROTO((tree)); extern tree push_using_decl PROTO((tree, tree)); extern tree push_using_directive PROTO((tree)); extern void push_class_level_binding PROTO((tree, tree)); -extern tree push_using_decl PROTO((tree, tree)); extern tree implicitly_declare PROTO((tree)); extern tree lookup_label PROTO((tree)); extern tree shadow_label PROTO((tree)); extern tree define_label PROTO((char *, int, tree)); extern void push_switch PROTO((void)); extern void pop_switch PROTO((void)); -extern void define_case_label PROTO((tree)); +extern void define_case_label PROTO((void)); extern tree getdecls PROTO((void)); extern tree gettags PROTO((void)); #if 0 @@ -2392,6 +2828,7 @@ extern tree binding_for_name PROTO((tree, tree)); extern tree namespace_binding PROTO((tree, tree)); extern void set_namespace_binding PROTO((tree, tree, tree)); extern tree lookup_namespace_name PROTO((tree, tree)); +extern tree build_typename_type PROTO((tree, tree, tree, tree)); extern tree make_typename_type PROTO((tree, tree)); extern tree lookup_name_nonclass PROTO((tree)); extern tree lookup_function_nonclass PROTO((tree, tree)); @@ -2408,8 +2845,9 @@ extern tree auto_function PROTO((tree, tree, enum built_in_function)); extern void init_decl_processing PROTO((void)); extern int init_type_desc PROTO((void)); extern tree define_function - PROTO((char *, tree, enum built_in_function, - void (*) (tree), char *)); + PROTO((const char *, tree, enum built_in_function, + void (*) (tree), const char *)); +extern tree check_tag_decl PROTO((tree)); extern void shadow_tag PROTO((tree)); extern tree groktypename PROTO((tree)); extern tree start_decl PROTO((tree, tree, int, tree, tree)); @@ -2424,44 +2862,60 @@ extern int parmlist_is_exprlist PROTO((tree)); extern int copy_args_p PROTO((tree)); extern int grok_ctor_properties PROTO((tree, tree)); extern void grok_op_properties PROTO((tree, int, int)); -extern tree xref_tag PROTO((tree, tree, tree, int)); +extern tree xref_tag PROTO((tree, tree, int)); extern tree xref_tag_from_type PROTO((tree, tree, int)); extern void xref_basetypes PROTO((tree, tree, tree, tree)); extern tree start_enum PROTO((tree)); -extern tree finish_enum PROTO((tree, tree)); -extern tree build_enumerator PROTO((tree, tree)); -extern tree grok_enum_decls PROTO((tree)); +extern tree finish_enum PROTO((tree)); +extern tree build_enumerator PROTO((tree, tree, tree)); extern int start_function PROTO((tree, tree, tree, int)); extern void expand_start_early_try_stmts PROTO((void)); extern void store_parm_decls PROTO((void)); extern void store_return_init PROTO((tree, tree)); extern void finish_function PROTO((int, int, int)); -extern tree start_method PROTO((tree, tree)); +extern tree start_method PROTO((tree, tree, tree)); extern tree finish_method PROTO((tree)); extern void hack_incomplete_structures PROTO((tree)); extern tree maybe_build_cleanup_and_delete PROTO((tree)); extern tree maybe_build_cleanup PROTO((tree)); extern void cplus_expand_expr_stmt PROTO((tree)); extern void finish_stmt PROTO((void)); -extern int id_in_current_class PROTO((tree)); extern void push_cp_function_context PROTO((tree)); extern void pop_cp_function_context PROTO((tree)); extern int in_function_p PROTO((void)); extern void replace_defarg PROTO((tree, tree)); extern void print_other_binding_stack PROTO((struct binding_level *)); extern void revert_static_member_fn PROTO((tree*, tree*, tree*)); -extern void cat_namespace_levels PROTO((void)); +extern void fixup_anonymous_union PROTO((tree)); +extern int check_static_variable_definition PROTO((tree, tree)); +extern void push_local_binding PROTO((tree, tree, int)); +extern int push_class_binding PROTO((tree, tree)); +extern tree check_default_argument PROTO((tree, tree)); +extern tree push_overloaded_decl PROTO((tree, int)); +extern void clear_identifier_class_values PROTO((void)); +extern void storetags PROTO((tree)); +extern int vtable_decl_p PROTO((tree, void *)); +extern int vtype_decl_p PROTO((tree, void *)); +extern int sigtable_decl_p PROTO((tree, void *)); +typedef int (*walk_globals_pred) PROTO((tree, void *)); +typedef int (*walk_globals_fn) PROTO((tree *, void *)); +extern int walk_globals PROTO((walk_globals_pred, + walk_globals_fn, + void *)); +typedef int (*walk_namespaces_fn) PROTO((tree, void *)); +extern int walk_namespaces PROTO((walk_namespaces_fn, + void *)); +extern int wrapup_globals_for_namespace PROTO((tree, void *)); /* in decl2.c */ -extern int check_java_method PROTO((tree, tree)); -extern int flag_assume_nonnull_objects; +extern int check_java_method PROTO((tree)); extern int lang_decode_option PROTO((int, char **)); extern tree grok_method_quals PROTO((tree, tree, tree)); extern void warn_if_unknown_interface PROTO((tree)); -extern tree grok_x_components PROTO((tree, tree)); +extern void grok_x_components PROTO((tree)); extern void maybe_retrofit_in_chrg PROTO((tree)); extern void maybe_make_one_only PROTO((tree)); -extern void grokclassfn PROTO((tree, tree, tree, enum overload_flags, tree)); +extern void grokclassfn PROTO((tree, tree, enum overload_flags, tree)); extern tree grok_alignof PROTO((tree)); extern tree grok_array_decl PROTO((tree, tree)); extern tree delete_sanity PROTO((tree, tree, int, int)); @@ -2482,17 +2936,13 @@ extern tree get_temp_name PROTO((tree, int)); extern tree get_temp_regvar PROTO((tree, tree)); extern void finish_anon_union PROTO((tree)); extern tree finish_table PROTO((tree, tree, tree, int)); -extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree)); +extern void finish_builtin_type PROTO((tree, const char *, + tree *, int, tree)); extern tree coerce_new_type PROTO((tree)); extern tree coerce_delete_type PROTO((tree)); extern void comdat_linkage PROTO((tree)); extern void import_export_class PROTO((tree)); extern void import_export_vtable PROTO((tree, tree, int)); -extern int finish_prevtable_vardecl PROTO((tree, tree)); -extern int walk_vtables PROTO((void (*)(tree, tree), - int (*)(tree, tree))); -extern void walk_sigtables PROTO((void (*)(tree, tree), - void (*)(tree, tree))); extern void import_export_decl PROTO((tree)); extern tree build_cleanup PROTO((tree)); extern void finish_file PROTO((void)); @@ -2502,10 +2952,12 @@ extern tree build_expr_from_tree PROTO((tree)); extern tree reparse_decl_as_expr PROTO((tree, tree)); extern tree finish_decl_parsing PROTO((tree)); extern tree check_cp_case_value PROTO((tree)); -extern void set_decl_namespace PROTO((tree, tree)); +extern void set_decl_namespace PROTO((tree, tree, int)); extern tree current_decl_namespace PROTO((void)); extern void push_decl_namespace PROTO((tree)); extern void pop_decl_namespace PROTO((void)); +extern void push_scope PROTO((tree)); +extern void pop_scope PROTO((tree)); extern void do_namespace_alias PROTO((tree, tree)); extern void do_toplevel_using_decl PROTO((tree)); extern void do_local_using_decl PROTO((tree)); @@ -2515,16 +2967,19 @@ extern void check_default_args PROTO((tree)); extern void mark_used PROTO((tree)); extern tree handle_class_head PROTO((tree, tree, tree)); extern tree lookup_arg_dependent PROTO((tree, tree, tree)); +extern void finish_static_data_member_decl PROTO((tree, tree, tree, int, int)); /* in errfn.c */ -extern void cp_error (); -extern void cp_error_at (); -extern void cp_warning (); -extern void cp_warning_at (); -extern void cp_pedwarn (); -extern void cp_pedwarn_at (); -extern void cp_compiler_error (); -extern void cp_sprintf (); +/* The cp_* functions aren't suitable for ATTRIBUTE_PRINTF. */ +extern void cp_error PVPROTO((const char *, ...)); +extern void cp_error_at PVPROTO((const char *, ...)); +extern void cp_warning PVPROTO((const char *, ...)); +extern void cp_warning_at PVPROTO((const char *, ...)); +extern void cp_pedwarn PVPROTO((const char *, ...)); +extern void cp_pedwarn_at PVPROTO((const char *, ...)); +extern void cp_compiler_error PVPROTO((const char *, ...)); +extern void cp_sprintf PVPROTO((const char *, ...)); +extern void cp_deprecated PROTO((const char*)); /* in error.c */ extern void init_error PROTO((void)); @@ -2566,7 +3021,9 @@ extern void do_case PROTO((tree, tree)); /* friend.c */ extern int is_friend PROTO((tree, tree)); extern void make_friend_class PROTO((tree, tree)); -extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int)); +extern void add_friend PROTO((tree, tree)); +extern void add_friends PROTO((tree, tree, tree)); +extern tree do_friend PROTO((tree, tree, tree, tree, tree, enum overload_flags, tree, int)); /* in init.c */ extern void init_init_processing PROTO((void)); @@ -2574,7 +3031,7 @@ extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree)); extern void emit_base_init PROTO((tree, int)); extern void check_base_init PROTO((tree)); extern void expand_member_init PROTO((tree, tree, tree)); -extern void expand_aggr_init PROTO((tree, tree, int, int)); +extern void expand_aggr_init PROTO((tree, tree, int)); extern int is_aggr_typedef PROTO((tree, int)); extern int is_aggr_type PROTO((tree, int)); extern tree get_aggr_from_typedef PROTO((tree, int)); @@ -2586,7 +3043,7 @@ extern tree decl_constant_value PROTO((tree)); extern tree build_new PROTO((tree, tree, tree, int)); extern tree build_new_1 PROTO((tree)); extern tree expand_vec_init PROTO((tree, tree, tree, tree, int)); -extern tree build_x_delete PROTO((tree, tree, int, tree)); +extern tree build_x_delete PROTO((tree, int, tree)); extern tree build_delete PROTO((tree, tree, tree, int, int)); extern tree build_vbase_delete PROTO((tree, tree)); extern tree build_vec_delete PROTO((tree, tree, tree, tree, int)); @@ -2594,7 +3051,7 @@ extern tree build_vec_delete PROTO((tree, tree, tree, tree, int)); /* in input.c */ /* in lex.c */ -extern char *file_name_nondirectory PROTO((char *)); +extern char *file_name_nondirectory PROTO((const char *)); extern tree make_pointer_declarator PROTO((tree, tree)); extern tree make_reference_declarator PROTO((tree, tree)); extern tree make_call_declarator PROTO((tree, tree, tree, tree)); @@ -2602,7 +3059,6 @@ extern void set_quals_and_spec PROTO((tree, tree, tree)); extern char *operator_name_string PROTO((tree)); extern void lang_init PROTO((void)); extern void lang_finish PROTO((void)); -extern void init_filename_times PROTO((void)); #if 0 extern void reinit_lang_specific PROTO((void)); #endif @@ -2629,12 +3085,14 @@ extern tree identifier_typedecl_value PROTO((tree)); extern int real_yylex PROTO((void)); extern int is_rid PROTO((tree)); extern tree build_lang_decl PROTO((enum tree_code, tree, tree)); +extern void retrofit_lang_decl PROTO((tree)); extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree)); extern void copy_lang_decl PROTO((tree)); extern tree make_lang_type PROTO((enum tree_code)); extern void dump_time_statistics PROTO((void)); -/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */ -extern void yyerror PROTO((char *)); +extern void compiler_error PVPROTO((const char *, ...)) + ATTRIBUTE_PRINTF_1; +extern void yyerror PROTO((const char *)); extern void clear_inline_text_obstack PROTO((void)); extern void maybe_snarf_defarg PROTO((void)); extern tree snarf_defarg PROTO((void)); @@ -2642,6 +3100,7 @@ extern void add_defarg_fn PROTO((tree)); extern void do_pending_defargs PROTO((void)); extern int identifier_type PROTO((tree)); extern void yyhook PROTO((int)); +extern int cp_type_qual_from_rid PROTO((tree)); /* in method.c */ extern void init_method PROTO((void)); @@ -2649,7 +3108,9 @@ extern void do_inline_function_hair PROTO((tree, tree)); extern char *build_overload_name PROTO((tree, int, int)); extern tree build_static_name PROTO((tree, tree)); extern tree build_decl_overload PROTO((tree, tree, int)); -extern tree build_template_decl_overload PROTO((tree, tree, tree, tree, tree, int)); +extern tree build_decl_overload_real PROTO((tree, tree, tree, tree, + tree, int)); +extern void set_mangled_name_for_decl PROTO((tree)); extern tree build_typename_overload PROTO((tree)); extern tree build_overload_with_type PROTO((tree, tree)); extern tree build_destructor_name PROTO((tree)); @@ -2661,22 +3122,21 @@ extern void synthesize_method PROTO((tree)); extern tree get_id_2 PROTO((char *, tree)); /* in pt.c */ -extern tree innermost_args PROTO ((tree, int)); -extern tree tsubst PROTO ((tree, tree, tree)); -extern tree tsubst_expr PROTO ((tree, tree, tree)); -extern tree tsubst_copy PROTO ((tree, tree, tree)); -extern tree tsubst_chain PROTO((tree, tree)); +extern void check_template_shadow PROTO ((tree)); +extern tree innermost_args PROTO ((tree)); +extern tree tsubst PROTO ((tree, tree, int, tree)); +extern tree tsubst_expr PROTO ((tree, tree, int, tree)); +extern tree tsubst_copy PROTO ((tree, tree, int, tree)); extern void maybe_begin_member_template_processing PROTO((tree)); -extern void maybe_end_member_template_processing PROTO((tree)); -extern tree finish_member_template_decl PROTO((tree, tree)); +extern void maybe_end_member_template_processing PROTO((void)); +extern tree finish_member_template_decl PROTO((tree)); extern void begin_template_parm_list PROTO((void)); extern void begin_specialization PROTO((void)); extern void reset_specialization PROTO((void)); extern void end_specialization PROTO((void)); extern void begin_explicit_instantiation PROTO((void)); extern void end_explicit_instantiation PROTO((void)); -extern tree determine_specialization PROTO((tree, tree, tree *, int, int)); -extern tree check_explicit_specialization PROTO((tree, tree, int, int)); +extern tree check_explicit_specialization PROTO((tree, tree, int, int)); extern tree process_template_parm PROTO((tree, tree)); extern tree end_template_parm_list PROTO((tree)); extern void end_template_decl PROTO((void)); @@ -2684,14 +3144,13 @@ extern tree current_template_args PROTO((void)); extern tree push_template_decl PROTO((tree)); extern tree push_template_decl_real PROTO((tree, int)); extern void redeclare_class_template PROTO((tree, tree)); -extern tree lookup_template_class PROTO((tree, tree, tree, tree)); +extern tree lookup_template_class PROTO((tree, tree, tree, tree, int)); extern tree lookup_template_function PROTO((tree, tree)); extern int uses_template_parms PROTO((tree)); extern tree instantiate_class_template PROTO((tree)); extern tree instantiate_template PROTO((tree, tree)); extern void overload_template_name PROTO((tree)); -extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, tree)); -extern int type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, int)); +extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t)); struct tinst_level *tinst_for_decl PROTO((void)); extern void mark_decl_instantiated PROTO((tree, int)); extern int more_specialized PROTO((tree, tree, tree)); @@ -2699,7 +3158,6 @@ extern void mark_class_instantiated PROTO((tree, int)); extern void do_decl_instantiation PROTO((tree, tree, tree)); extern void do_type_instantiation PROTO((tree, tree)); extern tree instantiate_decl PROTO((tree)); -extern tree lookup_nested_type_by_name PROTO((tree, tree)); extern tree do_poplevel PROTO((void)); extern tree get_bindings PROTO((tree, tree, tree)); /* CONT ... */ @@ -2708,15 +3166,19 @@ extern void begin_tree PROTO((void)); extern void end_tree PROTO((void)); extern void add_maybe_template PROTO((tree, tree)); extern void pop_tinst_level PROTO((void)); -extern tree most_specialized PROTO((tree, tree, tree)); -extern tree most_specialized_class PROTO((tree, tree, tree)); extern int more_specialized_class PROTO((tree, tree)); extern void do_pushlevel PROTO((void)); extern int is_member_template PROTO((tree)); +extern int template_parms_equal PROTO((tree, tree)); extern int comp_template_parms PROTO((tree, tree)); extern int template_class_depth PROTO((tree)); extern int is_specialization_of PROTO((tree, tree)); extern int comp_template_args PROTO((tree, tree)); +extern void maybe_process_partial_specialization PROTO((tree)); +extern void maybe_check_template_type PROTO((tree)); +extern tree most_specialized_instantiation PROTO((tree, tree)); +extern void print_candidates PROTO((tree)); +extern int instantiate_pending_templates PROTO((void)); extern int processing_specialization; extern int processing_explicit_instantiation; @@ -2725,7 +3187,7 @@ extern int processing_template_parmlist; /* in repo.c */ extern void repo_template_used PROTO((tree)); extern void repo_template_instantiated PROTO((tree, int)); -extern void init_repo PROTO((char*)); +extern void init_repo PROTO((const char *)); extern void finish_repo PROTO((void)); /* in rtti.c */ @@ -2735,46 +3197,43 @@ extern tree build_typeid PROTO((tree)); extern tree build_x_typeid PROTO((tree)); extern tree get_tinfo_fn PROTO((tree)); extern tree get_typeid PROTO((tree)); +extern tree get_typeid_1 PROTO((tree)); extern tree build_dynamic_cast PROTO((tree, tree)); extern void synthesize_tinfo_fn PROTO((tree)); /* in search.c */ extern int types_overlap_p PROTO((tree, tree)); -extern void push_memoized_context PROTO((tree, int)); -extern void pop_memoized_context PROTO((int)); extern tree get_vbase PROTO((tree, tree)); extern tree get_binfo PROTO((tree, tree, int)); extern int get_base_distance PROTO((tree, tree, int, tree *)); -extern tree compute_access PROTO((tree, tree)); +extern int accessible_p PROTO((tree, tree)); extern tree lookup_field PROTO((tree, tree, int, int)); -extern tree lookup_nested_field PROTO((tree, int)); +extern int lookup_fnfields_1 PROTO((tree, tree)); extern tree lookup_fnfields PROTO((tree, tree, int)); extern tree lookup_member PROTO((tree, tree, int, int)); extern tree lookup_nested_tag PROTO((tree, tree)); extern tree get_matching_virtual PROTO((tree, tree, int)); extern tree get_abstract_virtuals PROTO((tree)); -extern tree get_baselinks PROTO((tree, tree, tree)); -extern tree next_baselink PROTO((tree)); extern tree init_vbase_pointers PROTO((tree, tree)); extern void expand_indirect_vtbls_init PROTO((tree, tree, tree)); extern void clear_search_slots PROTO((tree)); extern tree get_vbase_types PROTO((tree)); -extern void build_mi_matrix PROTO((tree)); -extern void free_mi_matrix PROTO((void)); -extern void build_mi_virtuals PROTO((int, int)); -extern void add_mi_virtuals PROTO((int, tree)); -extern void report_ambiguous_mi_virtuals PROTO((int, tree)); extern void note_debug_info_needed PROTO((tree)); extern void push_class_decls PROTO((tree)); extern void pop_class_decls PROTO((void)); extern void unuse_fields PROTO((tree)); -extern void unmark_finished_struct PROTO((tree)); extern void print_search_statistics PROTO((void)); extern void init_search_processing PROTO((void)); extern void reinit_search_statistics PROTO((void)); extern tree current_scope PROTO((void)); extern tree lookup_conversions PROTO((tree)); -extern tree get_template_base PROTO((tree, tree)); +extern tree binfo_for_vtable PROTO((tree)); +extern tree dfs_walk PROTO((tree, + tree (*)(tree, void *), + tree (*) (tree, void *), + void *)); +extern tree dfs_unmark PROTO((tree, void *)); +extern tree markedp PROTO((tree, void *)); /* in semantics.c */ extern void finish_expr_stmt PROTO((tree)); @@ -2821,7 +3280,7 @@ extern tree finish_this_expr PROTO((void)); extern tree finish_object_call_expr PROTO((tree, tree, tree)); extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree)); extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree)); -extern tree finish_globally_qualified_member_call_expr PROTO ((tree, tree)); +extern tree finish_qualified_call_expr PROTO ((tree, tree)); extern tree finish_label_address_expr PROTO((tree)); extern tree finish_unary_op_expr PROTO((enum tree_code, tree)); extern tree finish_id_expr PROTO((tree)); @@ -2835,14 +3294,22 @@ extern tree finish_template_type_parm PROTO((tree, tree)); extern tree finish_template_template_parm PROTO((tree, tree)); extern tree finish_parmlist PROTO((tree, int)); extern tree begin_class_definition PROTO((tree)); -extern tree finish_class_definition PROTO((tree, tree, tree, int)); +extern tree finish_class_definition PROTO((tree, tree, int, int)); extern void finish_default_args PROTO((void)); extern void begin_inline_definitions PROTO((void)); -extern tree finish_member_class_template PROTO((tree, tree)); +extern void finish_inline_definitions PROTO((void)); +extern tree finish_member_class_template PROTO((tree)); +extern void finish_template_decl PROTO((tree)); +extern tree finish_template_type PROTO((tree, tree, int)); +extern void enter_scope_of PROTO((tree)); +extern tree finish_base_specifier PROTO((tree, tree, int)); +extern void finish_member_declaration PROTO((tree)); +extern void check_multiple_declarators PROTO((void)); +extern tree finish_typeof PROTO((tree)); /* in sig.c */ -extern tree build_signature_pointer_type PROTO((tree, int, int)); -extern tree build_signature_reference_type PROTO((tree, int, int)); +extern tree build_signature_pointer_type PROTO((tree)); +extern tree build_signature_reference_type PROTO((tree)); extern tree build_signature_pointer_constructor PROTO((tree, tree)); extern tree build_signature_method_call PROTO((tree, tree)); extern tree build_optr_ref PROTO((tree)); @@ -2855,13 +3322,15 @@ extern int yylex PROTO((void)); extern tree arbitrate_lookup PROTO((tree, tree, tree)); /* in tree.c */ +extern int pod_type_p PROTO((tree)); +extern void unshare_base_binfos PROTO((tree)); extern int member_p PROTO((tree)); extern int real_lvalue_p PROTO((tree)); extern tree build_min PVPROTO((enum tree_code, tree, ...)); extern tree build_min_nt PVPROTO((enum tree_code, ...)); extern tree min_tree_cons PROTO((tree, tree, tree)); extern int lvalue_p PROTO((tree)); -extern int lvalue_or_else PROTO((tree, char *)); +extern int lvalue_or_else PROTO((tree, const char *)); extern tree build_cplus_new PROTO((tree, tree)); extern tree get_target_expr PROTO((tree)); extern tree break_out_cleanups PROTO((tree)); @@ -2872,17 +3341,17 @@ extern tree build_cplus_array_type PROTO((tree, tree)); extern int layout_basetypes PROTO((tree, int)); extern tree build_vbase_pointer_fields PROTO((tree)); extern tree build_base_fields PROTO((tree)); -extern tree hash_tree_cons PROTO((int, int, int, tree, tree, tree)); +extern tree hash_tree_cons PROTO((tree, tree, tree)); extern tree hash_tree_chain PROTO((tree, tree)); extern tree hash_chainon PROTO((tree, tree)); -extern tree get_decl_list PROTO((tree)); -extern tree make_binfo PROTO((tree, tree, tree, tree, tree)); +extern tree make_binfo PROTO((tree, tree, tree, tree)); extern tree binfo_value PROTO((tree, tree)); extern tree reverse_path PROTO((tree)); extern int count_functions PROTO((tree)); extern int is_overloaded_fn PROTO((tree)); extern tree get_first_fn PROTO((tree)); extern tree binding_init PROTO((struct tree_binding*)); +extern int bound_pmf_p PROTO((tree)); extern tree ovl_cons PROTO((tree, tree)); extern tree scratch_ovl_cons PROTO((tree, tree)); extern int ovl_member PROTO((tree, tree)); @@ -2895,6 +3364,7 @@ extern char *lang_printable_name PROTO((tree, int)); extern tree build_exception_variant PROTO((tree, tree)); extern tree copy_template_template_parm PROTO((tree)); extern tree copy_to_permanent PROTO((tree)); +extern tree permanent_p PROTO((tree)); extern void print_lang_statistics PROTO((void)); extern void __eprintf PROTO((const char *, const char *, unsigned, const char *)); @@ -2904,21 +3374,29 @@ extern tree break_out_target_exprs PROTO((tree)); extern tree get_type_decl PROTO((tree)); extern tree vec_binfo_member PROTO((tree, tree)); extern tree hack_decl_function_context PROTO((tree)); +extern tree decl_namespace_context PROTO((tree)); extern tree lvalue_type PROTO((tree)); extern tree error_type PROTO((tree)); extern tree make_temp_vec PROTO((int)); extern tree build_ptr_wrapper PROTO((void *)); extern tree build_expr_ptr_wrapper PROTO((void *)); extern tree build_int_wrapper PROTO((int)); -extern tree build_srcloc PROTO((char *, int)); extern tree build_srcloc_here PROTO((void)); extern int varargs_function_p PROTO((tree)); extern int really_overloaded_fn PROTO((tree)); extern int cp_tree_equal PROTO((tree, tree)); extern int can_free PROTO((struct obstack *, tree)); extern tree mapcar PROTO((tree, tree (*) (tree))); +extern tree no_linkage_check PROTO((tree)); extern void debug_binfo PROTO((tree)); extern void push_expression_obstack PROTO((void)); +extern tree build_dummy_object PROTO((tree)); +extern tree maybe_dummy_object PROTO((tree, tree *)); +extern int is_dummy_object PROTO((tree)); +extern tree search_tree PROTO((tree, tree (*)(tree))); +extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree)); +extern tree make_ptrmem_cst PROTO((tree, tree)); + #define scratchalloc expralloc #define scratch_tree_cons expr_tree_cons #define build_scratch_list build_expr_list @@ -2926,21 +3404,22 @@ extern void push_expression_obstack PROTO((void)); #define push_scratch_obstack push_expression_obstack /* in typeck.c */ +extern int string_conv_p PROTO((tree, tree, int)); extern tree condition_conversion PROTO((tree)); extern tree target_type PROTO((tree)); extern tree require_complete_type PROTO((tree)); +extern tree require_complete_type_in_void PROTO((tree)); extern tree complete_type PROTO((tree)); -extern tree complete_type_or_else PROTO((tree)); +extern tree complete_type_or_else PROTO((tree, tree)); extern int type_unknown_p PROTO((tree)); extern int fntype_p PROTO((tree)); -extern tree require_instantiated_type PROTO((tree, tree, tree)); extern tree commonparms PROTO((tree, tree)); extern tree original_type PROTO((tree)); extern tree common_type PROTO((tree, tree)); extern int compexcepttypes PROTO((tree, tree)); extern int comptypes PROTO((tree, tree, int)); extern int comp_target_types PROTO((tree, tree, int)); -extern int compparms PROTO((tree, tree, int)); +extern int compparms PROTO((tree, tree)); extern int comp_target_types PROTO((tree, tree, int)); extern int comp_cv_qualification PROTO((tree, tree)); extern int comp_cv_qual_signature PROTO((tree, tree)); @@ -2959,19 +3438,18 @@ extern tree build_object_ref PROTO((tree, tree, tree)); extern tree build_component_ref_1 PROTO((tree, tree, int)); extern tree build_component_ref PROTO((tree, tree, tree, int)); extern tree build_x_component_ref PROTO((tree, tree, tree, int)); -extern tree build_x_indirect_ref PROTO((tree, char *)); -extern tree build_indirect_ref PROTO((tree, char *)); +extern tree build_x_indirect_ref PROTO((tree, const char *)); +extern tree build_indirect_ref PROTO((tree, const char *)); extern tree build_array_ref PROTO((tree, tree)); extern tree build_x_function_call PROTO((tree, tree, tree)); extern tree get_member_function_from_ptrfunc PROTO((tree *, tree)); extern tree build_function_call_real PROTO((tree, tree, int, int)); extern tree build_function_call PROTO((tree, tree)); extern tree build_function_call_maybe PROTO((tree, tree)); -extern tree convert_arguments PROTO((tree, tree, tree, tree, int)); +extern tree convert_arguments PROTO((tree, tree, tree, int)); extern tree build_x_binary_op PROTO((enum tree_code, tree, tree)); -extern tree build_binary_op PROTO((enum tree_code, tree, tree, int)); +extern tree build_binary_op PROTO((enum tree_code, tree, tree)); extern tree build_binary_op_nodefault PROTO((enum tree_code, tree, tree, enum tree_code)); -extern tree build_component_addr PROTO((tree, tree, char *)); extern tree build_x_unary_op PROTO((enum tree_code, tree)); extern tree build_unary_op PROTO((enum tree_code, tree, int)); extern tree unary_complex_lvalue PROTO((enum tree_code, tree)); @@ -2986,24 +3464,31 @@ extern tree build_const_cast PROTO((tree, tree)); extern tree build_c_cast PROTO((tree, tree)); extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree)); extern tree build_modify_expr PROTO((tree, enum tree_code, tree)); -extern int language_lvalue_valid PROTO((tree)); -extern void warn_for_assignment PROTO((char *, char *, char *, tree, int, int)); -extern tree convert_for_initialization PROTO((tree, tree, tree, int, char *, tree, int)); +extern tree convert_for_initialization PROTO((tree, tree, tree, int, const char *, tree, int)); extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, int, char *, int)); extern void c_expand_return PROTO((tree)); extern tree c_expand_start_case PROTO((tree)); extern int comp_ptr_ttypes PROTO((tree, tree)); extern int ptr_reasonably_similar PROTO((tree, tree)); extern tree build_ptrmemfunc PROTO((tree, tree, int)); +extern int cp_type_quals PROTO((tree)); +extern int cp_has_mutable_p PROTO((tree)); +extern int at_least_as_qualified_p PROTO((tree, tree)); +extern int more_qualified_p PROTO((tree, tree)); +extern tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, tree)); +extern void expand_ptrmemfunc_cst PROTO((tree, tree *, tree *, tree *, tree *)); +extern tree delta2_from_ptrmemfunc PROTO((tree)); +extern tree pfn_from_ptrmemfunc PROTO((tree)); /* in typeck2.c */ extern tree error_not_base_type PROTO((tree, tree)); extern tree binfo_or_else PROTO((tree, tree)); -extern void readonly_error PROTO((tree, char *, int)); +extern void readonly_error PROTO((tree, const char *, int)); extern void abstract_virtuals_error PROTO((tree, tree)); extern void signature_error PROTO((tree, tree)); extern void incomplete_type_error PROTO((tree, tree)); -extern void my_friendly_abort PROTO((int)); +extern void my_friendly_abort PROTO((int)) + ATTRIBUTE_NORETURN; extern void my_friendly_assert PROTO((int, int)); extern tree store_init_value PROTO((tree, tree)); extern tree digest_init PROTO((tree, tree, tree *)); @@ -3013,18 +3498,18 @@ extern tree build_m_component_ref PROTO((tree, tree)); extern tree build_functional_cast PROTO((tree, tree)); extern char *enum_name_string PROTO((tree, tree)); extern void report_case_error PROTO((int, tree, tree, tree)); -extern void check_for_new_type PROTO((char *,flagged_type_tree)); +extern void check_for_new_type PROTO((const char *, flagged_type_tree)); extern tree initializer_constant_valid_p PROTO((tree, tree)); /* in xref.c */ -extern void GNU_xref_begin PROTO((char *)); +extern void GNU_xref_begin PROTO((const char *)); extern void GNU_xref_end PROTO((int)); -extern void GNU_xref_file PROTO((char *)); +extern void GNU_xref_file PROTO((const char *)); extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT)); extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int)); -extern void GNU_xref_ref PROTO((tree, char *)); +extern void GNU_xref_ref PROTO((tree, const char *)); extern void GNU_xref_decl PROTO((tree, tree)); -extern void GNU_xref_call PROTO((tree, char *)); +extern void GNU_xref_call PROTO((tree, const char *)); extern void GNU_xref_function PROTO((tree, tree)); extern void GNU_xref_assign PROTO((tree)); extern void GNU_xref_hier PROTO((tree, tree, int, int, int)); diff --git a/contrib/gcc/cp/cvt.c b/contrib/gcc/cp/cvt.c index 18b7d8b..7082726 100644 --- a/contrib/gcc/cp/cvt.c +++ b/contrib/gcc/cp/cvt.c @@ -1,5 +1,5 @@ /* Language-level data type conversion for GNU C++. - Copyright (C) 1987, 88, 92-96, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -31,12 +31,12 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "cp-tree.h" #include "convert.h" - -extern tree static_aggregates; +#include "toplev.h" +#include "decl.h" static tree cp_convert_to_pointer PROTO((tree, tree)); static tree convert_to_pointer_force PROTO((tree, tree)); -static tree build_up_reference PROTO((tree, tree, int, int)); +static tree build_up_reference PROTO((tree, tree, int)); /* Change of width--truncation and extension of integers or reals-- is represented with NOP_EXPR. Proper functioning of many things @@ -85,7 +85,7 @@ cp_convert_to_pointer (type, expr) return error_mark_node; } - rval = build_type_conversion (CONVERT_EXPR, type, expr, 1); + rval = build_type_conversion (type, expr, 1); if (rval) { if (rval == error_mark_node) @@ -95,9 +95,6 @@ cp_convert_to_pointer (type, expr) } } - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); - /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ if (TREE_CODE (type) == POINTER_TYPE && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE @@ -107,21 +104,8 @@ cp_convert_to_pointer (type, expr) functions. */ if (TYPE_PTRMEMFUNC_P (intype)) { - tree decl, basebinfo; tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype)); - tree t = TYPE_METHOD_BASETYPE (fntype); - - if (current_class_type == 0 - || get_base_distance (t, current_class_type, 0, &basebinfo) - == -1) - { - decl = build1 (NOP_EXPR, t, error_mark_node); - } - else if (current_class_ptr == 0) - decl = build1 (NOP_EXPR, t, error_mark_node); - else - decl = current_class_ref; - + tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0); expr = build (OFFSET_REF, fntype, decl, expr); } @@ -141,20 +125,26 @@ cp_convert_to_pointer (type, expr) intype = TREE_TYPE (expr); } - if (TYPE_PTRMEMFUNC_P (intype)) - intype = TYPE_PTRMEMFUNC_FN_TYPE (intype); - form = TREE_CODE (intype); - if (form == POINTER_TYPE || form == REFERENCE_TYPE) + if (POINTER_TYPE_P (intype)) { intype = TYPE_MAIN_VARIANT (intype); if (TYPE_MAIN_VARIANT (type) != intype + && TREE_CODE (type) == POINTER_TYPE && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE && IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype)) - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) + && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE + /* If EXPR is NULL, then we don't need to do any arithmetic + to convert it: + + [conv.ptr] + + The null pointer value is converted to the null pointer + value of the destination type. */ + && !integer_zerop (expr)) { enum tree_code code = PLUS_EXPR; tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1); @@ -186,13 +176,8 @@ cp_convert_to_pointer (type, expr) } } } - if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) - return build_ptrmemfunc (type, expr, 1); - if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE - && TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) { tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type)); tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)); @@ -210,10 +195,7 @@ cp_convert_to_pointer (type, expr) if (binfo && ! TREE_VIA_VIRTUAL (binfo)) expr = size_binop (code, expr, BINFO_OFFSET (binfo)); } - - if (TREE_CODE (TREE_TYPE (intype)) == METHOD_TYPE - || (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)) + else if (TYPE_PTRMEMFUNC_P (type)) { cp_error ("cannot convert `%E' from type `%T' to type `%T'", expr, intype, type); @@ -224,6 +206,14 @@ cp_convert_to_pointer (type, expr) TREE_CONSTANT (rval) = TREE_CONSTANT (expr); return rval; } + else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) + return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 1); + else if (TYPE_PTRMEMFUNC_P (intype)) + { + cp_error ("cannot convert `%E' from type `%T' to type `%T'", + expr, intype, type); + return error_mark_node; + } my_friendly_assert (form != OFFSET_TYPE, 186); @@ -233,8 +223,8 @@ cp_convert_to_pointer (type, expr) if (integer_zerop (expr)) { - if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) - return build_ptrmemfunc (type, expr, 0); + if (TYPE_PTRMEMFUNC_P (type)) + return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); expr = build_int_2 (0, 0); TREE_TYPE (expr) = type; return expr; @@ -254,6 +244,9 @@ cp_convert_to_pointer (type, expr) return convert_to_pointer (type, expr); } + if (type_unknown_p (expr)) + return instantiate_type (type, expr, 1); + cp_error ("cannot convert `%E' from type `%T' to type `%T'", expr, intype, type); return error_mark_node; @@ -335,9 +328,9 @@ convert_to_pointer_force (type, expr) DIRECT_BIND in FLAGS controls how any temporaries are generated. */ static tree -build_up_reference (type, arg, flags, checkconst) +build_up_reference (type, arg, flags) tree type, arg; - int flags, checkconst; + int flags; { tree rval; tree argtype = TREE_TYPE (arg); @@ -356,11 +349,13 @@ build_up_reference (type, arg, flags, checkconst) DECL_ARTIFICIAL (arg) = 1; } DECL_INITIAL (arg) = targ; - cp_finish_decl (arg, targ, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); + cp_finish_decl (arg, targ, NULL_TREE, 0, + LOOKUP_ONLYCONVERTING|DIRECT_BIND); } else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg)) { tree slot = build_decl (VAR_DECL, NULL_TREE, argtype); + DECL_ARTIFICIAL (slot) = 1; arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE); TREE_SIDE_EFFECTS (arg) = 1; } @@ -369,6 +364,9 @@ build_up_reference (type, arg, flags, checkconst) address, transform all occurrences of the register, into a memory reference we could win better. */ rval = build_unary_op (ADDR_EXPR, arg, 1); + if (rval == error_mark_node) + return error_mark_node; + if ((flags & LOOKUP_PROTECT) && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) && IS_AGGR_TYPE (argtype) @@ -409,6 +407,16 @@ convert_to_reference (reftype, expr, convtype, flags, decl) tree rval_as_conversion = NULL_TREE; int i; + if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node) + { + expr = instantiate_type (type, expr, + (flags & LOOKUP_COMPLAIN) != 0); + if (expr == error_mark_node) + return error_mark_node; + + intype = TREE_TYPE (expr); + } + if (TREE_CODE (intype) == REFERENCE_TYPE) my_friendly_abort (364); @@ -422,7 +430,7 @@ convert_to_reference (reftype, expr, convtype, flags, decl) /* Look for a user-defined conversion to lvalue that we can use. */ rval_as_conversion - = build_type_conversion (CONVERT_EXPR, reftype, expr, 1); + = build_type_conversion (reftype, expr, 1); if (rval_as_conversion && rval_as_conversion != error_mark_node && real_lvalue_p (rval_as_conversion)) @@ -440,37 +448,35 @@ convert_to_reference (reftype, expr, convtype, flags, decl) if (flags & LOOKUP_COMPLAIN) { tree ttl = TREE_TYPE (reftype); - tree ttr; - - { - int r = TREE_READONLY (expr); - int v = TREE_THIS_VOLATILE (expr); - ttr = cp_build_type_variant (TREE_TYPE (expr), r, v); - } + tree ttr = lvalue_type (expr); - if (! real_lvalue_p (expr) && ! TYPE_READONLY (ttl)) + /* [dcl.init.ref] says that if an rvalue is used to + initialize a reference, then the reference must be to a + non-volatile const type. */ + if (! real_lvalue_p (expr) + && !CP_TYPE_CONST_NON_VOLATILE_P (ttl)) { - if (decl) - /* Ensure semantics of [dcl.init.ref] */ - cp_pedwarn ("initialization of non-const reference `%#T' from rvalue `%T'", - reftype, intype); + const char *msg; + + if (CP_TYPE_VOLATILE_P (ttl) && decl) + msg = "initialization of volatile reference type `%#T'"; + else if (CP_TYPE_VOLATILE_P (ttl)) + msg = "conversion to volatile reference type `%#T'"; + else if (decl) + msg = "initialization of non-const reference type `%#T'"; else - cp_pedwarn ("conversion to non-const `%T' from rvalue `%T'", - reftype, intype); - } - else if (! (convtype & CONV_CONST)) - { - if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) - cp_pedwarn ("conversion from `%T' to `%T' discards const", - ttr, reftype); - else if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) - cp_pedwarn ("conversion from `%T' to `%T' discards volatile", - ttr, reftype); + msg = "conversion to non-const reference type `%#T'"; + + cp_pedwarn (msg, reftype); + cp_pedwarn ("from rvalue of type `%T'", intype); } + else if (! (convtype & CONV_CONST) + && !at_least_as_qualified_p (ttl, ttr)) + cp_pedwarn ("conversion from `%T' to `%T' discards qualifiers", + ttr, reftype); } - return build_up_reference (reftype, expr, flags, - ! (convtype & CONV_CONST)); + return build_up_reference (reftype, expr, flags); } else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr)) { @@ -482,7 +488,8 @@ 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, -1))) + && (comptypes (TREE_TYPE (intype), type, + COMPARE_BASE | COMPARE_RELAXED ))) cp_warning ("casting `%T' to `%T' does not dereference pointer", intype, reftype); @@ -497,11 +504,11 @@ convert_to_reference (reftype, expr, convtype, flags, decl) { rval = convert_for_initialization (NULL_TREE, type, expr, flags, "converting", 0, 0); - if (rval == error_mark_node) - return error_mark_node; - rval = build_up_reference (reftype, rval, flags, 1); + if (rval == NULL_TREE || rval == error_mark_node) + return rval; + rval = build_up_reference (reftype, rval, flags); - if (rval && ! TYPE_READONLY (TREE_TYPE (reftype))) + if (rval && ! CP_TYPE_CONST_P (TREE_TYPE (reftype))) cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", reftype, intype); } @@ -569,29 +576,29 @@ convert_pointer_to_real (binfo, expr) binfo = NULL_TREE; } - ptr_type = cp_build_type_variant (type, TYPE_READONLY (TREE_TYPE (intype)), - TYPE_VOLATILE (TREE_TYPE (intype))); + ptr_type = cp_build_qualified_type (type, + CP_TYPE_QUALS (TREE_TYPE (intype))); ptr_type = build_pointer_type (ptr_type); - if (ptr_type == TYPE_MAIN_VARIANT (intype)) + if (same_type_p (ptr_type, TYPE_MAIN_VARIANT (intype))) return expr; my_friendly_assert (!integer_zerop (expr), 191); + intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype)); if (TREE_CODE (type) == RECORD_TYPE - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE - && type != TYPE_MAIN_VARIANT (TREE_TYPE (intype))) + && TREE_CODE (intype) == RECORD_TYPE + && type != intype) { tree path; int distance - = get_base_distance (binfo, TYPE_MAIN_VARIANT (TREE_TYPE (intype)), - 0, &path); + = get_base_distance (binfo, intype, 0, &path); /* This function shouldn't be called with unqualified arguments but if it is, give them an error message that they can read. */ if (distance < 0) { cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'", - TREE_TYPE (intype), type); + intype, type); if (distance == -2) cp_error ("because `%T' is an ambiguous base class", type); @@ -663,11 +670,27 @@ ocp_convert (type, expr, convtype, flags) && TYPE_HAS_CONSTRUCTOR (type)) /* We need a new temporary; don't take this shortcut. */; else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) - /* Trivial conversion: cv-qualifiers do not matter on rvalues. */ - return fold (build1 (NOP_EXPR, type, e)); - + { + 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 + 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. */ + return e; + else + return fold (build1 (NOP_EXPR, type, e)); + } + if (code == VOID_TYPE && (convtype & CONV_STATIC)) - return build1 (CONVERT_EXPR, type, e); + { + e = require_complete_type_in_void (e); + if (e != error_mark_node) + e = build1 (CONVERT_EXPR, void_type_node, e); + + return e; + } #if 0 /* This is incorrect. A truncation can't be stripped this way. @@ -698,8 +721,7 @@ ocp_convert (type, expr, convtype, flags) tree intype = TREE_TYPE (e); /* enum = enum, enum = int, enum = float, (enum)pointer are all errors. */ - if (flag_int_enum_equivalence == 0 - && TREE_CODE (type) == ENUMERAL_TYPE + if (TREE_CODE (type) == ENUMERAL_TYPE && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC)) || (TREE_CODE (intype) == POINTER_TYPE))) { @@ -711,7 +733,7 @@ ocp_convert (type, expr, convtype, flags) if (IS_AGGR_TYPE (intype)) { tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, e, 1); + rval = build_type_conversion (type, e, 1); if (rval) return rval; if (flags & LOOKUP_COMPLAIN) @@ -738,7 +760,7 @@ ocp_convert (type, expr, convtype, flags) if (IS_AGGR_TYPE (TREE_TYPE (e))) { tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, e, 1); + rval = build_type_conversion (type, e, 1); if (rval) return rval; else @@ -794,6 +816,12 @@ ocp_convert (type, expr, convtype, flags) ctor = e; + if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type)) + { + abstract_virtuals_error (NULL_TREE, type); + return error_mark_node; + } + if ((flags & LOOKUP_ONLYCONVERTING) && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) /* For copy-initialization, first we create a temp of the proper type @@ -918,8 +946,7 @@ convert_force (type, expr, convtype) (jason 8/9/95) */ tree -build_type_conversion (code, xtype, expr, for_sure) - enum tree_code code; +build_type_conversion (xtype, expr, for_sure) tree xtype, expr; int for_sure; { @@ -941,10 +968,15 @@ build_expr_type_conversion (desires, expr, complain) int complain; { tree basetype = TREE_TYPE (expr); - tree conv; + tree conv = NULL_TREE; tree winner = NULL_TREE; - if (TREE_CODE (basetype) == OFFSET_TYPE) + if (expr == null_node + && (desires & WANT_INT) + && !(desires & WANT_NULL)) + cp_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); @@ -953,8 +985,7 @@ build_expr_type_conversion (desires, expr, complain) switch (TREE_CODE (basetype)) { case INTEGER_TYPE: - if ((desires & WANT_NULL) && TREE_CODE (expr) == INTEGER_CST - && integer_zerop (expr)) + if ((desires & WANT_NULL) && null_ptr_cst_p (expr)) return expr; /* else fall through... */ @@ -1045,13 +1076,12 @@ tree type_promotes_to (type) tree type; { - int constp, volatilep; + int type_quals; if (type == error_mark_node) return error_mark_node; - constp = TYPE_READONLY (type); - volatilep = TYPE_VOLATILE (type); + type_quals = CP_TYPE_QUALS (type); type = TYPE_MAIN_VARIANT (type); /* bool always promotes to int (not unsigned), even if it's the same @@ -1085,10 +1115,9 @@ type_promotes_to (type) else if (type == float_type_node) type = double_type_node; - return cp_build_type_variant (type, constp, volatilep); + return cp_build_qualified_type (type, type_quals); } - /* The routines below this point are carefully written to conform to the standard. They use the same terminology, and follow the rules closely. Although they are used only in pt.c at the moment, they @@ -1103,7 +1132,9 @@ perform_qualification_conversions (type, expr) tree type; tree expr; { - if (comp_target_types (type, TREE_TYPE (expr), 0) == 1) + 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); else return error_mark_node; diff --git a/contrib/gcc/cp/decl.c b/contrib/gcc/cp/decl.c index 68f62ae..c60acc7 100644 --- a/contrib/gcc/cp/decl.c +++ b/contrib/gcc/cp/decl.c @@ -1,5 +1,5 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "except.h" #include "toplev.h" +#include "../hash.h" #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free @@ -60,9 +61,8 @@ extern tree current_namespace; extern tree global_namespace; extern void (*print_error_function) PROTO((char *)); +extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree)); -/* Stack of places to restore the search obstack back to. */ - /* Obstack used for remembering local class declarations (like enums and static (const) members. */ #include "stack.h" @@ -133,8 +133,7 @@ static struct stack_level *decl_stack; static tree grokparms PROTO((tree, int)); static tree lookup_nested_type PROTO((tree, tree)); -static char *redeclaration_error_message PROTO((tree, tree)); -static tree push_overloaded_decl PROTO((tree, int)); +static const char *redeclaration_error_message PROTO((tree, tree)); static struct stack_level *push_decl_level PROTO((struct stack_level *, struct obstack *)); @@ -144,11 +143,9 @@ static void pop_binding_level PROTO((void)); static void suspend_binding_level PROTO((void)); static void resume_binding_level PROTO((struct binding_level *)); static struct binding_level *make_binding_level PROTO((void)); -static int namespace_bindings_p PROTO((void)); static void declare_namespace_level PROTO((void)); -static void signal_catch PROTO((int)); +static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN; static void storedecls PROTO((tree)); -static void storetags PROTO((tree)); static void require_complete_types_for_parms PROTO((tree)); static void push_overloaded_decl_1 PROTO((tree)); static int ambi_op_p PROTO((tree)); @@ -162,20 +159,39 @@ static void warn_extern_redeclared_static PROTO((tree, tree)); static void grok_reference_init PROTO((tree, tree, tree)); static tree grokfndecl PROTO((tree, tree, tree, tree, int, enum overload_flags, tree, - tree, tree, int, int, int, int, int, int, tree)); + tree, int, int, int, int, int, int, tree)); static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree)); static tree lookup_tag PROTO((enum tree_code, tree, struct binding_level *, int)); static void set_identifier_type_value_with_scope PROTO((tree, tree, struct binding_level *)); -static void set_identifier_local_value_with_scope - PROTO((tree, tree, struct binding_level *)); -static void record_builtin_type PROTO((enum rid, char *, tree)); -static void record_unknown_type PROTO((tree, char *)); -static int member_function_or_else PROTO((tree, tree, char *)); -static void bad_specifiers PROTO((tree, char *, int, int, int, int, +static void record_builtin_type PROTO((enum rid, const char *, tree)); +static void record_unknown_type PROTO((tree, const char *)); +static int member_function_or_else PROTO((tree, tree, const char *)); +static void bad_specifiers PROTO((tree, const char *, int, int, int, int, int)); static void lang_print_error_function PROTO((char *)); +static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*)); +static void check_for_uninitialized_const_var PROTO((tree)); +static unsigned long typename_hash PROTO((hash_table_key)); +static boolean typename_compare PROTO((hash_table_key, hash_table_key)); +static void push_binding PROTO((tree, tree, struct binding_level*)); +static int add_binding PROTO((tree, tree)); +static void pop_binding PROTO((tree, tree)); +static tree local_variable_p PROTO((tree)); +static tree find_binding PROTO((tree, tree)); +static tree select_decl PROTO((tree, int)); +static tree unqualified_namespace_lookup PROTO((tree, int)); +static int lookup_flags PROTO((int, int)); +static tree qualify_lookup PROTO((tree, int)); +static tree record_builtin_java_type PROTO((const char *, int)); +static const char *tag_name PROTO((enum tag_types code)); +static void find_class_binding_level PROTO((void)); +static struct binding_level *innermost_nonclass_level PROTO((void)); +static tree poplevel_class PROTO((void)); +static void warn_about_implicit_typename_lookup PROTO((tree, tree)); +static int walk_namespaces_r PROTO((tree, walk_namespaces_fn, void *)); +static int walk_globals_r PROTO((tree, void *)); #if defined (DEBUG_CP_BINDING_LEVELS) static void indent PROTO((void)); @@ -228,13 +244,17 @@ tree intQI_type_node; tree intHI_type_node; tree intSI_type_node; tree intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 tree intTI_type_node; +#endif tree unsigned_intQI_type_node; tree unsigned_intHI_type_node; tree unsigned_intSI_type_node; tree unsigned_intDI_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 tree unsigned_intTI_type_node; +#endif tree java_byte_type_node; tree java_short_type_node; @@ -328,6 +348,7 @@ tree sigtable_entry_type; /* Array type `vtable_entry_type[]' */ tree vtbl_type_node; +tree vtbl_ptr_type_node; /* namespace std */ tree std_node; @@ -364,6 +385,10 @@ tree ctor_label; tree abort_fndecl; +/* A FUNCTION_DECL for the default `::operator delete'. */ + +tree global_delete_fndecl; + extern rtx cleanup_label, return_label; /* If original DECL_RESULT of current function was a register, @@ -428,9 +453,8 @@ tree static_aggregates; tree integer_zero_node; tree null_pointer_node; -/* The value for __null (NULL), either of type `void *' or, with -ansi, - an integer type of the same size. */ - +/* The value for __null (NULL), namely, a zero of an integer type with + the same number of bits as a pointer. */ tree null_node; /* A node for the integer constants 1, 2, and 3. */ @@ -496,11 +520,6 @@ int current_function_returns_null; tree current_function_return_value; -/* Set to nonzero by `grokdeclarator' for a function - whose return type is defaulted, if warnings for this are desired. */ - -static int warn_about_return_type; - /* Nonzero means give `double' the same size as `float'. */ extern int flag_short_double; @@ -559,6 +578,10 @@ extern tree previous_class_values; node, but signed. */ tree signed_size_zero_node; +/* The name of the anonymous namespace, throughout this translation + unit. */ +tree anonymous_namespace_name; + /* Allocate a level of searching. */ @@ -590,7 +613,10 @@ push_decl_level (stack, obstack) 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. */ + 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. */ @@ -599,7 +625,8 @@ struct binding_level { /* A chain of _DECL nodes for all variables, constants, functions, and typedef types. These are in the reverse of the order - supplied. */ + supplied. There may be OVERLOADs on this list, too, but they + are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ tree names; /* A list of structure, union and enum definitions, for looking up @@ -619,16 +646,17 @@ struct binding_level VALUE the common ancestor with this binding_level's namespace. */ tree using_directives; - /* 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; - - /* Same, for IDENTIFIER_CLASS_VALUE. */ + /* 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_VALUE is + the IDENTIFIER_CLASS_VALUE before we entered the class. Thus, + when leaving class scope, we can restore the + IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is + the DECL bound by this name in the class. */ tree class_shadowed; - /* Same, for IDENTIFIER_TYPE_VALUE. */ + /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and + is used for all binding levels. */ tree type_shadowed; /* For each level (except not the global one), @@ -649,7 +677,8 @@ struct binding_level /* List of VAR_DECLS saved from a previous for statement. These would be dead in ANSI-conforming code, but might - be referenced in ARM-era code. */ + 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. @@ -691,7 +720,7 @@ struct binding_level #define NULL_BINDING_LEVEL ((struct binding_level *) NULL) -/* The (non-class) binding level currently in effect. */ +/* The binding level currently in effect. */ static struct binding_level *current_binding_level; @@ -699,11 +728,6 @@ static struct binding_level *current_binding_level; static struct binding_level *class_binding_level; -/* The current (class or non-class) binding level currently in effect. */ - -#define inner_binding_level \ - (class_binding_level ? class_binding_level : current_binding_level) - /* A chain of binding_level structures awaiting reuse. */ static struct binding_level *free_binding_level; @@ -746,15 +770,7 @@ push_binding_level (newlevel, tag_transparent, keep) /* Add this level to the front of the chain (stack) of levels that are active. */ *newlevel = clear_binding_level; - if (class_binding_level) - { - newlevel->level_chain = class_binding_level; - class_binding_level = (struct binding_level *)0; - } - else - { - newlevel->level_chain = current_binding_level; - } + newlevel->level_chain = current_binding_level; current_binding_level = newlevel; newlevel->tag_transparent = tag_transparent; newlevel->more_cleanups_ok = 1; @@ -769,12 +785,25 @@ push_binding_level (newlevel, tag_transparent, keep) #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ } +/* Find the innermost enclosing class scope, and reset + CLASS_BINDING_LEVEL appropriately. */ + static void -pop_binding_level () +find_class_binding_level () { - if (class_binding_level) - current_binding_level = class_binding_level; + struct 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 (global_binding_level) { /* Cannot pop a level, if there are none left to pop. */ @@ -803,13 +832,8 @@ pop_binding_level () if (level->binding_depth != binding_depth) abort (); #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - free_binding_level = level; - - class_binding_level = current_binding_level; - if (class_binding_level->parm_flag != 2) - class_binding_level = 0; - while (current_binding_level->parm_flag == 2) - current_binding_level = current_binding_level->level_chain; + free_binding_level = level; + find_class_binding_level (); } } @@ -839,14 +863,8 @@ suspend_binding_level () } is_class_level = 0; #endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - { - current_binding_level = current_binding_level->level_chain; - class_binding_level = current_binding_level; - if (class_binding_level->parm_flag != 2) - class_binding_level = 0; - while (current_binding_level->parm_flag == 2) - current_binding_level = current_binding_level->level_chain; - } + current_binding_level = current_binding_level->level_chain; + find_class_binding_level (); } static void @@ -887,25 +905,44 @@ global_bindings_p () return current_binding_level == global_binding_level; } +/* Return the innermost binding level that is not for a class scope. */ + +static struct binding_level * +innermost_nonclass_level () +{ + struct 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 pseudo-global level. */ + binding level. Since there are no non-toplevel namespace levels, + this really means any namespace or pseudo-global level. We also + include a class whose context is toplevel. */ int toplevel_bindings_p () { - return current_binding_level->namespace_p - || current_binding_level->pseudo_global; + struct binding_level *b = innermost_nonclass_level (); + + return b->namespace_p || b->pseudo_global; } -/* Nonzero if this is a namespace scope. */ +/* 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. */ -static int +int namespace_bindings_p () { - return current_binding_level->namespace_p; + struct binding_level *b = innermost_nonclass_level (); + + return b->namespace_p; } void @@ -949,7 +986,9 @@ declare_namespace_level () int pseudo_global_level_p () { - return current_binding_level->pseudo_global; + struct binding_level *b = innermost_nonclass_level (); + + return b->pseudo_global; } void @@ -1018,6 +1057,255 @@ pushlevel_temporary (tag_transparent) expand_start_bindings (0); } +/* For a binding between a name and an entity at a block scope, + this is the `struct binding_level' for the block. */ +#define BINDING_LEVEL(NODE) \ + (((struct tree_binding*)NODE)->scope.level) + +/* These are currently unused, but permanent, CPLUS_BINDING nodes. + They are kept here because they are allocated from the permanent + obstack and cannot be easily freed. */ +static tree free_binding_nodes; + +/* 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 binding_level* level; +{ + tree binding; + + if (!free_binding_nodes) + { + /* There are no free nodes, so we must build one here. */ + push_obstacks_nochange (); + end_temporary_allocation (); + binding = make_node (CPLUS_BINDING); + pop_obstacks (); + } + else + { + /* There are nodes on the free list. Grab the first one. */ + binding = free_binding_nodes; + + /* And update the free list. */ + free_binding_nodes = TREE_CHAIN (free_binding_nodes); + } + + /* 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); + + /* And put it on the front of the list of bindings for ID. */ + TREE_CHAIN (binding) = 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 + legal here. Returns nonzero if the new binding was successful. */ +static int +add_binding (id, decl) + tree id; + tree decl; +{ + tree binding = IDENTIFIER_BINDING (id); + int ok = 1; + + 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 + { + cp_error ("declaration of `%#D'", decl); + cp_error_at ("conflicts with previous declaration `%#D'", + BINDING_VALUE (binding)); + ok = 0; + } + + return ok; +} + +/* Bind DECL to ID in the current_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 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. */ + TREE_CHAIN (decl) = b->names; + b->names = decl; +} + +/* 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; + tree binding = IDENTIFIER_BINDING (id); + tree context; + + /* Note that we declared this value so that we can issue an error if + this an illegal 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 (TREE_CODE (decl) == TYPE_DECL + && IMPLICIT_TYPENAME_P (TREE_TYPE (decl))) + INHERITED_VALUE_BINDING_P (binding) = 1; + else + { + if (TREE_CODE (decl) == OVERLOAD) + context = DECL_REAL_CONTEXT (OVL_CURRENT (decl)); + else + { + my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', + 0); + context = DECL_REAL_CONTEXT (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; + + return result; +} + +/* Remove the binding for DECL which should be the innermost binding + for ID. */ + +static void +pop_binding (id, decl) + tree id; + tree decl; +{ + tree 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_TREE, 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 + my_friendly_abort (0); + + 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) = TREE_CHAIN (binding); + + /* And place it on the free list. */ + TREE_CHAIN (binding) = free_binding_nodes; + free_binding_nodes = binding; + } +} + /* 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. @@ -1026,12 +1314,6 @@ pushlevel_temporary (tag_transparent) and create a "block" (a BLOCK node) for the level to record its declarations and subblocks for symbol table output. - If KEEP == 2, this level's subblocks go to the front, - not the back of the current binding level. This happens, - for instance, when code for constructors and destructors - need to generate code at the end of a function which must - be moved up to the front of the function. - 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. @@ -1057,6 +1339,18 @@ poplevel (keep, reverse, functionbody) tree block = NULL_TREE; tree decl; int block_previously_created; + int leaving_for_scope; + + if (current_binding_level->parm_flag == 2) + return poplevel_class (); + + my_friendly_assert (!current_binding_level->class_shadowed, + 19990414); + + /* We used to use KEEP == 2 to indicate that the new block should go + at the beginning of the list of blocks at this binding level, + rather than the end. This hack is no longer used. */ + my_friendly_assert (keep == 0 || keep == 1, 0); GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, (HOST_WIDE_INT) current_binding_level->level_chain, @@ -1116,9 +1410,8 @@ poplevel (keep, reverse, functionbody) if (decls || tags || subblocks) { if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block)) - { - warning ("internal compiler error: debugging info corrupted"); - } + warning ("internal compiler error: debugging info corrupted"); + BLOCK_VARS (block) = decls; BLOCK_TYPE_TAGS (block) = tags; @@ -1137,7 +1430,8 @@ poplevel (keep, reverse, functionbody) BLOCK_VARS (block) = decls; BLOCK_TYPE_TAGS (block) = tags; BLOCK_SUBBLOCKS (block) = subblocks; - /* Otherwise, for a new block, install a new BLOCK_END_NOTE value. */ + /* Otherwise, for a new block, install a new BLOCK_END_NOTE + value. */ remember_end_note (block); } } @@ -1148,92 +1442,123 @@ poplevel (keep, reverse, functionbody) for (link = subblocks; link; link = TREE_CHAIN (link)) BLOCK_SUPERCONTEXT (link) = block; - /* Clear out the meanings of the local variables of this level. */ + /* 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 + nonzero. */ + leaving_for_scope + = current_binding_level->is_for_scope && flag_new_for_scope == 1; - if (current_binding_level->is_for_scope && flag_new_for_scope == 1) + /* Remove declarations for all the DECLs in this level. */ + for (link = decls; link; link = TREE_CHAIN (link)) { - struct binding_level *outer = current_binding_level->level_chain; - for (link = decls; link; link = TREE_CHAIN (link)) + if (leaving_for_scope && TREE_CODE (link) == VAR_DECL) { - if (TREE_CODE (link) == VAR_DECL) - DECL_DEAD_FOR_LOCAL (link) = 1; - else - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE; - } + tree outer_binding + = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link))); + tree ns_binding; - /* Save declarations made in a 'for' statement so we can support pre-ANSI - 'for' scoping semantics. */ - - for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) - { - tree id = TREE_PURPOSE (link); - tree decl = IDENTIFIER_LOCAL_VALUE (id); + if (!outer_binding) + ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link)); + else + ns_binding = NULL_TREE; - if (decl && DECL_DEAD_FOR_LOCAL (decl)) - { - /* In this case keep the dead for-decl visible, - but remember what (if anything) it shadowed. */ - DECL_SHADOWED_FOR_VAR (decl) = TREE_VALUE (link); - TREE_CHAIN (decl) = outer->dead_vars_from_for; - outer->dead_vars_from_for = decl; - } + if (outer_binding + && (BINDING_LEVEL (outer_binding) + == current_binding_level->level_chain)) + /* We have something like: + + int i; + for (int i; ;); + + and we are leaving the `for' scope. There's no reason to + 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)) + /* Here, we have something like: + + typedef int I; + + void f () { + for (int I; ;); + } + + We must pop the for-scope binding so we know what's a + type and what isn't. */ + pop_binding (DECL_NAME (link), link); else - IDENTIFIER_LOCAL_VALUE (id) = TREE_VALUE (link); - } - } - else /* Not special for scope. */ - { - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != NULL_TREE) { - /* If the ident. was used or addressed via a local extern decl, - don't forget that fact. */ - if (DECL_EXTERNAL (link)) - { - if (TREE_USED (link)) - TREE_USED (DECL_ASSEMBLER_NAME (link)) = 1; - if (TREE_ADDRESSABLE (link)) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; - } - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = NULL_TREE; - } - } - - /* 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); - - /* We first restore the regular decls and *then* the dead_vars_from_for - to handle this case: - - int i; // i#1 - { - for (int i; ; ) { ...} // i#2 - int i; // i#3 - } // we are here + /* Mark this VAR_DECL as dead so that we can tell we left it + there only for backward compatibility. */ + DECL_DEAD_FOR_LOCAL (link) = 1; + + /* Keep track of what should of have happenned when we + popped the binding. */ + if (outer_binding && BINDING_VALUE (outer_binding)) + DECL_SHADOWED_FOR_VAR (link) + = BINDING_VALUE (outer_binding); + + /* Add it to the list of dead variables in the next + outermost binding to that we can remove these when we + leave that binding. */ + current_binding_level->level_chain->dead_vars_from_for + = tree_cons (NULL_TREE, link, + current_binding_level->level_chain-> + dead_vars_from_for); + + /* Although we don't pop the CPLUS_BINDING, we do clear + its BINDING_LEVEL since the level is going away now. */ + BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) + = 0; + } + } + else + { + /* Remove the binding. */ + decl = link; + if (TREE_CODE (decl) == TREE_LIST) + decl = TREE_VALUE (decl); + if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') + pop_binding (DECL_NAME (decl), decl); + else if (TREE_CODE (decl) == OVERLOAD) + pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl); + else + my_friendly_abort (0); + } + } + + /* Remove declarations for any `for' variables from inner scopes + that we kept around. */ + for (link = current_binding_level->dead_vars_from_for; + link; link = TREE_CHAIN (link)) + pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link)); - In this case, we want remove the binding for i#3, restoring - that of i#2. Then we want to remove the binding for i#2, - and restore that of i#1. */ + /* Restore the IDENTIFIER_TYPE_VALUEs. */ + for (link = current_binding_level->type_shadowed; + link; link = TREE_CHAIN (link)) + SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); + + /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs + list if a `using' declaration put them there. The debugging + back-ends won't understand OVERLOAD, so we remove them here. + Because the BLOCK_VARS are (temporarily) shared with + CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have + popped all the bindings. */ + if (block) + { + tree* d; - link = current_binding_level->dead_vars_from_for; - for (; link != NULL_TREE; link = TREE_CHAIN (link)) + for (d = &BLOCK_VARS (block); *d; ) { - tree id = DECL_NAME (link); - if (IDENTIFIER_LOCAL_VALUE (id) == link) - IDENTIFIER_LOCAL_VALUE (id) = DECL_SHADOWED_FOR_VAR (link); + if (TREE_CODE (*d) == TREE_LIST) + *d = TREE_CHAIN (*d); + else + d = &TREE_CHAIN (*d); } - - for (link = current_binding_level->class_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->type_shadowed; - link; link = TREE_CHAIN (link)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); } /* If the level being exited is the top level of a function, @@ -1308,14 +1633,8 @@ poplevel (keep, reverse, functionbody) must be carried forward so they will later become subblocks of something else. */ else if (subblocks) - { - if (keep == 2) - current_binding_level->blocks - = chainon (subblocks, current_binding_level->blocks); - else - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - } + current_binding_level->blocks + = chainon (current_binding_level->blocks, subblocks); /* Take care of compiler's internal binding structures. */ if (tmp == 2) @@ -1402,9 +1721,7 @@ pushlevel_class () free_binding_level = free_binding_level->level_chain; } else - { - newlevel = make_binding_level (); - } + newlevel = make_binding_level (); #if defined(DEBUG_CP_BINDING_LEVELS) is_class_level = 1; @@ -1415,42 +1732,56 @@ pushlevel_class () decl_stack = push_decl_level (decl_stack, &decl_obstack); class_binding_level = current_binding_level; class_binding_level->parm_flag = 2; - /* We have just pushed into a new binding level. Now, fake out the rest - of the compiler. Set the `current_binding_level' back to point to - the most closely containing non-class binding level. */ - do - { - current_binding_level = current_binding_level->level_chain; - } - while (current_binding_level->parm_flag == 2); } -/* ...and a poplevel for class declarations. FORCE is used to force - clearing out of CLASS_VALUEs after a class definition. */ +/* ...and a poplevel for class declarations. */ -tree -poplevel_class (force) - int force; +static tree +poplevel_class () { register struct binding_level *level = class_binding_level; - tree block = NULL_TREE; tree shadowed; my_friendly_assert (level != 0, 354); decl_stack = pop_stack_level (decl_stack); - for (shadowed = level->shadowed; shadowed; shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); /* 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 || force) - for (shadowed = level->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); + if (current_class_depth != 1) + { + struct 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)) + { + tree t; + + t = IDENTIFIER_BINDING (TREE_PURPOSE (shadowed)); + while (t && BINDING_LEVEL (t) != b) + t = TREE_CHAIN (t); + + if (t) + IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) + = BINDING_VALUE (t); + } + } else /* Remember to save what IDENTIFIER's were bound in this scope so we can recover from cache misses. */ @@ -1463,24 +1794,243 @@ poplevel_class (force) 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)); + GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level, (HOST_WIDE_INT) class_binding_level->level_chain, class_binding_level->parm_flag, class_binding_level->keep); - if (class_binding_level->parm_flag != 2) - class_binding_level = (struct binding_level *)0; + /* Now, pop out of the binding level which we created up in the + `pushlevel_class' routine. */ +#if defined(DEBUG_CP_BINDING_LEVELS) + is_class_level = 1; +#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ + + pop_binding_level (); + + return NULL_TREE; +} + +/* 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 non-zero if T is a virtual function table. */ + +int +vtable_decl_p (t, data) + tree t; + void *data ATTRIBUTE_UNUSED; +{ + return (TREE_CODE (t) == VAR_DECL && DECL_VIRTUAL_P (t)); +} + +/* Returns non-zero if T is a TYPE_DECL for a type with virtual + functions. */ + +int +vtype_decl_p (t, data) + tree t; + void *data ATTRIBUTE_UNUSED; +{ + return (TREE_CODE (t) == TYPE_DECL + && TREE_TYPE (t) != error_mark_node + && TYPE_LANG_SPECIFIC (TREE_TYPE (t)) + && CLASSTYPE_VSIZE (TREE_TYPE (t))); +} + +/* Returns non-zero if T is a signature table. */ + +int +sigtable_decl_p (t, data) + tree t; + void *data ATTRIBUTE_UNUSED; +{ + return (TREE_CODE (t) == VAR_DECL + && TREE_TYPE (t) != error_mark_node + && IS_SIGNATURE (TREE_TYPE (t))); +} + +/* Walk all the namespaces contained NAMESPACE, including NAMESPACE + 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; +{ + tree current; + int result = 0; + + result |= (*f) (namespace, data); + + for (current = NAMESPACE_LEVEL (namespace)->names; + current; + current = TREE_CHAIN (current)) + { + if (TREE_CODE (current) != NAMESPACE_DECL + || DECL_NAMESPACE_ALIAS (current)) + continue; + if (!DECL_LANG_SPECIFIC (current)) + { + /* Hmm. std. */ + my_friendly_assert (current == std_node, 393); + continue; + } + + /* We found a namespace. */ + result |= walk_namespaces_r (current, f, data); + } + + return result; +} + +/* Walk all the namespaces, calling F for each. The DATA is passed to + F as well. */ + +int +walk_namespaces (f, data) + walk_namespaces_fn f; + void *data; +{ + return walk_namespaces_r (global_namespace, f, data); +} + +struct walk_globals_data { + walk_globals_pred p; + walk_globals_fn f; + void *data; +}; + +/* Walk the global declarations in NAMESPACE. Whenever one is found + for which P returns non-zero, call F with its address. If any call + to F returns a non-zero value, return a non-zero value. */ + +static int +walk_globals_r (namespace, data) + tree namespace; + void *data; +{ + struct walk_globals_data* wgd = (struct walk_globals_data *) data; + walk_globals_pred p = wgd->p; + walk_globals_fn f = wgd->f; + void *d = wgd->data; + tree *t; + int result = 0; + + t = &NAMESPACE_LEVEL (namespace)->names; + + while (*t) + { + tree glbl = *t; + + if ((*p) (glbl, d)) + result |= (*f) (t, d); + + /* If F changed *T, then *T still points at the next item to + examine. */ + if (*t == glbl) + t = &TREE_CHAIN (*t); + } + + return result; +} + +/* Walk the global declarations. Whenever one is found for which P + returns non-zero, call F with its address. If any call to F + returns a non-zero value, return a non-zero value. */ + +int +walk_globals (p, f, data) + walk_globals_pred p; + walk_globals_fn f; + void *data; +{ + struct walk_globals_data wgd; + wgd.p = p; + wgd.f = f; + wgd.data = data; + + return walk_namespaces (walk_globals_r, &wgd); +} + +/* Call wrapup_globals_declarations for the globals in NAMESPACE. If + DATA is non-NULL, this is the last time we will call + wrapup_global_declarations for this NAMESPACE. */ + +int +wrapup_globals_for_namespace (namespace, data) + tree namespace; + void *data; +{ + tree globals = NAMESPACE_LEVEL (namespace)->names; + int len = list_length (globals); + tree *vec = (tree *) alloca (sizeof (tree) * len); + int i; + int result; + tree decl; + int last_time = (data != 0); + + if (last_time && namespace == global_namespace) + /* Let compile_file handle the global namespace. */ + return 0; + + /* 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; + + if (last_time) + { + check_global_declarations (vec, len); + return 0; + } - /* Now, pop out of the binding level which we created up in the - `pushlevel_class' routine. */ -#if defined(DEBUG_CP_BINDING_LEVELS) - is_class_level = 1; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ + /* Temporarily mark vtables as external. That prevents + wrapup_global_declarations from writing them out; we must process + them ourselves in finish_vtable_vardecl. */ + for (i = 0; i < len; ++i) + if (vtable_decl_p (vec[i], /*data=*/0) && !DECL_EXTERNAL (vec[i])) + { + DECL_NOT_REALLY_EXTERN (vec[i]) = 1; + DECL_EXTERNAL (vec[i]) = 1; + } - pop_binding_level (); + /* Write out any globals that need to be output. */ + result = wrapup_global_declarations (vec, len); - return block; + /* Undo the hack to DECL_EXTERNAL above. */ + for (i = 0; i < len; ++i) + if (vtable_decl_p (vec[i], /*data=*/0) + && DECL_NOT_REALLY_EXTERN (vec[i])) + { + DECL_NOT_REALLY_EXTERN (vec[i]) = 0; + DECL_EXTERNAL (vec[i]) = 0; + } + + return result; } + /* For debugging. */ static int no_print_functions = 0; @@ -1569,15 +2119,6 @@ print_binding_level (lvl) if (i) fprintf (stderr, "\n"); } - if (lvl->shadowed) - { - fprintf (stderr, " shadowed:"); - for (t = lvl->shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } if (lvl->class_shadowed) { fprintf (stderr, " class-shadowed:"); @@ -1769,7 +2310,7 @@ void push_namespace (name) tree name; { - tree d; + tree d = NULL_TREE; int need_new = 1; int implicit_use = 0; int global = 0; @@ -1783,10 +2324,9 @@ push_namespace (name) { /* The name of anonymous namespace is unique for the translation unit. */ - static tree anon_name = NULL_TREE; - if (!anon_name) - anon_name = get_file_function_name ('N'); - name = anon_name; + 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. */ @@ -1854,34 +2394,6 @@ pop_namespace () suspend_binding_level (); } -/* Concatenate the binding levels of all namespaces. */ - -void -cat_namespace_levels() -{ - tree current; - tree last; - struct binding_level *b; - - last = NAMESPACE_LEVEL (global_namespace) -> names; - /* The nested namespaces appear in the names list of their ancestors. */ - for (current = last; current; current = TREE_CHAIN (current)) - { - if (TREE_CODE (current) != NAMESPACE_DECL - || DECL_NAMESPACE_ALIAS (current)) - continue; - if (!DECL_LANG_SPECIFIC (current)) - { - /* Hmm. std. */ - my_friendly_assert (current == std_node, 393); - continue; - } - b = NAMESPACE_LEVEL (current); - while (TREE_CHAIN (last)) - last = TREE_CHAIN (last); - TREE_CHAIN (last) = NAMESPACE_LEVEL (current) -> names; - } -} /* Subroutines for reverting temporarily to top-level for instantiation of templates and such. We actually need to clear out the class- and @@ -1893,7 +2405,9 @@ struct saved_scope { tree old_bindings; tree old_namespace; struct saved_scope *prev; - tree class_name, class_type, function_decl; + tree class_name, class_type; + tree access_specifier; + tree function_decl; struct binding_level *class_bindings; tree *lang_base, *lang_stack, lang_name; int lang_stacksize; @@ -1904,6 +2418,7 @@ struct saved_scope { tree previous_class_type, previous_class_values; int processing_specialization; int processing_explicit_instantiation; + char *class_cache_firstobj; }; static struct saved_scope *current_saved_scope; @@ -1926,9 +2441,11 @@ store_bindings (names, old_bindings) else id = DECL_NAME (t); - if (!id - || (!IDENTIFIER_LOCAL_VALUE (id) - && !IDENTIFIER_CLASS_VALUE (id))) + 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 = old_bindings; t1; t1 = TREE_CHAIN (t1)) @@ -1948,9 +2465,9 @@ store_bindings (names, old_bindings) my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); TREE_VEC_ELT (binding, 0) = id; TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id); - TREE_VEC_ELT (binding, 2) = IDENTIFIER_LOCAL_VALUE (id); + TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id); TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); - IDENTIFIER_LOCAL_VALUE (id) = NULL_TREE; + IDENTIFIER_BINDING (id) = NULL_TREE; IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; } TREE_CHAIN (binding) = old_bindings; @@ -1968,11 +2485,10 @@ maybe_push_to_top_level (pseudo) extern int current_lang_stacksize; struct saved_scope *s = (struct saved_scope *) xmalloc (sizeof (struct saved_scope)); - struct binding_level *b = inner_binding_level; + struct binding_level *b = current_binding_level; tree old_bindings = NULL_TREE; - if (current_function_decl) - push_cp_function_context (NULL_TREE); + push_cp_function_context (NULL_TREE); if (previous_class_type) old_bindings = store_bindings (previous_class_values, old_bindings); @@ -2007,6 +2523,7 @@ maybe_push_to_top_level (pseudo) s->old_namespace = current_namespace; s->class_name = current_class_name; s->class_type = current_class_type; + s->access_specifier = current_access_specifier; s->function_decl = current_function_decl; s->class_bindings = class_binding_level; s->lang_stack = current_lang_stack; @@ -2019,6 +2536,7 @@ maybe_push_to_top_level (pseudo) s->processing_template_decl = processing_template_decl; s->previous_class_type = previous_class_type; s->previous_class_values = previous_class_values; + s->class_cache_firstobj = class_cache_firstobj; s->processing_specialization = processing_specialization; s->processing_explicit_instantiation = processing_explicit_instantiation; @@ -2034,6 +2552,7 @@ maybe_push_to_top_level (pseudo) shadowed_labels = NULL_TREE; minimal_parse_mode = 0; previous_class_type = previous_class_values = NULL_TREE; + class_cache_firstobj = 0; processing_specialization = 0; processing_explicit_instantiation = 0; current_template_parms = NULL_TREE; @@ -2062,10 +2581,7 @@ pop_from_top_level () /* Clear out class-level bindings cache. */ if (previous_class_type) - { - popclass (-1); - previous_class_type = NULL_TREE; - } + invalidate_class_lookup_cache (); pop_obstacks (); @@ -2078,7 +2594,7 @@ pop_from_top_level () if (id) { SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1)); - IDENTIFIER_LOCAL_VALUE (id) = TREE_VEC_ELT (t, 2); + IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2); IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3); } t = TREE_CHAIN (t); @@ -2088,6 +2604,7 @@ pop_from_top_level () current_namespace = s->old_namespace; current_class_name = s->class_name; current_class_type = s->class_type; + current_access_specifier = s->access_specifier; current_function_decl = s->function_decl; class_binding_level = s->class_bindings; free (current_lang_base); @@ -2107,11 +2624,11 @@ pop_from_top_level () previous_class_values = s->previous_class_values; processing_specialization = s->processing_specialization; processing_explicit_instantiation = s->processing_explicit_instantiation; + class_cache_firstobj = s->class_cache_firstobj; free (s); - if (current_function_decl) - pop_cp_function_context (NULL_TREE); + pop_cp_function_context (NULL_TREE); } /* Push a definition of struct, union or enum tag "name". @@ -2151,34 +2668,14 @@ set_identifier_type_value_with_scope (id, type, b) SET_IDENTIFIER_TYPE_VALUE (id, type); } -/* As set_identifier_type_value_with_scope, but using inner_binding_level. */ +/* 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, inner_binding_level); -} - -static void -set_identifier_local_value_with_scope (id, val, b) - tree id, val; - struct binding_level *b; -{ - tree oldlocal; - my_friendly_assert (! b->namespace_p, 980716); - - oldlocal = IDENTIFIER_LOCAL_VALUE (id); - b->shadowed = tree_cons (id, oldlocal, b->shadowed); - IDENTIFIER_LOCAL_VALUE (id) = val; -} - -void -set_identifier_local_value (id, val) - tree id, val; -{ - set_identifier_local_value_with_scope (id, val, current_binding_level); + set_identifier_type_value_with_scope (id, type, current_binding_level); } /* Return the type associated with id. */ @@ -2211,10 +2708,10 @@ pop_everything () #ifdef DEBUG_CP_BINDING_LEVELS fprintf (stderr, "XXX entering pop_everything ()\n"); #endif - while (! toplevel_bindings_p () && ! pseudo_global_level_p ()) + while (!toplevel_bindings_p ()) { - if (class_binding_level) - pop_nested_class (1); + if (current_binding_level->parm_flag == 2) + pop_nested_class (); else poplevel (0, 0, 0); } @@ -2223,6 +2720,90 @@ pop_everything () #endif } +/* 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 non-zero, 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 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 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 (/* If !GLOBALIZE then we are looking at a definition. + It may not be a primary template. (For example, in: + + template + struct S1 { class S2 {}; } + + we have to push_template_decl for S2.) */ + (processing_template_decl && !globalize) + /* If we are declaring a friend template class, we will + have GLOBALIZE set, since something like: + + template + struct S1 { + template + friend class S2; + }; + + declares S2 to be at global scope. */ + || PROCESSING_REAL_TEMPLATE_DECL_P ()) + { + /* 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->pseudo_global + && 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. */ + b->level_chain->tags = + saveable_tree_cons (name, type, b->level_chain->tags); + if (TYPE_SIZE (current_class_type) == NULL_TREE) + CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; + } + } + } + + return decl; +} + /* 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. @@ -2234,10 +2815,8 @@ pushtag (name, type, globalize) int globalize; { register struct binding_level *b; - tree context = 0; - tree c_decl = 0; - b = inner_binding_level; + b = current_binding_level; while (b->tag_transparent || (globalize && b->parm_flag == 2)) b = b->level_chain; @@ -2249,32 +2828,34 @@ pushtag (name, type, globalize) if (name) { - context = type ? TYPE_CONTEXT (type) : NULL_TREE; - if (! context) - { - tree cs = current_scope (); - - if (! globalize) - context = cs; - else if (cs != NULL_TREE - && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') - /* 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 = hack_decl_function_context (get_type_decl (cs)); - } - if (context) - c_decl = TREE_CODE (context) == FUNCTION_DECL - ? context : TYPE_MAIN_DECL (context); - - if (!context) - context = current_namespace; - /* Do C++ gratuitous typedefing. */ if (IDENTIFIER_TYPE_VALUE (name) != type) { register tree d = NULL_TREE; int newdecl = 0, in_class = 0; + tree context; + tree c_decl = NULL_TREE; + + context = type ? TYPE_CONTEXT (type) : NULL_TREE; + if (! context) + { + tree cs = current_scope (); + + if (! globalize) + context = cs; + else if (cs != NULL_TREE + && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') + /* 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 = hack_decl_function_context (get_type_decl (cs)); + } + if (context) + c_decl = TREE_CODE (context) == FUNCTION_DECL + ? context : TYPE_MAIN_DECL (context); + + if (!context) + context = current_namespace; if ((b->pseudo_global && b->level_chain->parm_flag == 2) || b->parm_flag == 2) @@ -2298,66 +2879,20 @@ pushtag (name, type, globalize) TYPE_NAME (type) = d; DECL_CONTEXT (d) = FROB_CONTEXT (context); - 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: + d = maybe_process_template_type_declaration (type, + globalize, b); - template struct S; - - is a forward-declaration of `A'. */ - ; - else if (IS_AGGR_TYPE (type) - && (/* If !GLOBALIZE then we are looking at a - definition. It may not be a primary template. - (For example, in: - - template - struct S1 { class S2 {}; } - - we have to push_template_decl for S2.) */ - (processing_template_decl && !globalize) - /* If we are declaring a friend template class, we - will have GLOBALIZE set, since something like: - - template - struct S1 { - template - friend class S2; - }; - - declares S2 to be at global scope. */ - || (processing_template_decl > - template_class_depth (current_class_type)))) + if (b->parm_flag == 2) { - d = push_template_decl_real (d, 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 (!globalize && b->pseudo_global && - b->level_chain->parm_flag == 2) - { - pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type), - b->level_chain); - /* 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. */ - b->level_chain->tags = - saveable_tree_cons (name, type, b->level_chain->tags); - TREE_NONLOCAL_FLAG (type) = 1; - if (TYPE_SIZE (current_class_type) == NULL_TREE) - CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; - } + if (newdecl && !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); } - - if (b->parm_flag == 2) - d = pushdecl_class_level (d); else d = pushdecl_with_scope (d, b); @@ -2368,13 +2903,13 @@ pushtag (name, type, globalize) TYPE_CONTEXT (type) = DECL_CONTEXT (d); DECL_ASSEMBLER_NAME (d) = DECL_NAME (d); - DECL_ASSEMBLER_NAME (d) - = get_identifier (build_overload_name (type, 1, 1)); + if (!uses_template_parms (type)) + DECL_ASSEMBLER_NAME (d) + = get_identifier (build_overload_name (type, 1, 1)); } } if (b->parm_flag == 2) { - TREE_NONLOCAL_FLAG (type) = 1; if (TYPE_SIZE (current_class_type) == NULL_TREE) CLASSTYPE_TAGS (current_class_type) = b->tags; } @@ -2458,8 +2993,15 @@ decls_match (newdecl, olddecl) { int types_match; - if (TREE_CODE (newdecl) == FUNCTION_DECL - && TREE_CODE (olddecl) == FUNCTION_DECL) + if (newdecl == olddecl) + return 1; + + if (TREE_CODE (newdecl) != TREE_CODE (olddecl)) + /* If the two DECLs are not even the same kind of thing, we're not + interested in their types. */ + return 0; + + if (TREE_CODE (newdecl) == FUNCTION_DECL) { tree f1 = TREE_TYPE (newdecl); tree f2 = TREE_TYPE (olddecl); @@ -2494,7 +3036,7 @@ decls_match (newdecl, olddecl) return 0; } - if (comptypes (TREE_TYPE (f1), TREE_TYPE (f2), 1)) + if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) { if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c && p2 == NULL_TREE) @@ -2510,13 +3052,12 @@ decls_match (newdecl, olddecl) TREE_TYPE (newdecl) = TREE_TYPE (olddecl); } else - types_match = compparms (p1, p2, 3); + types_match = compparms (p1, p2); } else types_match = 0; } - else if (TREE_CODE (newdecl) == TEMPLATE_DECL - && TREE_CODE (olddecl) == TEMPLATE_DECL) + else if (TREE_CODE (newdecl) == TEMPLATE_DECL) { if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), DECL_TEMPLATE_PARMS (olddecl))) @@ -2536,20 +3077,10 @@ decls_match (newdecl, olddecl) types_match = TREE_TYPE (newdecl) == NULL_TREE; else if (TREE_TYPE (newdecl) == NULL_TREE) types_match = 0; - /* Qualifiers must match, and they may be present on either, the type - or the decl. */ - else if ((TREE_READONLY (newdecl) - || TYPE_READONLY (TREE_TYPE (newdecl))) - == (TREE_READONLY (olddecl) - || TYPE_READONLY (TREE_TYPE (olddecl))) - && (TREE_THIS_VOLATILE (newdecl) - || TYPE_VOLATILE (TREE_TYPE (newdecl))) - == (TREE_THIS_VOLATILE (olddecl) - || TYPE_VOLATILE (TREE_TYPE (olddecl)))) - types_match = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (newdecl)), - TYPE_MAIN_VARIANT (TREE_TYPE (olddecl)), 1); else - types_match = 0; + types_match = comptypes (TREE_TYPE (newdecl), + TREE_TYPE (olddecl), + COMPARE_REDECLARATION); } return types_match; @@ -2571,9 +3102,9 @@ warn_extern_redeclared_static (newdecl, olddecl) { tree name; - static char *explicit_extern_static_warning + static const char *explicit_extern_static_warning = "`%D' was declared `extern' and later `static'"; - static char *implicit_extern_static_warning + static const char *implicit_extern_static_warning = "`%D' was declared implicitly `extern' and later `static'"; if (TREE_CODE (newdecl) == TYPE_DECL) @@ -2709,6 +3240,11 @@ duplicate_decls (newdecl, olddecl) } else if (!types_match) { + if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)) + /* These are certainly not duplicate declarations; they're + from different scopes. */ + return 0; + if (TREE_CODE (newdecl) == TEMPLATE_DECL) { /* The name of a class template may not be declared to refer to @@ -2724,7 +3260,7 @@ duplicate_decls (newdecl, olddecl) else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))), - TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))), 3) + TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)))) && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), DECL_TEMPLATE_PARMS (olddecl))) { @@ -2743,7 +3279,7 @@ duplicate_decls (newdecl, olddecl) cp_error_at ("previous declaration `%#D' here", olddecl); } else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), - TYPE_ARG_TYPES (TREE_TYPE (olddecl)), 3)) + TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) { cp_error ("new declaration `%#D'", newdecl); cp_error_at ("ambiguates old declaration `%#D'", olddecl); @@ -2793,7 +3329,7 @@ duplicate_decls (newdecl, olddecl) return 1; else { - char *errmsg = redeclaration_error_message (newdecl, olddecl); + const char *errmsg = redeclaration_error_message (newdecl, olddecl); if (errmsg) { cp_error (errmsg, newdecl); @@ -2873,13 +3409,6 @@ duplicate_decls (newdecl, olddecl) olddecl); } } - /* These bits are logically part of the type for non-functions. */ - else if (TREE_READONLY (newdecl) != TREE_READONLY (olddecl) - || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)) - { - cp_pedwarn ("type qualifiers for `%#D'", newdecl); - cp_pedwarn_at ("conflict with previous decl `%#D'", olddecl); - } } /* If new decl is `static' and an `extern' was seen previously, @@ -2945,17 +3474,13 @@ duplicate_decls (newdecl, olddecl) if (TREE_CODE (newdecl) == TEMPLATE_DECL) { - if (DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl)) == NULL_TREE) - { - if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl), - DECL_TEMPLATE_RESULT (olddecl))) - cp_error ("invalid redeclaration of %D", newdecl); - TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)); - DECL_TEMPLATE_PARMS (olddecl) = DECL_TEMPLATE_PARMS (newdecl); - DECL_TEMPLATE_INFO (olddecl) = DECL_TEMPLATE_INFO (newdecl); - } - DECL_TEMPLATE_SPECIALIZATIONS (newdecl) - = DECL_TEMPLATE_SPECIALIZATIONS (olddecl); + if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl), + DECL_TEMPLATE_RESULT (olddecl))) + cp_error ("invalid redeclaration of %D", newdecl); + TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)); + DECL_TEMPLATE_SPECIALIZATIONS (olddecl) + = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), + DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); return 1; } @@ -2991,7 +3516,8 @@ duplicate_decls (newdecl, olddecl) TREE_TYPE (olddecl) = build_exception_variant (newtype, TYPE_RAISES_EXCEPTIONS (oldtype)); - if ((pedantic || ! DECL_IN_SYSTEM_HEADER (olddecl)) + if ((pedantic || (! DECL_IN_SYSTEM_HEADER (olddecl) + && ! DECL_IN_SYSTEM_HEADER (newdecl))) && DECL_SOURCE_LINE (olddecl) != 0 && flag_exceptions && ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) @@ -3004,7 +3530,7 @@ duplicate_decls (newdecl, olddecl) TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; /* Lay the type out, unless already done. */ - if (newtype != canonical_type_variant (oldtype) + if (! same_type_p (newtype, oldtype) && TREE_TYPE (newdecl) != error_mark_node && !(processing_template_decl && uses_template_parms (newdecl))) layout_type (TREE_TYPE (newdecl)); @@ -3030,6 +3556,9 @@ duplicate_decls (newdecl, olddecl) DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); + if (DECL_LANG_SPECIFIC (newdecl) + && DECL_LANG_SPECIFIC (olddecl)) + DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); } /* Merge the section attribute. @@ -3076,17 +3605,22 @@ duplicate_decls (newdecl, olddecl) DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); + DECL_TEMPLATE_INSTANTIATED (newdecl) + |= DECL_TEMPLATE_INSTANTIATED (olddecl); /* Don't really know how much of the language-specific values we should copy from old to new. */ DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); - if (DECL_TEMPLATE_INFO (newdecl) == NULL_TREE) - { - DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); - DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl); - } + DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); olddecl_friend = DECL_FRIEND_P (olddecl); + + /* Only functions have DECL_BEFRIENDING_CLASSES. */ + if (TREE_CODE (newdecl) == FUNCTION_DECL + || DECL_FUNCTION_TEMPLATE_P (newdecl)) + DECL_BEFRIENDING_CLASSES (newdecl) + = chainon (DECL_BEFRIENDING_CLASSES (newdecl), + DECL_BEFRIENDING_CLASSES (olddecl)); } if (TREE_CODE (newdecl) == FUNCTION_DECL) @@ -3292,23 +3826,30 @@ pushdecl (x) { register tree t; register tree name = DECL_ASSEMBLER_NAME (x); - register struct binding_level *b = current_binding_level; + int need_new_binding = 1; - 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)) - /* Don't change DECL_CONTEXT of virtual methods. */ - && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) - && ! DECL_CONTEXT (x)) - DECL_CONTEXT (x) = current_function_decl; - if (!DECL_CONTEXT (x)) - DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); + 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)) + /* Don't change DECL_CONTEXT of virtual methods. */ + && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) + && !DECL_CONTEXT (x)) + DECL_CONTEXT (x) = current_function_decl; + if (!DECL_CONTEXT (x)) + DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); + } /* Type are looked up using the DECL_NAME, as that is what the rest of the compiler wants to use. */ if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL - || TREE_CODE (x) == NAMESPACE_DECL || TREE_CODE (x) == TEMPLATE_TYPE_PARM - || TREE_CODE (x) == TEMPLATE_TEMPLATE_PARM) + || TREE_CODE (x) == NAMESPACE_DECL) name = DECL_NAME (x); if (name) @@ -3422,14 +3963,30 @@ pushdecl (x) } } + check_template_shadow (x); + + /* If this is a function conjured up by the backend, massage it + so it looks friendly. */ + if (TREE_CODE (x) == FUNCTION_DECL + && ! DECL_LANG_SPECIFIC (x)) + { + retrofit_lang_decl (x); + DECL_LANGUAGE (x) = lang_c; + } + if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x)) { - t = push_overloaded_decl (x, 1); + t = push_overloaded_decl (x, PUSH_LOCAL); if (t != x || DECL_LANGUAGE (x) == lang_c) return 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)) - return push_overloaded_decl (x, 0); + return push_overloaded_decl (x, PUSH_GLOBAL); /* 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 @@ -3442,7 +3999,12 @@ pushdecl (x) if (TYPE_NAME (type) == 0) TYPE_NAME (type) = x; } - else if (type != error_mark_node && 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))) { push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); @@ -3458,7 +4020,9 @@ pushdecl (x) if (type != error_mark_node && TYPE_NAME (type) && TYPE_IDENTIFIER (type)) - set_identifier_type_value_with_scope (DECL_NAME (x), type, b); + set_identifier_type_value_with_scope (DECL_NAME (x), type, + current_binding_level); + } /* Multiple external decls of the same identifier ought to match. @@ -3470,19 +4034,18 @@ pushdecl (x) if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL) { tree decl; - tree bindings = binding_for_name (name, current_namespace); - if (BINDING_VALUE (bindings) != NULL_TREE - && (DECL_EXTERNAL (BINDING_VALUE (bindings)) - || TREE_PUBLIC (BINDING_VALUE (bindings)))) - decl = BINDING_VALUE (bindings); + if (IDENTIFIER_NAMESPACE_VALUE (name) != NULL_TREE + && (DECL_EXTERNAL (IDENTIFIER_NAMESPACE_VALUE (name)) + || TREE_PUBLIC (IDENTIFIER_NAMESPACE_VALUE (name)))) + decl = IDENTIFIER_NAMESPACE_VALUE (name); else decl = NULL_TREE; if (decl /* If different sort of thing, we already gave an error. */ && TREE_CODE (decl) == TREE_CODE (x) - && ! comptypes (TREE_TYPE (x), TREE_TYPE (decl), 1)) + && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl))) { cp_pedwarn ("type mismatch with previous external decl", x); cp_pedwarn_at ("previous external decl of `%#D'", decl); @@ -3494,23 +4057,20 @@ pushdecl (x) if (namespace_bindings_p ()) { /* Install a global value. */ - tree bindings = binding_for_name (name, current_namespace); /* If the first global decl has external linkage, warn if we later see static one. */ - if (BINDING_VALUE (bindings) == NULL_TREE && TREE_PUBLIC (x)) + if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x)) TREE_PUBLIC (name) = 1; - /* Don't install an artificial TYPE_DECL if we already have - another _DECL with that name. */ - if (TREE_CODE (x) != TYPE_DECL - || t == NULL_TREE - || ! DECL_ARTIFICIAL (x)) + if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x) + && t != NULL_TREE)) { if (TREE_CODE (x) == FUNCTION_DECL) - my_friendly_assert ((BINDING_VALUE (bindings) == NULL_TREE) - || BINDING_VALUE (bindings) == x, 378); - BINDING_VALUE (bindings) = x; + my_friendly_assert + ((IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE) + || (IDENTIFIER_GLOBAL_VALUE (name) == x), 378); + SET_IDENTIFIER_NAMESPACE_VALUE (name, x); } /* Don't forget if the function was used via an implicit decl. */ @@ -3539,61 +4099,65 @@ pushdecl (x) else { /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); - tree oldglobal = binding_for_name (name, current_namespace); + tree oldlocal = IDENTIFIER_VALUE (name); + tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name); - /* Don't install an artificial TYPE_DECL if we already have - another _DECL with that name. */ - if (TREE_CODE (x) != TYPE_DECL - || t == NULL_TREE - || ! DECL_ARTIFICIAL (x)) - set_identifier_local_value_with_scope (name, x, b); + 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), b); + 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, b); + set_identifier_type_value_with_scope (name, NULL_TREE, + current_binding_level); /* 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) - && BINDING_VALUE (oldglobal) != NULL_TREE + && oldglobal != NULL_TREE && TREE_CODE (x) == FUNCTION_DECL - && TREE_CODE (BINDING_VALUE (oldglobal)) == FUNCTION_DECL) + && TREE_CODE (oldglobal) == FUNCTION_DECL) { /* We have one. Their types must agree. */ - if (decls_match (x, BINDING_VALUE (oldglobal))) + if (decls_match (x, oldglobal)) /* OK */; else { cp_warning ("extern declaration of `%#D' doesn't match", x); - cp_warning_at ("global declaration `%#D'", BINDING_VALUE (oldglobal)); + 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 - && BINDING_VALUE (oldglobal) == NULL_TREE + && oldglobal == NULL_TREE && DECL_EXTERNAL (x) && TREE_PUBLIC (x)) - { - TREE_PUBLIC (name) = 1; - } + TREE_PUBLIC (name) = 1; if (DECL_FROM_INLINE (x)) /* Inline decls shadow nothing. */; /* Warn if shadowing an argument at the top level of the body. */ else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) - && TREE_CODE (oldlocal) == PARM_DECL - && TREE_CODE (x) != PARM_DECL) + && TREE_CODE (oldlocal) == PARM_DECL + /* Don't complain if it's from an enclosing function. */ + && 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. */ @@ -3606,7 +4170,8 @@ pushdecl (x) if (b->parm_flag == 1) cp_error ("declaration of `%#D' shadows a parameter", name); } - else if (warn_shadow && oldlocal != NULL_TREE && b->is_for_scope + else if (warn_shadow && oldlocal != NULL_TREE + && current_binding_level->is_for_scope && !DECL_DEAD_FOR_LOCAL (oldlocal)) { warning ("variable `%s' shadows local", @@ -3620,7 +4185,7 @@ pushdecl (x) /* No shadow warnings for vars made for inlining. */ && ! DECL_FROM_INLINE (x)) { - char *warnstring = NULL; + const char *warnstring = NULL; if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL) warnstring = "declaration of `%s' shadows a parameter"; @@ -3630,7 +4195,7 @@ pushdecl (x) warnstring = "declaration of `%s' shadows a member of `this'"; else if (oldlocal != NULL_TREE) warnstring = "declaration of `%s' shadows previous local"; - else if (BINDING_VALUE (oldglobal) != NULL_TREE) + else if (oldglobal != NULL_TREE) /* XXX shadow warnings in outer-more namespaces */ warnstring = "declaration of `%s' shadows global declaration"; @@ -3650,15 +4215,20 @@ pushdecl (x) /* RTTI TD entries are created while defining the type_info. */ || (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) && TYPE_BEING_DEFINED (TREE_TYPE (x))))) - b->incomplete = tree_cons (NULL_TREE, x, b->incomplete); + current_binding_level->incomplete + = tree_cons (NULL_TREE, x, current_binding_level->incomplete); } - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = b->names; - b->names = x; - if (! (b != global_binding_level || TREE_PERMANENT (x))) - my_friendly_abort (124); + if (need_new_binding) + { + /* Put decls on list in reverse order. + We will reverse them later if necessary. */ + TREE_CHAIN (x) = current_binding_level->names; + current_binding_level->names = x; + if (current_binding_level == global_binding_level + && !TREE_PERMANENT (x)) + my_friendly_abort (124); + } return x; } @@ -3700,7 +4270,7 @@ tree pushdecl_namespace_level (x) tree x; { - register struct binding_level *b = inner_binding_level; + register struct binding_level *b = current_binding_level; register tree t; t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace)); @@ -3755,46 +4325,33 @@ pushdecl_top_level (x) /* Make the declaration of X appear in CLASS scope. */ -tree +void pushdecl_class_level (x) tree x; { /* Don't use DECL_ASSEMBLER_NAME here! Everything that looks in class scope looks for the pre-mangled name. */ - register tree name = DECL_NAME (x); + register tree name; + + if (TREE_CODE (x) == OVERLOAD) + x = OVL_CURRENT (x); + name = DECL_NAME (x); if (name) { - if (TYPE_BEING_DEFINED (current_class_type)) - { - /* A name N used in a class S shall refer to the same declaration - in its context and when re-evaluated in the completed scope of S. - - Types, enums, and static vars are checked here; other - members are checked in finish_struct. */ - tree icv = IDENTIFIER_CLASS_VALUE (name); - - if (icv && icv != x - && flag_optional_diags - /* Don't complain about inherited names. */ - && id_in_current_class (name) - /* Or shadowed tags. */ - && !(DECL_DECLARES_TYPE_P (icv) - && DECL_CONTEXT (icv) == current_class_type)) - { - cp_pedwarn ("declaration of identifier `%D' as `%#D'", name, x); - cp_pedwarn_at ("conflicts with previous use in class as `%#D'", - icv); - } - } - push_class_level_binding (name, x); if (TREE_CODE (x) == TYPE_DECL) - { - set_identifier_type_value (name, TREE_TYPE (x)); - } + set_identifier_type_value (name, TREE_TYPE (x)); + } + else if (ANON_UNION_TYPE_P (TREE_TYPE (x))) + { + tree f; + + for (f = TYPE_FIELDS (TREE_TYPE (x)); + f; + f = TREE_CHAIN (f)) + pushdecl_class_level (f); } - return x; } #if 0 @@ -3828,22 +4385,78 @@ push_class_level_binding (name, x) tree name; tree x; { + tree binding; /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) return; - if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x) - && purpose_member (name, class_binding_level->class_shadowed)) - return; + /* 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); + + /* There was already a binding for X containing fewer + functions than are named in X. Find the previous + declaration of X 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; + return; + } + } - maybe_push_cache_obstack (); - class_binding_level->class_shadowed - = tree_cons (name, IDENTIFIER_CLASS_VALUE (name), - class_binding_level->class_shadowed); - pop_obstacks (); - IDENTIFIER_CLASS_VALUE (name) = x; - obstack_ptr_grow (&decl_obstack, x); + /* If we didn't replace an existing binding, put the binding on the + stack of bindings for the identifier, and update + IDENTIFIER_CLASS_VALUE. */ + if (push_class_binding (name, x)) + { + push_cache_obstack (); + class_binding_level->class_shadowed + = tree_cons (name, IDENTIFIER_CLASS_VALUE (name), + class_binding_level->class_shadowed); + pop_obstacks (); + /* 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; + } } /* Insert another USING_DECL into the current binding level, @@ -3897,31 +4510,38 @@ push_using_directive (used) return ud; } -/* DECL is a FUNCTION_DECL 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 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_RESULT slot. 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 (decl, forgettable) +tree +push_overloaded_decl (decl, flags) tree decl; - int forgettable; + int flags; { - tree orig_name = DECL_NAME (decl); + tree name = DECL_NAME (decl); tree old; - int doing_global = (namespace_bindings_p () || ! forgettable); + tree new_binding; + int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); if (doing_global) { - old = namespace_binding (orig_name, DECL_CONTEXT (decl)); + old = namespace_binding (name, DECL_CONTEXT (decl)); if (old && TREE_CODE (old) == FUNCTION_DECL && DECL_ARTIFICIAL (old) && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) @@ -3932,16 +4552,7 @@ push_overloaded_decl (decl, forgettable) } } else - { - old = IDENTIFIER_LOCAL_VALUE (orig_name); - - if (! purpose_member (orig_name, current_binding_level->shadowed)) - { - current_binding_level->shadowed - = tree_cons (orig_name, old, current_binding_level->shadowed); - old = NULL_TREE; - } - } + old = lookup_name_current_level (name); if (old) { @@ -3959,9 +4570,19 @@ push_overloaded_decl (decl, forgettable) tree tmp; for (tmp = old; tmp; tmp = OVL_NEXT (tmp)) - if (decl == OVL_CURRENT (tmp) - || duplicate_decls (decl, OVL_CURRENT (tmp))) - return OVL_CURRENT (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)))) + cp_error ("`%#D' conflicts with previous using declaration `%#D'", + decl, fn); + + if (duplicate_decls (decl, fn)) + return fn; + } } else { @@ -3974,17 +4595,57 @@ push_overloaded_decl (decl, forgettable) if (old || TREE_CODE (decl) == TEMPLATE_DECL) { if (old && TREE_CODE (old) != OVERLOAD) - old = ovl_cons (old, NULL_TREE); - old = ovl_cons (decl, old); + 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 - /* orig_name is not ambiguous. */ - old = decl; + /* NAME is not ambiguous. */ + new_binding = decl; if (doing_global) - set_namespace_binding (orig_name, current_namespace, old); + set_namespace_binding (name, current_namespace, new_binding); else - IDENTIFIER_LOCAL_VALUE (orig_name) = old; + { + /* 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 = build_tree_list (NULL_TREE, new_binding); + + /* And update the CPLUS_BINDING node. */ + BINDING_VALUE (IDENTIFIER_BINDING (name)) + = new_binding; + return decl; + } + + /* We should always find a previous binding in this case. */ + my_friendly_abort (0); + } + + /* Install the new binding. */ + push_local_binding (name, new_binding, flags); + } return decl; } @@ -4040,7 +4701,7 @@ implicitly_declare (functionid) Otherwise return an error message format string with a %s where the identifier should go. */ -static char * +static const char * redeclaration_error_message (newdecl, olddecl) tree newdecl, olddecl; { @@ -4049,7 +4710,7 @@ redeclaration_error_message (newdecl, olddecl) /* Because C++ can put things into name space for free, constructs like "typedef struct foo { ... } foo" would look like an erroneous redeclaration. */ - if (comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 0)) + if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) return 0; else return "redefinition of `%#D'"; @@ -4279,20 +4940,42 @@ define_label (filename, line, name) and they should be cleaned up by the time we get to the label. */ && ! DECL_ARTIFICIAL (new_decls) - && ((DECL_INITIAL (new_decls) != NULL_TREE - && DECL_INITIAL (new_decls) != error_mark_node) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) + && !(DECL_INITIAL (new_decls) == NULL_TREE + && pod_type_p (TREE_TYPE (new_decls)))) { - if (! identified) + /* This is really only important if we're crossing + an initialization. The POD stuff is just + pedantry; why should it matter if the class + contains a field of pointer to member type? */ + int problem = (DECL_INITIAL (new_decls) + || (TYPE_NEEDS_CONSTRUCTING + (TREE_TYPE (new_decls)))); + + if (! identified) { - cp_error ("jump to label `%D'", decl); - error_with_file_and_line (uses->filename_o_goto, - uses->lineno_o_goto, - " from here"); + if (problem) + { + cp_error ("jump to label `%D'", decl); + error_with_file_and_line + (uses->filename_o_goto, + uses->lineno_o_goto, " from here"); + } + else + { + cp_pedwarn ("jump to label `%D'", decl); + pedwarn_with_file_and_line + (uses->filename_o_goto, + uses->lineno_o_goto, " from here"); + } identified = 1; } - cp_error_at (" crosses initialization of `%#D'", - new_decls); + + if (problem) + cp_error_at (" crosses initialization of `%#D'", + new_decls); + else + cp_pedwarn_at (" enters scope of non-POD `%#D'", + new_decls); } new_decls = TREE_CHAIN (new_decls); } @@ -4346,8 +5029,7 @@ pop_switch () /* XXX Note decl is never actually used. (bpk) */ void -define_case_label (decl) - tree decl; +define_case_label () { tree cleanup = last_cleanup_this_contour (); struct binding_level *b = current_binding_level; @@ -4429,7 +5111,7 @@ storedecls (decls) /* Similarly, store the list of tags of the current level. */ -static void +void storetags (tags) tree tags; { @@ -4455,6 +5137,9 @@ lookup_tag (form, name, binding_level, thislevel_only) int thislevel_only; { register struct binding_level *level; + /* Non-zero if, we should look past a pseudo-global level, even if + THISLEVEL_ONLY. */ + int allow_pseudo_global = 1; for (level = binding_level; level; level = level->level_chain) { @@ -4469,10 +5154,21 @@ lookup_tag (form, name, binding_level, thislevel_only) } else if (level->namespace_p) /* Do namespace lookup. */ - /* XXX: is this a real lookup, considering using-directives etc. ??? */ for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) { - tree old = BINDING_TYPE (binding_for_name (name, tail)); + tree old = binding_for_name (name, tail); + + /* If we just skipped past a pseudo global 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_pseudo_global + && old && BINDING_VALUE (old) + && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old))) + old = TREE_TYPE (BINDING_VALUE (old)); + else + old = BINDING_TYPE (old); + /* If it has an original type, it is a typedef, and we should not return it. */ if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old))) @@ -4509,16 +5205,24 @@ lookup_tag (form, name, binding_level, thislevel_only) } if (thislevel_only && ! level->tag_transparent) { - if (level->pseudo_global) - { - tree t = IDENTIFIER_CLASS_VALUE (name); - if (t && DECL_CLASS_TEMPLATE_P (t)) - return TREE_TYPE (t); - t = IDENTIFIER_NAMESPACE_VALUE (name); - if (t && DECL_CLASS_TEMPLATE_P (t)) - return TREE_TYPE (t); + if (level->pseudo_global && allow_pseudo_global) + { + /* We must deal with cases like this: + + template struct S; + template 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 non-zero. */ + allow_pseudo_global = 0; + continue; } - return NULL_TREE; + else + return NULL_TREE; } if (current_class_type && level->level_chain->namespace_p) { @@ -4667,36 +5371,165 @@ lookup_namespace_name (namespace, name) struct tree_binding _b; tree val; - my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); - - val = binding_init (&_b); - if (!qualified_lookup_using_namespace (name, namespace, val, 0)) - return error_mark_node; + my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); + + if (TREE_CODE (name) == NAMESPACE_DECL) + /* This happens for A::B when B is a namespace. */ + return name; + else if (TREE_CODE (name) == TEMPLATE_DECL) + { + /* This happens for A::B where B is a template, and there are no + template arguments. */ + cp_error ("invalid use of `%D'", name); + return error_mark_node; + } + + namespace = ORIGINAL_NAMESPACE (namespace); + + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); + + val = binding_init (&_b); + if (!qualified_lookup_using_namespace (name, namespace, val, 0)) + return error_mark_node; + + if (BINDING_VALUE (val)) + { + val = BINDING_VALUE (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); + return val; + } + + cp_error ("`%D' undeclared in namespace `%D'", name, namespace); + return error_mark_node; +} + +/* Hash a TYPENAME_TYPE. K is really of type `tree'. */ + +static unsigned long +typename_hash (k) + hash_table_key k; +{ + unsigned long hash; + tree t; + + t = (tree) k; + hash = (((unsigned long) TYPE_CONTEXT (t)) + ^ ((unsigned long) DECL_NAME (TYPE_NAME (t)))); + + return hash; +} + +/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ + +static boolean +typename_compare (k1, k2) + hash_table_key k1; + hash_table_key k2; +{ + tree t1; + tree t2; + tree d1; + tree d2; + + t1 = (tree) k1; + t2 = (tree) k2; + d1 = TYPE_NAME (t1); + d2 = TYPE_NAME (t2); + + return (DECL_NAME (d1) == DECL_NAME (d2) + && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)) + && ((TREE_TYPE (t1) != NULL_TREE) + == (TREE_TYPE (t2) != NULL_TREE)) + && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) + && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2)); +} + +/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is + the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE + is non-NULL, this type is being created by the implicit typename + extension, and BASE_TYPE is a type named `t' in some base class of + `T' which depends on template parameters. + + Returns the new TYPENAME_TYPE. */ + +tree +build_typename_type (context, name, fullname, base_type) + tree context; + tree name; + tree fullname; + tree base_type; +{ + tree t; + tree d; + struct hash_entry* e; + + static struct hash_table ht; + + push_obstacks (&permanent_obstack, &permanent_obstack); + + if (!ht.table + && !hash_table_init (&ht, &hash_newfunc, &typename_hash, + &typename_compare)) + fatal ("virtual memory exhausted"); + + /* The FULLNAME needs to exist for the life of the hash table, i.e., + for the entire compilation. */ + if (!TREE_PERMANENT (fullname)) + fullname = copy_to_permanent (fullname); + + /* Build the TYPENAME_TYPE. */ + t = make_lang_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); + TYPE_NAME (TREE_TYPE (d)) = d; + TYPE_STUB_DECL (TREE_TYPE (d)) = d; + DECL_CONTEXT (d) = FROB_CONTEXT (context); + DECL_ARTIFICIAL (d) = 1; - if (BINDING_VALUE (val)) + /* See if we already have this type. */ + e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0); + if (e) { - val = BINDING_VALUE (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); - return val; + /* This will free not only TREE_TYPE, but the lang-specific data + and the TYPE_DECL as well. */ + obstack_free (&permanent_obstack, t); + t = (tree) e->key; } + else + /* Insert the type into the table. */ + hash_lookup (&ht, t, /*create=*/true, /*copy=*/0); - cp_error ("`%D' undeclared in namespace `%D'", name, namespace); - return error_mark_node; + pop_obstacks (); + + return t; } tree make_typename_type (context, name) tree context, name; { - tree t, d; + tree t; tree fullname; if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') - name = TYPE_IDENTIFIER (name); + { + if (!(TYPE_LANG_SPECIFIC (name) + && (CLASSTYPE_IS_TEMPLATE (name) + || CLASSTYPE_USE_TEMPLATE (name)))) + name = TYPE_IDENTIFIER (name); + else + /* Create a TEMPLATE_ID_EXPR for the type. */ + name = build_nt (TEMPLATE_ID_EXPR, + CLASSTYPE_TI_TEMPLATE (name), + CLASSTYPE_TI_ARGS (name)); + } else if (TREE_CODE (name) == TYPE_DECL) name = DECL_NAME (name); @@ -4711,59 +5544,60 @@ make_typename_type (context, name) if (TREE_CODE (name) != IDENTIFIER_NODE) my_friendly_abort (2000); + if (TREE_CODE (context) == NAMESPACE_DECL) + { + /* We can get here from typename_sub0 in the explicit_template_type + expansion. Just fail. */ + cp_error ("no class template named `%#T' in `%#T'", + name, context); + return error_mark_node; + } + if (! uses_template_parms (context) || currently_open_class (context)) { if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR) { + tree tmpl = NULL_TREE; if (IS_AGGR_TYPE (context)) - t = lookup_field (context, name, 0, 0); - else - t = NULL_TREE; - - if (t == NULL_TREE || TREE_CODE (t) != TEMPLATE_DECL - || TREE_CODE (DECL_RESULT (t)) != TYPE_DECL) + tmpl = lookup_field (context, name, 0, 0); + if (!tmpl || !DECL_CLASS_TEMPLATE_P (tmpl)) { cp_error ("no class template named `%#T' in `%#T'", name, context); return error_mark_node; } - return lookup_template_class (t, TREE_OPERAND (fullname, 1), - NULL_TREE, context); + return lookup_template_class (tmpl, + TREE_OPERAND (fullname, 1), + NULL_TREE, context, + /*entering_scope=*/0); } else { if (IS_AGGR_TYPE (context)) t = lookup_field (context, name, 0, 1); else - t = NULL_TREE; - - if (t == NULL_TREE) { cp_error ("no type named `%#T' in `%#T'", name, context); return error_mark_node; } - return TREE_TYPE (t); + if (t) + return TREE_TYPE (t); } } - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - t = make_lang_type (TYPENAME_TYPE); - TYPENAME_TYPE_FULLNAME (t) = fullname; - d = build_decl (TYPE_DECL, name, t); - if (processing_template_decl) - pop_obstacks (); - - TYPE_CONTEXT (t) = FROB_CONTEXT (context); - TYPE_NAME (TREE_TYPE (d)) = d; - TYPE_STUB_DECL (TREE_TYPE (d)) = d; - DECL_CONTEXT (d) = FROB_CONTEXT (context); - CLASSTYPE_GOT_SEMICOLON (t) = 1; - - return t; + /* 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) && !t) + { + cp_error ("no type named `%#T' in `%#T'", name, context); + return error_mark_node; + } + + + return build_typename_type (context, name, fullname, NULL_TREE); } /* Select the right _DECL from multiple choices. */ @@ -4791,7 +5625,8 @@ select_decl (binding, flags) 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 - && (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL)) + && (TREE_CODE (val) != TEMPLATE_DECL + || !DECL_CLASS_TEMPLATE_P (val))) val = NULL_TREE; return val; @@ -4828,7 +5663,7 @@ unqualified_namespace_lookup (name, flags) if (!lookup_using_namespace (name, b, level->using_directives, scope, flags)) /* Give up because of error. */ - return NULL_TREE; + return error_mark_node; /* Add all _DECLs seen through global using-directives. */ /* XXX local and global using lists should work equally. */ @@ -4838,7 +5673,7 @@ unqualified_namespace_lookup (name, flags) if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), scope, flags)) /* Give up because of error. */ - return NULL_TREE; + return error_mark_node; if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } @@ -4888,6 +5723,32 @@ qualify_lookup (val, flags) 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 + && CLASSTYPE_TEMPLATE_INFO (subtype) + && CLASSTYPE_TI_TEMPLATE (subtype) == binding) + && ! (TREE_CODE (binding) == TYPE_DECL + && same_type_p (TREE_TYPE (binding), subtype))) + { + cp_warning ("lookup of `%D' finds `%#D'", + name, binding); + cp_warning (" instead of `%D' from dependent base class", + typename); + cp_warning (" (use `typename %T::%D' if that's what you meant)", + constructor_name (current_class_type), name); + } +} + /* 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 @@ -4907,11 +5768,12 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) tree name; int prefer_type, nonclass, namespaces_only; { - register tree val; + tree t; + tree val = NULL_TREE; int yylex = 0; tree from_obj = NULL_TREE; - tree locval, classval; int flags; + int val_is_implicit_typename = 0; /* Hack: copy flag set by parser, if set. */ if (only_namespace_names) @@ -4926,8 +5788,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) prefer_type = looking_for_typename; flags = lookup_flags (prefer_type, namespaces_only); - /* During parsing, we need to complain. */ - flags |= LOOKUP_COMPLAIN; /* If the next thing is '<', class templates are types. */ if (looking_for_template) flags |= LOOKUP_TEMPLATES_EXPECTED; @@ -4957,6 +5817,7 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) { struct tree_binding b; val = binding_init (&b); + flags |= LOOKUP_COMPLAIN; if (!qualified_lookup_using_namespace (name, type, val, flags)) return NULL_TREE; val = select_decl (val, flags); @@ -4967,26 +5828,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) || TREE_CODE (type) == TYPENAME_TYPE) /* Someone else will give an error about this if needed. */ val = NULL_TREE; - else if (TYPE_BEING_DEFINED (type)) - { - val = IDENTIFIER_CLASS_VALUE (name); - if (val && DECL_CONTEXT (val) != type) - { - struct binding_level *b = class_binding_level; - for (val = NULL_TREE; b; b = b->level_chain) - { - tree t = purpose_member (name, b->class_shadowed); - if (t && TREE_VALUE (t) - && DECL_CONTEXT (TREE_VALUE (t)) == type) - { - val = TREE_VALUE (t); - break; - } - } - } - if (val == NULL_TREE) - val = lookup_field (type, name, 0, 1); - } else if (type == current_class_type) val = IDENTIFIER_CLASS_VALUE (name); else @@ -5001,73 +5842,56 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) from_obj = val; } else - flags = lookup_flags (prefer_type, namespaces_only); - - locval = classval = NULL_TREE; - - if (! namespace_bindings_p ()) - locval = qualify_lookup (IDENTIFIER_LOCAL_VALUE (name), flags); - - /* In C++ class fields are between local and global scope, - just before the global scope. */ - if (current_class_type && ! nonclass) { - classval = IDENTIFIER_CLASS_VALUE (name); - if (classval == NULL_TREE && TYPE_BEING_DEFINED (current_class_type)) - /* Try to find values from base classes if we are presently - defining a type. We are presently only interested in - TYPE_DECLs. */ - classval = lookup_field (current_class_type, name, 0, 1); - - /* Add implicit 'typename' to types from template bases. lookup_field - will do this for us. If classval is actually from an enclosing - scope, lookup_nested_field will get it for us. */ - if (processing_template_decl - && classval && TREE_CODE (classval) == TYPE_DECL - && ! currently_open_class (DECL_CONTEXT (classval)) - && uses_template_parms (current_class_type) - && ! DECL_ARTIFICIAL (classval)) - classval = lookup_field (current_class_type, name, 0, 1); + flags = lookup_flags (prefer_type, namespaces_only); + /* If we're not parsing, we need to complain. */ + flags |= LOOKUP_COMPLAIN; + } - /* yylex() calls this with -2, since we should never start digging for - the nested name at the point where we haven't even, for example, - created the COMPONENT_REF or anything like that. */ - if (classval == NULL_TREE) - classval = lookup_nested_field (name, ! yylex); + /* First, look in non-namespace scopes. */ + for (t = IDENTIFIER_BINDING (name); t; t = TREE_CHAIN (t)) + { + tree binding; - classval = qualify_lookup (classval, flags); + if (!LOCAL_BINDING_P (t) && 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 (t), flags)) + binding = BINDING_VALUE (t); + else if ((flags & LOOKUP_PREFER_TYPES) + && qualify_lookup (BINDING_TYPE (t), flags)) + binding = BINDING_TYPE (t); + else + binding = NULL_TREE; + + if (binding + && (!val || !(TREE_CODE (binding) == TYPE_DECL + && IMPLICIT_TYPENAME_P (TREE_TYPE (binding))))) + { + if (val_is_implicit_typename && !yylex) + warn_about_implicit_typename_lookup (val, binding); + val = binding; + val_is_implicit_typename + = (TREE_CODE (val) == TYPE_DECL + && IMPLICIT_TYPENAME_P (TREE_TYPE (val))); + if (!val_is_implicit_typename) + break; + } } - if (locval && classval) + /* Now lookup in namespace scopes. */ + if (!val || val_is_implicit_typename) { - if (current_scope () == current_function_decl - && ! hack_decl_function_context (current_function_decl)) - /* Not in a nested function. */ - val = locval; - else + t = unqualified_namespace_lookup (name, flags); + if (t) { - /* This is incredibly horrible. The whole concept of - IDENTIFIER_LOCAL_VALUE / IDENTIFIER_CLASS_VALUE / - IDENTIFIER_GLOBAL_VALUE needs to be scrapped for local - classes. */ - tree lctx = hack_decl_function_context (locval); - tree cctx = hack_decl_function_context (classval); - - if (lctx == current_scope ()) - val = locval; - else if (lctx == cctx) - val = classval; - else - /* I don't know which is right; let's just guess for now. */ - val = locval; + if (val_is_implicit_typename && !yylex) + warn_about_implicit_typename_lookup (val, t); + val = t; } } - else if (locval) - val = locval; - else if (classval) - val = classval; - else - val = unqualified_namespace_lookup (name, flags); done: if (val) @@ -5092,17 +5916,6 @@ lookup_name_real (name, prefer_type, nonclass, namespaces_only) val = from_obj; } - if ((TREE_CODE (val) == TEMPLATE_DECL && looking_for_template) - || TREE_CODE (val) == TYPE_DECL || prefer_type <= 0) - ; - /* Caller wants a class-or-namespace-name. */ - else if (prefer_type == 1 && TREE_CODE (val) == NAMESPACE_DECL) - ; - else if (IDENTIFIER_HAS_TYPE_VALUE (name)) - val = TYPE_MAIN_DECL (IDENTIFIER_TYPE_VALUE (name)); - else if (TREE_TYPE (val) == error_mark_node) - val = 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); @@ -5144,15 +5957,21 @@ lookup_name (name, prefer_type) return lookup_name_real (name, prefer_type, 0, 0); } -/* Similar to `lookup_name' but look only at current binding level. */ +/* Similar to `lookup_name' but look only in the innermost non-class + binding level. */ tree lookup_name_current_level (name) tree name; { - register tree t = NULL_TREE; + struct binding_level *b; + tree t = NULL_TREE; + + b = current_binding_level; + while (b->parm_flag == 2) + b = b->level_chain; - if (current_binding_level->namespace_p) + if (b->namespace_p) { t = IDENTIFIER_NAMESPACE_VALUE (name); @@ -5160,13 +5979,14 @@ lookup_name_current_level (name) if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) t = TREE_VALUE (t); } - else if (IDENTIFIER_LOCAL_VALUE (name) != NULL_TREE) + else if (IDENTIFIER_BINDING (name) + && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) { - struct binding_level *b = current_binding_level; while (1) { - if (purpose_member (name, b->shadowed)) - return IDENTIFIER_LOCAL_VALUE (name); + if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b) + return IDENTIFIER_VALUE (name); + if (b->keep == 2) b = b->level_chain; else @@ -5260,7 +6080,7 @@ static int builtin_type_tdescs_len, builtin_type_tdescs_max; static void record_builtin_type (rid_index, name, type) enum rid rid_index; - char *name; + const char *name; tree type; { tree rname = NULL_TREE, tname = NULL_TREE; @@ -5303,7 +6123,7 @@ record_builtin_type (rid_index, name, type) static tree record_builtin_java_type (name, size) - char *name; + const char *name; int size; { tree type, decl; @@ -5322,7 +6142,12 @@ record_builtin_java_type (name, size) } record_builtin_type (RID_MAX, name, type); decl = TYPE_NAME (type); + + /* Suppress generate debug symbol entries for these types, + since for normal C++ they are just clutter. + However, push_lang_context undoes this if extern "Java" is seen. */ DECL_IGNORED_P (decl) = 1; + TYPE_FOR_JAVA (type) = 1; return type; } @@ -5332,7 +6157,7 @@ record_builtin_java_type (name, size) static void record_unknown_type (type, name) tree type; - char *name; + 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. */ @@ -5350,7 +6175,7 @@ static void push_overloaded_decl_1 (x) tree x; { - push_overloaded_decl (x, 0); + push_overloaded_decl (x, PUSH_GLOBAL); } #ifdef __GNUC__ @@ -5382,13 +6207,12 @@ init_decl_processing () int wchar_type_size; tree temp; tree array_domain_type; - extern int flag_strict_prototype; tree vb_off_identifier = NULL_TREE; /* Function type `char *(char *, char *)' and similar ones */ tree string_ftype_ptr_ptr, int_ftype_string_string; tree sizetype_endlink; tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype; - tree void_ftype, void_ftype_int, void_ftype_ptr, ptr_ftype_void; + tree void_ftype, void_ftype_int, void_ftype_ptr; /* Have to make these distinct before we try using them. */ lang_name_cplusplus = get_identifier ("C++"); @@ -5404,12 +6228,11 @@ init_decl_processing () current_lang_name = NULL_TREE; if (flag_strict_prototype == 2) - { - if (pedantic) - strict_prototypes_lang_c = strict_prototypes_lang_cplusplus; - } - else - strict_prototypes_lang_c = flag_strict_prototype; + flag_strict_prototype = pedantic; + if (! flag_permissive && ! pedantic) + flag_pedantic_errors = 1; + + strict_prototypes_lang_c = flag_strict_prototype; /* Initially, C. */ current_lang_name = lang_name_c; @@ -5420,7 +6243,6 @@ init_decl_processing () current_binding_level = NULL_BINDING_LEVEL; free_binding_level = NULL_BINDING_LEVEL; -#ifndef __CYGWIN32__ /* Because most segmentation signals can be traced back into user code, catch them and at least give the user a chance of working around compiler bugs. */ @@ -5442,13 +6264,6 @@ init_decl_processing () #ifdef SIGBUS signal (SIGBUS, signal_catch); #endif -#else /* ndef __CYGWIN32__ */ - /* Cygwin32 cannot handle catching signals other than - SIGABRT yet. We hope this will cease to be the case soon. */ -#ifdef SIGABRT - signal (SIGABRT, signal_catch); -#endif -#endif /* ndef __CYGWIN32__ */ gcc_obstack_init (&decl_obstack); @@ -5496,6 +6311,9 @@ init_decl_processing () : make_unsigned_type (CHAR_TYPE_SIZE)); record_builtin_type (RID_CHAR, "char", char_type_node); + /* `signed' is the same as `int' */ + record_builtin_type (RID_SIGNED, NULL_PTR, integer_type_node); + long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); record_builtin_type (RID_LONG, "long int", long_integer_type_node); @@ -5545,8 +6363,10 @@ init_decl_processing () pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); +#if HOST_BITS_PER_WIDE_INT >= 64 intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intTI_type_node)); + pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node)); +#endif unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode)); @@ -5555,8 +6375,10 @@ init_decl_processing () pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); +#if HOST_BITS_PER_WIDE_INT >= 64 unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intTI_type_node)); + pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node)); +#endif float_type_node = make_node (REAL_TYPE); TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; @@ -5652,7 +6474,8 @@ init_decl_processing () string_type_node = build_pointer_type (char_type_node); const_string_type_node - = build_pointer_type (build_type_variant (char_type_node, 1, 0)); + = build_pointer_type (build_qualified_type (char_type_node, + TYPE_QUAL_CONST)); #if 0 record_builtin_type (RID_MAX, NULL_PTR, string_type_node); #endif @@ -5682,7 +6505,8 @@ init_decl_processing () ptr_type_node = build_pointer_type (void_type_node); const_ptr_type_node - = build_pointer_type (build_type_variant (void_type_node, 1, 0)); + = build_pointer_type (build_qualified_type (void_type_node, + TYPE_QUAL_CONST)); #if 0 record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node); #endif @@ -5779,10 +6603,6 @@ init_decl_processing () builtin_function ("__builtin_frame_address", ptr_ftype_unsigned, BUILT_IN_FRAME_ADDRESS, NULL_PTR); - ptr_ftype_void = build_function_type (ptr_type_node, endlink); - builtin_function ("__builtin_fp", ptr_ftype_void, BUILT_IN_FP, NULL_PTR); - builtin_function ("__builtin_sp", ptr_ftype_void, BUILT_IN_SP, NULL_PTR); - builtin_function ("__builtin_alloca", ptr_ftype_sizetype, BUILT_IN_ALLOCA, "alloca"); builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); @@ -5951,10 +6771,7 @@ init_decl_processing () /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ TREE_TYPE (unknown_type_node) = unknown_type_node; - if (flag_ansi) - TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0); - else - TREE_TYPE (null_node) = build_pointer_type (unknown_type_node); + TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0); /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same result. */ @@ -6018,15 +6835,19 @@ init_decl_processing () DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node); TREE_UNSIGNED (fields[3]) = 0; TREE_CHAIN (fields[2]) = fields[3]; - vtable_entry_type = build_type_variant (vtable_entry_type, 1, 0); + vtable_entry_type = build_qualified_type (vtable_entry_type, + TYPE_QUAL_CONST); } record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); vtbl_type_node - = build_array_type (vtable_entry_type, NULL_TREE); + = build_cplus_array_type (vtable_entry_type, NULL_TREE); layout_type (vtbl_type_node); - vtbl_type_node = cp_build_type_variant (vtbl_type_node, 1, 0); + vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST); record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node); + vtbl_ptr_type_node = build_pointer_type (vtable_entry_type); + layout_type (vtbl_ptr_type_node); + record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node); /* Simplify life by making a "sigtable_entry_type". Give its fields names so that the debugger can use them. */ @@ -6061,7 +6882,8 @@ init_decl_processing () TREE_UNSIGNED (fields[5]) = 0; TREE_CHAIN (fields[4]) = fields[5]; - sigtable_entry_type = build_type_variant (sigtable_entry_type, 1, 0); + sigtable_entry_type = build_qualified_type (sigtable_entry_type, + TYPE_QUAL_CONST); record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type); } @@ -6081,7 +6903,7 @@ init_decl_processing () if (flag_honor_std) push_namespace (get_identifier ("std")); bad_alloc_type_node = xref_tag - (class_type_node, get_identifier ("bad_alloc"), NULL_TREE, 1); + (class_type_node, get_identifier ("bad_alloc"), 1); if (flag_honor_std) pop_namespace (); newtype = build_exception_variant @@ -6090,7 +6912,8 @@ init_decl_processing () (void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE)); auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN); auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN); - auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN); + global_delete_fndecl + = auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN); auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype, NOT_BUILT_IN); } @@ -6126,6 +6949,12 @@ init_decl_processing () print_error_function = lang_print_error_function; lang_get_alias_set = &c_get_alias_set; + valid_lang_attribute = cp_valid_lang_attribute; + + /* Maintain consistency. Perhaps we should just complain if they + say -fwritable-strings? */ + if (flag_writable_strings) + flag_const_strings = 0; } /* Function to print any language-specific context for an error message. */ @@ -6148,11 +6977,11 @@ lang_print_error_function (file) tree define_function (name, type, function_code, pfn, library_name) - char *name; + const char *name; tree type; enum built_in_function function_code; void (*pfn) PROTO((tree)); - char *library_name; + const char *library_name; { tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type); DECL_EXTERNAL (decl) = 1; @@ -6177,52 +7006,80 @@ define_function (name, type, function_code, pfn, library_name) return 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 - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. +/* When we call finish_struct for an anonymous union, we create + default copy constructors and such. But, an anonymous union + shouldn't have such things; this function undoes the damage to the + anonymous union type T. - C++: may have to grok the declspecs to learn about static, - complain for anonymous unions. */ + (The reason that we create the synthesized methods is that we don't + distinguish `union { int i; }' from `typedef union { int i; } U'. + The first is an anonymous union; the second is just an ordinary + union type.) */ void -shadow_tag (declspecs) +fixup_anonymous_union (t) + tree t; +{ + tree *q; + + /* Wipe out memory of synthesized methods */ + TYPE_HAS_CONSTRUCTOR (t) = 0; + TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; + TYPE_HAS_INIT_REF (t) = 0; + TYPE_HAS_CONST_INIT_REF (t) = 0; + TYPE_HAS_ASSIGN_REF (t) = 0; + TYPE_HAS_CONST_ASSIGN_REF (t) = 0; + + /* Splice the implicitly generated functions out of the TYPE_METHODS + list. */ + q = &TYPE_METHODS (t); + while (*q) + { + if (DECL_ARTIFICIAL (*q)) + *q = TREE_CHAIN (*q); + else + q = &TREE_CHAIN (*q); + } + + /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have + function members. */ + if (TYPE_METHODS (t)) + error ("an anonymous union cannot have function members"); +} + +/* Make sure that a declaration with no declarator is well-formed, i.e. + just defines a tagged type or anonymous union. + + Returns the type defined, if any. */ + +tree +check_tag_decl (declspecs) tree declspecs; { - int found_tag = 0; + int found_type = 0; tree ob_modifier = NULL_TREE; register tree link; - register enum tree_code code, ok_code = ERROR_MARK; register tree t = NULL_TREE; for (link = declspecs; link; link = TREE_CHAIN (link)) { register tree value = TREE_VALUE (link); - code = TREE_CODE (value); - if (IS_AGGR_TYPE_CODE (code) || code == ENUMERAL_TYPE) + if (TYPE_P (value)) { - my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); + ++found_type; - if (IS_AGGR_TYPE (value) && CLASSTYPE_USE_TEMPLATE (value)) + if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE) { - if (CLASSTYPE_IMPLICIT_INSTANTIATION (value) - && TYPE_SIZE (value) == NULL_TREE) - { - SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (value); - if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL (value)); - } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION (value)) - cp_error ("specialization after instantiation of `%T'", value); + my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); + t = value; } - - t = value; - ok_code = code; - found_tag++; + } + else if (value == ridpointers[(int) RID_FRIEND]) + { + if (current_class_type == NULL_TREE + || current_scope () != current_class_type) + ob_modifier = value; } else if (value == ridpointers[(int) RID_STATIC] || value == ridpointers[(int) RID_EXTERN] @@ -6230,47 +7087,77 @@ shadow_tag (declspecs) || value == ridpointers[(int) RID_REGISTER] || value == ridpointers[(int) RID_INLINE] || value == ridpointers[(int) RID_VIRTUAL] + || value == ridpointers[(int) RID_CONST] + || value == ridpointers[(int) RID_VOLATILE] || value == ridpointers[(int) RID_EXPLICIT]) ob_modifier = value; } + if (found_type > 1) + error ("multiple types in one declaration"); + + /* Inside a class, we might be in a friend or access declaration. + Until we have a good way of detecting the latter, don't warn. */ + if (t == NULL_TREE && ! current_class_type) + pedwarn ("declaration does not declare anything"); + + /* Check for an anonymous union. We're careful + accessing TYPE_IDENTIFIER because some built-in types, like + pointer-to-member types, do not have TYPE_NAME. */ + else if (t && TREE_CODE (t) == UNION_TYPE + && TYPE_NAME (t) + && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + { + /* Anonymous unions are objects, so they can have specifiers. */; + SET_ANON_UNION_TYPE_P (t); + } + + else if (ob_modifier) + { + if (ob_modifier == ridpointers[(int) RID_INLINE] + || ob_modifier == ridpointers[(int) RID_VIRTUAL]) + cp_error ("`%D' can only be specified for functions", ob_modifier); + else if (ob_modifier == ridpointers[(int) RID_FRIEND]) + cp_error ("`%D' can only be specified inside a class", ob_modifier); + else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) + cp_error ("`%D' can only be specified for constructors", + ob_modifier); + else + cp_error ("`%D' can only be specified for objects and functions", + ob_modifier); + } + + return t; +} + +/* 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 + from a containing scope, shadow that tag name for the current scope + with a forward reference. + If its type defines a new named structure or union + or defines an enum, it is valid but we need not do anything here. + Otherwise, it is an error. + + C++: may have to grok the declspecs to learn about static, + complain for anonymous unions. */ + +void +shadow_tag (declspecs) + tree declspecs; +{ + tree t = check_tag_decl (declspecs); + + if (t) + 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 (ok_code == UNION_TYPE - && t != NULL_TREE - && ((TREE_CODE (TYPE_NAME (t)) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (TYPE_NAME (t))) - || (TREE_CODE (TYPE_NAME (t)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))))) - { - /* See also grok_x_components. */ - tree *q; - - /* Wipe out memory of synthesized methods */ - TYPE_HAS_CONSTRUCTOR (t) = 0; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - TYPE_HAS_INIT_REF (t) = 0; - TYPE_HAS_CONST_INIT_REF (t) = 0; - TYPE_HAS_ASSIGN_REF (t) = 0; - TYPE_HAS_ASSIGNMENT (t) = 0; - TYPE_HAS_CONST_ASSIGN_REF (t) = 0; - - q = &TYPE_METHODS (t); - while (*q) - { - if (DECL_ARTIFICIAL (*q)) - *q = TREE_CHAIN (*q); - else - q = &TREE_CHAIN (*q); - } - - /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have - function members. */ - if (TYPE_METHODS (t)) - error ("an anonymous union cannot have function members"); + if (t && ANON_UNION_TYPE_P (t)) + { + fixup_anonymous_union (t); if (TYPE_FIELDS (t)) { @@ -6279,29 +7166,6 @@ shadow_tag (declspecs) finish_anon_union (decl); } } - else - { - /* Anonymous unions are objects, that's why we only check for - inappropriate specifiers in this branch. */ - - if (ob_modifier) - { - if (ob_modifier == ridpointers[(int) RID_INLINE] - || ob_modifier == ridpointers[(int) RID_VIRTUAL]) - cp_error ("`%D' can only be specified for functions", ob_modifier); - else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) - cp_error ("`%D' can only be specified for constructors", - ob_modifier); - else - cp_error ("`%D' can only be specified for objects and functions", - ob_modifier); - } - - if (found_tag == 0) - cp_error ("abstract declarator used as declaration"); - else if (found_tag > 1) - pedwarn ("multiple types in one declaration"); - } } /* Decode a "typename", such as "int **", returning a ..._TYPE node. */ @@ -6347,6 +7211,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) tree context; extern int have_extern_spec; extern int used_extern_spec; + tree attrlist; #if 0 /* See code below that used this. */ @@ -6361,13 +7226,22 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) used_extern_spec = 1; } + if (attributes || prefix_attributes) + attrlist = build_scratch_list (attributes, prefix_attributes); + else + attrlist = NULL_TREE; + decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, - NULL_TREE); + attrlist); + if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) return NULL_TREE; type = TREE_TYPE (decl); + if (type == error_mark_node) + return NULL_TREE; + /* Don't lose if destructors must be executed at file-level. */ if (! processing_template_decl && TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (complete_type (type)) @@ -6468,8 +7342,17 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) DECL_INITIAL (decl) = error_mark_node; } +#ifdef SET_DEFAULT_DECL_ATTRIBUTES + SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes); +#endif + + /* Set attributes here so if duplicate decl, will have proper attributes. */ + cplus_decl_attributes (decl, attributes, prefix_attributes); + if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE) { + push_nested_class (context, 2); + if (TREE_CODE (decl) == VAR_DECL) { tree field = lookup_field (context, DECL_NAME (decl), 0, 0); @@ -6506,18 +7389,23 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) DECL_IN_AGGR_P (decl) = 0; if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) || CLASSTYPE_USE_TEMPLATE (context)) - SET_DECL_TEMPLATE_SPECIALIZATION (decl); + { + SET_DECL_TEMPLATE_SPECIALIZATION (decl); + /* [temp.expl.spec] An explicit specialization of a static data + member of a template is a definition if the declaration + includes an initializer; otherwise, it is a declaration. + + We check for processing_specialization so this only applies + to the new specialization syntax. */ + if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization) + DECL_EXTERNAL (decl) = 1; + } if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) cp_pedwarn ("declaration of `%#D' outside of class is not definition", decl); - - pushclass (context, 2); } - /* Set attributes here so if duplicate decl, will have proper attributes. */ - cplus_decl_attributes (decl, attributes, prefix_attributes); - /* 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. */ @@ -6557,7 +7445,7 @@ start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) data segment. */ DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem); #endif - + if (! processing_template_decl) start_decl_1 (tem); @@ -6600,6 +7488,9 @@ start_decl_1 (decl) tree type = TREE_TYPE (decl); int initialized = (DECL_INITIAL (decl) != NULL_TREE); + if (type == error_mark_node) + return; + /* If this type of object needs a cleanup, and control may jump past it, make a new binding level so that it is cleaned up only when it is initialized first. */ @@ -6614,9 +7505,7 @@ start_decl_1 (decl) { /* Don't allow initializations for incomplete types except for arrays which might be completed by the initialization. */ - if (type == error_mark_node) - ; /* Don't complain again. */ - else if (TYPE_SIZE (complete_type (type)) != NULL_TREE) + if (TYPE_SIZE (complete_type (type)) != NULL_TREE) ; /* A complete type is ok. */ else if (TREE_CODE (type) != ARRAY_TYPE) { @@ -6716,10 +7605,6 @@ grok_reference_init (decl, type, init) return; } - if (TREE_TYPE (init) && TREE_CODE (TREE_TYPE (init)) == UNKNOWN_TYPE) - /* decay_conversion is probably wrong for references to functions. */ - init = decay_conversion (instantiate_type (TREE_TYPE (type), init, 1)); - if (TREE_CODE (init) == TREE_LIST) init = build_compound_expr (init); @@ -6800,6 +7685,25 @@ obscure_complex_init (decl, init) return init; } +/* Issue an error message if DECL is an uninitialized const variable. */ + +static void +check_for_uninitialized_const_var (decl) + tree decl; +{ + tree type = TREE_TYPE (decl); + + /* ``Unless explicitly declared extern, a const object does not have + external linkage and must be initialized. ($8.4; $12.1)'' ARM + 7.1.6 */ + if (TREE_CODE (decl) == VAR_DECL + && TREE_CODE (type) != REFERENCE_TYPE + && CP_TYPE_CONST_P (type) + && !TYPE_NEEDS_CONSTRUCTING (type) + && !DECL_INITIAL (decl)) + cp_error ("uninitialized const `%D'", decl); +} + /* Finish processing of a declaration; install its line number and initial value. If the length of an array type is not known before, @@ -6836,6 +7740,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) char *asmspec = NULL; int was_readonly = 0; int already_used = 0; + tree core_type; /* If this is 0, then we did not change obstacks. */ if (! decl) @@ -6856,6 +7761,12 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) init = NULL_TREE; } + if (current_class_type + && DECL_REAL_CONTEXT (decl) == current_class_type + && TYPE_BEING_DEFINED (current_class_type) + && (DECL_INITIAL (decl) || init)) + DECL_DEFINED_IN_CLASS_P (decl) = 1; + if (TREE_CODE (decl) == VAR_DECL && DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL @@ -6882,6 +7793,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) return; } + if (TYPE_HAS_MUTABLE_P (type)) + TREE_READONLY (decl) = 0; + if (processing_template_decl) { if (init && DECL_INITIAL (decl)) @@ -6982,6 +7896,10 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) GNU_xref_decl (current_function_decl, decl); + core_type = type; + while (TREE_CODE (core_type) == ARRAY_TYPE) + core_type = TREE_TYPE (core_type); + if (TREE_CODE (decl) == FIELD_DECL) ; else if (TREE_CODE (decl) == CONST_DECL) @@ -7000,7 +7918,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) { if (TREE_CODE (type) == ARRAY_TYPE) init = digest_init (type, init, (tree *) 0); - else if (TREE_CODE (init) == CONSTRUCTOR) + else if (TREE_CODE (init) == CONSTRUCTOR + && TREE_HAS_CONSTRUCTOR (init)) { if (TYPE_NON_AGGREGATE_CLASS (type)) { @@ -7029,44 +7948,25 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) { - tree ctype = type; - while (TREE_CODE (ctype) == ARRAY_TYPE) - ctype = TREE_TYPE (ctype); - if (! TYPE_NEEDS_CONSTRUCTING (ctype)) + if (! TYPE_NEEDS_CONSTRUCTING (core_type)) { - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype)) + if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)) cp_error ("structure `%D' with uninitialized const members", decl); - if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype)) + if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)) cp_error ("structure `%D' with uninitialized reference members", decl); } - if (TREE_CODE (decl) == VAR_DECL - && !DECL_INITIAL (decl) - && !TYPE_NEEDS_CONSTRUCTING (type) - && (TYPE_READONLY (type) || TREE_READONLY (decl))) - cp_error ("uninitialized const `%D'", decl); + check_for_uninitialized_const_var (decl); if (TYPE_SIZE (type) != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (type)) init = obscure_complex_init (decl, NULL_TREE); - } - else if (TREE_CODE (decl) == VAR_DECL - && TREE_CODE (type) != REFERENCE_TYPE - && (TYPE_READONLY (type) || TREE_READONLY (decl))) - { - /* ``Unless explicitly declared extern, a const object does not have - external linkage and must be initialized. ($8.4; $12.1)'' ARM 7.1.6 - However, if it's `const int foo = 1; const int foo;', don't complain - about the second decl, since it does have an initializer before. - We deliberately don't complain about arrays, because they're - supposed to be initialized by a constructor. */ - if (! DECL_INITIAL (decl) - && TREE_CODE (type) != ARRAY_TYPE - && (!pedantic || !current_class_type)) - cp_error ("uninitialized const `%#D'", decl); - } + } + else + check_for_uninitialized_const_var (decl); + /* For top-level declaration, the initial value was read in the temporary obstack. MAXINDEX, rtl, etc. to be made below must go in the permanent obstack; but don't discard the @@ -7234,7 +8134,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) else if (! DECL_ARTIFICIAL (decl)) { 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; + cp_warning_at (" you can work around this by removing the initializer", decl); } } } @@ -7242,31 +8142,9 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) else if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl) && DECL_COMDAT (decl)) - { - /* Dynamically initialized vars go into common. */ - if (DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node) - DECL_COMMON (decl) = 1; - else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) - { - DECL_COMMON (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; - } - else - { - /* Statically initialized vars are weak or comdat, if - supported. */ - if (flag_weak) - make_decl_one_only (decl); - else - { - /* We can't do anything useful; leave vars for explicit - instantiation. */ - DECL_EXTERNAL (decl) = 1; - DECL_NOT_REALLY_EXTERN (decl) = 0; - } - } - } + /* Set it up again; we might have set DECL_INITIAL since the + last time. */ + comdat_linkage (decl); if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) make_decl_rtl (decl, NULL_PTR, toplev); @@ -7343,17 +8221,17 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) resume_temporary_allocation (); if (type != error_mark_node - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - abstract_virtuals_error (decl, type); + && TYPE_LANG_SPECIFIC (core_type) + && CLASSTYPE_ABSTRACT_VIRTUALS (core_type)) + abstract_virtuals_error (decl, core_type); else if ((TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (type))) abstract_virtuals_error (decl, TREE_TYPE (type)); - if (TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE (type)) - signature_error (decl, type); + if (TYPE_LANG_SPECIFIC (core_type) && IS_SIGNATURE (core_type)) + signature_error (decl, core_type); else if ((TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) @@ -7414,7 +8292,8 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) if (current_binding_level->is_for_scope) { - struct binding_level *outer = current_binding_level->level_chain; + struct 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, @@ -7426,36 +8305,20 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) Otherwise, we need to preserve the temp slot for decl to last into the outer binding level. */ - int handling_dead_for_vars = 0; - tree link = outer->names; - for (; ; link = TREE_CHAIN (link)) + tree outer_binding + = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl))); + + if (outer_binding && BINDING_LEVEL (outer_binding) == outer + && (TREE_CODE (BINDING_VALUE (outer_binding)) + == VAR_DECL) + && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding))) { - if (link == NULL && handling_dead_for_vars == 0) - { - link = outer->dead_vars_from_for; - handling_dead_for_vars = 1; - } - if (link == NULL) - { - if (DECL_IN_MEMORY_P (decl)) - preserve_temp_slots (DECL_RTL (decl)); - break; - } - if (DECL_NAME (link) == DECL_NAME (decl)) - { - if (handling_dead_for_vars) - { - tree shadowing - = purpose_member (DECL_NAME (decl), - current_binding_level->shadowed); - if (shadowing && TREE_VALUE (shadowing) == link) - TREE_VALUE (shadowing) - = DECL_SHADOWED_FOR_VAR (link); - } - current_binding_level->is_for_scope = 0; - break; - } + 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)); } expand_start_target_temps (); @@ -7470,7 +8333,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) { emit_line_note (DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - expand_aggr_init (decl, init, 0, flags); + expand_aggr_init (decl, init, flags); } /* Set this to 0 so we can tell whether an aggregate which @@ -7524,7 +8387,7 @@ cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) the binding level.. */ && TYPE_SIZE (context) != NULL_TREE && context == current_class_type) - popclass (1); + pop_nested_class (); } } @@ -7582,7 +8445,7 @@ expand_static_init (decl, init) if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) cp_error ("multiple initializations given for `%D'", decl); } - else if (! toplevel_bindings_p () && ! pseudo_global_level_p ()) + else if (! toplevel_bindings_p ()) { /* Emit code to perform this initialization but once. */ tree temp; @@ -7590,30 +8453,65 @@ expand_static_init (decl, init) /* Remember this information until end of file. */ push_obstacks (&permanent_obstack, &permanent_obstack); - /* Emit code to perform this initialization but once. */ + /* Emit code to perform this initialization but once. This code + looks like: + + static int temp = 0; + if (!temp) { + // Do initialization. + temp = 1; + // Register variable for destruction at end of program. + } + + Note that the `temp' variable is only set to 1 *after* the + initialization is complete. This ensures that an exception, + thrown during the construction, will cause the variable to + reinitialized when we pass through this code again, as per: + + [stmt.dcl] + + If the initialization exits by throwing an exception, the + initialization is not complete, so it will be tried again + the next time control enters the declaration. + + In theory, this process should be thread-safe, too; multiple + threads should not be able to initialize the variable more + than once. We don't yet attempt to ensure thread-safety. */ temp = get_temp_name (integer_type_node, 1); rest_of_decl_compilation (temp, NULL_PTR, 0, 0); + + /* Begin the conditional initialization. */ expand_start_cond (build_binary_op (EQ_EXPR, temp, - integer_zero_node, 1), 0); + integer_zero_node), 0); expand_start_target_temps (); - expand_assignment (temp, integer_one_node, 0, 0); + /* Do the initialization itself. */ if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) || (init && TREE_CODE (init) == TREE_LIST)) { - expand_aggr_init (decl, init, 0, 0); + expand_aggr_init (decl, init, 0); do_pending_stack_adjust (); } else if (init) expand_assignment (decl, init, 0, 0); - /* Cleanup any temporaries needed for the initial value. */ + /* Set TEMP to 1. */ + expand_assignment (temp, integer_one_node, 0, 0); + + /* Cleanup any temporaries needed for the initial value. If + destroying one of the temporaries causes an exception to be + thrown, then the object itself has still been fully + constructed. */ expand_end_target_temps (); + /* Use atexit to register a function for destroying this static + variable. */ if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) { tree cleanup, fcall; static tree Atexit = 0; + int saved_flag_access_control; + if (Atexit == 0) { tree atexit_fndecl, PFV, pfvlist; @@ -7630,38 +8528,55 @@ expand_static_init (decl, init) build_function_type (void_type_node, pfvlist), NOT_BUILT_IN, NULL_PTR); - assemble_external (atexit_fndecl); + mark_used (atexit_fndecl); Atexit = default_conversion (atexit_fndecl); pop_lang_context (); pop_obstacks (); } + /* Call build_cleanup before we enter the anonymous function + so that any access checks will be done relative to the + current scope, rather than the scope of the anonymous + function. */ + build_cleanup (decl); + + /* Now start the function. */ cleanup = start_anon_func (); - expand_expr_stmt (build_cleanup (decl)); + + /* Now, recompute the cleanup. It may contain SAVE_EXPRs + that refer 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; + fcall = build_cleanup (decl); + flag_access_control = saved_flag_access_control; + + /* Finish off the function. */ + expand_expr_stmt (fcall); end_anon_func (); + + /* Call atexit with the cleanup function. */ mark_addressable (cleanup); cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); - fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE)); + fcall = build_function_call (Atexit, + expr_tree_cons (NULL_TREE, + cleanup, + NULL_TREE)); expand_expr_stmt (fcall); } expand_end_cond (); - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) - { - static_aggregates = perm_tree_cons (temp, decl, static_aggregates); - TREE_STATIC (static_aggregates) = 1; - } - /* Resume old (possibly temporary) allocation. */ pop_obstacks (); } else { - /* This code takes into account memory allocation - policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING - does not hold for this object, then we must make permanent - the storage currently in the temporary obstack. */ - if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) + /* This code takes into account memory allocation policy of + `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING does not + hold for this object, then we must make permanent the storage + currently in the temporary obstack. */ + if (!TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) preserve_initializer (); static_aggregates = perm_tree_cons (init, decl, static_aggregates); } @@ -7669,7 +8584,7 @@ expand_static_init (decl, init) /* Make TYPE a complete type based on INITIAL_VALUE. Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ + 2 if there was no information (in which case assume 0 if DO_DEFAULT). */ int complete_array_type (type, initial_value, do_default) @@ -7678,7 +8593,10 @@ complete_array_type (type, initial_value, do_default) { register tree maxindex = NULL_TREE; int value = 0; - + + /* Allocate on the same obstack as TYPE. */ + push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); + if (initial_value) { /* Note MAXINDEX is really the maximum index, @@ -7708,6 +8626,8 @@ complete_array_type (type, initial_value, do_default) /* Make an error message unless that happened already. */ if (initial_value != error_mark_node) value = 1; + else + initial_value = NULL_TREE; /* Prevent further error messages. */ maxindex = build_int_2 (0, 0); @@ -7724,23 +8644,28 @@ complete_array_type (type, initial_value, do_default) if (maxindex) { tree itype; + tree domain; + + domain = build_index_type (maxindex); + TYPE_DOMAIN (type) = domain; - TYPE_DOMAIN (type) = build_index_type (maxindex); if (! TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (type); + TREE_TYPE (maxindex) = domain; if (initial_value) itype = TREE_TYPE (initial_value); else itype = NULL; if (itype && !TYPE_DOMAIN (itype)) - TYPE_DOMAIN (itype) = TYPE_DOMAIN (type); + TYPE_DOMAIN (itype) = domain; /* The type of the main variant should never be used for arrays of different sizes. It should only ever be completed with the size of the array. */ if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) - TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = TYPE_DOMAIN (type); + TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain; } + pop_obstacks(); + /* Lay out the type now that we can get the real answer. */ layout_type (type); @@ -7755,7 +8680,7 @@ complete_array_type (type, initial_value, do_default) static int member_function_or_else (ctype, cur_type, string) tree ctype, cur_type; - char *string; + const char *string; { if (ctype && ctype != cur_type) { @@ -7773,7 +8698,7 @@ member_function_or_else (ctype, cur_type, string) static void bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises) tree object; - char *type; + const char *type; int virtualp, quals, friendp, raises, inlinep; { if (virtualp) @@ -7799,23 +8724,27 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises) or `volatile'. RAISES is a list of exceptions that this function can raise. CHECK is 1 if we must find this method in CTYPE, 0 if we should - not look, and -1 if we should not call `grokclassfn' at all. */ + not look, and -1 if we should not call `grokclassfn' at all. + + Returns `NULL_TREE' if something goes wrong, after issuing + applicable error messages. */ static tree grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, - raises, attrlist, check, friendp, publicp, inlinep, funcdef_flag, + 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, attrlist; + tree quals, raises; int check, friendp, publicp, inlinep, funcdef_flag, template_count; tree in_namespace; { tree cname, decl; int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; + int has_default_arg = 0; tree t; if (ctype) @@ -7834,9 +8763,23 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (TYPE_VOLATILE (type)) TREE_THIS_VOLATILE (decl) = 1; - /* This decl is not from the current namespace. */ + /* If this decl has namespace scope, set that up. */ if (in_namespace) - set_decl_namespace (decl, in_namespace); + set_decl_namespace (decl, in_namespace, friendp); + else if (publicp && ! ctype) + DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); + + /* `main' and builtins have implicit 'C' linkage. */ + if ((MAIN_NAME_P (declarator) + || (IDENTIFIER_LENGTH (declarator) > 10 + && IDENTIFIER_POINTER (declarator)[0] == '_' + && IDENTIFIER_POINTER (declarator)[1] == '_' + && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)) + && current_lang_name == lang_name_cplusplus + && ctype == NULL_TREE + /* NULL_TREE means global namespace. */ + && DECL_CONTEXT (decl) == NULL_TREE) + DECL_LANGUAGE (decl) = lang_c; /* Should probably propagate const out from type to decl I bet (mrs). */ if (staticp) @@ -7848,8 +8791,10 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (ctype) DECL_CLASS_CONTEXT (decl) = ctype; - if (ctype == NULL_TREE && MAIN_NAME_P (declarator)) + if (ctype == NULL_TREE && DECL_MAIN_P (decl)) { + if (processing_template_decl) + error ("cannot declare `main' to be a template"); if (inlinep) error ("cannot declare `main' to be inline"); else if (! publicp) @@ -7857,7 +8802,37 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, inlinep = 0; publicp = 1; } - + + /* Members of anonymous types and local classes have no linkage; make + them internal. */ + if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype)) + || hack_decl_function_context (TYPE_MAIN_DECL (ctype)))) + publicp = 0; + + if (publicp) + { + /* [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. + + Only check this for public decls for now. */ + t = no_linkage_check (TREE_TYPE (decl)); + if (t) + { + if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + { + if (DECL_LANGUAGE (decl) == lang_c) + /* Allow this; it's pretty common in C. */; + else + cp_pedwarn ("non-local function `%#D' uses anonymous type", + decl); + } + else + cp_pedwarn ("non-local function `%#D' uses local type `%T'", + decl, t); + } + } + TREE_PUBLIC (decl) = publicp; if (! publicp) { @@ -7886,7 +8861,7 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) { - add_defarg_fn (decl); + has_default_arg = 1; break; } @@ -7899,6 +8874,15 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, orig_declarator); else { + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + { + /* Something like `template friend void f()'. */ + cp_error ("template-id `%D' in declaration of primary template", + orig_declarator); + return NULL_TREE; + } + + /* A friend declaration of the form friend void f<>(). Record the information in the TEMPLATE_ID_EXPR. */ SET_DECL_IMPLICIT_INSTANTIATION (decl); @@ -7906,9 +8890,37 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, = perm_tree_cons (TREE_OPERAND (orig_declarator, 0), TREE_OPERAND (orig_declarator, 1), NULL_TREE); + + if (has_default_arg) + { + cp_error ("default arguments are not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } + + if (inlinep) + { + cp_error ("`inline' is not allowed in declaration of friend template specialization `%D'", + decl); + return NULL_TREE; + } } } + if (has_default_arg) + add_defarg_fn (decl); + + /* Plain overloading: will not be grok'd by grokclassfn. */ + if (! ctype && ! processing_template_decl + && DECL_LANGUAGE (decl) != lang_c + && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1)) + set_mangled_name_for_decl (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. */ + DECL_INITIAL (decl) = error_mark_node; + /* Caller will do the rest of this. */ if (check < 0) return decl; @@ -7926,14 +8938,16 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, the following calls is supposed to do. */ DECL_CONSTRUCTOR_P (decl) = 1; - grokclassfn (ctype, declarator, decl, flags, quals); + grokclassfn (ctype, decl, flags, quals); decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * (funcdef_flag != 0) + 4 * (friendp != 0)); + if (decl == error_mark_node) + return NULL_TREE; - if ((! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl)) + if ((! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) && check) { tmp = check_classfn (ctype, decl); @@ -7948,22 +8962,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, } if (! grok_ctor_properties (ctype, decl)) return NULL_TREE; - - if (check == 0 && ! current_function_decl) - { - /* Assembler names live in the global namespace. */ - tmp = IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl)); - if (tmp == NULL_TREE) - SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl); - else if (TREE_CODE (tmp) != TREE_CODE (decl)) - cp_error ("inconsistent declarations for `%D'", decl); - else - { - duplicate_decls (decl, tmp); - decl = tmp; - } - make_decl_rtl (decl, NULL_PTR, 1); - } } else { @@ -7973,14 +8971,17 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, This call may change the type of the function (because of default parameters)! */ if (ctype != NULL_TREE) - grokclassfn (ctype, cname, decl, flags, quals); + grokclassfn (ctype, decl, flags, quals); decl = check_explicit_specialization (orig_declarator, decl, template_count, 2 * (funcdef_flag != 0) + 4 * (friendp != 0)); + if (decl == error_mark_node) + return NULL_TREE; + if (ctype != NULL_TREE - && (! TYPE_FOR_JAVA (ctype) || check_java_method (ctype, decl)) + && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) && check) { tmp = check_classfn (ctype, decl); @@ -8000,8 +9001,11 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, cp_error ("definition of implicitly-declared `%D'", tmp); if (tmp) { + /* Attempt to merge the declarations. This can fail, in + the case of some illegal specialization declarations. */ if (!duplicate_decls (decl, tmp)) - my_friendly_abort (892); + cp_error ("no `%#D' member function declared in class `%T'", + decl, ctype); return tmp; } } @@ -8009,37 +9013,6 @@ grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, if (ctype == NULL_TREE || check) return decl; - /* Now install the declaration of this function so that others may - find it (esp. its DECL_FRIENDLIST). Don't do this for local class - methods, though. */ - if (! current_function_decl) - { - if (!DECL_TEMPLATE_SPECIALIZATION (decl)) - { - /* We don't do this for specializations since the - equivalent checks will be done later. Also, at this - point the DECL_ASSEMBLER_NAME is not yet fully - accurate. */ - - /* FIXME: this should only need to look at - IDENTIFIER_GLOBAL_VALUE. */ - tmp = lookup_name (DECL_ASSEMBLER_NAME (decl), 0); - if (tmp == NULL_TREE) - SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (decl), decl); - else if (TREE_CODE (tmp) != TREE_CODE (decl)) - cp_error ("inconsistent declarations for `%D'", decl); - else - { - duplicate_decls (decl, tmp); - decl = tmp; - } - } - - if (attrlist) - cplus_decl_attributes (decl, TREE_PURPOSE (attrlist), - TREE_VALUE (attrlist)); - make_decl_rtl (decl, NULL_PTR, 1); - } if (virtualp) { DECL_VIRTUAL_P (decl) = 1; @@ -8078,16 +9051,27 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) } else { - tree context = in_namespace ? in_namespace : current_namespace; + tree context; + + if (in_namespace) + context = in_namespace; + else if (namespace_bindings_p () || RIDBIT_SETP (RID_EXTERN, specbits)) + context = current_namespace; + else + context = NULL_TREE; + decl = build_decl (VAR_DECL, declarator, complete_type (type)); - if (context != global_namespace && namespace_bindings_p () - && current_lang_name != lang_name_c) - DECL_ASSEMBLER_NAME (decl) = build_static_name (context, - declarator); + + if (context) + set_decl_namespace (decl, context, 0); + + context = DECL_CONTEXT (decl); + if (declarator && context && current_lang_name != lang_name_c) + DECL_ASSEMBLER_NAME (decl) = build_static_name (context, declarator); } if (in_namespace) - set_decl_namespace (decl, in_namespace); + set_decl_namespace (decl, in_namespace, 0); if (RIDBIT_SETP (RID_EXTERN, specbits)) { @@ -8117,10 +9101,30 @@ grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits); TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); } + + if (TREE_PUBLIC (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. + + Only check this for public decls for now. */ + tree t = no_linkage_check (TREE_TYPE (decl)); + if (t) + { + if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) + /* Ignore for now; `enum { foo } e' is pretty common. */; + else + cp_pedwarn ("non-local variable `%#D' uses local type `%T'", + decl, t); + } + } + return decl; } -/* Create a canonical pointer to member function type. */ +/* Create and return a canonical pointer to member function type, for + TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */ tree build_ptrmemfunc_type (type) @@ -8140,7 +9144,7 @@ build_ptrmemfunc_type (type) push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); u = make_lang_type (UNION_TYPE); - IS_AGGR_TYPE (u) = 0; + SET_IS_AGGR_TYPE (u, 0); fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type); fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier, delta_type_node); @@ -8152,7 +9156,7 @@ build_ptrmemfunc_type (type) /* Let the front-end know this is a pointer to member function... */ TYPE_PTRMEMFUNC_FLAG (t) = 1; /* ... and not really an aggregate. */ - IS_AGGR_TYPE (t) = 0; + SET_IS_AGGR_TYPE (t, 0); fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, delta_type_node); @@ -8174,6 +9178,41 @@ build_ptrmemfunc_type (type) return t; } +/* DECL is a VAR_DECL defined in-class, whose TYPE is also given. + Check to see that the definition is valid. Issue appropriate error + messages. Return 1 if the definition is particularly bad, or 0 + otherwise. */ + +int +check_static_variable_definition (decl, type) + 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 + may appear either in the declaration (within the class), or in + the definition, but not both. If it appears in the class, the + member is a member constant. The file-scope definition is always + required. */ + if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE) + { + cp_error ("in-class initialization of static data member of non-integral type `%T'", + type); + /* If we just return the declaration, crashes will sometimes + occur. We therefore return void_type_node, as if this was a + friend declaration, to cause callers to completely ignore + this declaration. */ + return 1; + } + else if (!CP_TYPE_CONST_P (type)) + cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'", + decl); + else if (pedantic && !INTEGRAL_TYPE_P (type)) + cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type); + + return 0; +} + /* Given declspecs and a declarator, determine the name and type of the object declared and construct a ..._DECL node for it. @@ -8201,6 +9240,9 @@ build_ptrmemfunc_type (type) BITFIELD for a field with specified width. INITIALIZED is 1 if the decl has an initializer. + ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and + normal attributes in TREE_PURPOSE, or NULL_TREE. + In the TYPENAME case, DECLARATOR is really an absolute declarator. It may also be so in the PARM case, for a prototype where the argument type is specified but not the name. @@ -8246,7 +9288,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree type = NULL_TREE; int longlong = 0; int constp; + int restrictp; int volatilep; + int type_quals; int virtualp, explicitp, friendp, inlinep, staticp; int explicit_int = 0; int explicit_char = 0; @@ -8279,6 +9323,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) tree raises = NULL_TREE; int template_count = 0; tree in_namespace = NULL_TREE; + tree inner_attrs; + int ignore_attrs; RIDBIT_RESET_ALL (specbits); if (decl_context == FUNCDEF) @@ -8300,6 +9346,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) decl = *next; switch (TREE_CODE (decl)) { + case TREE_LIST: + /* For attributes. */ + next = &TREE_VALUE (decl); + break; + case COND_EXPR: ctype = NULL_TREE; next = &TREE_OPERAND (decl, 0); @@ -8359,18 +9410,38 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) case CALL_EXPR: if (parmlist_is_exprlist (TREE_OPERAND (decl, 1))) { - /* 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... */ + /* 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, prefix_attributes; *next = TREE_OPERAND (decl, 0); init = TREE_OPERAND (decl, 1); - decl = start_decl (declarator, declspecs, 1, NULL_TREE, NULL_TREE); - /* Look for __unused__ attribute */ - if (TREE_USED (TREE_TYPE (decl))) - TREE_USED (decl) = 1; - finish_decl (decl, init, NULL_TREE); + if (attrlist) + { + attributes = TREE_PURPOSE (attrlist); + prefix_attributes = TREE_VALUE (attrlist); + } + else + { + attributes = NULL_TREE; + prefix_attributes = NULL_TREE; + } + + decl = start_decl (declarator, declspecs, 1, + attributes, prefix_attributes); + if (decl) + { + /* Look for __unused__ attribute */ + if (TREE_USED (TREE_TYPE (decl))) + TREE_USED (decl) = 1; + finish_decl (decl, init, NULL_TREE); + } + else + cp_error ("invalid declarator"); return 0; } innermost_code = TREE_CODE (decl); @@ -8403,12 +9474,15 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (TREE_CODE (fns) == LOOKUP_EXPR) fns = TREE_OPERAND (fns, 0); - if (TREE_CODE (fns) == IDENTIFIER_NODE) - dname = fns; - else if (is_overloaded_fn (fns)) - dname = DECL_NAME (get_first_fn (fns)); - else - my_friendly_abort (0); + dname = fns; + if (TREE_CODE (dname) == COMPONENT_REF) + dname = TREE_OPERAND (dname, 1); + if (TREE_CODE (dname) != IDENTIFIER_NODE) + { + my_friendly_assert (is_overloaded_fn (dname), + 19990331); + dname = DECL_NAME (get_first_fn (dname)); + } } /* Fall through. */ @@ -8747,24 +9821,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } else { - if (funcdef_flag) - { - if (warn_return_type - && return_type == return_normal) - /* Save warning until we know what is really going on. */ - warn_about_return_type = 1; - } - else if (RIDBIT_SETP (RID_TYPEDEF, specbits)) - pedwarn ("ANSI C++ forbids typedef which does not specify a type"); - else if (innermost_code != CALL_EXPR || pedantic - || (warn_return_type && return_type == return_normal)) - { - if (innermost_code == CALL_EXPR) - cp_pedwarn ("return-type of `%D' defaults to `int'", dname); - else - cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type", - dname); - } + /* We handle `main' specially here, because 'main () { }' is so + common. With no options, it is allowed. With -Wreturn-type, + it is a warning. It is only an error with -pedantic-errors. */ + int is_main = (funcdef_flag + && MAIN_NAME_P (dname) + && ctype == NULL_TREE + && in_namespace == NULL_TREE + && current_namespace == global_namespace); + + if (in_system_header) + /* Allow it, sigh. */; + else if (pedantic || ! is_main) + cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type", + dname); + else if (warn_return_type) + cp_warning ("ANSI C++ forbids declaration `%D' with no type", + dname); + type = integer_type_node; } } @@ -8780,7 +9854,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } else if (return_type == return_conversion) { - if (comptypes (type, ctor_return_type, 1) == 0) + if (!same_type_p (type, ctor_return_type)) cp_error ("operator `%T' declared to return `%T'", ctor_return_type, type); else @@ -8801,8 +9875,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && TYPE_MAIN_VARIANT (type) == double_type_node) { RIDBIT_RESET (RID_LONG, specbits); - type = build_type_variant (long_double_type_node, TYPE_READONLY (type), - TYPE_VOLATILE (type)); + type = build_qualified_type (long_double_type_node, + CP_TYPE_QUALS (type)); } /* Check all other uses of type modifiers. */ @@ -8924,17 +9998,24 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (return_type == return_conversion && (RIDBIT_SETP (RID_CONST, specbits) - || RIDBIT_SETP (RID_VOLATILE, specbits))) - cp_error ("`operator %T' cannot be cv-qualified", + || RIDBIT_SETP (RID_VOLATILE, specbits) + || RIDBIT_SETP (RID_RESTRICT, specbits))) + cp_error ("qualifiers are not allowed on declaration of `operator %T'", ctor_return_type); /* Set CONSTP if this declaration is `const', whether by explicit specification or via a typedef. Likewise for VOLATILEP. */ - constp = !! RIDBIT_SETP (RID_CONST, specbits) + TYPE_READONLY (type); - volatilep = !! RIDBIT_SETP (RID_VOLATILE, specbits) + TYPE_VOLATILE (type); - type = build_type_variant (type, 0, 0); + constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type); + restrictp = + !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type); + volatilep = + !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type); + type_quals = ((constp ? TYPE_QUAL_CONST : 0) + | (restrictp ? TYPE_QUAL_RESTRICT : 0) + | (volatilep ? TYPE_QUAL_VOLATILE : 0)); + type = cp_build_qualified_type (type, type_quals); staticp = 0; inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); @@ -8954,6 +10035,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) friendp = RIDBIT_SETP (RID_FRIEND, specbits); RIDBIT_RESET (RID_FRIEND, specbits); + /* $7.1.2, Function specifiers */ + if (friendp && explicitp) + error ("only declarations of constructors can be `explicit'"); + if (RIDBIT_SETP (RID_MUTABLE, specbits)) { if (decl_context == PARM) @@ -9011,16 +10096,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && IS_SIGNATURE (current_class_type) && RIDBIT_NOTSETP (RID_TYPEDEF, specbits)) { - if (constp) + if (type_quals != TYPE_UNQUALIFIED) { - error ("`const' specified for signature member function `%s'", name); - constp = 0; - } - if (volatilep) - { - error ("`volatile' specified for signature member function `%s'", - name); - volatilep = 0; + error ("type qualifiers specified for signature member function `%s'", name); + type_quals = TYPE_UNQUALIFIED; } if (inlinep) { @@ -9107,7 +10186,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { /* It's common practice (and completely valid) to have a const be initialized and declared extern. */ - if (! constp) + if (!(type_quals & TYPE_QUAL_CONST)) warning ("`%s' initialized and declared `extern'", name); } else @@ -9129,6 +10208,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) Descend through it, creating more complex types, until we reach the declared identifier (or NULL_TREE, in an absolute declarator). */ + inner_attrs = NULL_TREE; + ignore_attrs = 0; + while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) { @@ -9175,8 +10257,32 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) quals = NULL_TREE; } } + + /* See the comment for the TREE_LIST case, below. */ + if (ignore_attrs) + ignore_attrs = 0; + else if (inner_attrs) + { + decl_attributes (type, inner_attrs, NULL_TREE); + inner_attrs = NULL_TREE; + } + switch (TREE_CODE (declarator)) { + case TREE_LIST: + { + /* We encode a declarator with embedded attributes using + a TREE_LIST. The attributes apply to the declarator + directly inside them, so we have to skip an iteration + before applying them to the type. If the declarator just + inside is the declarator-id, we apply the attrs to the + decl itself. */ + inner_attrs = TREE_PURPOSE (declarator); + ignore_attrs = 1; + declarator = TREE_VALUE (declarator); + } + break; + case ARRAY_REF: { register tree itype = NULL_TREE; @@ -9230,10 +10336,27 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) if (size == error_mark_node) type = error_mark_node; + else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + { + /* [dcl.array] + + the constant expressions that specify the bounds of + the arrays can be omitted only for the first member + of the sequence. */ + cp_error ("declaration of `%D' as multidimensional array", + dname); + cp_error ("must have bounds for all dimensions except the first"); + type = error_mark_node; + } if (type == error_mark_node) continue; + /* VC++ spells a zero-sized array with []. */ + if (size == NULL_TREE && decl_context == FIELD && ! staticp + && ! RIDBIT_SETP (RID_TYPEDEF, specbits)) + size = integer_zero_node; + if (size) { /* Must suspend_momentary here because the index @@ -9248,19 +10371,33 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0))) size = TREE_OPERAND (size, 0); - /* If this involves a template parameter, it'll be - constant, but we don't know what the value is yet. */ + /* 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) { - itype = make_node (INTEGER_TYPE); - TYPE_MIN_VALUE (itype) = size_zero_node; - TYPE_MAX_VALUE (itype) = build_min - (MINUS_EXPR, sizetype, size, integer_one_node); + /* 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; + } + + itype = build_index_type (build_min + (MINUS_EXPR, sizetype, size, integer_one_node)); goto dont_grok_size; } if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE) + && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE + && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE) { cp_error ("size of array `%D' has non-integer type", dname); @@ -9301,7 +10438,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) = fold (build_binary_op (MINUS_EXPR, cp_convert (index_type, size), cp_convert (index_type, - integer_one_node), 1)); + integer_one_node))); if (! TREE_CONSTANT (itype)) itype = variable_size (itype); else if (TREE_OVERFLOW (itype)) @@ -9328,15 +10465,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) resume_momentary (yes); } - /* 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 - is set correctly. */ - type = build_cplus_array_type (type, itype); - if (constp || volatilep) - type = cp_build_type_variant (type, constp, volatilep); - ctype = NULL_TREE; } break; @@ -9350,23 +10479,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* Declaring a function type. Make sure we have a valid type for the function to return. */ -#if 0 - /* Is this an error? Should they be merged into TYPE here? */ - if (pedantic && (constp || volatilep)) - pedwarn ("function declared to return const or volatile result"); -#else - /* Merge any constancy or volatility into the function return - type. */ - if (constp || volatilep) - { - type = cp_build_type_variant (type, constp, volatilep); - if (IS_AGGR_TYPE (type)) - build_pointer_type (type); - constp = 0; - volatilep = 0; - } -#endif + /* We now know that the TYPE_QUALS don't apply to the + decl, but to its return type. */ + type_quals = TYPE_UNQUALIFIED; /* Warn about some types functions can't return. */ @@ -9574,21 +10690,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* Merge any constancy or volatility into the target type for the pointer. */ - if (constp || volatilep) - { - /* A const or volatile signature pointer/reference is - pointing to a const or volatile object, i.e., the - `optr' is const or volatile, respectively, not the - signature pointer/reference itself. */ - if (! IS_SIGNATURE (type)) - { - type = cp_build_type_variant (type, constp, volatilep); - if (IS_AGGR_TYPE (type)) - build_pointer_type (type); - constp = 0; - volatilep = 0; - } - } + /* We now know that the TYPE_QUALS don't apply to the decl, + but to the target of the pointer. */ + type_quals = TYPE_UNQUALIFIED; if (IS_SIGNATURE (type)) { @@ -9599,8 +10703,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) cp_warning ("empty signature `%T' used in signature reference declaration", type); #if 0 - type = build_signature_reference_type (type, - constp, volatilep); + type = build_signature_reference_type (type); #else sorry ("signature reference"); return NULL_TREE; @@ -9612,31 +10715,18 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && TYPE_SIZE (type)) cp_warning ("empty signature `%T' used in signature pointer declaration", type); - type = build_signature_pointer_type (type, - constp, volatilep); + type = build_signature_pointer_type (type); } - constp = 0; - volatilep = 0; } else if (TREE_CODE (declarator) == ADDR_EXPR) { - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("cannot declare references to functions; use pointer to function instead"); - type = build_pointer_type (type); - } + if (TREE_CODE (type) == VOID_TYPE) + error ("invalid type: `void &'"); else - { - if (TREE_CODE (type) == VOID_TYPE) - error ("invalid type: `void &'"); - else - type = build_reference_type (type); - } + type = build_reference_type (type); } else if (TREE_CODE (type) == METHOD_TYPE) - { - type = build_ptrmemfunc_type (build_pointer_type (type)); - } + type = build_ptrmemfunc_type (build_pointer_type (type)); else type = build_pointer_type (type); @@ -9647,25 +10737,37 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { register tree typemodlist; int erred = 0; + + constp = 0; + volatilep = 0; + restrictp = 0; for (typemodlist = TREE_TYPE (declarator); typemodlist; typemodlist = TREE_CHAIN (typemodlist)) { - if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_CONST]) + tree qualifier = TREE_VALUE (typemodlist); + + if (qualifier == ridpointers[(int) RID_CONST]) constp++; - else if (TREE_VALUE (typemodlist) == ridpointers[(int) RID_VOLATILE]) + else if (qualifier == ridpointers[(int) RID_VOLATILE]) volatilep++; + else if (qualifier == ridpointers[(int) RID_RESTRICT]) + restrictp++; else if (!erred) { erred = 1; - error ("invalid type modifier within %s declarator", - TREE_CODE (declarator) == ADDR_EXPR - ? "reference" : "pointer"); + error ("invalid type modifier within pointer declarator"); } } 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) + | (volatilep ? TYPE_QUAL_VOLATILE : 0)); if (TREE_CODE (declarator) == ADDR_EXPR && (constp || volatilep)) { @@ -9673,8 +10775,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) pedwarn ("discarding `const' applied to a reference"); if (volatilep) pedwarn ("discarding `volatile' applied to a reference"); - constp = volatilep = 0; + type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); } + type = cp_build_qualified_type (type, type_quals); } declarator = TREE_OPERAND (declarator, 0); ctype = NULL_TREE; @@ -9718,14 +10821,14 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) && uses_template_parms (current_class_type)) { tree args = current_template_args (); - type = tsubst (type, args, NULL_TREE); + type = tsubst (type, args, /*complain=*/1, 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 (1); + pop_nested_class (); TREE_COMPLEXITY (declarator) = current_class_depth; } else @@ -9743,7 +10846,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) ctype = TREE_OPERAND (declarator, 0); t = ctype; - while (t != NULL_TREE) + while (t != NULL_TREE && CLASS_TYPE_P (t)) { if (CLASSTYPE_TEMPLATE_INFO (t) && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) @@ -9779,8 +10882,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { if (current_class_type == NULL_TREE || friendp) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); + type = build_cplus_method_type (ctype, TREE_TYPE (type), + TYPE_ARG_TYPES (type)); else { cp_error ("cannot declare member function `%T::%s' within `%T'", @@ -9808,10 +10911,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { if (TREE_CODE (type) == FUNCTION_TYPE) type - = build_cplus_method_type (build_type_variant (ctype, - constp, - volatilep), - TREE_TYPE (type), + = build_cplus_method_type (ctype, TREE_TYPE (type), TYPE_ARG_TYPES (type)); } else @@ -9834,7 +10934,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) else { if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), TREE_TYPE (type), TYPE_ARG_TYPES (type)); + type = build_cplus_method_type (ctype, TREE_TYPE (type), + TYPE_ARG_TYPES (type)); else type = build_offset_type (ctype, type); } @@ -9861,19 +10962,28 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } - if (explicitp == 1) + /* See the comment for the TREE_LIST case, above. */ + if (inner_attrs) { - error ("only constructors can be declared `explicit'"); - explicitp = 0; + if (! ignore_attrs) + decl_attributes (type, inner_attrs, NULL_TREE); + else if (attrlist) + TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist)); + else + attrlist = build_decl_list (NULL_TREE, inner_attrs); } /* Now TYPE has the actual type. */ - /* If this is declaring a typedef name, return a TYPE_DECL. */ + if (explicitp == 1) + { + error ("only constructors can be declared `explicit'"); + explicitp = 0; + } if (RIDBIT_SETP (RID_MUTABLE, specbits)) { - if (constp) + if (type_quals & TYPE_QUAL_CONST) { error ("const `%s' cannot be declared `mutable'", name); RIDBIT_RESET (RID_MUTABLE, specbits); @@ -9885,20 +10995,35 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } + if (declarator == NULL_TREE + || TREE_CODE (declarator) == IDENTIFIER_NODE + || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR + && (TREE_CODE (type) == FUNCTION_TYPE + || TREE_CODE (type) == METHOD_TYPE))) + /* OK */; + else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) + { + cp_error ("template-id `%D' used as a declarator", declarator); + declarator = dname; + } + else + /* Unexpected declarator format. */ + my_friendly_abort (990210); + + /* If this is declaring a typedef name, return a TYPE_DECL. */ + if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME) { tree decl; /* Note that the grammar rejects storage classes in typenames, fields or parameters. */ - if (constp || volatilep) - type = cp_build_type_variant (type, constp, volatilep); if (current_lang_name == lang_name_java) TYPE_FOR_JAVA (type) = 1; if (decl_context == FIELD) { - if (declarator == current_class_name) + if (declarator == constructor_name (current_class_type)) cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class", declarator); decl = build_lang_decl (TYPE_DECL, declarator, type); @@ -9921,18 +11046,32 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) refer to it, so nothing needs know about the name change. The TYPE_NAME field was filled in by build_struct_xref. */ if (type != error_mark_node - && !TYPE_READONLY (type) && !TYPE_VOLATILE (type) && TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) { + tree oldname = TYPE_NAME (type); + tree t; + + /* FIXME: This is bogus; we should not be doing this for + cv-qualified types. */ + /* Replace the anonymous name with the real name everywhere. */ lookup_tag_reverse (type, declarator); - TYPE_NAME (type) = decl; + for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + if (TYPE_NAME (t) == oldname) + TYPE_NAME (t) = decl; if (TYPE_LANG_SPECIFIC (type)) TYPE_WAS_ANONYMOUS (type) = 1; + /* If this is a typedef within a template class, the nested + type is a (non-primary) template. The name for the + template needs updating as well. */ + if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) + DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) + = TYPE_IDENTIFIER (type); + /* XXX Temporarily set the scope. When returning, start_decl expects it as NULL_TREE, and will then then set it using pushdecl. */ @@ -9946,6 +11085,9 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) DECL_ASSEMBLER_NAME (decl) = get_identifier (build_overload_name (type, 1, 1)); DECL_CONTEXT (decl) = NULL_TREE; + + /* FIXME remangle member functions; member functions of a + type with external linkage have external linkage. */ } if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE) @@ -9971,9 +11113,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; if (RIDBIT_SETP (RID_MUTABLE, specbits)) - { - error ("non-object member `%s' cannot be declared mutable", name); - } + error ("non-object member `%s' cannot be declared mutable", name); bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); @@ -10003,21 +11143,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { /* Note that the grammar rejects storage classes in typenames, fields or parameters. */ - if (constp || volatilep) + if (type_quals != TYPE_UNQUALIFIED) { if (IS_SIGNATURE (type)) - error ("`const' or `volatile' specified with signature type"); - else - type = cp_build_type_variant (type, constp, volatilep); + error ("type qualifiers specified for signature type"); + type_quals = TYPE_UNQUALIFIED; } /* Special case: "friend class foo" looks like a TYPENAME context. */ if (friendp) { - if (volatilep) + if (type_quals != TYPE_UNQUALIFIED) { - cp_error ("`volatile' specified for friend class declaration"); - volatilep = 0; + cp_error ("type qualifiers specified for friend class declaration"); + type_quals = TYPE_UNQUALIFIED; } if (inlinep) { @@ -10084,36 +11223,38 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* Now create the decl, which may be a VAR_DECL, a PARM_DECL or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ + if (decl_context == PARM || decl_context == CATCHPARM) + { + if (ctype || in_namespace) + error ("cannot use `::' in parameter declaration"); + + /* A parameter declared as an array of T is really a pointer to T. + One declared as a function is really a pointer to a function. + One declared as a member is really a pointer to member. */ + + if (TREE_CODE (type) == ARRAY_TYPE) + { + /* Transfer const-ness of array into that of type pointed to. */ + type = build_pointer_type (TREE_TYPE (type)); + type_quals = TYPE_UNQUALIFIED; + } + else if (TREE_CODE (type) == FUNCTION_TYPE) + type = build_pointer_type (type); + else if (TREE_CODE (type) == OFFSET_TYPE) + type = build_pointer_type (type); + else if (TREE_CODE (type) == VOID_TYPE && declarator) + { + error ("declaration of `%s' as void", name); + return NULL_TREE; + } + } + { register tree decl; if (decl_context == PARM) { - if (ctype) - error ("cannot use `::' in parameter declaration"); - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. - One declared as a member is really a pointer to member. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type pointed to. */ - type = build_pointer_type - (cp_build_type_variant (TREE_TYPE (type), constp, volatilep)); - volatilep = constp = 0; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == OFFSET_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == VOID_TYPE && declarator) - { - error ("declaration of `%s' as void", name); - return NULL_TREE; - } - - decl = build_decl (PARM_DECL, declarator, complete_type (type)); + decl = build_decl (PARM_DECL, declarator, type); bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); @@ -10143,6 +11284,12 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) are error_mark_node, for example. */ decl = NULL_TREE; } + else if (in_namespace && !friendp) + { + /* Something like struct S { int N::j; }; */ + cp_error ("invalid use of `::'"); + decl = NULL_TREE; + } else if (TREE_CODE (type) == FUNCTION_TYPE) { int publicp = 0; @@ -10191,8 +11338,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } } else if (staticp < 2) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); + type = build_cplus_method_type (ctype, TREE_TYPE (type), + TYPE_ARG_TYPES (type)); } /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ @@ -10204,19 +11351,48 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) TREE_CODE (declarator) != TEMPLATE_ID_EXPR ? declarator : dname, declarator, - virtualp, flags, quals, raises, attrlist, + virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, publicp, inlinep, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) - return NULL_TREE; + return decl; #if 0 /* This clobbers the attrs stored in `decl' from `attrlist'. */ /* The decl and setting of decl_machine_attr is also turned off. */ decl = build_decl_attribute_variant (decl, decl_machine_attr); #endif + /* [class.conv.ctor] + + A constructor declared without the function-specifier + explicit that can be called with a single parameter + specifies a conversion from the type of its first + parameter to the type of its class. Such a constructor + is called a converting constructor. */ if (explicitp == 2) DECL_NONCONVERTING_P (decl) = 1; + else if (DECL_CONSTRUCTOR_P (decl)) + { + /* The constructor can be called with exactly one + parameter if there is at least one parameter, and + any subsequent parameters have default arguments. + We don't look at the first parameter, which is + really just the `this' parameter for the new + object. */ + tree arg_types = + TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))); + + /* Skip the `in_chrg' argument too, if present. */ + if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl))) + arg_types = TREE_CHAIN (arg_types); + + if (arg_types == void_list_node + || (arg_types + && TREE_CHAIN (arg_types) + && TREE_CHAIN (arg_types) != void_list_node + && !TREE_PURPOSE (TREE_CHAIN (arg_types)))) + DECL_NONCONVERTING_P (decl) = 1; + } } else if (TREE_CODE (type) == METHOD_TYPE) { @@ -10225,7 +11401,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) /* All method decls are public, so tell grokfndecl to set TREE_PUBLIC, also. */ decl = grokfndecl (ctype, type, declarator, declarator, - virtualp, flags, quals, raises, attrlist, + virtualp, flags, quals, raises, friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) @@ -10273,9 +11449,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { tree t = NULL_TREE; if (decl && DECL_NAME (decl)) - t = do_friend (ctype, declarator, decl, - last_function_parms, flags, quals, - funcdef_flag); + { + 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; @@ -10303,42 +11491,39 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) the rest of the compiler does not correctly handle the initialization unless the member is static so we make it static below. */ - cp_pedwarn ("ANSI C++ forbids initialization of %s `%D'", - constp ? "const member" : "member", + cp_pedwarn ("ANSI C++ forbids initialization of member `%D'", declarator); cp_pedwarn ("making `%D' static", declarator); staticp = 1; } - /* Motion 10 at San Diego: If a static const integral data - member is initialized with an integral constant - expression, the initializer may appear either in the - declaration (within the class), or in the definition, - but not both. If it appears in the class, the member is - a member constant. The file-scope definition is always - required. */ - if (! constp) - /* According to Mike Stump, we generate bad code for - this case, so we might as well always make it an - error. */ - cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'", - declarator); - - if (pedantic && ! INTEGRAL_TYPE_P (type) - && !uses_template_parms (type)) - cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", declarator, type); + if (uses_template_parms (type)) + /* We'll check at instantiation time. */ + ; + else if (check_static_variable_definition (declarator, + type)) + /* If we just return the declaration, crashes + will sometimes occur. We therefore return + void_type_node, as if this was a friend + declaration, to cause callers to completely + ignore this declaration. */ + return void_type_node; } + /* 9.2p13 [class.mem] */ + if (declarator == constructor_name (current_class_type) + /* Divergence from the standard: In extern "C", we + allow non-static data members here, because C does + and /usr/include/netinet/in.h uses that. */ + && (staticp || ! in_system_header)) + cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class", + declarator); + if (staticp) { - /* ANSI C++ Apr '95 wp 9.2 */ - if (declarator == current_class_name) - cp_pedwarn ("ANSI C++ forbids static member `%D' with same name as enclosing class", - declarator); - /* C++ allows static class members. All other work for this is done by grokfield. - This VAR_DECL is built by build_lang_field_decl. + This VAR_DCL is built by build_lang_field_decl. All other VAR_DECLs are built by build_decl. */ decl = build_lang_field_decl (VAR_DECL, declarator, type); TREE_STATIC (decl) = 1; @@ -10398,22 +11583,10 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) error ("virtual non-class function `%s'", name); virtualp = 0; } - - if (current_lang_name == lang_name_cplusplus - && ! processing_template_decl - && ! MAIN_NAME_P (original_name) - && ! (IDENTIFIER_LENGTH (original_name) > 10 - && IDENTIFIER_POINTER (original_name)[0] == '_' - && IDENTIFIER_POINTER (original_name)[1] == '_' - && strncmp (IDENTIFIER_POINTER (original_name)+2, "builtin_", 8) == 0)) - /* Plain overloading: will not be grok'd by grokclassfn. */ - if (name_mangling_version < 1 - || TREE_CODE (declarator) != TEMPLATE_ID_EXPR) - declarator = build_decl_overload (dname, TYPE_ARG_TYPES (type), 0); } else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) - type = build_cplus_method_type (build_type_variant (ctype, constp, volatilep), - TREE_TYPE (type), TYPE_ARG_TYPES (type)); + type = build_cplus_method_type (ctype, TREE_TYPE (type), + TYPE_ARG_TYPES (type)); /* Record presence of `static'. */ publicp = (ctype != NULL_TREE @@ -10421,23 +11594,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) || !RIDBIT_SETP (RID_STATIC, specbits)); decl = grokfndecl (ctype, type, original_name, declarator, - virtualp, flags, quals, raises, attrlist, + virtualp, flags, quals, raises, 1, friendp, publicp, inlinep, funcdef_flag, template_count, in_namespace); if (decl == NULL_TREE) return NULL_TREE; - /* Among other times, could occur from check_explicit_specialization - returning an error_mark_node. */ - if (decl == error_mark_node) - return error_mark_node; - - if (ctype == NULL_TREE && DECL_LANGUAGE (decl) != lang_c - && (! DECL_USE_TEMPLATE (decl) || - name_mangling_version < 1)) - DECL_ASSEMBLER_NAME (decl) = declarator; - if (staticp == 1) { int illegal_static = 0; @@ -10467,35 +11630,11 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) { /* It's a variable. */ - if (decl_context == CATCHPARM) - { - if (ctype) - { - ctype = NULL_TREE; - error ("cannot use `::' in parameter declaration"); - } - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. - One declared as a member is really a pointer to member. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type - pointed to. */ - type = build_pointer_type - (cp_build_type_variant (TREE_TYPE (type), constp, volatilep)); - volatilep = constp = 0; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == OFFSET_TYPE) - type = build_pointer_type (type); - } - /* An uninitialized decl with `extern' is a reference. */ decl = grokvardecl (type, declarator, &specbits, - initialized, constp, in_namespace); + initialized, + (type_quals & TYPE_QUAL_CONST) != 0, + in_namespace); bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, inlinep, friendp, raises != NULL_TREE); @@ -10540,14 +11679,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) DECL_THIS_STATIC (decl) = 1; /* Record constancy and volatility. */ - - if (constp) - TREE_READONLY (decl) = TREE_CODE (type) != REFERENCE_TYPE; - if (volatilep) - { - TREE_SIDE_EFFECTS (decl) = 1; - TREE_THIS_VOLATILE (decl) = 1; - } + /* FIXME: Disallow `restrict' pointer-to-member declarations. */ + c_apply_type_quals_to_decl (type_quals, decl); return decl; } @@ -10580,18 +11713,14 @@ parmlist_is_exprlist (exprs) return 1; } -/* Subroutine of `grokparms'. In a fcn definition, arg types must - be complete. - - C++: also subroutine of `start_function'. */ +/* 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; { - if (processing_template_decl) - return; - while (parms) { tree type = TREE_TYPE (parms); @@ -10604,35 +11733,110 @@ require_complete_types_for_parms (parms) error ("parameter has incomplete type"); TREE_TYPE (parms) = error_mark_node; } -#if 0 - /* 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. */ - /* This is not the right behavior for C++, but not having - it is also probably wrong. */ 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 (TYPE_SIZE (type) == NULL_TREE) - { - if (DECL_NAME (parm) != NULL_TREE) - warning ("parameter `%s' points to incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parm))); - else - warning ("parameter points to incomplete type"); - } - } -#endif + layout_decl (parms, 0); + parms = TREE_CHAIN (parms); } } +/* Returns DECL if DECL is a local variable (or parameter). Returns + NULL_TREE otherwise. */ + +static tree +local_variable_p (t) + tree t; +{ + if ((TREE_CODE (t) == VAR_DECL + /* A VAR_DECL with a context that is a _TYPE is a static data + member. */ + && !TYPE_P (CP_DECL_CONTEXT (t)) + /* Any other non-local variable must be at namespace scope. */ + && TREE_CODE (CP_DECL_CONTEXT (t)) != NAMESPACE_DECL) + || (TREE_CODE (t) == PARM_DECL)) + return t; + + return NULL_TREE; +} + +/* Check that ARG, which is a default-argument expression for a + parameter DECL, is legal. Returns ARG, or ERROR_MARK_NODE, if + something goes wrong. DECL may also be a _TYPE node, rather than a + DECL, if there is no DECL available. */ + +tree +check_default_argument (decl, arg) + tree decl; + tree arg; +{ + tree var; + tree decl_type; + + if (TREE_CODE (arg) == DEFAULT_ARG) + /* We get a DEFAULT_ARG when looking at an in-class declaration + with a default argument. Ignore the argument for now; we'll + deal with it after the class is complete. */ + return arg; + + if (processing_template_decl || uses_template_parms (arg)) + /* We don't do anything checking until instantiation-time. Note + that there may be uninstantiated arguments even for an + instantiated function, since default arguments are not + instantiated until they are needed. */ + return arg; + + if (TYPE_P (decl)) + { + decl_type = decl; + decl = NULL_TREE; + } + else + decl_type = TREE_TYPE (decl); + + if (arg == error_mark_node + || decl == error_mark_node + || TREE_TYPE (arg) == error_mark_node + || decl_type == error_mark_node) + /* Something already went wrong. There's no need to check + further. */ + return error_mark_node; + + /* [dcl.fct.default] + + A default argument expression is implicitly converted to the + parameter type. */ + if (!TREE_TYPE (arg) + || !can_convert_arg (decl_type, TREE_TYPE (arg), arg)) + { + if (decl) + cp_error ("default argument for `%#D' has type `%T'", + decl, TREE_TYPE (arg)); + else + cp_error ("default argument for paramter of type `%T' has type `%T'", + decl_type, TREE_TYPE (arg)); + + return error_mark_node; + } + + /* [dcl.fct.default] + + Local variables shall not be used in default argument + expressions. + + The keyword `this' shall not be used in a default argument of a + member function. */ + var = search_tree (arg, local_variable_p); + if (var) + { + cp_error ("default argument `%E' uses local variable `%D'", + arg, var); + return error_mark_node; + } + + /* All is well. */ + return arg; +} + /* Decode the list of parameter types for a function type. Given the list of things declared inside the parens, return a list of types. @@ -10725,9 +11929,13 @@ grokparms (first_parm, funcdef_flag) TREE_PURPOSE (decl), PARM, init != NULL_TREE, NULL_TREE); - if (! decl) + if (! decl || TREE_TYPE (decl) == error_mark_node) continue; - type = TREE_TYPE (decl); + + /* Top-level qualifiers on the parameters are + ignored for function types. */ + type = TYPE_MAIN_VARIANT (TREE_TYPE (decl)); + if (TREE_CODE (type) == VOID_TYPE) decl = void_type_node; else if (TREE_CODE (type) == METHOD_TYPE) @@ -10766,6 +11974,18 @@ grokparms (first_parm, funcdef_flag) signature_error (decl, type); any_error = 1; /* Seems like a good idea. */ } + else if (POINTER_TYPE_P (type)) + { + tree t = type; + while (POINTER_TYPE_P (t) + || (TREE_CODE (t) == ARRAY_TYPE + && TYPE_DOMAIN (t) != NULL_TREE)) + t = TREE_TYPE (t); + if (TREE_CODE (t) == ARRAY_TYPE) + cp_error ("parameter type `%T' includes %s to array of unknown bound", + type, + TYPE_PTR_P (type) ? "pointer" : "reference"); + } } if (TREE_CODE (decl) == VOID_TYPE) @@ -10794,43 +12014,10 @@ grokparms (first_parm, funcdef_flag) && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) DECL_ARG_TYPE (decl) = integer_type_node; #endif - if (!any_error) + if (!any_error && init) { - if (init) - { - any_init++; - if (TREE_CODE (init) == SAVE_EXPR) - PARM_DECL_EXPR (init) = 1; - else if (processing_template_decl) - ; - /* Unparsed default arg from in-class decl. */ - else if (TREE_CODE (init) == DEFAULT_ARG) - ; - else if (TREE_CODE (init) == VAR_DECL - || TREE_CODE (init) == PARM_DECL) - { - if (IDENTIFIER_LOCAL_VALUE (DECL_NAME (init))) - { - /* ``Local variables may not be used in default - argument expressions.'' dpANSI C++ 8.2.6 */ - /* If extern int i; within a function is not - considered a local variable, then this code is - wrong. */ - cp_error ("local variable `%D' may not be used as a default argument", init); - any_error = 1; - } - else if (TREE_READONLY_DECL_P (init)) - init = decl_constant_value (init); - } - else - init = require_instantiated_type (type, init, integer_zero_node); - if (! processing_template_decl - && init != error_mark_node - && TREE_CODE (init) != DEFAULT_ARG - && ! can_convert_arg (type, TREE_TYPE (init), init)) - cp_pedwarn ("invalid type `%T' for default argument to `%#D'", - TREE_TYPE (init), decl); - } + any_init++; + init = check_default_argument (decl, init); } else init = NULL_TREE; @@ -10875,10 +12062,6 @@ grokparms (first_parm, funcdef_flag) last_function_parms = decls; - /* In a fcn definition, arg types must be complete. */ - if (funcdef_flag > 0) - require_complete_types_for_parms (last_function_parms); - return result; } @@ -10943,19 +12126,45 @@ grok_ctor_properties (ctype, decl) parmtype = TREE_VALUE (parmtypes); } + /* [class.copy] + + A non-template constructor for class X is a copy constructor if + its first parameter is of type X&, const X&, volatile X& or const + volatile X&, and either there are no other parameters or else all + other parameters have default arguments. */ if (TREE_CODE (parmtype) == REFERENCE_TYPE && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype && (TREE_CHAIN (parmtypes) == NULL_TREE || TREE_CHAIN (parmtypes) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (parmtypes)))) + || TREE_PURPOSE (TREE_CHAIN (parmtypes))) + && !(DECL_TEMPLATE_INSTANTIATION (decl) + && is_member_template (DECL_TI_TEMPLATE (decl)))) { TYPE_HAS_INIT_REF (ctype) = 1; - if (TYPE_READONLY (TREE_TYPE (parmtype))) + if (CP_TYPE_CONST_P (TREE_TYPE (parmtype))) TYPE_HAS_CONST_INIT_REF (ctype) = 1; } + /* [class.copy] + + A declaration of a constructor for a class X is ill-formed if its + first parameter is of type (optionally cv-qualified) X and either + there are no other parameters or else all other parameters have + default arguments. + + We *don't* complain about member template instantiations that + have this form, though; they can occur as we try to decide what + constructor to use during overload resolution. Since overload + resolution will never prefer such a constructor to the + non-template copy constructor (which is either explicitly or + implicitly defined), there's no need to worry about their + existence. Theoretically, they should never even be + instantiated, but that's hard to forestall. */ else if (TYPE_MAIN_VARIANT (parmtype) == ctype - && TREE_CHAIN (parmtypes) != NULL_TREE - && TREE_CHAIN (parmtypes) == void_list_node) + && (TREE_CHAIN (parmtypes) == NULL_TREE + || TREE_CHAIN (parmtypes) == void_list_node + || TREE_PURPOSE (TREE_CHAIN (parmtypes))) + && !(DECL_TEMPLATE_INSTANTIATION (decl) + && is_member_template (DECL_TI_TEMPLATE (decl)))) { cp_error ("invalid constructor; you probably meant `%T (const %T&)'", ctype, ctype); @@ -10992,7 +12201,7 @@ unary_op_p (name) return (name == ansi_opname [(int) TRUTH_NOT_EXPR] || name == ansi_opname [(int) BIT_NOT_EXPR] || name == ansi_opname [(int) COMPONENT_REF] - || OPERATOR_TYPENAME_P (name)); + || IDENTIFIER_TYPENAME_P (name)); } /* Do a little sanity-checking on how they declared their operator. */ @@ -11011,8 +12220,16 @@ grok_op_properties (decl, virtualp, friendp) if (! friendp) { - if (name == ansi_opname[(int) MODIFY_EXPR]) - TYPE_HAS_ASSIGNMENT (current_class_type) = 1; + /* [class.copy] + + A user-declared copy assignment operator X::operator= is a + non-static non-template member function of class X with + exactly one parameter of type X, X&, const X&, volatile X& or + const volatile X&. */ + if (name == ansi_opname[(int) MODIFY_EXPR] + && !(DECL_TEMPLATE_INSTANTIATION (decl) + && is_member_template (DECL_TI_TEMPLATE (decl)))) + ; else if (name == ansi_opname[(int) CALL_EXPR]) TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1; else if (name == ansi_opname[(int) ARRAY_REF]) @@ -11075,7 +12292,7 @@ grok_op_properties (decl, virtualp, friendp) an enumeration, or a reference to an enumeration. 13.4.0.6 */ if (! methodp || DECL_STATIC_FUNCTION_P (decl)) { - if (OPERATOR_TYPENAME_P (name) + if (IDENTIFIER_TYPENAME_P (name) || name == ansi_opname[(int) CALL_EXPR] || name == ansi_opname[(int) MODIFY_EXPR] || name == ansi_opname[(int) COMPONENT_REF] @@ -11121,7 +12338,7 @@ grok_op_properties (decl, virtualp, friendp) else if (! friendp) { int ref = (TREE_CODE (t) == REFERENCE_TYPE); - char *what = 0; + const char *what = 0; if (ref) t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); @@ -11155,7 +12372,7 @@ grok_op_properties (decl, virtualp, friendp) { TYPE_HAS_ASSIGN_REF (current_class_type) = 1; if (TREE_CODE (parmtype) != REFERENCE_TYPE - || TYPE_READONLY (TREE_TYPE (parmtype))) + || CP_TYPE_CONST_P (TREE_TYPE (parmtype))) TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1; } } @@ -11175,7 +12392,7 @@ grok_op_properties (decl, virtualp, friendp) if ((name == ansi_opname[(int) POSTINCREMENT_EXPR] || name == ansi_opname[(int) POSTDECREMENT_EXPR]) && ! processing_template_decl - && TREE_VALUE (TREE_CHAIN (argtypes)) != integer_type_node) + && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node)) { if (methodp) cp_error ("postfix `%D' must take `int' as its argument", @@ -11207,14 +12424,14 @@ grok_op_properties (decl, virtualp, friendp) if (list_length (argtypes) == 2) { if (TREE_CODE (ret) != REFERENCE_TYPE - || !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), - arg, 1)) + || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), + arg)) cp_warning ("prefix `%D' should return `%T'", decl, build_reference_type (arg)); } else { - if (!comptypes (TYPE_MAIN_VARIANT (ret), arg, 1)) + if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) cp_warning ("postfix `%D' should return `%T'", decl, arg); } } @@ -11276,6 +12493,27 @@ grok_op_properties (decl, virtualp, friendp) } } +static const char * +tag_name (code) + enum tag_types code; +{ + switch (code) + { + case record_type: + return "struct"; + case class_type: + return "class"; + case union_type: + return "union "; + case enum_type: + return "enum"; + case signature_type: + return "signature"; + default: + my_friendly_abort (981122); + } +} + /* Get the struct, enum or union (CODE says which) with tag NAME. Define the tag as a forward-reference if it is not defined. @@ -11287,18 +12525,19 @@ grok_op_properties (decl, virtualp, friendp) scope.) */ tree -xref_tag (code_type_node, name, binfo, globalize) +xref_tag (code_type_node, name, globalize) tree code_type_node; - tree name, binfo; + tree name; int globalize; { enum tag_types tag_code; enum tree_code code; int temp = 0; register tree ref, t; - struct binding_level *b = inner_binding_level; + struct binding_level *b = current_binding_level; int got_type = 0; tree attributes = NULL_TREE; + tree context = NULL_TREE; /* If we are called from the parser, code_type_node will sometimes be a TREE_LIST. This indicates that the user wrote @@ -11338,37 +12577,41 @@ xref_tag (code_type_node, name, binfo, globalize) } else t = IDENTIFIER_TYPE_VALUE (name); + if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM) t = NULL_TREE; if (! globalize) { - if (pedantic && t && (TREE_CODE (t) == TEMPLATE_TYPE_PARM - || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)) - { - cp_pedwarn ("redeclaration of template type-parameter `%T'", name); - cp_pedwarn_at (" previously declared here", t); - } - if (t && TYPE_CONTEXT (t) && got_type) - ref = t; - else - { - /* 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); - } + /* 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); } else { if (t) - ref = t; - else - ref = lookup_tag (code, name, b, 0); + { + /* [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 != TYPE_MAIN_VARIANT (t) + || (CLASS_TYPE_P (t) && TYPE_WAS_ANONYMOUS (t))) + cp_pedwarn ("using typedef-name `%D' after `%s'", + TYPE_NAME (t), tag_name (tag_code)); + else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) + cp_error ("using template type parameter `%T' after `%s'", + t, tag_name (tag_code)); + ref = t; + } + else + ref = lookup_tag (code, name, b, 0); + if (! ref) { - /* Try finding it as a type declaration. If that wins, use it. */ + /* Try finding it as a type declaration. If that wins, + use it. */ ref = lookup_name (name, 1); if (ref != NULL_TREE @@ -11385,6 +12628,50 @@ xref_tag (code_type_node, name, binfo, globalize) else ref = NULL_TREE; } + + if (ref && current_class_type + && template_class_depth (current_class_type) + && PROCESSING_REAL_TEMPLATE_DECL_P ()) + { + /* Since GLOBALIZE is non-zero, we are not looking at a + definition of this tag. Since, in addition, we are currently + processing a (member) template declaration of a template + class, we must be very careful; consider: + + template + struct S1 + + template + struct S2 + { template + friend struct S1; }; + + Here, the S2::S1 declaration should not be confused with the + outer declaration. In particular, the inner version should + have a template parameter of level 2, not level 1. This + would be particularly important if the member declaration + were instead: + + template friend struct S1; + + say, when we should tsubst into `U' when instantiating + S2. On the other hand, when presented with: + + template + struct S1 { + template + struct S2 {}; + template + friend struct S2; + }; + + we must find the inner binding eventually. We + 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; + } } push_obstacks_nochange (); @@ -11430,6 +12717,7 @@ xref_tag (code_type_node, name, binfo, globalize) struct binding_level *old_b = class_binding_level; ref = make_lang_type (code); + TYPE_CONTEXT (ref) = context; if (tag_code == signature_type) { @@ -11466,9 +12754,6 @@ xref_tag (code_type_node, name, binfo, globalize) redeclare_class_template (ref, current_template_parms); } - if (binfo) - xref_basetypes (code_type_node, name, ref, binfo); - /* Until the type is defined, tentatively accept whatever structure tag the user hands us. */ if (TYPE_SIZE (ref) == NULL_TREE @@ -11505,9 +12790,15 @@ xref_tag_from_type (old, id, globalize) if (id == NULL_TREE) id = TYPE_IDENTIFIER (old); - return xref_tag (code_type_node, id, NULL_TREE, globalize); + return xref_tag (code_type_node, id, globalize); } +/* REF is a type (named NAME), for which we have just seen some + baseclasses. BINFO 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, + struct, or union. */ + void xref_basetypes (code_type_node, name, ref, binfo) tree code_type_node; @@ -11517,6 +12808,8 @@ xref_basetypes (code_type_node, name, ref, binfo) /* 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; + int i, len; enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); @@ -11529,6 +12822,13 @@ xref_basetypes (code_type_node, name, ref, binfo) len = list_length (binfo); push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref)); + /* 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)); + SET_CLASSTYPE_MARKED (ref); BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len); @@ -11567,16 +12867,14 @@ xref_basetypes (code_type_node, name, ref, binfo) GNU_xref_hier (name, basetype, via_public, via_virtual, 0); -#if 1 /* This code replaces similar code in layout_basetypes. We put the complete_type first for implicit `typename'. */ - if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE + if (TYPE_SIZE (basetype) == NULL_TREE && ! (current_template_parms && uses_template_parms (basetype))) { cp_error ("base class `%T' has incomplete type", basetype); continue; } -#endif else { if (CLASSTYPE_MARKED (basetype)) @@ -11600,9 +12898,12 @@ xref_basetypes (code_type_node, name, ref, binfo) individual inheritance contains flags which say what the `accessibility' of that particular inheritance is.) */ - base_binfo = make_binfo (integer_zero_node, basetype, - TYPE_BINFO_VTABLE (basetype), - TYPE_BINFO_VIRTUALS (basetype), NULL_TREE); + base_binfo + = make_binfo (integer_zero_node, basetype, + CLASS_TYPE_P (basetype) + ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE, + CLASS_TYPE_P (basetype) + ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE); TREE_VEC_ELT (binfos, i) = base_binfo; TREE_VIA_PUBLIC (base_binfo) = via_public; @@ -11610,6 +12911,10 @@ xref_basetypes (code_type_node, name, ref, binfo) 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 @@ -11620,9 +12925,12 @@ xref_basetypes (code_type_node, name, ref, binfo) TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; } - TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype); - TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); - CLASSTYPE_LOCAL_TYPEDECLS (ref) |= CLASSTYPE_LOCAL_TYPEDECLS (basetype); + if (CLASS_TYPE_P (basetype)) + { + TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype); + TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); + } + i += 1; } } @@ -11634,8 +12942,14 @@ xref_basetypes (code_type_node, name, ref, binfo) if (i > 1) TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; else if (i == 1) - TYPE_USES_MULTIPLE_INHERITANCE (ref) - = TYPE_USES_MULTIPLE_INHERITANCE (BINFO_TYPE (TREE_VEC_ELT (binfos, 0))); + { + tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0)); + + if (CLASS_TYPE_P (basetype)) + TYPE_USES_MULTIPLE_INHERITANCE (ref) + = TYPE_USES_MULTIPLE_INHERITANCE (basetype); + } + if (TYPE_USES_MULTIPLE_INHERITANCE (ref)) TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; @@ -11644,12 +12958,14 @@ xref_basetypes (code_type_node, name, ref, binfo) CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i))); CLEAR_CLASSTYPE_MARKED (ref); + /* Now that we know all the base-classes, set up the list of virtual + bases. */ + CLASSTYPE_VBASECLASSES (ref) = get_vbase_types (ref); + pop_obstacks (); } -tree current_local_enum = NULL_TREE; - /* Begin compiling the definition of an enumeration type. NAME is its name (or null if anonymous). Returns the type object, as yet incomplete. @@ -11661,15 +12977,11 @@ start_enum (name) tree name; { register tree enumtype = NULL_TREE; - struct binding_level *b = inner_binding_level; + struct binding_level *b = current_binding_level; /* We are wasting space here and putting these on the permanent_obstack so that typeid(local enum) will work correctly. */ -#if 0 - if (processing_template_decl && current_function_decl) -#endif - - end_temporary_allocation (); + push_obstacks (&permanent_obstack, &permanent_obstack); /* If this is the real definition for a previous forward reference, fill in the contents in the same object that used to be the @@ -11686,14 +12998,9 @@ start_enum (name) pushtag (name, enumtype, 0); } - if (b->pseudo_global) - cp_error ("template declaration of `%#T'", enumtype); - if (current_class_type) TREE_ADDRESSABLE (b->tags) = 1; - current_local_enum = NULL_TREE; - /* We don't copy this value because build_enumerator needs to do it. */ enum_next_value = integer_zero_node; enum_overflow = 0; @@ -11708,39 +13015,63 @@ start_enum (name) Returns ENUMTYPE. */ tree -finish_enum (enumtype, values) - register tree enumtype, values; +finish_enum (enumtype) + tree enumtype; { register tree minnode = NULL_TREE, maxnode = NULL_TREE; /* Calculate the maximum value of any enumerator in this type. */ + tree values = TYPE_VALUES (enumtype); if (values) { - register tree pair; - register tree value = DECL_INITIAL (TREE_VALUE (values)); + tree pair; - if (! processing_template_decl) + for (pair = values; pair; pair = TREE_CHAIN (pair)) { - /* Speed up the main loop by performing some precalculations */ - TREE_TYPE (TREE_VALUE (values)) = enumtype; - TREE_TYPE (value) = enumtype; - minnode = maxnode = value; - } - TREE_VALUE (values) = value; - - for (pair = TREE_CHAIN (values); pair; pair = TREE_CHAIN (pair)) - { - value = DECL_INITIAL (TREE_VALUE (pair)); - if (! processing_template_decl) - { - TREE_TYPE (TREE_VALUE (pair)) = enumtype; + tree decl; + tree value; + + /* The TREE_VALUE is a CONST_DECL for this enumeration + constant. */ + decl = TREE_VALUE (pair); + + /* The DECL_INITIAL will be NULL if we are processing a + template declaration and this enumeration constant had no + explicit initializer. */ + value = DECL_INITIAL (decl); + if (value && !processing_template_decl) + { + /* Set the TREE_TYPE for the VALUE as well. That's so + that when we call decl_constant_value we get an + entity of the right type (but with the constant + value). Since we shouldn't ever call + decl_constant_value on a template type, there's no + reason to do that when processing_template_decl. + And, if the expression is something like a + TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will + wreak havoc on the intended type of the expression. + + Of course, there's also no point in trying to compute + minimum or maximum values if we're in a template. */ TREE_TYPE (value) = enumtype; - if (tree_int_cst_lt (maxnode, value)) + + if (!minnode) + minnode = maxnode = value; + else if (tree_int_cst_lt (maxnode, value)) maxnode = value; else if (tree_int_cst_lt (value, minnode)) minnode = value; } - TREE_VALUE (pair) = value; + + if (processing_template_decl) + /* If this is just a template, leave the CONST_DECL + alone. That way tsubst_copy will find CONST_DECLs for + CONST_DECLs, and not INTEGER_CSTs. */ + ; + else + /* In the list we're building up, we want the enumeration + values, not the CONST_DECLs. */ + TREE_VALUE (pair) = value; } } else @@ -11750,76 +13081,76 @@ finish_enum (enumtype, values) if (processing_template_decl) { - if (current_function_decl) - { - add_tree (build_min (TAG_DEFN, enumtype)); - resume_temporary_allocation (); - } - return enumtype; + tree scope = current_scope (); + if (scope && TREE_CODE (scope) == FUNCTION_DECL) + add_tree (build_min (TAG_DEFN, enumtype)); } + else + { + int unsignedp = tree_int_cst_sgn (minnode) >= 0; + int lowprec = min_precision (minnode, unsignedp); + int highprec = min_precision (maxnode, unsignedp); + int precision = MAX (lowprec, highprec); + tree tem; - { - int unsignedp = tree_int_cst_sgn (minnode) >= 0; - int lowprec = min_precision (minnode, unsignedp); - int highprec = min_precision (maxnode, unsignedp); - int precision = MAX (lowprec, highprec); - - TYPE_SIZE (enumtype) = NULL_TREE; - - /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ + TYPE_SIZE (enumtype) = NULL_TREE; - TYPE_PRECISION (enumtype) = precision; - if (unsignedp) - fixup_unsigned_type (enumtype); - else - fixup_signed_type (enumtype); + /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ - 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 (type_for_size - (precision, 1)); - else - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); + TYPE_PRECISION (enumtype) = precision; + if (unsignedp) + fixup_unsigned_type (enumtype); + else + fixup_signed_type (enumtype); - TYPE_SIZE (enumtype) = 0; - layout_type (enumtype); - } + 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 (type_for_size + (precision, 1)); + else + TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - { - register tree tem; + TYPE_SIZE (enumtype) = 0; + layout_type (enumtype); - /* Fix up all variant types of this enum type. */ - for (tem = TYPE_MAIN_VARIANT (enumtype); tem; - tem = TYPE_NEXT_VARIANT (tem)) - { - TYPE_VALUES (tem) = TYPE_VALUES (enumtype); - TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); - TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); - TYPE_SIZE (tem) = TYPE_SIZE (enumtype); - TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); - TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); - TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); - TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); - } - } + /* Fix up all variant types of this enum type. */ + for (tem = TYPE_MAIN_VARIANT (enumtype); tem; + tem = TYPE_NEXT_VARIANT (tem)) + { + TYPE_VALUES (tem) = TYPE_VALUES (enumtype); + TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); + TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); + TYPE_SIZE (tem) = TYPE_SIZE (enumtype); + TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); + TYPE_MODE (tem) = TYPE_MODE (enumtype); + TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); + TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); + TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); + } + + /* Finish debugging output for this type. */ + rest_of_type_compilation (enumtype, namespace_bindings_p ()); + } - /* Finish debugging output for this type. */ - rest_of_type_compilation (enumtype, namespace_bindings_p ()); + /* In start_enum we pushed obstacks. Here, we must pop them. */ + pop_obstacks (); return enumtype; } -/* Build and install a CONST_DECL for one value of the - current enumeration type (one that was begun with start_enum). - Return a tree-list containing the name and its value. +/* Build and install a CONST_DECL for an enumeration constant of the + enumeration type TYPE whose NAME and VALUE (if any) are provided. Assignment of sequential values by default is handled here. */ tree -build_enumerator (name, value) - tree name, value; +build_enumerator (name, value, type) + tree name; + tree value; + tree type; { tree decl, result; + tree context; /* Remove no-op casts from the value. */ if (value) @@ -11856,41 +13187,43 @@ build_enumerator (name, value) /* Remove no-op casts from the value. */ if (value) STRIP_TYPE_NOPS (value); - - /* We have to always copy here; not all INTEGER_CSTs are unshared, - and there's no wedding ring. Look at size_int()...*/ - value = copy_node (value); #if 0 /* To fix MAX_VAL enum consts. (bkoz) */ TREE_TYPE (value) = integer_type_node; #endif } - /* C++ associates enums with global, function, or class declarations. */ - - decl = current_scope (); - if (decl && decl == current_class_type) - { - /* This enum declaration is local to the class, so we must put - it in that class's list of decls. */ - decl = build_lang_field_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - TREE_READONLY (decl) = 1; - pushdecl_class_level (decl); - TREE_CHAIN (decl) = current_local_enum; - current_local_enum = decl; - } - else - { - /* It's a global enum, or it's local to a function. (Note local to - a function could mean local to a class method. */ - decl = build_decl (CONST_DECL, name, integer_type_node); - DECL_INITIAL (decl) = value; - TREE_READONLY (decl) = 1; + /* We always have to copy here; not all INTEGER_CSTs are unshared. + Even in other cases, we will later (in finish_enum) be setting the + type of VALUE. */ + if (value != NULL_TREE) + value = copy_node (value); - pushdecl (decl); - GNU_xref_decl (current_function_decl, decl); - } + /* C++ associates enums with global, function, or class declarations. */ + + context = current_scope (); + if (context && context == current_class_type) + /* This enum declaration is local to the class. */ + decl = build_lang_field_decl (CONST_DECL, name, type); + else + /* It's a global enum, or it's local to a function. (Note local to + a function could mean local to a class method. */ + decl = build_decl (CONST_DECL, name, type); + + DECL_CONTEXT (decl) = FROB_CONTEXT (context); + 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.) */ + finish_member_declaration (decl); + else + { + pushdecl (decl); + GNU_xref_decl (current_function_decl, decl); + } if (! processing_template_decl) { @@ -11904,30 +13237,6 @@ build_enumerator (name, value) return result; } -tree -grok_enum_decls (decl) - tree decl; -{ - tree d = current_local_enum; - - if (d == NULL_TREE) - return decl; - - while (1) - { - if (TREE_CHAIN (d) == NULL_TREE) - { - TREE_CHAIN (d) = decl; - break; - } - d = TREE_CHAIN (d); - } - - decl = current_local_enum; - current_local_enum = NULL_TREE; - - return decl; -} static int function_depth; @@ -11936,6 +13245,15 @@ static int function_depth; they describe the function's name and the type it returns, but twisted together in a fashion that parallels the syntax of C. + If PRE_PARSED_P is non-zero then DECLARATOR is really the DECL for + the function we are about to process; DECLSPECS are ignored. For + example, we set PRE_PARSED_P when processing the definition of + inline function that was defined in-class; the definition is + actually processed when the class is complete. In this case, + PRE_PARSED_P is 2. We also set PRE_PARSED_P when instanting the + body of a template function, and when constructing thunk functions + and such; in these cases PRE_PARSED_P is 1. + This function creates a binding context for the function body as well as setting up the FUNCTION_DECL in current_function_decl. @@ -11972,7 +13290,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) /* Assume, until we see it does. */ current_function_returns_value = 0; current_function_returns_null = 0; - warn_about_return_type = 0; named_labels = 0; shadowed_labels = 0; current_function_assigns_this = 0; @@ -12037,17 +13354,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) doing_friend = 1; } - /* In a fcn definition, arg types must be complete. */ - require_complete_types_for_parms (DECL_ARGUMENTS (decl1)); - - /* In case some arg types were completed since the declaration was - parsed, fix up the decls. */ - { - tree t = DECL_ARGUMENTS (decl1); - for (; t; t = TREE_CHAIN (t)) - layout_decl (t, 0); - } - last_function_parms = DECL_ARGUMENTS (decl1); last_function_parm_tags = NULL_TREE; } @@ -12061,8 +13367,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) fntype = TREE_TYPE (decl1); restype = TREE_TYPE (fntype); - if (IS_AGGR_TYPE (restype) && ! TYPE_PTRMEMFUNC_P (restype) - && ! CLASSTYPE_GOT_SEMICOLON (restype)) + if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype)) { cp_error ("semicolon missing after declaration of `%#T'", restype); shadow_tag (build_expr_list (NULL_TREE, restype)); @@ -12088,7 +13393,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) pedwarn ("return type for `main' changed to `int'"); TREE_TYPE (decl1) = fntype = default_function_type; } - warn_about_return_type = 0; } } @@ -12098,16 +13402,37 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1))); + announce_function (decl1); + + /* Set up current_class_type, and enter the scope of the class, if + appropriate. */ + if (ctype) + push_nested_class (ctype, 1); + else if (DECL_STATIC_FUNCTION_P (decl1)) + push_nested_class (DECL_CONTEXT (decl1), 2); + + /* Now that we have entered the scope of the class, we must restore + the bindings for any template parameters surrounding DECL1, if it + is an inline member template. (Order is important; consider the + case where a template parameter has the same name as a field of + the class.) It is not until after this point that + PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly. */ + if (pre_parsed_p == 2) + maybe_begin_member_template_processing (decl1); + + /* We are now in the scope of the function being defined. */ current_function_decl = decl1; + /* 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_parm_tags = last_function_parm_tags; - announce_function (decl1); - if (! processing_template_decl) { + /* In a function definition, arg types must be complete. */ + require_complete_types_for_parms (current_function_parms); + if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE) { cp_error ("return-type `%#T' is an incomplete type", @@ -12128,8 +13453,10 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) TYPE_ARG_TYPES (TREE_TYPE (decl1))); DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (fntype))); - TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (TREE_TYPE (fntype)); - TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (TREE_TYPE (fntype)); + TREE_READONLY (DECL_RESULT (decl1)) + = CP_TYPE_CONST_P (TREE_TYPE (fntype)); + TREE_THIS_VOLATILE (DECL_RESULT (decl1)) + = CP_TYPE_VOLATILE_P (TREE_TYPE (fntype)); } if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype)) @@ -12137,9 +13464,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) abstract_virtuals_error (decl1, TREE_TYPE (fntype)); } - if (warn_about_return_type) - pedwarn ("return-type defaults to `int'"); - /* Effective C++ rule 15. See also c_expand_return. */ if (warn_ecpp && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR] @@ -12150,17 +13474,25 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) error_mark_node is replaced below (in poplevel) with the BLOCK. */ DECL_INITIAL (decl1) = error_mark_node; +#ifdef SET_DEFAULT_DECL_ATTRIBUTES + SET_DEFAULT_DECL_ATTRIBUTES (decl1, attrs); +#endif + /* This function exists in static storage. (This does not mean `static' in the C sense!) */ TREE_STATIC (decl1) = 1; + /* We must call push_template_decl after current_class_type is set + up. (If we are processing inline definitions after exiting a + class scope, current_class_type will be NULL_TREE until set above + by push_nested_class.) */ + if (processing_template_decl) + decl1 = push_template_decl (decl1); + /* Record the decl so that the function name is defined. If we already have a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ - - if (processing_template_decl) - decl1 = push_template_decl (decl1); - else if (pre_parsed_p == 0) + if (!processing_template_decl && pre_parsed_p == 0) { /* A specialization is not used to guide overload resolution. */ if ((flag_guiding_decls @@ -12196,21 +13528,41 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) } /* If this function belongs to an interface, it is public. If it belongs to someone else's interface, it is also external. - It doesn't matter whether it's inline or not. */ + This only affects inlines and template instantiations. */ else if (interface_unknown == 0 && (! DECL_TEMPLATE_INSTANTIATION (decl1) || flag_alt_external_templates)) { if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1) || processing_template_decl) - DECL_EXTERNAL (decl1) - = (interface_only - || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines)); + { + DECL_EXTERNAL (decl1) + = (interface_only + || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines + && !DECL_VINDEX (decl1))); + + /* For WIN32 we also want to put these in linkonce sections. */ + maybe_make_one_only (decl1); + } else DECL_EXTERNAL (decl1) = 0; DECL_NOT_REALLY_EXTERN (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; } + else if (interface_unknown && interface_only + && (! DECL_TEMPLATE_INSTANTIATION (decl1) + || flag_alt_external_templates)) + { + /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma + interface, we will have interface_only set but not + interface_known. In that case, we don't want to use the normal + heuristics because someone will supply a #pragma implementation + elsewhere, and deducing it here would produce a conflict. */ + comdat_linkage (decl1); + DECL_EXTERNAL (decl1) = 0; + DECL_INTERFACE_KNOWN (decl1) = 1; + DECL_DEFER_OUTPUT (decl1) = 1; + } else { /* This is a definition, not a reference. @@ -12240,8 +13592,6 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) if (ctype) { - push_nested_class (ctype, 1); - /* If we're compiling a friend function, neither of the variables current_class_ptr nor current_class_type will have values. */ if (! doing_friend) @@ -12258,13 +13608,24 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) { - int i = suspend_momentary (); + int i; + + if (! hack_decl_function_context (decl1)) + temporary_allocation (); + i = suspend_momentary (); - /* Fool build_indirect_ref. */ + /* Normally, build_indirect_ref returns + current_class_ref whenever current_class_ptr is + dereferenced. This time, however, we want it to + *create* current_class_ref, so we temporarily clear + current_class_ptr to fool it. */ current_class_ptr = NULL_TREE; current_class_ref = build_indirect_ref (t, NULL_PTR); current_class_ptr = t; + resume_momentary (i); + if (! hack_decl_function_context (decl1)) + end_temporary_allocation (); } else /* We're having a signature pointer here. */ @@ -12273,13 +13634,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) } } else - { - if (DECL_STATIC_FUNCTION_P (decl1)) - push_nested_class (DECL_CONTEXT (decl1), 2); - else - push_memoized_context (0, 1); - current_class_ptr = current_class_ref = NULL_TREE; - } + current_class_ptr = current_class_ref = NULL_TREE; pushlevel (0); current_binding_level->parm_flag = 1; @@ -12288,6 +13643,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) if (attrs) cplus_decl_attributes (decl1, NULL_TREE, attrs); + make_function_rtl (decl1); /* Promote the value to int before returning it. */ @@ -12303,8 +13659,8 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) { DECL_RESULT (decl1) = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); - TREE_READONLY (DECL_RESULT (decl1)) = TYPE_READONLY (restype); - TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = TYPE_VOLATILE (restype); + TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype); + TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype); } /* Allocate further tree nodes temporarily during compilation @@ -12381,9 +13737,6 @@ store_parm_decls () /* Initialize RTL machinery. */ init_function_start (fndecl, input_filename, lineno); - /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ - declare_function_name (); - /* Create a binding level for the parms. */ expand_start_bindings (0); @@ -12469,6 +13822,9 @@ store_parm_decls () storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); + /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ + declare_function_name (); + /* Initialize the RTL code for the function. */ DECL_SAVED_INSNS (fndecl) = NULL_RTX; if (! processing_template_decl) @@ -12579,18 +13935,23 @@ store_return_init (return_id, init) This is called after parsing the body of the function definition. LINENO is the current line number. - C++: CALL_POPLEVEL is non-zero if an extra call to poplevel - (and expand_end_bindings) must be made to take care of the binding - contour for the base initializers. This is only relevant for - constructors. + FLAGS is a bitwise or of the following values: + 1 - CALL_POPLEVEL + An extra call to poplevel (and expand_end_bindings) must be + made to take care of the binding contour for the base + initializers. This is only relevant for constructors. + 2 - INCLASS_INLINE + We just finished processing the body of an in-class inline + function definition. (This processing will have taken place + after the class definition is complete.) NESTED is nonzero if we were in the middle of compiling another function when we started on this one. */ void -finish_function (lineno, call_poplevel, nested) +finish_function (lineno, flags, nested) int lineno; - int call_poplevel; + int flags; int nested; { register tree fndecl = current_function_decl; @@ -12599,13 +13960,16 @@ finish_function (lineno, call_poplevel, nested) /* Label to use if this function is supposed to return a value. */ tree no_return_label = NULL_TREE; tree decls = NULL_TREE; + int call_poplevel = (flags & 1) != 0; + int inclass_inline = (flags & 2) != 0; + int in_template; /* When we get some parse errors, we can end up without a current_function_decl, so cope. */ if (fndecl == NULL_TREE) return; - if (! nested && function_depth > 1) + if (function_depth > 1) nested = 1; fntype = TREE_TYPE (fndecl); @@ -12698,7 +14062,8 @@ finish_function (lineno, call_poplevel, nested) pointer to represent the type of our base class. */ /* This side-effect makes call to `build_delete' generate the - code we have to have at the end of this destructor. */ + code we have to have at the end of this destructor. + `build_delete' will set the flag again. */ TYPE_HAS_DESTRUCTOR (current_class_type) = 0; /* These are two cases where we cannot delegate deletion. */ @@ -12757,8 +14122,6 @@ finish_function (lineno, call_poplevel, nested) expand_end_cond (); } - TYPE_HAS_DESTRUCTOR (current_class_type) = 1; - virtual_size = c_sizeof (current_class_type); /* At the end, call delete if that's what's requested. */ @@ -12792,7 +14155,7 @@ finish_function (lineno, call_poplevel, nested) /* End of destructor. */ expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0); - poplevel (2, 0, 0); /* XXX change to 1 */ + poplevel (getdecls () != NULL_TREE, 0, 0); /* Back to the top of destructor. */ /* Don't execute destructor code if `this' is NULL. */ @@ -12822,7 +14185,7 @@ finish_function (lineno, call_poplevel, nested) if (! ok_to_optimize_dtor) { cond = build_binary_op (NE_EXPR, - current_class_ptr, integer_zero_node, 1); + current_class_ptr, integer_zero_node); expand_start_cond (cond, 0); } @@ -12877,12 +14240,10 @@ finish_function (lineno, call_poplevel, nested) tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; - DECL_RETURNS_FIRST_ARG (fndecl) = 1; - if (flag_this_is_variable > 0) { cond = build_binary_op (EQ_EXPR, - current_class_ptr, integer_zero_node, 1); + current_class_ptr, integer_zero_node); thenclause = build_modify_expr (current_class_ptr, NOP_EXPR, build_new (NULL_TREE, current_class_type, void_type_node, 0)); } @@ -13005,6 +14366,20 @@ finish_function (lineno, call_poplevel, nested) /* Generate rtl for function exit. */ expand_function_end (input_filename, lineno, 1); } + + /* If we're processing a template, squirrel away the definition + until we do an instantiation. */ + if (processing_template_decl) + { + --minimal_parse_mode; + DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl)); + /* We have to save this value here in case + maybe_end_member_template_processing decides to pop all the + template parameters. */ + in_template = 1; + } + else + in_template = 0; /* This must come after expand_function_end because cleanups might have declarations (from inline functions) that need to go into @@ -13013,6 +14388,13 @@ finish_function (lineno, call_poplevel, nested) my_friendly_abort (122); poplevel (1, 0, 1); + /* If this is a in-class inline definition, we may have to pop the + bindings for the template parameters that we added in + maybe_begin_member_template_processing when start_function was + called. */ + if (inclass_inline) + maybe_end_member_template_processing (); + /* Reset scope for C++: if we were in the scope of a class, then when we finish this function, we are not longer so. This cannot be done until we know for sure that no more @@ -13021,10 +14403,8 @@ finish_function (lineno, call_poplevel, nested) if (current_class_name) { ctype = current_class_type; - pop_nested_class (1); + pop_nested_class (); } - else - pop_memoized_context (1); /* Must mark the RESULT_DECL as being in this function. */ DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; @@ -13033,7 +14413,7 @@ finish_function (lineno, call_poplevel, nested) to the FUNCTION_DECL node itself. */ BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - if (! processing_template_decl) + if (!in_template) { int saved_flag_keep_inline_functions = flag_keep_inline_functions; @@ -13117,12 +14497,6 @@ finish_function (lineno, call_poplevel, nested) /* Free all the tree nodes making up this function. */ /* Switch back to allocating nodes permanently until we start another function. */ - if (processing_template_decl) - { - --minimal_parse_mode; - DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl)); - } - if (! nested) permanent_allocation (1); @@ -13157,8 +14531,6 @@ finish_function (lineno, call_poplevel, nested) } /* Create the FUNCTION_DECL for a function definition. - LINE1 is the line number that the definition absolutely begins on. - LINE2 is the line number that the name of the function appears on. DECLSPECS and DECLARATOR are the parts of the declaration; they describe the return type and the name of the function, but twisted together in a fashion that parallels the syntax of C. @@ -13180,11 +14552,11 @@ finish_function (lineno, call_poplevel, nested) CHANGES TO CODE IN `grokfield'. */ tree -start_method (declspecs, declarator) - tree declarator, declspecs; +start_method (declspecs, declarator, attrlist) + tree declarator, declspecs, attrlist; { tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, - NULL_TREE); + attrlist); /* Something too ugly to handle. */ if (fndecl == NULL_TREE) @@ -13213,12 +14585,15 @@ start_method (declspecs, declarator) return void_type_node; } + check_template_shadow (fndecl); + DECL_THIS_INLINE (fndecl) = 1; if (flag_default_inline) DECL_INLINE (fndecl) = 1; - if (processing_template_decl) + /* We process method specializations in finish_struct_1. */ + if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl)) fndecl = push_template_decl (fndecl); /* We read in the parameters on the maybepermanent_obstack, @@ -13293,23 +14668,11 @@ finish_method (decl) for (link = current_binding_level->names; link; link = TREE_CHAIN (link)) { if (DECL_NAME (link) != NULL_TREE) - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0; + pop_binding (DECL_NAME (link), link); my_friendly_assert (TREE_CODE (link) != FUNCTION_DECL, 163); DECL_CONTEXT (link) = NULL_TREE; } - /* 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); - for (link = current_binding_level->class_shadowed; - link; link = TREE_CHAIN (link)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); - for (link = current_binding_level->type_shadowed; - link; link = TREE_CHAIN (link)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); - GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, (HOST_WIDE_INT) current_binding_level->level_chain, current_binding_level->parm_flag, @@ -13390,7 +14753,7 @@ maybe_build_cleanup_1 (decl, auto_delete) tree decl, auto_delete; { tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) + if (type != error_mark_node && TYPE_NEEDS_DESTRUCTOR (type)) { int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; tree rval; @@ -13467,38 +14830,30 @@ cplus_expand_expr_stmt (exp) /* Arrange for all temps to disappear. */ expand_start_target_temps (); - if (TREE_TYPE (exp) == unknown_type_node) + exp = require_complete_type_in_void (exp); + + if (TREE_CODE (exp) == FUNCTION_DECL) { - if (TREE_CODE (exp) == ADDR_EXPR || TREE_CODE (exp) == TREE_LIST) - error ("address of overloaded function with no contextual type information"); - else if (TREE_CODE (exp) == COMPONENT_REF) - warning ("useless reference to a member function name, did you forget the ()?"); + cp_warning ("reference, not call, to function `%D'", exp); + warning ("at this point in file"); } - else - { - if (TREE_CODE (exp) == FUNCTION_DECL) - { - cp_warning ("reference, not call, to function `%D'", exp); - warning ("at this point in file"); - } #if 0 - /* We should do this eventually, but right now this causes regex.o from - libg++ to miscompile, and tString to core dump. */ - exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); + /* We should do this eventually, but right now this causes regex.o from + libg++ to miscompile, and tString to core dump. */ + exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); #endif - /* Strip unused implicit INDIRECT_REFs of references. */ - if (TREE_CODE (exp) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE) - exp = TREE_OPERAND (exp, 0); + /* Strip unused implicit INDIRECT_REFs of references. */ + if (TREE_CODE (exp) == INDIRECT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE) + exp = TREE_OPERAND (exp, 0); - /* If we don't do this, we end up down inside expand_expr - trying to do TYPE_MODE on the ERROR_MARK, and really - go outside the bounds of the type. */ - if (exp != error_mark_node) - expand_expr_stmt (break_out_cleanups (exp)); - } + /* If we don't do this, we end up down inside expand_expr + trying to do TYPE_MODE on the ERROR_MARK, and really + go outside the bounds of the type. */ + if (exp != error_mark_node) + expand_expr_stmt (break_out_cleanups (exp)); /* Clean up any pending cleanups. This happens when a function call returns a cleanup-needing value that nobody uses. */ @@ -13547,15 +14902,14 @@ revert_static_member_fn (decl, fn, argtypes) tree function = fn ? *fn : TREE_TYPE (*decl); tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function); - if (TYPE_READONLY (TREE_TYPE (TREE_VALUE (args)))) - cp_error ("static member function `%#D' declared const", *decl); - if (TYPE_VOLATILE (TREE_TYPE (TREE_VALUE (args)))) - cp_error ("static member function `%#D' declared volatile", *decl); + if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args))) + != TYPE_UNQUALIFIED) + cp_error ("static member function `%#D' declared with type qualifiers", + *decl); args = TREE_CHAIN (args); tmp = build_function_type (TREE_TYPE (function), args); - tmp = build_type_variant (tmp, TYPE_READONLY (function), - TYPE_VOLATILE (function)); + tmp = build_qualified_type (tmp, CP_TYPE_QUALS (function)); tmp = build_exception_variant (tmp, TYPE_RAISES_EXCEPTIONS (function)); TREE_TYPE (*decl) = tmp; @@ -13568,23 +14922,16 @@ revert_static_member_fn (decl, fn, argtypes) *argtypes = args; } -int -id_in_current_class (id) - tree id; -{ - return !!purpose_member (id, class_binding_level->class_shadowed); -} - struct cp_function { int returns_value; int returns_null; - int warn_about_return_type; int assigns_this; int just_assigned_this; int parms_stored; int temp_name_counter; tree named_labels; + struct named_label_list *named_label_uses; tree shadowed_labels; tree ctor_label; tree dtor_label; @@ -13621,10 +14968,10 @@ push_cp_function_context (context) cp_function_chain = p; p->named_labels = named_labels; + p->named_label_uses = named_label_uses; p->shadowed_labels = shadowed_labels; p->returns_value = current_function_returns_value; p->returns_null = current_function_returns_null; - p->warn_about_return_type = warn_about_return_type; p->binding_level = current_binding_level; p->ctor_label = ctor_label; p->dtor_label = dtor_label; @@ -13663,10 +15010,10 @@ pop_cp_function_context (context) cp_function_chain = p->next; named_labels = p->named_labels; + named_label_uses = p->named_label_uses; shadowed_labels = p->shadowed_labels; current_function_returns_value = p->returns_value; current_function_returns_null = p->returns_null; - warn_about_return_type = p->warn_about_return_type; current_binding_level = p->binding_level; ctor_label = p->ctor_label; dtor_label = p->dtor_label; diff --git a/contrib/gcc/cp/decl.h b/contrib/gcc/cp/decl.h index f55dca5..fcb247e 100644 --- a/contrib/gcc/cp/decl.h +++ b/contrib/gcc/cp/decl.h @@ -42,11 +42,6 @@ extern tree this_identifier, in_charge_identifier; or a chain or parameter decls here. */ extern tree last_function_parms; -/* A list of static class variables. This is needed, because a - static class variable can be declared inside the class without - an initializer, and then initialized, staticly, outside the class. */ -extern tree pending_statics; - /* A list of objects which have constructors or destructors which reside in the global scope. The decl is stored in the TREE_VALUE slot and the initializer is stored diff --git a/contrib/gcc/cp/decl2.c b/contrib/gcc/cp/decl2.c index c87c607..84f491f 100644 --- a/contrib/gcc/cp/decl2.c +++ b/contrib/gcc/cp/decl2.c @@ -1,5 +1,5 @@ /* Process declarations and variables for C compiler. - Copyright (C) 1988, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -42,26 +42,60 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "dwarf2out.h" #include "dwarfout.h" +#include "splay-tree.h" +#include "varray.h" #if USE_CPPLIB #include "cpplib.h" extern cpp_reader parse_in; -extern cpp_options parse_options; -static int cpp_initialized; #endif +/* This structure contains information about the initializations + and/or destructions required for a particular priority level. */ +typedef struct priority_info_s { + /* A label indicating where we should generate the next + initialization with this priority. */ + rtx initialization_sequence; + /* A label indicating where we should generate the next destruction + with this priority. */ + rtx destruction_sequence; + /* Non-zero if there have been any initializations at this priority + throughout the translation unit. */ + int initializations_p; + /* Non-zero if there have been any destructions at this priority + throughout the translation unit. */ + int destructions_p; +} *priority_info; + static tree get_sentry PROTO((tree)); static void mark_vtable_entries PROTO((tree)); static void grok_function_init PROTO((tree, tree)); -static int finish_vtable_vardecl PROTO((tree, tree)); -static int prune_vtable_vardecl PROTO((tree, tree)); -static void finish_sigtable_vardecl PROTO((tree, tree)); +static int finish_vtable_vardecl PROTO((tree *, void *)); +static int prune_vtable_vardecl PROTO((tree *, void *)); +static int finish_sigtable_vardecl PROTO((tree *, void *)); static int is_namespace_ancestor PROTO((tree, tree)); static void add_using_namespace PROTO((tree, tree, int)); static tree ambiguous_decl PROTO((tree, tree, tree,int)); static tree build_anon_union_vars PROTO((tree, tree*, int, int)); -static void check_decl_namespace PROTO((void)); - +static int acceptable_java_type PROTO((tree)); +static void output_vtable_inherit PROTO((tree)); +static void start_objects PROTO((int, int)); +static void finish_objects PROTO((int, int)); +static tree merge_functions PROTO((tree, tree)); +static tree decl_namespace PROTO((tree)); +static tree validate_nonmember_using_decl PROTO((tree, tree *, tree *)); +static void do_nonmember_using_decl PROTO((tree, tree, tree, tree, + tree *, tree *)); +static void start_static_storage_duration_function PROTO((void)); +static int generate_inits_for_priority PROTO((splay_tree_node, void *)); +static void finish_static_storage_duration_function PROTO((void)); +static priority_info get_priority_info PROTO((int)); +static void do_static_initialization PROTO((tree, tree, tree, int)); +static void do_static_destruction PROTO((tree, tree, int)); +static void do_static_initialization_and_destruction PROTO((tree, tree)); +static void generate_ctor_or_dtor_function PROTO((int, int)); +static int generate_ctor_and_dtor_functions_for_priority + PROTO((splay_tree_node, void *)); extern int current_class_depth; /* A list of virtual function tables we must make sure to write out. */ @@ -70,11 +104,13 @@ tree pending_vtables; /* A list of static class variables. This is needed, because a static class variable can be declared inside the class without an initializer, and then initialized, staticly, outside the class. */ -tree pending_statics; +static varray_type pending_statics; +static size_t pending_statics_used; /* A list of functions which were declared inline, but which we may need to emit outline anyway. */ -static tree saved_inlines; +static varray_type saved_inlines; +static size_t saved_inlines_used; /* Used to help generate temporary names which are unique within a function. Reset to 0 by start_function. */ @@ -144,10 +180,6 @@ int flag_traditional; int flag_signed_bitfields = 1; -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident; - /* Nonzero means enable obscure ANSI features and disable GNU extensions that might cause ANSI-compliant code to be miscompiled. */ @@ -173,6 +205,12 @@ int flag_alt_external_templates; int flag_implicit_templates = 1; +/* Nonzero means that implicit instantiations of inline templates will be + emitted if needed, even if instantiations of non-inline templates + aren't. */ + +int flag_implicit_inline_templates = 1; + /* Nonzero means warn about implicit declarations. */ int warn_implicit = 1; @@ -203,9 +241,13 @@ int flag_use_repository; int flag_optional_diags = 1; -/* Nonzero means give string constants the type `const char *' - to get extra warnings from them. These warnings will be too numerous - to be useful, except in thoroughly ANSIfied programs. */ +/* Nonzero means give string constants the type `const char *', as mandated + by the standard. */ + +int flag_const_strings = 1; + +/* Nonzero means warn about deprecated conversion from string constant to + `char *'. */ int warn_write_strings; @@ -295,6 +337,15 @@ int warn_unknown_pragmas; /* Tri state variable. */ int warn_multichar = 1; +/* Nonzero means warn when non-templatized friend functions are + declared within a template */ + +int warn_nontemplate_friend = 1; + +/* Nonzero means complain about deprecated features. */ + +int warn_deprecated = 1; + /* Nonzero means `$' can be in an identifier. */ #ifndef DOLLARS_IN_IDENTIFIERS @@ -318,40 +369,22 @@ int flag_labels_ok; int flag_detailed_statistics; /* C++ specific flags. */ -/* Nonzero for -fall-virtual: make every member function (except - constructors) lay down in the virtual function table. Calls - can then either go through the virtual function table or not, - depending. */ - -int flag_all_virtual; - /* Zero means that `this' is a *const. This gives nice behavior in the 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. -2 means we're constructing an object and it has fixed type. */ int flag_this_is_variable; -/* Nonzero means memoize our member lookups. */ - -int flag_memoize_lookups; int flag_save_memoized_contexts; - /* 3 means write out only virtuals function tables `defined' in this implementation file. - 2 means write out only specific virtual function tables - and give them (C) public access. - 1 means write out virtual function tables and give them - (C) public access. 0 means write out virtual function tables and give them - (C) static access (default). - -1 means declare virtual function tables extern. */ + (C) static access (default). */ int write_virtuals; -/* Nonzero means we should attempt to elide constructors when possible. - FIXME: This flag is obsolete, and should be torn out along with the - old overloading code. */ +/* Nonzero means we should attempt to elide constructors when possible. */ -int flag_elide_constructors; +int flag_elide_constructors = 1; /* Nonzero means recognize and handle signature language constructs. */ @@ -362,11 +395,6 @@ int flag_handle_signatures; int flag_default_inline = 1; -/* Controls whether enums and ints freely convert. - 1 means with complete freedom. - 0 means enums can convert to ints, but not vice-versa. */ -int flag_int_enum_equivalence; - /* Controls whether compiler generates 'type descriptor' that give run-time type information. */ int flag_rtti = 1; @@ -375,18 +403,6 @@ int flag_rtti = 1; for the GNU class browser. */ extern int flag_gnu_xref; -/* Nonzero if compiler can make `reasonable' assumptions about - references and objects. For example, the compiler must be - conservative about the following and not assume that `a' is nonnull: - - obj &a = g (); - a.f (2); - - In general, it is `reasonable' to assume that for many programs, - and better code can be generated in that case. */ - -int flag_assume_nonnull_objects = 1; - /* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) objects. */ @@ -453,6 +469,14 @@ int flag_guiding_decls; and class qualifiers. */ int flag_do_squangling; +/* 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. */ + +int flag_permissive; /* Table of language-dependent -f options. STRING is the option name. VARIABLE is the address of the variable. @@ -460,8 +484,10 @@ int flag_do_squangling; if `-fSTRING' is seen as an option. (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ -static struct { char *string; int *variable; int on_value;} lang_f_options[] = +static struct { const char *string; int *variable; int on_value;} +lang_f_options[] = { + /* C/C++ options. */ {"signed-char", &flag_signed_char, 1}, {"unsigned-char", &flag_signed_char, 0}, {"signed-bitfields", &flag_signed_bitfields, 1}, @@ -469,41 +495,42 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = {"short-enums", &flag_short_enums, 1}, {"short-double", &flag_short_double, 1}, {"cond-mismatch", &flag_cond_mismatch, 1}, - {"squangle", &flag_do_squangling, 1}, {"asm", &flag_no_asm, 0}, {"builtin", &flag_no_builtin, 0}, - {"ident", &flag_no_ident, 0}, - {"labels-ok", &flag_labels_ok, 1}, - {"stats", &flag_detailed_statistics, 1}, - {"this-is-variable", &flag_this_is_variable, 1}, - {"strict-prototype", &flag_strict_prototype, 1}, - {"all-virtual", &flag_all_virtual, 1}, - {"memoize-lookups", &flag_memoize_lookups, 1}, + + /* C++-only options. */ + {"access-control", &flag_access_control, 1}, + {"check-new", &flag_check_new, 1}, + {"conserve-space", &flag_conserve_space, 1}, + {"const-strings", &flag_const_strings, 1}, + {"default-inline", &flag_default_inline, 1}, + {"dollars-in-identifiers", &dollars_in_ident, 1}, {"elide-constructors", &flag_elide_constructors, 1}, + {"external-templates", &flag_external_templates, 1}, + {"for-scope", &flag_new_for_scope, 2}, + {"gnu-keywords", &flag_no_gnu_keywords, 0}, {"handle-exceptions", &flag_exceptions, 1}, {"handle-signatures", &flag_handle_signatures, 1}, - {"default-inline", &flag_default_inline, 1}, - {"dollars-in-identifiers", &dollars_in_ident, 1}, - {"enum-int-equiv", &flag_int_enum_equivalence, 1}, {"honor-std", &flag_honor_std, 1}, - {"rtti", &flag_rtti, 1}, - {"xref", &flag_gnu_xref, 1}, - {"nonnull-objects", &flag_assume_nonnull_objects, 1}, + {"huge-objects", &flag_huge_objects, 1}, {"implement-inlines", &flag_implement_inlines, 1}, - {"external-templates", &flag_external_templates, 1}, + {"implicit-inline-templates", &flag_implicit_inline_templates, 1}, {"implicit-templates", &flag_implicit_templates, 1}, - {"huge-objects", &flag_huge_objects, 1}, - {"conserve-space", &flag_conserve_space, 1}, - {"vtable-thunks", &flag_vtable_thunks, 1}, - {"access-control", &flag_access_control, 1}, + {"labels-ok", &flag_labels_ok, 1}, {"nonansi-builtins", &flag_no_nonansi_builtin, 0}, - {"gnu-keywords", &flag_no_gnu_keywords, 0}, {"operator-names", &flag_operator_names, 1}, {"optional-diags", &flag_optional_diags, 1}, - {"check-new", &flag_check_new, 1}, + {"permissive", &flag_permissive, 1}, {"repo", &flag_use_repository, 1}, - {"for-scope", &flag_new_for_scope, 2}, - {"weak", &flag_weak, 1} + {"rtti", &flag_rtti, 1}, + {"squangle", &flag_do_squangling, 1}, + {"stats", &flag_detailed_statistics, 1}, + {"strict-prototype", &flag_strict_prototype, 1}, + {"this-is-variable", &flag_this_is_variable, 1}, + {"vtable-gc", &flag_vtable_gc, 1}, + {"vtable-thunks", &flag_vtable_thunks, 1}, + {"weak", &flag_weak, 1}, + {"xref", &flag_gnu_xref, 1} }; /* Decode the string P as a language-specific option. @@ -512,44 +539,24 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] = int lang_decode_option (argc, argv) - int argc; + int argc +#if !USE_CPPLIB + ATTRIBUTE_UNUSED +#endif + ; char **argv; { int strings_processed; char *p = argv[0]; #if USE_CPPLIB - if (! cpp_initialized) - { - cpp_reader_init (&parse_in); - parse_in.data = &parse_options; - cpp_options_init (&parse_options); - cpp_initialized = 1; - } strings_processed = cpp_handle_option (&parse_in, argc, argv); #else strings_processed = 0; #endif /* ! USE_CPPLIB */ if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - flag_writable_strings = 1, - flag_this_is_variable = 1, flag_new_for_scope = 0; - /* The +e options are for cfront compatibility. They come in as - `-+eN', to kludge around gcc.c's argument handling. */ - else if (p[0] == '-' && p[1] == '+' && p[2] == 'e') - { - int old_write_virtuals = write_virtuals; - if (p[3] == '1') - write_virtuals = 1; - else if (p[3] == '0') - write_virtuals = -1; - else if (p[3] == '2') - write_virtuals = 2; - else error ("invalid +e option"); - if (old_write_virtuals != 0 - && write_virtuals != old_write_virtuals) - error ("conflicting +e options given"); - } + /* ignore */; else if (p[0] == '-' && p[1] == 'f') { /* Some kind of -f option. @@ -565,16 +572,24 @@ lang_decode_option (argc, argv) || !strcmp (p, "no-handle-exceptions")) warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)"); - if (!strcmp (p, "save-memoized")) + if (!strcmp (p, "memoize-lookups") + || !strcmp (p, "no-memoize-lookups") + || !strcmp (p, "save-memoized") + || !strcmp (p, "no-save-memoized") + || !strcmp (p, "no-all-virtual") + || !strcmp (p, "no-enum-int-equiv") + || !strcmp (p, "nonnull-objects") + || !strcmp (p, "ansi-overloading")) { - flag_memoize_lookups = 1; - flag_save_memoized_contexts = 1; + /* ignore */ found = 1; } - else if (!strcmp (p, "no-save-memoized")) + else if (!strcmp (p, "all-virtual") + || !strcmp (p, "enum-int-equiv") + || !strcmp (p, "no-nonnull-objects") + || !strcmp (p, "no-ansi-overloading")) { - flag_memoize_lookups = 0; - flag_save_memoized_contexts = 0; + warning ("-f%s is no longer supported", p); found = 1; } else if (! strcmp (p, "alt-external-templates")) @@ -582,6 +597,7 @@ lang_decode_option (argc, argv) flag_external_templates = 1; flag_alt_external_templates = 1; found = 1; + cp_deprecated ("-falt-external-templates"); } else if (! strcmp (p, "no-alt-external-templates")) { @@ -605,13 +621,24 @@ lang_decode_option (argc, argv) flag_guiding_decls = 0; found = 1; } - else if (!strcmp (p, "ansi-overloading")) - found = 1; - else if (!strcmp (p, "no-ansi-overloading")) - { - error ("-fno-ansi-overloading is no longer supported"); - found = 1; - } + else if (!strcmp (p, "this-is-variable")) + { + flag_this_is_variable = 1; + found = 1; + cp_deprecated ("-fthis-is-variable"); + } + else if (!strcmp (p, "external-templates")) + { + flag_external_templates = 1; + found = 1; + cp_deprecated ("-fexternal-templates"); + } + else if (!strcmp (p, "handle-signatures")) + { + flag_handle_signatures = 1; + found = 1; + cp_deprecated ("-fhandle-signatures"); + } else if (!strcmp (p, "new-abi")) { flag_new_abi = 1; @@ -627,35 +654,13 @@ lang_decode_option (argc, argv) } else if (!strncmp (p, "template-depth-", 15)) { - char *endp = p + 15; - while (*endp) - { - if (*endp >= '0' && *endp <= '9') - endp++; - else - { - error ("Invalid option `%s'", p - 2); - goto template_depth_lose; - } - } - max_tinst_depth = atoi (p + 15); - template_depth_lose: ; + max_tinst_depth = + read_integral_parameter (p + 15, p - 2, max_tinst_depth); } else if (!strncmp (p, "name-mangling-version-", 22)) { - char *endp = p + 22; - while (*endp) - { - if (*endp >= '0' && *endp <= '9') - endp++; - else - { - error ("Invalid option `%s'", p - 2); - goto mangling_version_lose; - } - } - name_mangling_version = atoi (p + 22); - mangling_version_lose: ; + name_mangling_version = + read_integral_parameter (p + 22, p - 2, name_mangling_version); } else for (j = 0; !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); @@ -741,6 +746,10 @@ lang_decode_option (argc, argv) /* Set to greater than 1, so that even unknown pragmas in system headers will be warned about. */ warn_unknown_pragmas = setting * 2; + else if (!strcmp (p, "non-template-friend")) + warn_nontemplate_friend = setting; + else if (!strcmp (p, "deprecated")) + warn_deprecated = setting; else if (!strcmp (p, "comment")) ; /* cpp handles this one. */ else if (!strcmp (p, "comments")) @@ -754,25 +763,26 @@ lang_decode_option (argc, argv) warn_return_type = setting; warn_unused = setting; warn_implicit = setting; - warn_ctor_dtor_privacy = setting; warn_switch = setting; warn_format = setting; warn_parentheses = setting; warn_missing_braces = setting; warn_sign_compare = setting; - warn_extern_inline = setting; - warn_nonvdtor = setting; warn_multichar = setting; /* 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 = (setting ? 2 : 0); - warn_reorder = setting; - warn_sign_promo = setting; /* Only warn about unknown pragmas that are not in system headers. */ - warn_unknown_pragmas = 1; + warn_unknown_pragmas = 1; + + /* C++-specific warnings. */ + warn_ctor_dtor_privacy = setting; + warn_nonvdtor = setting; + warn_reorder = setting; + warn_nontemplate_friend = setting; } else return strings_processed; } @@ -802,36 +812,27 @@ grok_method_quals (ctype, function, quals) { tree fntype = TREE_TYPE (function); tree raises = TYPE_RAISES_EXCEPTIONS (fntype); + int type_quals = TYPE_UNQUALIFIED; + int dup_quals = TYPE_UNQUALIFIED; do { - extern tree ridpointers[]; - - if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST]) - { - if (TYPE_READONLY (ctype)) - error ("duplicate `%s' %s", - IDENTIFIER_POINTER (TREE_VALUE (quals)), - (TREE_CODE (function) == FUNCTION_DECL - ? "for member function" : "in type declaration")); - ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype)); - build_pointer_type (ctype); - } - else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE]) - { - if (TYPE_VOLATILE (ctype)) - error ("duplicate `%s' %s", - IDENTIFIER_POINTER (TREE_VALUE (quals)), - (TREE_CODE (function) == FUNCTION_DECL - ? "for member function" : "in type declaration")); - ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1); - build_pointer_type (ctype); - } + int tq = cp_type_qual_from_rid (TREE_VALUE (quals)); + + if (type_quals & tq) + dup_quals |= tq; else - my_friendly_abort (20); + type_quals |= tq; quals = TREE_CHAIN (quals); - } + } while (quals); + + if (dup_quals != TYPE_UNQUALIFIED) + cp_error ("duplicate type qualifiers in %s declaration", + TREE_CODE (function) == FUNCTION_DECL + ? "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)) @@ -878,121 +879,34 @@ warn_if_unknown_interface (decl) /* A subroutine of the parser, to handle a component list. */ -tree -grok_x_components (specs, components) - tree specs, components; +void +grok_x_components (specs) + tree specs; { - register tree t, x, tcode; - - /* We just got some friends. They have been recorded elsewhere. */ - if (components == void_type_node) - return NULL_TREE; - - if (components == NULL_TREE) - { - t = groktypename (build_decl_list (specs, NULL_TREE)); - - if (t == NULL_TREE) - { - error ("error in component specification"); - return NULL_TREE; - } - - switch (TREE_CODE (t)) - { - case VAR_DECL: - /* Static anonymous unions come out as VAR_DECLs. */ - if (ANON_UNION_TYPE_P (TREE_TYPE (t))) - return t; - - /* We return SPECS here, because in the parser it was ending - up with not doing anything to $$, which is what SPECS - represents. */ - return specs; - break; - - case RECORD_TYPE: - /* This code may be needed for UNION_TYPEs as - well. */ - tcode = record_type_node; - if (CLASSTYPE_DECLARED_CLASS (t)) - tcode = class_type_node; - else if (IS_SIGNATURE (t)) - tcode = signature_type_node; - - if (CLASSTYPE_IS_TEMPLATE (t)) - /* In this case, the TYPE_IDENTIFIER will be something - like S, rather than S, so to get the correct name we - look at the template. */ - x = DECL_NAME (CLASSTYPE_TI_TEMPLATE (t)); - else - x = TYPE_IDENTIFIER (t); - - t = xref_tag (tcode, x, NULL_TREE, 0); - return NULL_TREE; - break; + struct pending_inline **p; + tree t; - case UNION_TYPE: - case ENUMERAL_TYPE: - if (TREE_CODE (t) == UNION_TYPE) - tcode = union_type_node; - else - tcode = enum_type_node; + specs = strip_attrs (specs); - t = xref_tag (tcode, TYPE_IDENTIFIER (t), NULL_TREE, 0); - if (ANON_UNION_TYPE_P (t)) - { - /* See also shadow_tag. */ - - struct pending_inline **p; - tree *q; - x = build_lang_field_decl (FIELD_DECL, NULL_TREE, t); - - /* Wipe out memory of synthesized methods */ - TYPE_HAS_CONSTRUCTOR (t) = 0; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - TYPE_HAS_INIT_REF (t) = 0; - TYPE_HAS_CONST_INIT_REF (t) = 0; - TYPE_HAS_ASSIGN_REF (t) = 0; - TYPE_HAS_ASSIGNMENT (t) = 0; - TYPE_HAS_CONST_ASSIGN_REF (t) = 0; - - q = &TYPE_METHODS (t); - while (*q) - { - if (DECL_ARTIFICIAL (*q)) - *q = TREE_CHAIN (*q); - else - q = &TREE_CHAIN (*q); - } - if (TYPE_METHODS (t)) - error ("an anonymous union cannot have function members"); + check_tag_decl (specs); + t = groktypename (build_decl_list (specs, NULL_TREE)); - p = &pending_inlines; - for (; *p; *p = (*p)->next) - if (DECL_CONTEXT ((*p)->fndecl) != t) - break; - } - else if (TREE_CODE (t) == ENUMERAL_TYPE) - x = grok_enum_decls (NULL_TREE); - else - x = NULL_TREE; - return x; - break; + /* The only case where we need to do anything additional here is an + anonymous union field, e.g.: `struct S { union { int i; }; };'. */ + if (t == NULL_TREE || !ANON_UNION_TYPE_P (t)) + return; - default: - if (t != void_type_node) - error ("empty component declaration"); - return NULL_TREE; - } - } - else - /* There may or may not be any enum decls to grok, but - grok_enum_decls will just return components, if there aren't - any. We used to try to figure out whether or not there were - any enum decls based on the type of components, but that's too - hard; it might be something like `enum { a } *p;'. */ - return grok_enum_decls (components); + fixup_anonymous_union (t); + finish_member_declaration (build_lang_field_decl (FIELD_DECL, + NULL_TREE, + t)); + + /* Ignore any inline function definitions in the anonymous union + since an anonymous union may not have function members. */ + p = &pending_inlines; + for (; *p; *p = (*p)->next) + if (DECL_CONTEXT ((*p)->fndecl) != t) + break; } /* Constructors for types with virtual baseclasses need an "in-charge" flag @@ -1067,8 +981,8 @@ maybe_retrofit_in_chrg (fn) QUALS are the qualifiers for the this pointer. */ void -grokclassfn (ctype, cname, function, flags, quals) - tree ctype, cname, function; +grokclassfn (ctype, function, flags, quals) + tree ctype, function; enum overload_flags flags; tree quals; { @@ -1132,16 +1046,7 @@ grokclassfn (ctype, cname, function, flags, quals) TYPE_HAS_DESTRUCTOR (ctype) = 1; } else - { - if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE) - /* Only true for static member functions. */ - arg_types = hash_tree_chain (build_pointer_type (qualtype), - arg_types); - - DECL_ASSEMBLER_NAME (function) - = build_decl_overload (fn_name, arg_types, - 1 + DECL_CONSTRUCTOR_P (function)); - } + set_mangled_name_for_decl (function); } /* Work on the expr used by alignof (this is only called by the parser). */ @@ -1157,7 +1062,7 @@ grok_alignof (expr) return build_min (ALIGNOF_EXPR, sizetype, expr); if (TREE_CODE (expr) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) + && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) error ("`__alignof__' applied to a bit-field"); if (TREE_CODE (expr) == INDIRECT_REF) @@ -1223,7 +1128,9 @@ grok_array_decl (array_expr, 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. */ + /* 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; @@ -1302,7 +1209,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete) if (doing_vec == 2) { - maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1); + maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node); pedwarn ("anachronistic use of array size in vector delete"); } @@ -1317,6 +1224,10 @@ delete_sanity (exp, size, doing_vec, use_global_delete) return error_mark_node; } + /* Deleting ptr to void is undefined behaviour [expr.delete/3]. */ + if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE) + cp_warning ("`%T' is not a pointer-to-object type", type); + /* 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 @@ -1329,7 +1240,7 @@ delete_sanity (exp, size, doing_vec, use_global_delete) if (doing_vec) return build_vec_delete (t, maxindex, integer_one_node, - integer_two_node, use_global_delete); + integer_zero_node, use_global_delete); else { if (IS_AGGR_TYPE (TREE_TYPE (type)) @@ -1392,7 +1303,7 @@ check_member_template (tmpl) /* Return true iff TYPE is a valid Java parameter or return type. */ -int +static int acceptable_java_type (type) tree type; { @@ -1403,8 +1314,22 @@ acceptable_java_type (type) type = TREE_TYPE (type); if (TREE_CODE (type) == RECORD_TYPE) { - complete_type (type); - return TYPE_FOR_JAVA (type); + tree args; int i; + if (! TYPE_FOR_JAVA (type)) + return 0; + if (! CLASSTYPE_TEMPLATE_INFO (type)) + return 1; + args = CLASSTYPE_TI_ARGS (type); + i = TREE_VEC_LENGTH (args); + while (--i >= 0) + { + type = TREE_VEC_ELT (args, i); + if (TREE_CODE (type) == POINTER_TYPE) + type = TREE_TYPE (type); + if (! TYPE_FOR_JAVA (type)) + return 0; + } + return 1; } } return 0; @@ -1415,8 +1340,8 @@ acceptable_java_type (type) Otherwise, print appropriate error messages, and return 0. */ int -check_java_method (ctype, method) - tree ctype, method; +check_java_method (method) + tree method; { int jerr = 0; tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method)); @@ -1453,8 +1378,21 @@ check_classfn (ctype, function) tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype)); tree *methods = 0; tree *end = 0; - tree templates = NULL_TREE; - + + if (DECL_USE_TEMPLATE (function) + && is_member_template (DECL_TI_TEMPLATE (function))) + /* Since this is a specialization of a member template, + we're not going to find the declaration in the class. + For example, in: + + struct S { template void f(T); }; + template <> void S::f(int); + + we're not going to find `S::f(int)', but there's no + reason we should, either. We let our callers know we didn't + find the method, but we don't complain. */ + return NULL_TREE; + if (method_vec != 0) { methods = &TREE_VEC_ELT (method_vec, 0); @@ -1468,7 +1406,7 @@ check_classfn (ctype, function) && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))) goto got_it; - while (++methods != end) + while (++methods != end && *methods) { fndecl = *methods; if (fn_name == DECL_NAME (OVL_CURRENT (*methods))) @@ -1478,14 +1416,19 @@ check_classfn (ctype, function) fndecls = OVL_NEXT (fndecls)) { fndecl = OVL_CURRENT (fndecls); - /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL is + /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or + for a for member function of a template class, is not mangled, so the check below does not work - correctly in that case. Since mangled destructor names - do not include the type of the arguments, we - can't use this short-cut for them, either. */ - if (TREE_CODE (function) != TEMPLATE_DECL - && TREE_CODE (fndecl) != TEMPLATE_DECL - && !DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)) + correctly in that case. Since mangled destructor + names do not include the type of the arguments, + we can't use this short-cut for them, either. + (It's not legal to declare arguments for a + destructor, but some people try.) */ + if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)) + && (DECL_ASSEMBLER_NAME (function) + != DECL_NAME (function)) + && (DECL_ASSEMBLER_NAME (fndecl) + != DECL_NAME (fndecl)) && (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl))) return fndecl; @@ -1505,48 +1448,23 @@ check_classfn (ctype, function) && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) p1 = TREE_CHAIN (p1); - if (comptypes (TREE_TYPE (TREE_TYPE (function)), - TREE_TYPE (TREE_TYPE (fndecl)), 1) - && compparms (p1, p2, 3) + if (same_type_p (TREE_TYPE (TREE_TYPE (function)), + TREE_TYPE (TREE_TYPE (fndecl))) + && compparms (p1, p2) && (DECL_TEMPLATE_SPECIALIZATION (function) == DECL_TEMPLATE_SPECIALIZATION (fndecl)) && (!DECL_TEMPLATE_SPECIALIZATION (function) || (DECL_TI_TEMPLATE (function) == DECL_TI_TEMPLATE (fndecl)))) return fndecl; - - if (is_member_template (fndecl)) - /* This function might be an instantiation - or specialization of fndecl. */ - templates = - scratch_tree_cons (NULL_TREE, fndecl, templates); } } break; /* loser */ } - else if (TREE_CODE (fndecl) == TEMPLATE_DECL - && IDENTIFIER_TYPENAME_P (DECL_NAME (fndecl)) - && IDENTIFIER_TYPENAME_P (fn_name)) - /* The method in the class is a member template - conversion operator. We are declaring another - conversion operator. It is possible that even though - the names don't match, there is some specialization - occurring. */ - templates = - scratch_tree_cons (NULL_TREE, fndecl, templates); } } - if (templates) - /* This function might be an instantiation or a specialization. - We should verify that this is possible. If it is, we must - somehow add the new declaration to the method vector for the - class. Perhaps we should use add_method? For now, we simply - return NULL_TREE, which lets the caller know that this - function is new, but we don't print an error message. */ - return NULL_TREE; - - if (methods != end) + if (methods != end && *methods) { tree fndecl = *methods; cp_error ("prototype for `%#D' does not match any in class `%T'", @@ -1559,16 +1477,86 @@ check_classfn (ctype, function) else { methods = 0; - cp_error ("no `%#D' member function declared in class `%T'", - function, ctype); + if (TYPE_SIZE (ctype) == 0) + incomplete_type_error (function, ctype); + else + cp_error ("no `%#D' member function declared in class `%T'", + function, ctype); } /* If we did not find the method in the class, add it to avoid - spurious errors. */ - add_method (ctype, methods, function); + spurious errors (unless the CTYPE is not yet defined, in which + case we'll only confuse ourselves when the function is declared + properly within the class. */ + if (TYPE_SIZE (ctype)) + add_method (ctype, methods, function); return NULL_TREE; } +/* We have just processed the DECL, which is a static data member. + Its initializer, if present, is INIT. The ASMSPEC_TREE, if + present, is the assembly-language name for the data member. + NEED_POP and FLAGS are as for cp_finish_decl. */ + +void +finish_static_data_member_decl (decl, init, asmspec_tree, need_pop, flags) + tree decl; + tree init; + tree asmspec_tree; + int need_pop; + int flags; +{ + char* asmspec = 0; + + if (asmspec_tree) + asmspec = TREE_STRING_POINTER (asmspec_tree); + + my_friendly_assert (TREE_PUBLIC (decl), 0); + + /* We cannot call pushdecl here, because that would fill in the + decl of our TREE_CHAIN. Instead, we modify cp_finish_decl to do + the right thing, namely, to put this decl out straight away. */ + /* current_class_type can be NULL_TREE in case of error. */ + if (!asmspec && current_class_type) + { + DECL_INITIAL (decl) = error_mark_node; + DECL_ASSEMBLER_NAME (decl) + = build_static_name (current_class_type, DECL_NAME (decl)); + } + if (! processing_template_decl) + { + if (!pending_statics) + VARRAY_TREE_INIT (pending_statics, 32, "pending_statics"); + + if (pending_statics_used == pending_statics->num_elements) + VARRAY_GROW (pending_statics, + 2 * pending_statics->num_elements); + VARRAY_TREE (pending_statics, pending_statics_used) = decl; + ++pending_statics_used; + } + + /* Static consts need not be initialized in the class definition. */ + if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) + { + static int explanation = 0; + + error ("initializer invalid for static member with constructor"); + if (explanation++ == 0) + error ("(you really want to initialize it separately)"); + init = 0; + } + /* Force the compiler to know when an uninitialized static const + member is being used. */ + if (CP_TYPE_CONST_P (TREE_TYPE (decl)) && init == 0) + TREE_USED (decl) = 1; + DECL_INITIAL (decl) = init; + DECL_IN_AGGR_P (decl) = 1; + DECL_CONTEXT (decl) = current_class_type; + DECL_CLASS_CONTEXT (decl) = current_class_type; + + cp_finish_decl (decl, init, asmspec_tree, need_pop, flags); +} + /* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) of a structure component, returning a FIELD_DECL node. QUALS is a list of type qualifiers for this decl (such as for declaring @@ -1618,7 +1606,7 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0)))) ; else if (TREE_COMPLEXITY (declarator) == current_class_depth) - pop_nested_class (1); + pop_nested_class (); return do_class_using_decl (declarator); } @@ -1628,9 +1616,10 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) && TREE_CHAIN (init) == NULL_TREE) init = NULL_TREE; - value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE); - if (! value) - return value; /* friend or constructor went bad. */ + value = grokdeclarator (declarator, declspecs, FIELD, init != 0, attrlist); + if (! value || value == error_mark_node) + /* friend or constructor went bad. */ + return value; /* Pass friendly classes back. */ if (TREE_CODE (value) == VOID_TYPE) @@ -1648,15 +1637,14 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) DECL_NONLOCAL (value) = 1; DECL_CONTEXT (value) = current_class_type; DECL_CLASS_CONTEXT (value) = current_class_type; - CLASSTYPE_LOCAL_TYPEDECLS (current_class_type) = 1; /* Now that we've updated the context, we need to remangle the name for this TYPE_DECL. */ DECL_ASSEMBLER_NAME (value) = DECL_NAME (value); - DECL_ASSEMBLER_NAME (value) = - get_identifier (build_overload_name (TREE_TYPE (value), 1, 1)); + if (!uses_template_parms (value)) + DECL_ASSEMBLER_NAME (value) = + get_identifier (build_overload_name (TREE_TYPE (value), 1, 1)); - pushdecl_class_level (value); return value; } @@ -1669,8 +1657,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) if (DECL_IN_AGGR_P (value)) { - cp_error ("`%D' is already defined in the class %T", value, - DECL_CONTEXT (value)); + cp_error ("`%D' is already defined in `%T'", value, + DECL_CONTEXT (value)); return void_type_node; } @@ -1748,44 +1736,8 @@ grokfield (declarator, declspecs, init, asmspec_tree, attrlist) if (TREE_CODE (value) == VAR_DECL) { - my_friendly_assert (TREE_PUBLIC (value), 0); - - /* We cannot call pushdecl here, because that would - fill in the value of our TREE_CHAIN. Instead, we - modify cp_finish_decl to do the right thing, namely, to - put this decl out straight away. */ - /* current_class_type can be NULL_TREE in case of error. */ - if (asmspec == 0 && current_class_type) - { - TREE_PUBLIC (value) = 1; - DECL_INITIAL (value) = error_mark_node; - DECL_ASSEMBLER_NAME (value) - = build_static_name (current_class_type, DECL_NAME (value)); - } - if (! processing_template_decl) - pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics); - - /* Static consts need not be initialized in the class definition. */ - if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value))) - { - static int explanation = 0; - - error ("initializer invalid for static member with constructor"); - if (explanation++ == 0) - error ("(you really want to initialize it separately)"); - init = 0; - } - /* Force the compiler to know when an uninitialized static - const member is being used. */ - if (TYPE_READONLY (value) && init == 0) - TREE_USED (value) = 1; - DECL_INITIAL (value) = init; - DECL_IN_AGGR_P (value) = 1; - DECL_CONTEXT (value) = current_class_type; - DECL_CLASS_CONTEXT (value) = current_class_type; - - cp_finish_decl (value, init, asmspec_tree, 1, flags); - pushdecl_class_level (value); + finish_static_data_member_decl (value, init, asmspec_tree, + /*need_pop=*/1, flags); return value; } if (TREE_CODE (value) == FIELD_DECL) @@ -1855,6 +1807,17 @@ grokbitfield (declarator, declspecs, width) return NULL_TREE; } + /* Usually, finish_struct_1 catches bitifields with invalid types. + But, in the case of bitfields with function type, we confuse + ourselves into thinking they are member functions, so we must + check here. */ + if (TREE_CODE (value) == FUNCTION_DECL) + { + cp_error ("cannot declare bitfield `%D' with funcion type", + DECL_NAME (value)); + return NULL_TREE; + } + if (IS_SIGNATURE (current_class_type)) { error ("field declaration not allowed in signature"); @@ -1881,7 +1844,7 @@ grokbitfield (declarator, declspecs, width) { constant_expression_warning (width); DECL_INITIAL (value) = width; - DECL_BIT_FIELD (value) = 1; + SET_DECL_C_BIT_FIELD (value); } DECL_IN_AGGR_P (value) = 1; @@ -1934,7 +1897,7 @@ grokoptypename (declspecs, declarator) int copy_assignment_arg_p (parmtype, virtualp) tree parmtype; - int virtualp; + int virtualp ATTRIBUTE_UNUSED; { if (current_class_type == NULL_TREE) return 0; @@ -2093,28 +2056,14 @@ mark_inline_for_output (decl) return; my_friendly_assert (TREE_PERMANENT (decl), 363); DECL_SAVED_INLINE (decl) = 1; -#if 0 - if (DECL_PENDING_INLINE_INFO (decl) != 0 - && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu) - { - struct pending_inline *t = pending_inlines; - my_friendly_assert (DECL_SAVED_INSNS (decl) == 0, 198); - while (t) - { - if (t == DECL_PENDING_INLINE_INFO (decl)) - break; - t = t->next; - } - if (t == 0) - { - t = DECL_PENDING_INLINE_INFO (decl); - t->next = pending_inlines; - pending_inlines = t; - } - DECL_PENDING_INLINE_INFO (decl) = 0; - } -#endif - saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines); + if (!saved_inlines) + VARRAY_TREE_INIT (saved_inlines, 32, "saved_inlines"); + + if (saved_inlines_used == saved_inlines->num_elements) + VARRAY_GROW (saved_inlines, + 2 * saved_inlines->num_elements); + VARRAY_TREE (saved_inlines, saved_inlines_used) = decl; + ++saved_inlines_used; } void @@ -2198,7 +2147,7 @@ get_temp_regvar (type, init) returns a VAR_DECL whose size is the same as the size of the ANON_DECL, if one is available. */ -tree +static tree build_anon_union_vars (anon_decl, elems, static_p, external_p) tree anon_decl; tree* elems; @@ -2214,8 +2163,15 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p) field = TREE_CHAIN (field)) { tree decl; - if (TREE_CODE (field) != FIELD_DECL) + + 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", + field); + continue; + } if (TREE_PRIVATE (field)) cp_pedwarn_at ("private member `%#D' in anonymous union", field); @@ -2229,6 +2185,8 @@ build_anon_union_vars (anon_decl, elems, static_p, external_p) if (!decl) continue; } + else if (DECL_NAME (field) == NULL_TREE) + continue; else { decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); @@ -2297,18 +2255,16 @@ finish_anon_union (anon_union_decl) main_decl = build_anon_union_vars (anon_union_decl, &elems, static_p, external_p); + if (main_decl == NULL_TREE) + { + warning ("anonymous union with no members"); + return; + } + if (static_p) { - if (main_decl) - { - make_decl_rtl (main_decl, 0, toplevel_bindings_p ()); - DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); - } - else - { - warning ("anonymous union with no members"); - return; - } + make_decl_rtl (main_decl, 0, toplevel_bindings_p ()); + DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); } /* The following call assumes that there are never any cleanups @@ -2326,7 +2282,7 @@ finish_anon_union (anon_union_decl) void finish_builtin_type (type, name, fields, len, align_type) tree type; - char *name; + const char *name; tree fields[]; int len; tree align_type; @@ -2365,15 +2321,14 @@ coerce_new_type (type) if (TREE_CODE (type) == METHOD_TYPE) type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); - if (TREE_TYPE (type) != ptr_type_node) + if (! same_type_p (TREE_TYPE (type), ptr_type_node)) e1 = 1, error ("`operator new' must return type `void *'"); /* Technically the type must be `size_t', but we may not know what that is. */ if (TYPE_ARG_TYPES (type) == NULL_TREE) e1 = 1, error ("`operator new' takes type `size_t' parameter"); - else if (TREE_CODE (TREE_VALUE (TYPE_ARG_TYPES (type))) != INTEGER_TYPE - || TYPE_PRECISION (TREE_VALUE (TYPE_ARG_TYPES (type))) != TYPE_PRECISION (sizetype)) + else if (! same_type_p (TREE_VALUE (TYPE_ARG_TYPES (type)), sizetype)) e2 = 1, error ("`operator new' takes type `size_t' as first parameter"); if (e2) type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type)))); @@ -2402,7 +2357,7 @@ coerce_delete_type (type) e1 = 1, error ("`operator delete' must return type `void'"); if (arg_types == NULL_TREE - || TREE_VALUE (arg_types) != ptr_type_node) + || ! same_type_p (TREE_VALUE (arg_types), ptr_type_node)) e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); #if 0 @@ -2413,8 +2368,7 @@ coerce_delete_type (type) /* Again, technically this argument must be `size_t', but again we may not know what that is. */ tree t2 = TREE_VALUE (TREE_CHAIN (arg_types)); - if (TREE_CODE (t2) != INTEGER_TYPE - || TYPE_PRECISION (t2) != TYPE_PRECISION (sizetype)) + if (! same_type_p (t2, sizetype)) e3 = 1, error ("second argument to `operator delete' must be of type `size_t'"); else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node) { @@ -2456,21 +2410,19 @@ mark_vtable_entries (decl) { tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl)); - if (flag_rtti) - { - tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (TREE_CHAIN (entries)) - : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); - tree fn = TREE_OPERAND (fnaddr, 0); - TREE_ADDRESSABLE (fn) = 1; - mark_used (fn); - } - skip_rtti_stuff (&entries); - for (; entries; entries = TREE_CHAIN (entries)) { - tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) - : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); - tree fn = TREE_OPERAND (fnaddr, 0); + tree fnaddr; + tree fn; + + fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) + : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); + + if (TREE_CODE (fnaddr) == NOP_EXPR) + /* RTTI offset. */ + continue; + + fn = TREE_OPERAND (fnaddr, 0); TREE_ADDRESSABLE (fn) = 1; if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn)) { @@ -2496,8 +2448,30 @@ comdat_linkage (decl) { if (flag_weak) make_decl_one_only (decl); - else + else if (TREE_CODE (decl) == FUNCTION_DECL || DECL_VIRTUAL_P (decl)) + /* We can just emit functions and vtables statically; it doesn't really + matter if we have multiple copies. */ TREE_PUBLIC (decl) = 0; + else + { + /* Static data member template instantiations, however, cannot + have multiple copies. */ + if (DECL_INITIAL (decl) == 0 + || DECL_INITIAL (decl) == error_mark_node) + DECL_COMMON (decl) = 1; + else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) + { + DECL_COMMON (decl) = 1; + DECL_INITIAL (decl) = error_mark_node; + } + else + { + /* We can't do anything useful; leave vars for explicit + instantiation. */ + DECL_EXTERNAL (decl) = 1; + DECL_NOT_REALLY_EXTERN (decl) = 0; + } + } if (DECL_LANG_SPECIFIC (decl)) DECL_COMDAT (decl) = 1; @@ -2517,14 +2491,14 @@ maybe_make_one_only (decl) return; /* We can't set DECL_COMDAT on functions, or finish_file will think - we can get away with not emitting them if they aren't used. - We can't use make_decl_one_only for variables, because their - DECL_INITIAL may not have been set properly yet. */ + we can get away with not emitting them if they aren't used. We need + to for variables so that cp_finish_decl will update their linkage, + because their DECL_INITIAL may not have been set properly yet. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - make_decl_one_only (decl); - else - comdat_linkage (decl); + make_decl_one_only (decl); + + if (TREE_CODE (decl) == VAR_DECL && DECL_LANG_SPECIFIC (decl)) + DECL_COMDAT (decl) = 1; } /* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL, @@ -2541,12 +2515,10 @@ import_export_vtable (decl, type, final) if (DECL_INTERFACE_KNOWN (decl)) return; - /* +e0 or +e1 */ - if (write_virtuals < 2 && write_virtuals != 0) + if (TYPE_FOR_JAVA (type)) { TREE_PUBLIC (decl) = 1; - if (write_virtuals < 0) - DECL_EXTERNAL (decl) = 1; + DECL_EXTERNAL (decl) = 1; DECL_INTERFACE_KNOWN (decl) = 1; } else if (CLASSTYPE_INTERFACE_KNOWN (type)) @@ -2554,11 +2526,6 @@ import_export_vtable (decl, type, final) TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); DECL_INTERFACE_KNOWN (decl) = 1; - - /* For WIN32 we also want to put explicit instantiations in - linkonce sections. */ - if (CLASSTYPE_EXPLICIT_INSTANTIATION (type)) - maybe_make_one_only (decl); } else { @@ -2567,7 +2534,6 @@ import_export_vtable (decl, type, final) int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); -#ifndef MULTIPLE_SYMBOL_SPACES if (! found && ! final) { tree method; @@ -2581,7 +2547,6 @@ import_export_vtable (decl, type, final) break; } } -#endif if (final || ! found) { @@ -2609,10 +2574,20 @@ import_export_class (ctype) if (CLASSTYPE_INTERFACE_KNOWN (ctype)) return; + /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma interface, + we will have CLASSTYPE_INTERFACE_ONLY set but not + CLASSTYPE_INTERFACE_KNOWN. In that case, we don't want to use this + heuristic because someone will supply a #pragma implementation + elsewhere, and deducing it here would produce a conflict. */ + if (CLASSTYPE_INTERFACE_ONLY (ctype)) + return; + #ifdef VALID_MACHINE_TYPE_ATTRIBUTE /* FIXME this should really use some sort of target-independent macro. */ if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype))) import_export = -1; + else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype))) + import_export = 1; #endif /* If we got -fno-implicit-templates, we import template classes that @@ -2622,7 +2597,6 @@ import_export_class (ctype) && ! flag_implicit_templates) import_export = -1; -#ifndef MULTIPLE_SYMBOL_SPACES /* Base our import/export status on that of the first non-inline, non-abstract virtual function, if any. */ if (import_export == 0 @@ -2642,6 +2616,10 @@ import_export_class (ctype) } } } + +#ifdef MULTIPLE_SYMBOL_SPACES + if (import_export == -1) + import_export = 0; #endif if (import_export) @@ -2652,21 +2630,48 @@ import_export_class (ctype) } } -static int -finish_vtable_vardecl (prev, vars) - tree prev, vars; +/* 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; { - tree ctype = DECL_CONTEXT (vars); - import_export_class (ctype); - import_export_vtable (vars, ctype, 1); + tree parent; + rtx op[2]; - if (write_virtuals >= 0 - && ! DECL_EXTERNAL (vars) - && ((TREE_PUBLIC (vars) && ! DECL_WEAK (vars) && ! DECL_ONE_ONLY (vars)) - || CLASSTYPE_EXPLICIT_INSTANTIATION (DECL_CONTEXT (vars)) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)) - || (hack_decl_function_context (vars) && TREE_USED (vars))) - && ! TREE_ASM_WRITTEN (vars)) + op[0] = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */ + + parent = binfo_for_vtable (vars); + + if (parent == TYPE_BINFO (DECL_CONTEXT (vars))) + op[1] = const0_rtx; + else if (parent) + { + parent = TYPE_BINFO_VTABLE (BINFO_TYPE (parent)); + op[1] = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */ + } + else + my_friendly_abort (980826); + + output_asm_insn (".vtable_inherit %c0, %c1", op); +} + +static int +finish_vtable_vardecl (t, data) + tree *t; + void *data ATTRIBUTE_UNUSED; +{ + tree vars = *t; + tree ctype = DECL_CONTEXT (vars); + import_export_class (ctype); + import_export_vtable (vars, ctype, 1); + + if (! DECL_EXTERNAL (vars) + && (DECL_INTERFACE_KNOWN (vars) + || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)) + || (hack_decl_function_context (vars) && TREE_USED (vars))) + && ! TREE_ASM_WRITTEN (vars)) { /* Write it out. */ mark_vtable_entries (vars); @@ -2699,101 +2704,46 @@ finish_vtable_vardecl (prev, vars) DECL_IGNORED_P (vars) = 1; } + /* Always make vtables weak. */ + if (flag_weak) + comdat_linkage (vars); + rest_of_decl_compilation (vars, NULL_PTR, 1, 1); + + if (flag_vtable_gc) + output_vtable_inherit (vars); + return 1; } else if (! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars))) /* We don't know what to do with this one yet. */ return 0; - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); + *t = TREE_CHAIN (vars); return 0; } static int -prune_vtable_vardecl (prev, vars) - tree prev, vars; +prune_vtable_vardecl (t, data) + tree *t; + void *data ATTRIBUTE_UNUSED; { - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); + *t = TREE_CHAIN (*t); return 1; } -int -walk_vtables (typedecl_fn, vardecl_fn) - register void (*typedecl_fn) PROTO ((tree, tree)); - register int (*vardecl_fn) PROTO ((tree, tree)); -{ - tree prev, vars; - int flag = 0; - - for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) - { - register tree type = TREE_TYPE (vars); - - if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) - { - if (vardecl_fn) - flag |= (*vardecl_fn) (prev, vars); - - if (prev && TREE_CHAIN (prev) != vars) - continue; - } - else if (TREE_CODE (vars) == TYPE_DECL - && type != error_mark_node - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_VSIZE (type)) - { - if (typedecl_fn) (*typedecl_fn) (prev, vars); - } - - prev = vars; - } - - return flag; -} - -static void -finish_sigtable_vardecl (prev, vars) - tree prev, vars; +static int +finish_sigtable_vardecl (t, data) + tree *t; + void *data ATTRIBUTE_UNUSED; { /* We don't need to mark sigtable entries as addressable here as is done for vtables. Since sigtables, unlike vtables, are always written out, that was already done in build_signature_table_constructor. */ - rest_of_decl_compilation (vars, NULL_PTR, 1, 1); - - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); -} - -void -walk_sigtables (typedecl_fn, vardecl_fn) - register void (*typedecl_fn) PROTO((tree, tree)); - register void (*vardecl_fn) PROTO((tree, tree)); -{ - tree prev, vars; - - for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) - { - register tree type = TREE_TYPE (vars); - - if (TREE_CODE (vars) == TYPE_DECL - && type != error_mark_node - && IS_SIGNATURE (type)) - { - if (typedecl_fn) (*typedecl_fn) (prev, vars); - } - else if (TREE_CODE (vars) == VAR_DECL - && TREE_TYPE (vars) != error_mark_node - && IS_SIGNATURE (TREE_TYPE (vars))) - { - if (vardecl_fn) (*vardecl_fn) (prev, vars); - } - else - prev = vars; - } + rest_of_decl_compilation (*t, NULL_PTR, 1, 1); + *t = TREE_CHAIN (*t); + return 1; } /* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an @@ -2806,20 +2756,21 @@ import_export_decl (decl) if (DECL_INTERFACE_KNOWN (decl)) return; - if (DECL_TEMPLATE_INSTANTIATION (decl)) + if (DECL_TEMPLATE_INSTANTIATION (decl) + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) { DECL_NOT_REALLY_EXTERN (decl) = 1; - if (DECL_IMPLICIT_INSTANTIATION (decl) - && (flag_implicit_templates || DECL_THIS_INLINE (decl))) + if ((DECL_IMPLICIT_INSTANTIATION (decl) + || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) + && (flag_implicit_templates + || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl)))) { if (!TREE_PUBLIC (decl)) /* Templates are allowed to have internal linkage. See [basic.link]. */ ; - else if (TREE_CODE (decl) == FUNCTION_DECL) - comdat_linkage (decl); else - DECL_COMDAT (decl) = 1; + comdat_linkage (decl); } else DECL_NOT_REALLY_EXTERN (decl) = 0; @@ -2833,13 +2784,19 @@ import_export_decl (decl) { DECL_NOT_REALLY_EXTERN (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); + || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines + && !DECL_VINDEX (decl))); + + /* Always make artificials weak. */ + if (DECL_ARTIFICIAL (decl) && flag_weak) + comdat_linkage (decl); + else + maybe_make_one_only (decl); } else comdat_linkage (decl); } - /* tinfo function */ - else if (DECL_ARTIFICIAL (decl) && DECL_MUTABLE_P (decl)) + else if (DECL_TINFO_FN_P (decl)) { tree ctype = TREE_TYPE (DECL_NAME (decl)); @@ -2853,18 +2810,19 @@ import_export_decl (decl) since it will not be emitted when the vtable for the type is output (which is when the unqualified version is generated). */ - && ctype == TYPE_MAIN_VARIANT (ctype)) + && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) { DECL_NOT_REALLY_EXTERN (decl) = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); + || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines + && !DECL_VINDEX (decl))); - /* For WIN32 we also want to put explicit instantiations in - linkonce sections. */ - if (CLASSTYPE_EXPLICIT_INSTANTIATION (ctype)) - maybe_make_one_only (decl); + /* Always make artificials weak. */ + if (flag_weak) + comdat_linkage (decl); } - else if (TYPE_BUILT_IN (ctype) && ctype == TYPE_MAIN_VARIANT (ctype)) + else if (TYPE_BUILT_IN (ctype) + && same_type_p (ctype, TYPE_MAIN_VARIANT (ctype))) DECL_NOT_REALLY_EXTERN (decl) = 0; else comdat_linkage (decl); @@ -2896,8 +2854,6 @@ build_cleanup (decl) } extern int parse_time, varconst_time; -extern tree pending_templates; -extern tree maybe_templates; static tree get_sentry (base) @@ -2929,14 +2885,30 @@ get_sentry (base) or destructors. Subroutine of do_[cd]tors. */ static void -start_objects (method_type) - int method_type; +start_objects (method_type, initp) + int method_type, initp; { tree fnname; + char type[10]; /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ - fnname = get_file_function_name (method_type); + if (initp != DEFAULT_INIT_PRIORITY) + { + char joiner; + +#ifdef JOINER + joiner = JOINER; +#else + joiner = '_'; +#endif + + sprintf (type, "%c%c%.5u", method_type, joiner, initp); + } + else + sprintf (type, "%c", method_type); + + fnname = get_file_function_name_long (type); start_function (void_list_node, make_call_declarator (fnname, void_list_node, NULL_TREE, @@ -2954,29 +2926,23 @@ start_objects (method_type) clear_last_expr (); push_momentary (); expand_start_bindings (0); + + /* 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 + out anyhow. */ + current_function_cannot_inline + = "static constructors and destructors cannot be inlined"; } /* Finish the process of running a particular set of global constructors or destructors. Subroutine of do_[cd]tors. */ static void -finish_objects (method_type) - int method_type; +finish_objects (method_type, initp) + int method_type, initp; { - char *fnname; - - tree list = (method_type == 'I' ? static_ctors : static_dtors); - - if (! current_function_decl && list) - start_objects (method_type); - - for (; list; list = TREE_CHAIN (list)) - expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE)); - - if (! current_function_decl) - return; - - fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); + char *fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); /* Finish up. */ expand_end_bindings (getdecls (), 1, 0); @@ -2984,422 +2950,790 @@ finish_objects (method_type) pop_momentary (); finish_function (lineno, 0, 0); - if (method_type == 'I') - assemble_constructor (fnname); + if (initp == DEFAULT_INIT_PRIORITY) + { + if (method_type == 'I') + assemble_constructor (fnname); + else + assemble_destructor (fnname); + } + +#if defined (ASM_OUTPUT_SECTION_NAME) && defined (ASM_OUTPUT_CONSTRUCTOR) + /* If we're using init priority we can't use assemble_*tor, but on ELF + targets we can stick the references into named sections for GNU ld + to collect. */ else - assemble_destructor (fnname); + { + char buf[15]; + sprintf (buf, ".%ctors.%.5u", method_type == 'I' ? 'c' : 'd', + /* invert the numbering so the linker puts us in the proper + order; constructors are run from right to left, and the + linker sorts in increasing order. */ + MAX_INIT_PRIORITY - initp); + named_section (NULL_TREE, buf, 0); + assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname), + POINTER_SIZE / BITS_PER_UNIT, 1); + } +#endif } -/* Generate a function to run a set of global destructors. Subroutine of - finish_file. */ +/* The names of the parameters to the function created to handle + initializations and destructions for objects with static storage + duration. */ +#define INITIALIZE_P_IDENTIFIER "__initialize_p" +#define PRIORITY_IDENTIFIER "__priority" + +/* The name of the function we create to handle initializations and + destructions for objects with static storage duration. */ +#define SSDF_IDENTIFIER "__static_initialization_and_destruction" + +/* The declaration for the __INITIALIZE_P argument. */ +static tree initialize_p_decl; + +/* The declaration for the __PRIORITY argument. */ +static tree priority_decl; + +/* The declaration for the static storage duration function. */ +static tree ssdf_decl; + +/* All the static storage duration functions created in this + translation unit. */ +static varray_type ssdf_decls; +static size_t ssdf_decls_used; + +/* A map from priority levels to information about that priority + level. There may be many such levels, so efficient lookup is + important. */ +static splay_tree priority_info_map; + +/* Begins the generation of the function that will handle all + initialization and destruction of objects with static storage + duration. The function generated takes two parameters of type + `int': __INITIALIZE_P and __PRIORITY. If __INITIALIZE_P is + non-zero, it performs initializations. Otherwise, it performs + destructions. It only performs those initializations or + destructions with the indicated __PRIORITY. The generated function + returns no value. + + It is assumed that this function will only be called once per + translation unit. */ static void -do_dtors () +start_static_storage_duration_function () { - tree vars = static_aggregates; + static unsigned ssdf_number; - for (; vars; vars = TREE_CHAIN (vars)) + tree parm_types; + tree type; + char id[sizeof (SSDF_IDENTIFIER) + 1 /* '\0' */ + 32]; + + /* Create the identifier for this function. It will be of the form + SSDF_IDENTIFIER_. */ + sprintf (id, "%s_%u", SSDF_IDENTIFIER, ssdf_number++); + if (ssdf_number == 0) { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - tree temp; + /* Overflow occurred. That means there are at least 4 billion + initialization functions. */ + sorry ("too many initialization functions required"); + my_friendly_abort (19990430); + } - if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars) - && ! DECL_EXTERNAL (decl)) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); + /* Create the parameters. */ + parm_types = void_list_node; + parm_types = perm_tree_cons (NULL_TREE, integer_type_node, parm_types); + parm_types = perm_tree_cons (NULL_TREE, integer_type_node, parm_types); + type = build_function_type (void_type_node, parm_types); + + /* Create the FUNCTION_DECL itself. */ + ssdf_decl = build_lang_decl (FUNCTION_DECL, + get_identifier (id), + type); + TREE_PUBLIC (ssdf_decl) = 0; + DECL_ARTIFICIAL (ssdf_decl) = 1; + + /* Put this function in the list of functions to be called from the + static constructors and destructors. */ + if (!ssdf_decls) + { + VARRAY_TREE_INIT (ssdf_decls, 32, "ssdf_decls"); + + /* Take this opportunity to initialize the map from priority + numbers to information about that priority level. */ + priority_info_map = splay_tree_new (splay_tree_compare_ints, + /*delete_key_fn=*/0, + /*delete_value_fn=*/ + (splay_tree_delete_value_fn) &free); + + /* We always need to generate functions for the + DEFAULT_INIT_PRIORITY so enter it now. That way when we walk + priorities later, we'll be sure to find the + DEFAULT_INIT_PRIORITY. */ + get_priority_info (DEFAULT_INIT_PRIORITY); + } + + if (ssdf_decls_used == ssdf_decls->num_elements) + VARRAY_GROW (ssdf_decls, 2 * ssdf_decls_used); + VARRAY_TREE (ssdf_decls, ssdf_decls_used) = ssdf_decl; + ++ssdf_decls_used; + + /* Create the argument list. */ + initialize_p_decl = build_decl (PARM_DECL, + get_identifier (INITIALIZE_P_IDENTIFIER), + integer_type_node); + DECL_CONTEXT (initialize_p_decl) = ssdf_decl; + DECL_ARG_TYPE (initialize_p_decl) = integer_type_node; + TREE_USED (initialize_p_decl) = 1; + priority_decl = build_decl (PARM_DECL, get_identifier (PRIORITY_IDENTIFIER), + integer_type_node); + DECL_CONTEXT (priority_decl) = ssdf_decl; + DECL_ARG_TYPE (priority_decl) = integer_type_node; + TREE_USED (priority_decl) = 1; + + TREE_CHAIN (initialize_p_decl) = priority_decl; + DECL_ARGUMENTS (ssdf_decl) = initialize_p_decl; + + /* Start the function itself. This is equivalent to declarating the + function as: + + static void __ssdf (int __initialize_p, init __priority_p); + + It is static because we only need to call this function from the + various constructor and destructor functions for this module. */ + start_function (/*specs=*/NULL_TREE, + ssdf_decl, + /*attrs=*/NULL_TREE, + /*pre_parsed_p=*/1); + + /* Set up the scope of the outermost block in the function. */ + store_parm_decls (); + pushlevel (0); + clear_last_expr (); + push_momentary (); + expand_start_bindings (0); - if (! current_function_decl) - start_objects ('D'); + /* This function must not be deferred because we are depending on + its compilation to tell us what is TREE_SYMBOL_REFERENCED. */ + current_function_cannot_inline + = "static storage duration functions cannot be inlined"; +} - temp = build_cleanup (decl); +/* Generate the initialization code for the priority indicated in N. */ - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0); - sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1); - expand_start_cond (sentry, 0); - } +static int +generate_inits_for_priority (n, data) + splay_tree_node n; + void *data ATTRIBUTE_UNUSED; +{ + int priority = (int) n->key; + priority_info pi = (priority_info) n->value; + + /* For each priority N which has been used generate code which looks + like: + + if (__priority == N) { + if (__initialize_p) + ... + else + ... + } + + We use the sequences we've accumulated to fill in the `...'s. */ + expand_start_cond (build_binary_op (EQ_EXPR, + priority_decl, + build_int_2 (priority, 0)), + /*exit_flag=*/0); + + /* Do the initializations. */ + expand_start_cond (build_binary_op (NE_EXPR, + initialize_p_decl, + integer_zero_node), + /*exit_flag=*/0); + if (pi->initialization_sequence) + { + rtx insns; - expand_expr_stmt (temp); + push_to_sequence (pi->initialization_sequence); + insns = gen_sequence (); + end_sequence (); - if (protect) - expand_end_cond (); - } + emit_insn (insns); + pi->initialization_sequence = NULL_RTX; + pi->initializations_p = 1; + } + + /* Do the destructions. */ + expand_start_else (); + if (pi->destruction_sequence) + { + rtx insns; + + push_to_sequence (pi->destruction_sequence); + insns = gen_sequence (); + end_sequence (); + + emit_insn (insns); + pi->destruction_sequence = NULL_RTX; + pi->destructions_p = 1; } + + /* Close out the conditionals. */ + expand_end_cond (); + expand_end_cond (); - finish_objects ('D'); + /* Don't stop iterating. */ + return 0; } -/* Generate a function to run a set of global constructors. Subroutine of - finish_file. */ +/* Finish the generation of the function which performs initialization + and destruction of objects with static storage duration. After + this point, no more such objects can be created. */ static void -do_ctors () +finish_static_storage_duration_function () { - tree vars = static_aggregates; + splay_tree_foreach (priority_info_map, + generate_inits_for_priority, + /*data=*/0); - /* Reverse the list so it's in the right order for ctors. */ - vars = nreverse (vars); + /* Close out the function. */ + expand_end_bindings (getdecls (), 1, 0); + poplevel (1, 0, 0); + pop_momentary (); + finish_function (lineno, 0, 0); +} + +/* Return the information about the indicated PRIORITY level. If no + code to handle this level has yet been generated, generate the + appropriate prologue. */ - for (; vars; vars = TREE_CHAIN (vars)) +static priority_info +get_priority_info (priority) + int priority; +{ + priority_info pi; + splay_tree_node n; + + n = splay_tree_lookup (priority_info_map, + (splay_tree_key) priority); + if (!n) { - tree decl = TREE_VALUE (vars); - tree init = TREE_PURPOSE (vars); - - /* If this was a static attribute within some function's scope, - then don't initialize it here. Also, don't bother - with initializers that contain errors. */ - if (TREE_STATIC (vars) - || DECL_EXTERNAL (decl) - || (init && TREE_CODE (init) == TREE_LIST - && value_member (error_mark_node, init))) - continue; + /* Create a new priority information structure, and insert it + into the map. */ + pi = (priority_info) xmalloc (sizeof (struct priority_info_s)); + pi->initialization_sequence = NULL_RTX; + pi->destruction_sequence = NULL_RTX; + pi->initializations_p = 0; + pi->destructions_p = 0; + splay_tree_insert (priority_info_map, + (splay_tree_key) priority, + (splay_tree_value) pi); + } + else + pi = (priority_info) n->value; - if (TREE_CODE (decl) == VAR_DECL) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); - - if (! current_function_decl) - start_objects ('I'); - - /* Set these global variables so that GDB at least puts - us near the declaration which required the initialization. */ - input_filename = DECL_SOURCE_FILE (decl); - lineno = DECL_SOURCE_LINE (decl); - emit_note (input_filename, lineno); - - /* 9.5p5: The initializer of a static member of a class has - the same access rights as a member function. */ - if (member_p (decl)) - { - DECL_CLASS_CONTEXT (current_function_decl) - = DECL_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (current_function_decl) = 1; - } + return pi; +} - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0); - sentry = build_binary_op - (EQ_EXPR, sentry, integer_one_node, 1); - expand_start_cond (sentry, 0); - } +/* Generate code to do the static initialization of DECL. The + initialization is INIT. If DECL may be initialized more than once + in different object files, SENTRY is the guard variable to + check. PRIORITY is the priority for the initialization. */ - expand_start_target_temps (); +static void +do_static_initialization (decl, init, sentry, priority) + tree decl; + tree init; + tree sentry; + int priority; +{ + priority_info pi; - if (IS_AGGR_TYPE (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - expand_aggr_init (decl, init, 0, 0); - else if (TREE_CODE (init) == TREE_VEC) - { - expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), - TREE_VEC_ELT (init, 1), - TREE_VEC_ELT (init, 2), 0), - const0_rtx, VOIDmode, EXPAND_NORMAL); - } - else - expand_assignment (decl, init, 0, 0); - - /* The expression might have involved increments and - decrements. */ - emit_queue (); + /* Get the priority information for this PRIORITY, */ + pi = get_priority_info (priority); + if (!pi->initialization_sequence) + start_sequence (); + else + push_to_sequence (pi->initialization_sequence); + + /* Tell the debugger that we are at the location of the static + variable in question. */ + emit_note (input_filename, lineno); + + /* If there's a SENTRY, we only do the initialization if it is + zero, i.e., if we are the first to initialize it. */ + if (sentry) + expand_start_cond (build_binary_op (EQ_EXPR, + build_unary_op (PREINCREMENT_EXPR, + sentry, + /*noconvert=*/0), + integer_one_node), + /*exit_flag=*/0); + + /* Prepare a binding level for temporaries created during the + initialization. */ + expand_start_target_temps (); + + if (IS_AGGR_TYPE (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) + expand_aggr_init (decl, init, 0); + else if (TREE_CODE (init) == TREE_VEC) + expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), + TREE_VEC_ELT (init, 1), + TREE_VEC_ELT (init, 2), 0), + const0_rtx, VOIDmode, EXPAND_NORMAL); + else + expand_assignment (decl, init, 0, 0); + + /* The expression might have involved increments and decrements. */ + emit_queue (); - /* Cleanup any temporaries needed for the initial value. */ - expand_end_target_temps (); + /* Cleanup any temporaries needed for the initial value. */ + expand_end_target_temps (); - if (protect) - expand_end_cond (); + /* Cleanup any deferred pops from function calls. This would be done + by expand_end_cond, but we also need it when !SENTRY, since we are + constructing these sequences by parts. */ + do_pending_stack_adjust (); - DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; - DECL_STATIC_FUNCTION_P (current_function_decl) = 0; - } - else if (decl == error_mark_node) - /* OK */; - else - my_friendly_abort (22); - } + /* Close the conditional opened above. */ + if (sentry) + expand_end_cond (); - finish_objects ('I'); + /* Save the sequence for later use. */ + pi->initialization_sequence = get_insns (); + end_sequence (); } -/* 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. */ +/* Generate code to do the static destruction of DECL. If DECL may be + initialized more than once in different object files, SENTRY is the + guard variable to check. PRIORITY is the priority for the + destruction. */ -void -finish_file () +static void +do_static_destruction (decl, sentry, priority) + tree decl; + tree sentry; + int priority; { - extern int lineno; - int start_time, this_time; + rtx new_insns; + priority_info pi; - tree fnname; - tree vars; - int needs_cleaning = 0, needs_messing_up = 0; + /* If we don't need a destructor, there's nothing to do. */ + if (!TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) + return; + + /* Get the priority information for this PRIORITY, */ + pi = get_priority_info (priority); + if (!pi->destruction_sequence) + start_sequence (); + else + push_to_sequence (pi->destruction_sequence); - at_eof = 1; + /* Start a new sequence to handle just this destruction. */ + start_sequence (); - /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type) - return; + /* Tell the debugger that we are at the location of the static + variable in question. */ + emit_note (input_filename, lineno); + + /* If there's a SENTRY, we only do the destruction if it is one, + i.e., if we are the last to destroy it. */ + if (sentry) + expand_start_cond (build_binary_op (EQ_EXPR, + build_unary_op (PREDECREMENT_EXPR, + sentry, + /*nonconvert=*/1), + integer_zero_node), + /*exit_flag=*/0); + + /* Actually to the destruction. */ + expand_expr_stmt (build_cleanup (decl)); + + /* Cleanup any deferred pops from function calls. This would be done + by expand_end_cond, but we also need it when !SENTRY, since we are + constructing these sequences by parts. */ + do_pending_stack_adjust (); + + /* Close the conditional opened above. */ + if (sentry) + expand_end_cond (); + + /* Insert the NEW_INSNS before the current insns. (Destructions are + run in reverse order of initializations.) */ + new_insns = gen_sequence (); + end_sequence (); + if (pi->destruction_sequence) + emit_insn_before (new_insns, pi->destruction_sequence); + else + emit_insn (new_insns); - check_decl_namespace (); + /* Save the sequence for later use. */ + pi->destruction_sequence = get_insns (); + end_sequence (); +} - start_time = get_run_time (); +/* Add code to the static storage duration function that will handle + DECL (a static variable that needs initializing and/or destruction) + with the indicated PRIORITY. If DECL needs initializing, INIT is + the initializer. */ - /* Otherwise, GDB can get confused, because in only knows - about source for LINENO-1 lines. */ - lineno -= 1; +static void +do_static_initialization_and_destruction (decl, init) + tree decl; + tree init; +{ + tree sentry = NULL_TREE; + int priority; - interface_unknown = 1; - interface_only = 0; + /* Deal gracefully with error. */ + if (decl == error_mark_node) + return; - for (fnname = pending_templates; fnname; fnname = TREE_CHAIN (fnname)) - { - tree srcloc = TREE_PURPOSE (fnname); - tree decl = TREE_VALUE (fnname); + /* The only things that can be initialized are variables. */ + my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 19990420); - input_filename = SRCLOC_FILE (srcloc); - lineno = SRCLOC_LINE (srcloc); + /* If this object is not defined, we don't need to do anything + here. */ + if (DECL_EXTERNAL (decl)) + return; - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') - { - instantiate_class_template (decl); - if (CLASSTYPE_TEMPLATE_INSTANTIATION (decl)) - for (vars = TYPE_METHODS (decl); vars; vars = TREE_CHAIN (vars)) - if (! DECL_ARTIFICIAL (vars)) - instantiate_decl (vars); - } - else - instantiate_decl (decl); - } + /* Also, if the initializer already contains errors, we can bail out + now. */ + if (init && TREE_CODE (init) == TREE_LIST + && value_member (error_mark_node, init)) + return; - for (fnname = maybe_templates; fnname; fnname = TREE_CHAIN (fnname)) - { - tree args, fn, decl = TREE_VALUE (fnname); + /* Trick the compiler into thinking we are at the file and line + 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); - if (DECL_INITIAL (decl)) - continue; + /* Because of: - fn = TREE_PURPOSE (fnname); - args = get_bindings (fn, decl, NULL_TREE); - fn = instantiate_template (fn, args); - instantiate_decl (fn); - } + [class.access.spec] - cat_namespace_levels(); + Access control for implicit calls to the constructors, + the conversion functions, or the destructor called to + create and destroy a static data member is performed as + if these calls appeared in the scope of the member's + class. - /* Push into C language context, because that's all - we'll need here. */ - push_lang_context (lang_name_c); + we pretend we are in a static member function of the class of + which the DECL is a member. */ + if (member_p (decl)) + { + DECL_CLASS_CONTEXT (current_function_decl) = DECL_CONTEXT (decl); + DECL_STATIC_FUNCTION_P (current_function_decl) = 1; + } + + /* We need a sentry if this is an object with external linkage that + might be initialized in more than one place. */ + if (TREE_PUBLIC (decl) && (DECL_COMMON (decl) + || DECL_ONE_ONLY (decl) + || DECL_WEAK (decl))) + sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); + + /* Generate the code to actually do the intialization and + destruction. */ + priority = DECL_INIT_PRIORITY (decl); + if (!priority) + priority = DEFAULT_INIT_PRIORITY; + do_static_initialization (decl, init, sentry, priority); + do_static_destruction (decl, sentry, priority); + + /* Now that we're done with DECL we don't need to pretend to be a + member of its class any longer. */ + DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; + DECL_STATIC_FUNCTION_P (current_function_decl) = 0; +} -#if 1 - /* The reason for pushing garbage onto the global_binding_level is to - ensure that we can slice out _DECLs which pertain to virtual function - tables. If the last thing pushed onto the global_binding_level was a - virtual function table, then slicing it out would slice away all the - decls (i.e., we lose the head of the chain). - - There are several ways of getting the same effect, from changing the - way that iterators over the chain treat the elements that pertain to - virtual function tables, moving the implementation of this code to - decl.c (where we can manipulate global_binding_level directly), - popping the garbage after pushing it and slicing away the vtable - stuff, or just leaving it alone. */ - - /* Make last thing in global scope not be a virtual function table. */ -#if 0 /* not yet, should get fixed properly later */ - vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node); -#else - vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node); -#endif - DECL_IGNORED_P (vars) = 1; - SET_DECL_ARTIFICIAL (vars); - pushdecl (vars); -#endif +/* Generate a static constructor (if CONSTRUCTOR_P) or destructor + (otherwise) that will initialize all gobal objects with static + storage duration having the indicated PRIORITY. */ - for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars)) - if (! TREE_ASM_WRITTEN (TREE_VALUE (vars))) - rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1); - vars = static_aggregates; +static void +generate_ctor_or_dtor_function (constructor_p, priority) + int constructor_p; + int priority; +{ + char function_key; + tree arguments; + size_t i; + + /* We use `I' to indicate initialization and `D' to indicate + destruction. */ + if (constructor_p) + function_key = 'I'; + else + function_key = 'D'; - if (static_ctors || vars) - needs_messing_up = 1; - if (static_dtors || vars) - needs_cleaning = 1; + /* Begin the function. */ + start_objects (function_key, priority); - /* The aggregates are listed in reverse declaration order, for cleaning. */ - if (needs_cleaning) + /* Call the static storage duration function with appropriate + arguments. */ + for (i = 0; i < ssdf_decls_used; ++i) { - do_dtors (); + arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0), + NULL_TREE); + arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0), + arguments); + expand_expr_stmt (build_function_call (VARRAY_TREE (ssdf_decls, i), + arguments)); } - /* do_ctors will reverse the lists for messing up. */ - if (needs_messing_up) + /* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in + calls to any functions marked with attributes indicating that + they should be called at initialization- or destruction-time. */ + if (priority == DEFAULT_INIT_PRIORITY) { - do_ctors (); + tree fns; + + for (fns = constructor_p ? static_ctors : static_dtors; + fns; + fns = TREE_CHAIN (fns)) + expand_expr_stmt (build_function_call (TREE_VALUE (fns), NULL_TREE)); } - permanent_allocation (1); + /* Close out the function. */ + finish_objects (function_key, priority); +} - /* Done with C language context needs. */ - pop_lang_context (); +/* Generate constructor and destructor functions for the priority + indicated by N. */ - /* Now write out any static class variables (which may have since - learned how to be initialized). */ - while (pending_statics) - { - tree decl = TREE_VALUE (pending_statics); +static int +generate_ctor_and_dtor_functions_for_priority (n, data) + splay_tree_node n; + void *data ATTRIBUTE_UNUSED; +{ + int priority = (int) n->key; + priority_info pi = (priority_info) n->value; + + /* Generate the functions themselves, but only if they are really + needed. */ + if (pi->initializations_p + || (priority == DEFAULT_INIT_PRIORITY && static_ctors)) + generate_ctor_or_dtor_function (/*constructor_p=*/1, + priority); + if (pi->destructions_p + || (priority == DEFAULT_INIT_PRIORITY && static_dtors)) + generate_ctor_or_dtor_function (/*constructor_p=*/0, + priority); + + /* Keep iterating. */ + return 0; +} - /* Output DWARF debug information. */ -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_file_scope_decl (decl, 1); -#endif -#ifdef DWARF2_DEBUGGING_INFO - if (write_symbols == DWARF2_DEBUG) - dwarf2out_decl (decl); -#endif +/* 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. */ - DECL_DEFER_OUTPUT (decl) = 0; - rest_of_decl_compilation - (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1); +void +finish_file () +{ + extern int lineno; + int start_time, this_time; + tree vars; + int reconsider; + size_t i; - pending_statics = TREE_CHAIN (pending_statics); - } + at_eof = 1; - this_time = get_run_time (); - parse_time -= this_time - start_time; - varconst_time += this_time - start_time; + /* Bad parse errors. Just forget about it. */ + if (! global_bindings_p () || current_class_type || decl_namespace_list) + return; start_time = get_run_time (); - if (flag_handle_signatures) - walk_sigtables ((void (*) PROTO ((tree, tree))) 0, - finish_sigtable_vardecl); + /* Otherwise, GDB can get confused, because in only knows + about source for LINENO-1 lines. */ + lineno -= 1; - for (fnname = saved_inlines; fnname; fnname = TREE_CHAIN (fnname)) - { - tree decl = TREE_VALUE (fnname); - import_export_decl (decl); - } + interface_unknown = 1; + interface_only = 0; - mark_all_runtime_matches (); + /* We now have to write out all the stuff we put off writing out. + These include: - /* Now write out inline functions which had their addresses taken and - which were not declared virtual and which were not declared `extern - inline'. */ - { - int reconsider = 1; /* More may be referenced; check again */ + o Template specializations that we have not yet instantiated, + but which are needed. + o Initialization and destruction for non-local objects with + static storage duration. (Local objects with static storage + duration are initialized when their scope is first entered, + and are cleaned up via atexit.) + o Virtual function tables. - while (reconsider) - { - tree *p = &saved_inlines; - reconsider = 0; + All of these may cause others to be needed. For example, + instantiating one function may cause another to be needed, and + generating the intiailzer for an object may cause templates to be + instantiated, etc., etc. */ - /* We need to do this each time so that newly completed template - types don't wind up at the front of the list. Sigh. */ - vars = build_decl (TYPE_DECL, make_anon_name (), integer_type_node); - DECL_IGNORED_P (vars) = 1; - SET_DECL_ARTIFICIAL (vars); - pushdecl (vars); + this_time = get_run_time (); + parse_time -= this_time - start_time; + varconst_time += this_time - start_time; + start_time = get_run_time (); + permanent_allocation (1); - reconsider |= walk_vtables ((void (*) PROTO((tree, tree))) 0, - finish_vtable_vardecl); + do + { + /* Non-zero if we need a static storage duration function on + this iteration through the loop. */ + int need_ssdf_p = 0; + + reconsider = 0; + + /* If there are templates that we've put off instantiating, do + them now. */ + instantiate_pending_templates (); + + /* Write out signature-tables and 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 (flag_handle_signatures + && walk_globals (sigtable_decl_p, + finish_sigtable_vardecl, + /*data=*/0)) + reconsider = 1; + if (walk_globals (vtable_decl_p, + finish_vtable_vardecl, + /*data=*/0)) + reconsider = 1; + + /* The list of objects with static storage duration is built up + in reverse order, so we reverse it here. We also clear + STATIC_AGGREGATES so that any new aggregates added during the + initialization of these will be initialized in the correct + order when we next come around the loop. */ + vars = nreverse (static_aggregates); + static_aggregates = NULL_TREE; + while (vars) + { + if (! TREE_ASM_WRITTEN (TREE_VALUE (vars))) + rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1); + if (!need_ssdf_p) + { + /* We need to start a new initialization function each + time through the loop. That's because we need to + know which vtables have been referenced, and + TREE_SYMBOL_REFERENCED isn't computed until a + function is finished, and written out. That's a + deficiency in the back-end. When this is fixed, + these initialization functions could all become + inline, with resulting performance improvements. */ + start_static_storage_duration_function (); + need_ssdf_p = 1; + } - while (*p) - { - tree decl = TREE_VALUE (*p); + do_static_initialization_and_destruction (TREE_VALUE (vars), + TREE_PURPOSE (vars)); + reconsider = 1; + vars = TREE_CHAIN (vars); + } + + /* Finish up the static storage duration function for this + round. */ + if (need_ssdf_p) + finish_static_storage_duration_function (); + + /* Go through the various inline functions, and see if any need + synthesizing. */ + for (i = 0; i < saved_inlines_used; ++i) + { + tree decl = VARRAY_TREE (saved_inlines, i); + import_export_decl (decl); + if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) + && TREE_USED (decl) + && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) + { + /* Even though we're already at the top-level, we push + there again. That way, when we pop back a few lines + hence, all of our state is restored. Otherwise, + finish_function doesn't clean things up, and we end + up with CURRENT_FUNCTION_DECL set. */ + push_to_top_level (); + if (DECL_TINFO_FN_P (decl)) + synthesize_tinfo_fn (decl); + else + synthesize_method (decl); + pop_from_top_level (); + reconsider = 1; + } + } - if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) - && TREE_USED (decl) - && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) - { - if (DECL_MUTABLE_P (decl)) - synthesize_tinfo_fn (decl); - else - synthesize_method (decl); - reconsider = 1; - } + /* Mark all functions that might deal with exception-handling as + referenced. */ + mark_all_runtime_matches (); - /* Catch new template instantiations. */ - if (decl != TREE_VALUE (*p)) - continue; - - if (TREE_ASM_WRITTEN (decl) - || (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl))) - *p = TREE_CHAIN (*p); - else if (DECL_INITIAL (decl) == 0) - p = &TREE_CHAIN (*p); - else if ((TREE_PUBLIC (decl) && ! DECL_COMDAT (decl)) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) - || flag_keep_inline_functions) - { - if (DECL_NOT_REALLY_EXTERN (decl)) - { - DECL_EXTERNAL (decl) = 0; - reconsider = 1; - /* We can't inline this function after it's been - emitted. We want a variant of - output_inline_function that doesn't prevent - subsequent integration... */ - DECL_INLINE (decl) = 0; - output_inline_function (decl); - permanent_allocation (1); - } - - *p = TREE_CHAIN (*p); - } - else - p = &TREE_CHAIN (*p); - } - } + /* 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 unncessarily. But, we must stop lying + when the functions are referenced, or if they are not comdat + since they need to be put out now. */ + for (i = 0; i < saved_inlines_used; ++i) + { + tree decl = VARRAY_TREE (saved_inlines, i); + + if (DECL_NOT_REALLY_EXTERN (decl) + && DECL_INITIAL (decl) + && (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) + || !DECL_COMDAT (decl))) + DECL_EXTERNAL (decl) = 0; + } - /* It's possible that some of the remaining inlines will still be - needed. For example, a static inline whose address is used in - the initializer for a file-scope static variable will be - needed. Code in compile_file will handle this, but we mustn't - pretend that there are no definitions for the inlines, or it - won't be able to. + if (saved_inlines_used + && wrapup_global_declarations (&VARRAY_TREE (saved_inlines, 0), + saved_inlines_used)) + reconsider = 1; + if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0)) + reconsider = 1; - FIXME: This won't catch member functions. We should really - unify this stuff with the compile_file stuff. */ - for (vars = saved_inlines; vars != NULL_TREE; vars = TREE_CHAIN (vars)) - { - tree decl = TREE_VALUE (vars); + /* 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)) + continue; + import_export_decl (decl); + if (DECL_NOT_REALLY_EXTERN (decl) && ! DECL_IN_AGGR_P (decl)) + DECL_EXTERNAL (decl) = 0; + } + if (pending_statics + && wrapup_global_declarations (&VARRAY_TREE (pending_statics, 0), + pending_statics_used)) + reconsider = 1; + } + while (reconsider); - if (DECL_NOT_REALLY_EXTERN (decl) - && !DECL_COMDAT (decl) - && DECL_INITIAL (decl) != NULL_TREE) - DECL_EXTERNAL (decl) = 0; - } - } + /* We give C linkage to static constructors and destructors. */ + push_lang_context (lang_name_c); - /* Now delete from the chain of variables all virtual function tables. - We output them all ourselves, because each will be treated specially. */ + /* Generate initialization and destruction functions for all + priorities for which they are required. */ + if (priority_info_map) + splay_tree_foreach (priority_info_map, + generate_ctor_and_dtor_functions_for_priority, + /*data=*/0); - walk_vtables ((void (*) PROTO((tree, tree))) 0, - prune_vtable_vardecl); + /* We're done with the splay-tree now. */ + if (priority_info_map) + splay_tree_delete (priority_info_map); - if (write_virtuals == 2) - { - /* Now complain about an virtual function tables promised - but not delivered. */ - while (pending_vtables) - { - if (TREE_PURPOSE (pending_vtables) == NULL_TREE) - error ("virtual function table for `%s' not defined", - IDENTIFIER_POINTER (TREE_VALUE (pending_vtables))); - pending_vtables = TREE_CHAIN (pending_vtables); - } - } + /* We're done with static constructors, so we can go back to "C++" + linkage now. */ + pop_lang_context (); + + /* Now delete from the chain of variables all virtual function tables. + We output them all ourselves, because each will be treated + specially. */ + walk_globals (vtable_decl_p, prune_vtable_vardecl, /*data=*/0); + + /* Now, issue warnings about static, but not defined, functions, + etc. */ + walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider); finish_repo (); @@ -3432,11 +3766,13 @@ reparse_absdcl_as_expr (type, decl) return build_functional_cast (type, NULL_TREE); /* recurse */ - decl = reparse_decl_as_expr (type, TREE_OPERAND (decl, 0)); + decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0)); decl = build_x_function_call (decl, NULL_TREE, current_class_ref); - if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node) + if (TREE_CODE (decl) == CALL_EXPR + && (! TREE_TYPE (decl) + || TREE_CODE (TREE_TYPE (decl)) != VOID_TYPE)) decl = require_complete_type (decl); return decl; @@ -3484,7 +3820,8 @@ reparse_absdcl_as_casts (decl, expr) expr = build_c_cast (type, expr); } - if (warn_old_style_cast) + if (warn_old_style_cast && ! in_system_header + && current_lang_name != lang_name_c) warning ("use of old-style cast"); return expr; @@ -3655,11 +3992,30 @@ build_expr_from_tree (t) TREE_OPERAND (ref, 1), build_expr_from_tree (TREE_OPERAND (t, 2))); } - return build_method_call - (build_expr_from_tree (TREE_OPERAND (t, 1)), - TREE_OPERAND (t, 0), - build_expr_from_tree (TREE_OPERAND (t, 2)), - NULL_TREE, LOOKUP_NORMAL); + 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) @@ -3716,10 +4072,22 @@ build_expr_from_tree (t) } case COMPONENT_REF: - return build_x_component_ref - (build_expr_from_tree (TREE_OPERAND (t, 0)), - TREE_OPERAND (t, 1), NULL_TREE, 1); - + { + tree object = build_expr_from_tree (TREE_OPERAND (t, 0)); + tree field = TREE_OPERAND (t, 1); + + /* We use a COMPONENT_REF to indicate things of the form `x.b' + and `x.A::b'. We must distinguish between those cases + here. */ + if (TREE_CODE (field) == SCOPE_REF) + return build_object_ref (object, + TREE_OPERAND (field, 0), + TREE_OPERAND (field, 1)); + else + return build_x_component_ref (object, field, + NULL_TREE, 1); + } + case THROW_EXPR: return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0))); @@ -3733,6 +4101,7 @@ build_expr_from_tree (t) r = build_nt (CONSTRUCTOR, NULL_TREE, build_expr_from_tree (CONSTRUCTOR_ELTS (t))); + TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); if (TREE_TYPE (t)) return digest_init (TREE_TYPE (t), r, 0); @@ -3800,6 +4169,10 @@ finish_decl_parsing (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; default: my_friendly_abort (5); return NULL_TREE; @@ -3916,7 +4289,9 @@ add_using_namespace (user, used, indirect) /* 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). */ + 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) @@ -3958,8 +4333,7 @@ ambiguous_decl (name, old, new, flags) /* If we expect types or namespaces, and not templates, or this is not a template class. */ if (LOOKUP_QUALIFIERS_ONLY (flags) - && (!(flags & LOOKUP_TEMPLATES_EXPECTED) - || !DECL_CLASS_TEMPLATE_P (val))) + && !DECL_CLASS_TEMPLATE_P (val)) val = NULL_TREE; break; case TYPE_DECL: @@ -3990,9 +4364,15 @@ ambiguous_decl (name, old, new, flags) /* Some declarations are functions, some are not. */ if (flags & LOOKUP_COMPLAIN) { - cp_error ("use of `%D' is ambiguous", name); - cp_error_at (" first declared as `%#D' here", - BINDING_VALUE (old)); + /* 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) + { + cp_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); } return error_mark_node; @@ -4086,9 +4466,10 @@ qualified_lookup_using_namespace (name, scope, result, flags) outside scope. */ void -set_decl_namespace (decl, scope) +set_decl_namespace (decl, scope, friendp) tree decl; tree scope; + int friendp; { tree old; if (scope == std_node) @@ -4096,7 +4477,8 @@ set_decl_namespace (decl, scope) /* Get rid of namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); - if (!is_namespace_ancestor (current_namespace, scope)) + /* It is ok for friends to be qualified in parallel space. */ + if (!friendp && !is_namespace_ancestor (current_namespace, scope)) cp_error ("declaration of `%D' not in a namespace surrounding `%D'", decl, scope); DECL_CONTEXT (decl) = FROB_CONTEXT (scope); @@ -4115,6 +4497,12 @@ set_decl_namespace (decl, scope) /* 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; @@ -4128,7 +4516,7 @@ set_decl_namespace (decl, scope) /* Compute the namespace where a declaration is defined. */ -tree +static tree decl_namespace (decl) tree decl; { @@ -4181,10 +4569,28 @@ pop_decl_namespace () decl_namespace_list = TREE_CHAIN (decl_namespace_list); } -static void -check_decl_namespace () +/* Enter a class or namespace scope. */ + +void +push_scope (t) + tree t; +{ + if (TREE_CODE (t) == NAMESPACE_DECL) + push_decl_namespace (t); + else + pushclass (t, 2); +} + +/* Leave scope pushed by push_scope. */ + +void +pop_scope (t) + tree t; { - my_friendly_assert (decl_namespace_list == NULL_TREE, 980711); + if (TREE_CODE (t) == NAMESPACE_DECL) + pop_decl_namespace (); + else + popclass (); } /* [basic.lookup.koenig] */ @@ -4201,6 +4607,10 @@ struct arg_lookup static int arg_assoc PROTO((struct arg_lookup*, tree)); static int arg_assoc_args PROTO((struct arg_lookup*, tree)); +static int arg_assoc_type PROTO((struct arg_lookup*, tree)); +static int add_function PROTO((struct arg_lookup *, tree)); +static int arg_assoc_namespace PROTO((struct arg_lookup *, tree)); +static int arg_assoc_class PROTO((struct arg_lookup *, tree)); /* Add a function to the lookup structure. Returns 1 on error. */ @@ -4300,7 +4710,7 @@ arg_assoc_class (k, type) /* Process template arguments. */ if (CLASSTYPE_TEMPLATE_INFO (type)) { - list = innermost_args (CLASSTYPE_TI_ARGS (type), 0); + list = innermost_args (CLASSTYPE_TI_ARGS (type)); for (i = 0; i < TREE_VEC_LENGTH (list); ++i) arg_assoc (k, TREE_VEC_ELT (list, i)); } @@ -4351,6 +4761,7 @@ arg_assoc_type (k, type) /* Associate the return type. */ return arg_assoc_type (k, TREE_TYPE (type)); case TEMPLATE_TYPE_PARM: + case TEMPLATE_TEMPLATE_PARM: return 0; case LANG_TYPE: if (type == unknown_type_node) @@ -4393,14 +4804,80 @@ arg_assoc (k, 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); - my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715); + 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; 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. ] */ + tree template = TREE_OPERAND (n, 0); + tree args = TREE_OPERAND (n, 1); + tree ctx; + tree arg; + + /* 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; - for (; n; n = TREE_CHAIN (n)) - if (arg_assoc (k, OVL_FUNCTION (n))) - return 1; + /* Now the arguments. */ + for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) + { + tree t = TREE_VALUE (arg); + + if (TREE_CODE (t) == TEMPLATE_DECL) + { + ctx = CP_DECL_CONTEXT (t); + if (TREE_CODE (ctx) == NAMESPACE_DECL) + { + if (arg_assoc_namespace (k, ctx) == 1) + return 1; + } + else if (arg_assoc_class (k, ctx) == 1) + return 1; + } + else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't' + && arg_assoc_type (k, t) == 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; } @@ -4432,9 +4909,6 @@ void do_namespace_alias (alias, namespace) tree alias, namespace; { - tree binding; - tree old; - if (TREE_CODE (namespace) != NAMESPACE_DECL) { /* The parser did not find it, so it's not there. */ @@ -4462,6 +4936,16 @@ validate_nonmember_using_decl (decl, scope, name) if (TREE_CODE (decl) == SCOPE_REF && TREE_OPERAND (decl, 0) == std_node) { + if (namespace_bindings_p () + && current_namespace == global_namespace) + /* There's no need for a using declaration at all, here, + since `std' is the same as `::'. We can't just pass this + on because we'll complain later about declaring something + in the same scope as a using declaration with the same + name. We return NULL_TREE which indicates to the caller + that there's no need to do any further processing. */ + return NULL_TREE; + *scope = global_namespace; *name = TREE_OPERAND (decl, 1); } @@ -4469,9 +4953,23 @@ validate_nonmember_using_decl (decl, scope, name) { *scope = TREE_OPERAND (decl, 0); *name = TREE_OPERAND (decl, 1); + + /* [namespace.udecl] + + A using-declaration for a class member shall be a + member-declaration. */ + if (TREE_CODE (*scope) != NAMESPACE_DECL) + { + if (TYPE_P (*scope)) + cp_error ("`%T' is not a namespace", *scope); + else + cp_error ("`%D' is not a namespace", *scope); + return NULL_TREE; + } } else if (TREE_CODE (decl) == IDENTIFIER_NODE - || TREE_CODE (decl) == TYPE_DECL) + || TREE_CODE (decl) == TYPE_DECL + || TREE_CODE (decl) == TEMPLATE_DECL) { *scope = global_namespace; *name = decl; @@ -4521,17 +5019,37 @@ do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) *newval = oldval; for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp)) { - /* Compare each new function with each old one. - If the old function was also used, there is no conflict. */ + 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)) - if (OVL_CURRENT (tmp) == OVL_CURRENT (tmp1)) - break; - else if (OVL_USED (tmp1)) - continue; - else if (duplicate_decls (OVL_CURRENT (tmp), OVL_CURRENT (tmp1))) - return; + { + tree old_fn = OVL_CURRENT (tmp1); + + if (!OVL_USED (tmp1) + && 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. */ + cp_error ("`%D' is already declared in this scope", + name); + break; + } + else if (duplicate_decls (new_fn, old_fn)) + /* We're re-using something we already used + before. We don't need to add it again. */ + break; + } - /* Duplicate use, ignore */ + /* 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; @@ -4604,7 +5122,27 @@ do_local_using_decl (decl) do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); if (newval) - set_identifier_local_value (name, 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); } @@ -4694,31 +5232,61 @@ mark_used (decl) if (processing_template_decl) return; assemble_external (decl); + /* Is it a synthesized method that needs to be synthesized? */ if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CLASS_CONTEXT (decl) && DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) /* Kludge: don't synthesize for default args. */ && current_function_decl) synthesize_method (decl); - if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) + + /* If this is a function or variable that is an instance of some + template, we now know that we will need to actually do the + instantiation. A TEMPLATE_DECL may also have DECL_TEMPLATE_INFO, + if it's a partial instantiation, but there's no need to + instantiate such a thing. We check that DECL is not an explicit + instantiation because that is not checked in instantiate_decl. */ + if (TREE_CODE (decl) != TEMPLATE_DECL + && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && !DECL_EXPLICIT_INSTANTIATION (decl)) instantiate_decl (decl); } -/* Helper function for named_class_head_sans_basetype nonterminal. */ +/* Helper function for named_class_head_sans_basetype nonterminal. We + have just seen something of the form `AGGR SCOPE::ID'. Return a + TYPE_DECL for the type declared by ID in SCOPE. */ tree handle_class_head (aggr, scope, id) tree aggr, scope, id; { + tree decl; + if (TREE_CODE (id) == TYPE_DECL) - return id; + decl = id; + else if (DECL_CLASS_TEMPLATE_P (id)) + decl = DECL_TEMPLATE_RESULT (id); + else + { + if (scope) + cp_error ("`%T' does not have a nested type named `%D'", scope, id); + else + cp_error ("no file-scope type named `%D'", id); + + decl = TYPE_MAIN_DECL (xref_tag (aggr, make_anon_name (), 1)); + } - if (scope) - cp_error ("`%T' does not have a nested type named `%D'", scope, id); - else - cp_error ("no file-scope type named `%D'", id); + /* This syntax is only allowed when we're defining a type, so we + enter the SCOPE. */ + push_scope (CP_DECL_CONTEXT (decl)); + + /* If we see something like: - id = xref_tag - (aggr, make_anon_name (), NULL_TREE, 1); - return TYPE_MAIN_DECL (id); + template struct S::I .... + + we must create a TEMPLATE_DECL for the nested type. */ + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + decl = push_template_decl (decl); + + return decl; } diff --git a/contrib/gcc/cp/errfn.c b/contrib/gcc/cp/errfn.c index 8d20682..b5d3eec 100644 --- a/contrib/gcc/cp/errfn.c +++ b/contrib/gcc/cp/errfn.c @@ -1,5 +1,5 @@ /* Provide a call-back mechanism for handling error output. - Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc. Contributed by Jason Merrill (jason@cygnus.com) This file is part of GNU CC. @@ -22,14 +22,9 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" #include "tree.h" +#include "cp-tree.h" #include "toplev.h" -#ifdef __STDC__ -#include -#else -#include -#endif - /* cp_printer is the type of a function which converts an argument into a string for digestion by printf. The cp_printer function should deal with all memory management; the functions in this file will not free @@ -45,25 +40,19 @@ int cp_silent = 0; typedef void errorfn (); /* deliberately vague */ -extern char* cp_file_of PROTO((tree)); -extern int cp_line_of PROTO((tree)); +static void cp_thing PROTO ((errorfn *, int, const char *, va_list)); #define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap) /* This function supports only `%s', `%d', `%%', and the C++ print codes. */ -#ifdef __STDC__ -static void -cp_thing (errorfn *errfn, int atarg1, const char *format, va_list ap) -#else static void cp_thing (errfn, atarg1, format, ap) errorfn *errfn; int atarg1; const char *format; va_list ap; -#endif { static char *buf; static long buflen; @@ -155,18 +144,15 @@ cp_thing (errfn, atarg1, format, ap) } else if (*f == '%') { - /* A `%%' has occurred in the input string. Since the - string we produce here will be passed to vprintf we must - preserve both `%' characters. */ + /* A `%%' has occurred in the input string. Replace it with + a `%' in the formatted message buf. */ - len += 2; - if (len > buflen) + if (++len > buflen) { buflen = len; buf = xrealloc (buf, len); } - strcpy (buf + offset, "%%"); - offset += 2; + buf[offset++] = '%'; } else { @@ -196,88 +182,170 @@ cp_thing (errfn, atarg1, format, ap) { char *file = cp_file_of (atarg); int line = cp_line_of (atarg); - (*errfn) (file, line, buf); + (*errfn) (file, line, "%s", buf); } else - (*errfn) (buf); + (*errfn) ("%s", buf); } -#ifdef __STDC__ -#define DECLARE(name) void name (const char *format, ...) -#define INIT va_start (ap, format) -#else -#define DECLARE(name) void name (format, va_alist) char *format; va_dcl -#define INIT va_start (ap) -#endif - -DECLARE (cp_error) +void +cp_error VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) error, 0, format, ap); va_end (ap); } -DECLARE (cp_warning) +void +cp_warning VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) warning, 0, format, ap); va_end (ap); } -DECLARE (cp_pedwarn) +void +cp_pedwarn VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) pedwarn, 0, format, ap); va_end (ap); } -DECLARE (cp_compiler_error) +void +cp_compiler_error VPROTO((const char *format, ...)) { - extern errorfn compiler_error; +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) - cp_thing (compiler_error, 0, format, ap); + cp_thing ((errorfn *) compiler_error, 0, format, ap); va_end (ap); } -DECLARE (cp_sprintf) +void +cp_deprecated (msg) + const char *msg; { + extern int warn_deprecated; + if (!warn_deprecated) + return; + cp_warning ("%s is deprecated.", msg); + cp_warning ("Please see the documentation for details."); +} + +void +cp_sprintf VPROTO((const char *format, ...)) +{ +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + cp_thing ((errorfn *) sprintf, 0, format, ap); va_end (ap); } -DECLARE (cp_error_at) +void +cp_error_at VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) error_with_file_and_line, 1, format, ap); va_end (ap); } -DECLARE (cp_warning_at) +void +cp_warning_at VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) warning_with_file_and_line, 1, format, ap); va_end (ap); } -DECLARE (cp_pedwarn_at) +void +cp_pedwarn_at VPROTO((const char *format, ...)) { +#ifndef ANSI_PROTOTYPES + char *format; +#endif va_list ap; - INIT; + + VA_START (ap, format); + +#ifndef ANSI_PROTOTYPES + format = va_arg (ap, char *); +#endif + if (! cp_silent) cp_thing ((errorfn *) pedwarn_with_file_and_line, 1, format, ap); va_end (ap); diff --git a/contrib/gcc/cp/error.c b/contrib/gcc/cp/error.c index bb21bcb..4da1d2f 100644 --- a/contrib/gcc/cp/error.c +++ b/contrib/gcc/cp/error.c @@ -1,6 +1,6 @@ /* Call-backs for C++ error reporting. This code is non-reentrant. - Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1993, 94-97, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -32,6 +32,7 @@ typedef char* cp_printer (); #define C code_as_string #define D decl_as_string #define E expr_as_string +#define F fndecl_as_string #define L language_as_string #define O op_as_string #define P parm_as_string @@ -47,7 +48,7 @@ cp_printer * cp_printers[256] = o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */ - o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */ + o, A, o, C, D, E, F, o, o, o, o, o, L, o, o, O, /* 0x40 */ P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */ o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */ @@ -55,6 +56,7 @@ cp_printer * cp_printers[256] = #undef C #undef D #undef E +#undef F #undef L #undef O #undef P @@ -84,6 +86,11 @@ static char *scratch_firstobj; OB_PUTCP (digit_buffer); } while (0) # define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N)); +# define OB_END_TEMPLATE_ID() \ + ((obstack_next_free (&scratch_obstack) != obstack_base (&scratch_obstack) \ + && obstack_next_free (&scratch_obstack)[-1] == '>') \ + ? OB_PUTC2 (' ', '>') : OB_PUTC ('>')) + # define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) enum pad { none, before, after }; @@ -102,10 +109,13 @@ static void dump_type_suffix PROTO((tree, int, int)); static void dump_function_name PROTO((tree)); static void dump_expr_list PROTO((tree)); static void dump_global_iord PROTO((tree)); -static void dump_readonly_or_volatile PROTO((tree, enum pad)); +static void dump_qualifiers PROTO((tree, enum pad)); static void dump_char PROTO((int)); +static void dump_parameters PROTO((tree, int, int)); +static void dump_exception_spec PROTO((tree, int)); static char *aggr_variety PROTO((tree)); static tree ident_fndecl PROTO((tree)); +static int interesting_scope_p PROTO((tree)); void init_error () @@ -114,20 +124,61 @@ init_error () scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); } +/* Returns nonzero if SCOPE is something we want to print for random decls. */ + +static int +interesting_scope_p (scope) + tree scope; +{ + if (scope == NULL_TREE + || scope == global_namespace) + return 0; + + return (TREE_CODE (scope) == NAMESPACE_DECL + || AGGREGATE_TYPE_P (scope)); +} + static void -dump_readonly_or_volatile (t, p) +dump_qualifiers (t, p) tree t; enum pad p; { - if (TYPE_READONLY (t) || TYPE_VOLATILE (t)) + if (TYPE_QUALS (t)) { if (p == before) OB_PUTC (' '); - if (TYPE_READONLY (t)) - OB_PUTS ("const"); - if (TYPE_READONLY (t) && TYPE_VOLATILE (t)) - OB_PUTC (' '); - if (TYPE_VOLATILE (t)) - OB_PUTS ("volatile"); + switch (TYPE_QUALS (t)) + { + case TYPE_QUAL_CONST: + OB_PUTS ("const"); + break; + + case TYPE_QUAL_VOLATILE: + OB_PUTS ("volatile"); + break; + + case TYPE_QUAL_RESTRICT: + OB_PUTS ("__restrict"); + break; + + case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: + OB_PUTS ("const volatile"); + break; + + case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: + OB_PUTS ("const __restrict"); + break; + + case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: + OB_PUTS ("volatile __restrict"); + break; + + case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: + OB_PUTS ("const volatile __restrict"); + break; + + default: + my_friendly_abort (0); + } if (p == after) OB_PUTC (' '); } } @@ -161,26 +212,8 @@ dump_type_real (t, v, canonical_name) break; case TREE_LIST: - /* i.e. function taking no arguments */ - if (t != void_list_node) - { - dump_type_real (TREE_VALUE (t), v, canonical_name); - /* Can this happen other than for default arguments? */ - if (TREE_PURPOSE (t) && v) - { - OB_PUTS (" = "); - dump_expr (TREE_PURPOSE (t), 0); - } - if (TREE_CHAIN (t)) - { - if (TREE_CHAIN (t) != void_list_node) - { - OB_PUTC2 (',', ' '); - dump_type_real (TREE_CHAIN (t), v, canonical_name); - } - } - else OB_PUTS (" ..."); - } + /* A list of function parms. */ + dump_parameters (t, 0, canonical_name); break; case IDENTIFIER_NODE: @@ -197,8 +230,7 @@ dump_type_real (t, v, canonical_name) if (TYPE_LANG_SPECIFIC (t) && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t))) { - if (TYPE_READONLY (t) | TYPE_VOLATILE (t)) - dump_readonly_or_volatile (t, after); + dump_qualifiers (t, after); dump_type_real (SIGNATURE_TYPE (t), v, canonical_name); if (IS_SIGNATURE_POINTER (t)) OB_PUTC ('*'); @@ -211,6 +243,7 @@ dump_type_real (t, v, canonical_name) case TYPE_DECL: case TEMPLATE_DECL: + case NAMESPACE_DECL: dump_decl (t, v); break; @@ -231,7 +264,7 @@ dump_type_real (t, v, canonical_name) case BOOLEAN_TYPE: { tree type; - dump_readonly_or_volatile (t, after); + dump_qualifiers (t, after); type = canonical_name ? TYPE_MAIN_VARIANT (t) : t; if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) OB_PUTID (TYPE_IDENTIFIER (type)); @@ -244,7 +277,7 @@ dump_type_real (t, v, canonical_name) break; case TEMPLATE_TEMPLATE_PARM: - if (!CLASSTYPE_TEMPLATE_INFO (t)) + if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)) { /* For parameters inside template signature. */ if (TYPE_IDENTIFIER (t)) @@ -255,7 +288,7 @@ dump_type_real (t, v, canonical_name) else { int i; - tree args = CLASSTYPE_TI_ARGS (t); + tree args = TYPE_TI_ARGS (t); OB_PUTID (TYPE_IDENTIFIER (t)); OB_PUTC ('<'); for (i = 0; i < TREE_VEC_LENGTH (args); i++) @@ -269,12 +302,12 @@ dump_type_real (t, v, canonical_name) if (i < TREE_VEC_LENGTH (args)-1) OB_PUTC2 (',', ' '); } - OB_PUTC ('>'); + OB_END_TEMPLATE_ID (); } break; case TEMPLATE_TYPE_PARM: - dump_readonly_or_volatile (t, after); + dump_qualifiers (t, after); if (TYPE_IDENTIFIER (t)) OB_PUTID (TYPE_IDENTIFIER (t)); else @@ -298,7 +331,13 @@ dump_type_real (t, v, canonical_name) OB_PUTS ("typename "); dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); OB_PUTS ("::"); - OB_PUTID (TYPE_IDENTIFIER (t)); + dump_decl (TYPENAME_TYPE_FULLNAME (t), v); + break; + + case TYPEOF_TYPE: + OB_PUTS ("__typeof ("); + dump_expr (TYPE_FIELDS (t), 1); + OB_PUTC (')'); break; default: @@ -342,7 +381,7 @@ dump_aggr_type (t, v, canonical_name) tree name; char *variety = aggr_variety (t); - dump_readonly_or_volatile (t, after); + dump_qualifiers (t, after); if (v > 0) { @@ -352,7 +391,7 @@ dump_aggr_type (t, v, canonical_name) name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t); - if (name && DECL_CONTEXT (name) && DECL_CONTEXT (name) != global_namespace) + if (name && CP_DECL_CONTEXT (name) != global_namespace) { /* FUNCTION_DECL or RECORD_TYPE */ dump_decl (DECL_CONTEXT (name), 0); @@ -403,13 +442,14 @@ dump_type_prefix (t, v, canonical_name) switch (TREE_CODE (t)) { case POINTER_TYPE: + case REFERENCE_TYPE: { tree sub = TREE_TYPE (t); dump_type_prefix (sub, v, canonical_name); /* A tree for a member pointer looks like pointer to offset, so let the OFFSET_TYPE case handle it. */ - if (TREE_CODE (sub) != OFFSET_TYPE) + if (!TYPE_PTRMEM_P (t)) { switch (TREE_CODE (sub)) { @@ -424,42 +464,20 @@ dump_type_prefix (t, v, canonical_name) case POINTER_TYPE: /* We don't want "char * *" */ - if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub))) + if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED) break; /* But we do want "char *const *" */ default: OB_PUTC (' '); } - OB_PUTC ('*'); - dump_readonly_or_volatile (t, none); - } - } - break; - - case REFERENCE_TYPE: - { - tree sub = TREE_TYPE (t); - dump_type_prefix (sub, v, canonical_name); - - switch (TREE_CODE (sub)) - { - case ARRAY_TYPE: - OB_PUTC2 (' ', '('); - break; - - case POINTER_TYPE: - /* We don't want "char * &" */ - if (! (TYPE_READONLY (sub) || TYPE_VOLATILE (sub))) - break; - /* But we do want "char *const &" */ - - default: - OB_PUTC (' '); + if (TREE_CODE (t) == POINTER_TYPE) + OB_PUTC ('*'); + else + OB_PUTC ('&'); + dump_qualifiers (t, none); } } - OB_PUTC ('&'); - dump_readonly_or_volatile (t, none); break; case OFFSET_TYPE: @@ -472,7 +490,7 @@ dump_type_prefix (t, v, canonical_name) OB_PUTC2 (':', ':'); } OB_PUTC ('*'); - dump_readonly_or_volatile (t, none); + dump_qualifiers (t, none); break; /* Can only be reached through function pointer -- this would not be @@ -543,20 +561,20 @@ dump_type_suffix (t, v, canonical_name) case METHOD_TYPE: { tree arg; - OB_PUTC2 (')', '('); + OB_PUTC (')'); arg = TYPE_ARG_TYPES (t); if (TREE_CODE (t) == METHOD_TYPE) arg = TREE_CHAIN (arg); - if (arg) - dump_type (arg, v); - else - OB_PUTS ("..."); - OB_PUTC (')'); + /* Function pointers don't have default args. Not in standard C++, + anyway; they may in g++, but we'll just pretend otherwise. */ + dump_parameters (arg, 0, canonical_name); + if (TREE_CODE (t) == METHOD_TYPE) - dump_readonly_or_volatile + dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); dump_type_suffix (TREE_TYPE (t), v, canonical_name); + dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), canonical_name); break; } @@ -571,7 +589,7 @@ dump_type_suffix (t, v, canonical_name) else dump_expr (fold (build_binary_op (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), - integer_one_node, 1)), 0); + integer_one_node)), 0); } OB_PUTC (']'); dump_type_suffix (TREE_TYPE (t), v, canonical_name); @@ -666,12 +684,11 @@ dump_simple_decl (t, type, v) { dump_type_prefix (type, v, 0); OB_PUTC (' '); - dump_readonly_or_volatile (t, after); } - if (DECL_CLASS_SCOPE_P (t)) + if (interesting_scope_p (DECL_CONTEXT (t))) { - dump_type (DECL_CONTEXT (t), 0); - OB_PUTC2 (':', ':'); + dump_decl (DECL_CONTEXT (t), 0); + OB_PUTC2 (':',':'); } if (DECL_NAME (t)) dump_decl (DECL_NAME (t), v); @@ -718,7 +735,13 @@ dump_decl (t, v) if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) { OB_PUTS ("vtable for "); - dump_type (DECL_CONTEXT (t), v); + if (TYPE_P (DECL_CONTEXT (t))) + dump_type (DECL_CONTEXT (t), v); + else + /* This case can arise with -fno-vtable-thunks. See + expand_upcast_fixups. It's not clear what to print + here. */ + OB_PUTS ("{unknown type}"); break; } /* else fall through */ @@ -728,12 +751,15 @@ dump_decl (t, v) break; case NAMESPACE_DECL: - if (DECL_CONTEXT (t) != global_namespace) + if (CP_DECL_CONTEXT (t) != global_namespace) { dump_decl (DECL_CONTEXT (t), v); OB_PUTC2 (':',':'); } - OB_PUTID (DECL_NAME (t)); + if (DECL_NAME (t) == anonymous_namespace_name) + OB_PUTS ("{anonymous}"); + else + OB_PUTID (DECL_NAME (t)); break; case SCOPE_REF: @@ -790,6 +816,10 @@ dump_decl (t, v) } break; + case OVERLOAD: + t = OVL_CURRENT (t); + /* Fall through. */ + case FUNCTION_DECL: if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t))) dump_global_iord (DECL_ASSEMBLER_NAME (t)); @@ -843,12 +873,15 @@ dump_decl (t, v) } if (len != 0) OB_UNPUT (2); - OB_PUTC2 ('>', ' '); + OB_END_TEMPLATE_ID (); + OB_PUTC (' '); } nreverse(orig_args); if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) dump_type (TREE_TYPE (t), v); + else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) + dump_decl (DECL_TEMPLATE_RESULT (t), v); else if (TREE_TYPE (t) == NULL_TREE) my_friendly_abort (353); else switch (NEXT_CODE (t)) @@ -883,7 +916,7 @@ dump_decl (t, v) if (TREE_CHAIN (args)) OB_PUTC2 (',', ' '); } - OB_PUTC ('>'); + OB_END_TEMPLATE_ID (); } break; @@ -921,9 +954,15 @@ dump_decl (t, v) } } -/* Pretty printing for announce_function. T is the declaration of the - function we are interested in seeing. V is non-zero if we should print - the type that this function returns. */ +/* Pretty print a function decl. There are several ways we want to print a + function declaration. We use V to tell us what. + V - 01 23 + args - ++ ++ + retval - -+ ++ + default- -+ -+ + throw - -- ++ + As cp_error can only apply the '#' flag once to give 0 and 1 for V, there + is %D which doesn't print the throw specs, and %F which does. */ static void dump_function_decl (t, v) @@ -943,28 +982,28 @@ dump_function_decl (t, v) parmtypes = TYPE_ARG_TYPES (fntype); /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */ - if (DECL_CONTEXT (t)) + if (DECL_CLASS_SCOPE_P (t)) cname = DECL_CLASS_CONTEXT (t); /* this is for partially instantiated template methods */ else if (TREE_CODE (fntype) == METHOD_TYPE) cname = TREE_TYPE (TREE_VALUE (parmtypes)); - v = (v > 0); - - if (v) + /* Print the return type. */ + if (v > 0) { if (DECL_STATIC_FUNCTION_P (t)) OB_PUTS ("static "); - if (! IDENTIFIER_TYPENAME_P (name) + if (! DECL_CONV_FN_P (t) && ! DECL_CONSTRUCTOR_P (t) - && ! DESTRUCTOR_NAME_P (name)) + && ! DECL_DESTRUCTOR_P (t)) { dump_type_prefix (TREE_TYPE (fntype), 1, 0); OB_PUTC (' '); } } + /* Print the function name. */ if (cname) { dump_type (cname, 0); @@ -975,34 +1014,98 @@ dump_function_decl (t, v) /* Skip past "in_charge" identifier. */ parmtypes = TREE_CHAIN (parmtypes); } + else if (CP_DECL_CONTEXT (t) != global_namespace) + { + dump_decl (DECL_CONTEXT (t), 0); + OB_PUTC2 (':',':'); + } if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus) parmtypes = TREE_CHAIN (parmtypes); dump_function_name (t); - - OB_PUTC ('('); - - if (parmtypes) - dump_type (parmtypes, v); - else - OB_PUTS ("..."); - OB_PUTC (')'); + /* If V is negative, we don't print the argument types. */ + if (v < 0) + return; - if (v && ! IDENTIFIER_TYPENAME_P (name)) + dump_parameters (parmtypes, v & 1, 0); + + if (v && ! DECL_CONV_FN_P (t)) dump_type_suffix (TREE_TYPE (fntype), 1, 0); if (TREE_CODE (fntype) == METHOD_TYPE) { if (IS_SIGNATURE (cname)) /* We look at the type pointed to by the `optr' field of `this.' */ - dump_readonly_or_volatile + dump_qualifiers (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before); else - dump_readonly_or_volatile + dump_qualifiers (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before); } + + if (v >= 2) + dump_exception_spec (TYPE_RAISES_EXCEPTIONS (fntype), 0); +} + +/* Print a parameter list. V indicates if we show default values or not. If + these are for a member function, the member object ptr + (and any other hidden args) should have already been removed. */ + +static void +dump_parameters (parmtypes, v, canonical_name) + tree parmtypes; + int v; + int canonical_name; +{ + int first; + OB_PUTC ('('); + + for (first = 1; parmtypes != void_list_node; + parmtypes = TREE_CHAIN (parmtypes)) + { + if (!first) + OB_PUTC2 (',', ' '); + first = 0; + if (!parmtypes) + { + OB_PUTS ("..."); + break; + } + dump_type_real (TREE_VALUE (parmtypes), 0, canonical_name); + + if (TREE_PURPOSE (parmtypes) && v) + { + OB_PUTS (" = "); + dump_expr (TREE_PURPOSE (parmtypes), 0); + } + } + + OB_PUTC (')'); +} + +/* Print an exception specification. T is the exception specification. */ + +static void +dump_exception_spec (t, canonical_name) + tree t; + int canonical_name; +{ + if (t) + { + OB_PUTS (" throw ("); + if (TREE_VALUE (t) != NULL_TREE) + while (1) + { + dump_type_real (TREE_VALUE (t), 0, canonical_name); + t = TREE_CHAIN (t); + if (!t) + break; + OB_PUTC2 (',', ' '); + } + OB_PUTC (')'); + } } /* Handle the function name for a FUNCTION_DECL node, grokking operators @@ -1014,15 +1117,12 @@ dump_function_name (t) { tree name = DECL_NAME (t); - /* There ought to be a better way to find out whether or not something is - a destructor. */ - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (t)) - && DECL_LANGUAGE (t) == lang_cplusplus) + if (DECL_DESTRUCTOR_P (t)) { OB_PUTC ('~'); dump_decl (name, 0); } - else if (IDENTIFIER_TYPENAME_P (name)) + else if (DECL_CONV_FN_P (t)) { /* This cannot use the hack that the operator's return type is stashed off of its name because it may be @@ -1042,91 +1142,75 @@ dump_function_name (t) else dump_decl (name, 0); - if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t)) + if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t) + && DECL_TEMPLATE_INFO (t) + && (DECL_TEMPLATE_SPECIALIZATION (t) + || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL + || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t)) + || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) { tree args = DECL_TEMPLATE_INFO (t) ? DECL_TI_ARGS (t) : NULL_TREE; + OB_PUTC ('<'); - if (args != NULL_TREE - && DECL_CONTEXT (t) != NULL_TREE - && uses_template_parms (DECL_CONTEXT (t)) - /* This next clause checks that there is only one level of - template arguments. In that case, they are the - arguments for the class context. */ - && (TREE_CODE (args) == TREE_LIST - || (TREE_CODE (args) == TREE_VEC - && TREE_VEC_ELT (args, 0) != NULL_TREE - && TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC))) - /* We have something like this: - - template struct S { void f(); }; - - and we are printing S::f(). This is a template - instantiation, but we don't print anything after the f. */ - ; - else + /* Be careful only to print things when we have them, so as not + to crash producing error messages. */ + if (args) { - OB_PUTC ('<'); - - /* Be careful only to print things when we have them, so as not - to crash producing error messages. */ - if (args) + if (TREE_CODE (args) == TREE_LIST) { - if (TREE_CODE (args) == TREE_LIST) + tree arg; + int need_comma = 0; + + for (arg = args; arg; arg = TREE_CHAIN (arg)) { - tree arg; - int need_comma = 0; - - for (arg = args; arg; arg = TREE_CHAIN (arg)) - { - tree a = TREE_VALUE (arg); - - if (need_comma) - OB_PUTS (", "); - - if (a) - { - if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' - || TREE_CODE (a) == TEMPLATE_DECL) - dump_type (a, 0); - else - dump_expr (a, 0); - } + tree a = TREE_VALUE (arg); + + if (need_comma) + OB_PUTS (", "); - need_comma = 1; + if (a) + { + if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' + || TREE_CODE (a) == TEMPLATE_DECL) + dump_type (a, 0); + else + dump_expr (a, 0); } + + need_comma = 1; } - else if (TREE_CODE (args) == TREE_VEC) + } + else if (TREE_CODE (args) == TREE_VEC) + { + int i; + int need_comma = 0; + + 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); + + for (i = 0; i < TREE_VEC_LENGTH (args); i++) { - int i; - int need_comma = 0; - - 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); - - for (i = 0; i < TREE_VEC_LENGTH (args); i++) - { - tree a = TREE_VEC_ELT (args, i); - - if (need_comma) - OB_PUTS (", "); - - if (a) - { - if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' - || TREE_CODE (a) == TEMPLATE_DECL) - dump_type (a, 0); - else - dump_expr (a, 0); - } + tree a = TREE_VEC_ELT (args, i); + + if (need_comma) + OB_PUTS (", "); - need_comma = 1; + if (a) + { + if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' + || TREE_CODE (a) == TEMPLATE_DECL) + dump_type (a, 0); + else + dump_expr (a, 0); } + + need_comma = 1; } } - OB_PUTC ('>'); } + OB_END_TEMPLATE_ID (); } } @@ -1278,6 +1362,13 @@ dump_expr (t, nop) OB_PUTCP (digit_buffer); break; + case PTRMEM_CST: + OB_PUTC ('&'); + dump_type (PTRMEM_CST_CLASS (t), 0); + OB_PUTS ("::"); + OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t))); + break; + case STRING_CST: { char *p = TREE_STRING_POINTER (t); @@ -1310,7 +1401,6 @@ dump_expr (t, nop) { OB_PUTS ("new "); dump_type (TREE_TYPE (TREE_TYPE (t)), 0); - PARM_DECL_EXPR (t) = 1; } else { @@ -1485,6 +1575,7 @@ dump_expr (t, nop) else { if (TREE_OPERAND (t,0) != NULL_TREE + && TREE_TYPE (TREE_OPERAND (t, 0)) && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) dump_expr (TREE_OPERAND (t, 0), nop); else @@ -1544,11 +1635,20 @@ dump_expr (t, nop) if (integer_all_onesp (idx)) { tree pfn = PFN_FROM_PTRMEMFUNC (t); - dump_expr (pfn, 0); + dump_unary_op ("&", pfn, 0); break; } - if (TREE_CODE (idx) == INTEGER_CST - && TREE_INT_CST_HIGH (idx) == 0) + else if (TREE_CODE (idx) == INTEGER_CST + && tree_int_cst_equal (idx, integer_zero_node)) + { + /* A NULL pointer-to-member constant. */ + OB_PUTS ("(("); + dump_type (TREE_TYPE (t), 0); + OB_PUTS (") 0)"); + break; + } + else if (TREE_CODE (idx) == INTEGER_CST + && TREE_INT_CST_HIGH (idx) == 0) { tree virtuals; unsigned HOST_WIDE_INT n; @@ -1583,15 +1683,29 @@ dump_expr (t, nop) case OFFSET_REF: { tree ob = TREE_OPERAND (t, 0); - if (TREE_CODE (ob) == NOP_EXPR - && TREE_OPERAND (ob, 0) == error_mark_node - && TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL) - /* A::f */ - dump_expr (TREE_OPERAND (t, 1), 0); + if (is_dummy_object (ob)) + { + t = TREE_OPERAND (t, 1); + if (TREE_CODE (t) == FUNCTION_DECL) + /* A::f */ + dump_expr (t, 0); + else if (BASELINK_P (t)) + dump_expr (OVL_CURRENT (TREE_VALUE (t)), 0); + else + dump_decl (t, 0); + } else { - dump_expr (TREE_OPERAND (t, 0), 0); - OB_PUTS (" .* "); + if (TREE_CODE (ob) == INDIRECT_REF) + { + dump_expr (TREE_OPERAND (ob, 0), 0); + OB_PUTS (" ->* "); + } + else + { + dump_expr (ob, 0); + OB_PUTS (" .* "); + } dump_expr (TREE_OPERAND (t, 1), 0); } break; @@ -1666,6 +1780,10 @@ dump_expr (t, nop) dump_expr (TREE_OPERAND (t, 0), nop); break; + case TEMPLATE_ID_EXPR: + dump_decl (t, 0); + break; + case TREE_LIST: if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) { @@ -1714,12 +1832,20 @@ dump_unary_op (opstring, t, nop) if (!nop) OB_PUTC (')'); } +/* Print a function decl with exception specification included. */ + char * -fndecl_as_string (fndecl, print_ret_type_p) +fndecl_as_string (fndecl, print_default_args_p) tree fndecl; - int print_ret_type_p; + int print_default_args_p; { - return decl_as_string (fndecl, print_ret_type_p); + OB_INIT (); + + dump_function_decl (fndecl, 2 + print_default_args_p); + + OB_FINISH (); + + return (char *)obstack_base (&scratch_obstack); } /* Same, but handle a _TYPE. @@ -1825,6 +1951,8 @@ cp_file_of (t) return DECL_SOURCE_FILE (DECL_CONTEXT (t)); else if (TREE_CODE_CLASS (TREE_CODE (t)) == '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); } @@ -1836,11 +1964,14 @@ cp_line_of (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)) + if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t) + && TYPE_MAIN_DECL (TREE_TYPE (t))) t = TREE_TYPE (t); if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t)); + else if (TREE_CODE (t) == OVERLOAD) + line = DECL_SOURCE_LINE (OVL_FUNCTION (t)); else line = DECL_SOURCE_LINE (t); @@ -1954,7 +2085,7 @@ cv_as_string (p, v) { OB_INIT (); - dump_readonly_or_volatile (p, before); + dump_qualifiers (p, before); OB_FINISH (); diff --git a/contrib/gcc/cp/except.c b/contrib/gcc/cp/except.c index d294497..9e2d6af 100644 --- a/contrib/gcc/cp/except.c +++ b/contrib/gcc/cp/except.c @@ -1,5 +1,5 @@ /* Handle exceptional things in C++. - Copyright (C) 1989, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1989, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann Rewritten by Mike Stump , based upon an initial re-implementation courtesy Tad Hunt. @@ -52,12 +52,13 @@ static tree call_eh_info PROTO((void)); static void push_eh_info PROTO((void)); static tree get_eh_info PROTO((void)); static tree get_eh_value PROTO((void)); +#if 0 static tree get_eh_type PROTO((void)); static tree get_eh_caught PROTO((void)); static tree get_eh_handlers PROTO((void)); +#endif static tree do_pop_exception PROTO((void)); static void process_start_catch_block PROTO((tree, tree)); -static void process_start_catch_block_old PROTO((tree, tree)); static tree build_eh_type_type_ref PROTO((tree)); static tree build_terminate_handler PROTO((void)); static tree alloc_eh_object PROTO((tree)); @@ -248,14 +249,14 @@ call_eh_info () { tree fn; - fn = get_identifier ("__cp_eh_info"); + fn = get_identifier ("__start_cp_handler"); if (IDENTIFIER_GLOBAL_VALUE (fn)) fn = IDENTIFIER_GLOBAL_VALUE (fn); else { tree t1, t, fields[7]; - /* Declare cp_eh_info * __cp_eh_info (void), + /* Declare cp_eh_info * __start_cp_handler (void), as defined in exception.cc. */ push_obstacks_nochange (); end_temporary_allocation (); @@ -269,9 +270,11 @@ call_eh_info () get_identifier ("dynamic_handler_chain"), ptr_type_node); fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("info"), ptr_type_node); + fields[3] = build_lang_field_decl (FIELD_DECL, + get_identifier ("table_index"), ptr_type_node); /* N.B.: The fourth field LEN is expected to be the number of fields - 1, not the total number of fields. */ - finish_builtin_type (t1, "eh_context", fields, 2, ptr_type_node); + finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node); t1 = build_pointer_type (t1); t1= make_lang_type (RECORD_TYPE); @@ -315,9 +318,9 @@ call_eh_info () DECL_ARTIFICIAL (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); return build_function_call (fn, NULL_TREE); } @@ -360,6 +363,7 @@ get_eh_value () /* Returns a reference to the current exception type. */ +#if 0 static tree get_eh_type () { @@ -386,6 +390,7 @@ get_eh_handlers () return build_component_ref (get_eh_info (), get_identifier ("handlers"), NULL_TREE, 0); } +#endif /* Build a type value for use at runtime for a type that is matched against by the exception handling system. */ @@ -394,7 +399,7 @@ static tree build_eh_type_type (type) tree type; { - char *typestring; + const char *typestring; tree exp; if (type == error_mark_node) @@ -408,9 +413,7 @@ build_eh_type_type (type) type = TYPE_MAIN_VARIANT (type); if (flag_rtti) - { - return build1 (ADDR_EXPR, ptr_type_node, get_typeid (type)); - } + return build1 (ADDR_EXPR, ptr_type_node, get_typeid_1 (type)); typestring = build_overload_name (type, 1, 1); exp = combine_strings (build_string (strlen (typestring)+1, typestring)); @@ -424,7 +427,7 @@ static tree build_eh_type_type_ref (type) tree type; { - char *typestring; + const char *typestring; tree exp; if (type == error_mark_node) @@ -528,10 +531,10 @@ do_pop_exception () DECL_ARTIFICIAL (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); /* Arrange to do a dynamically scoped cleanup upon exit from this region. */ cleanup = lookup_name (get_identifier ("__exception_info"), 0); cleanup = build_function_call (fn, expr_tree_cons @@ -546,9 +549,6 @@ push_eh_cleanup () { int yes; - expand_expr (build_unary_op (PREINCREMENT_EXPR, get_eh_handlers (), 1), - const0_rtx, VOIDmode, EXPAND_NORMAL); - yes = suspend_momentary (); /* All cleanups must last longer than normal. */ expand_decl_cleanup (NULL_TREE, do_pop_exception ()); @@ -597,135 +597,14 @@ expand_start_catch_block (declspecs, declarator) if (! doing_eh (1)) return; - if (flag_new_exceptions) - process_start_catch_block (declspecs, declarator); - else - process_start_catch_block_old (declspecs, declarator); + process_start_catch_block (declspecs, declarator); } /* This function performs the expand_start_catch_block functionality for - exceptions implemented in the old style, where catch blocks were all - called, and had to check the runtime information themselves. */ - -static void -process_start_catch_block_old (declspecs, declarator) - tree declspecs, declarator; -{ - rtx false_label_rtx; - tree decl = NULL_TREE; - tree init; - - /* Create a binding level for the eh_info and the exception object - cleanup. */ - pushlevel (0); - expand_start_bindings (0); - - false_label_rtx = gen_label_rtx (); - push_label_entry (&false_label_stack, false_label_rtx, NULL_TREE); - - emit_line_note (input_filename, lineno); - - push_eh_info (); - - if (declspecs) - { - decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE); - - if (decl == NULL_TREE) - error ("invalid catch parameter"); - } - - if (decl) - { - tree exp; - rtx call_rtx, return_value_rtx; - tree init_type; - - /* Make sure we mark the catch param as used, otherwise we'll get - a warning about an unused ((anonymous)). */ - TREE_USED (decl) = 1; - - /* Figure out the type that the initializer is. */ - init_type = TREE_TYPE (decl); - if (TREE_CODE (init_type) != REFERENCE_TYPE - && TREE_CODE (init_type) != POINTER_TYPE) - init_type = build_reference_type (init_type); - - exp = get_eh_value (); - - /* Since pointers are passed by value, initialize a reference to - pointer catch parm with the address of the value slot. */ - if (TREE_CODE (init_type) == REFERENCE_TYPE - && TREE_CODE (TREE_TYPE (init_type)) == POINTER_TYPE) - exp = build_unary_op (ADDR_EXPR, exp, 1); - - exp = expr_tree_cons (NULL_TREE, - build_eh_type_type (TREE_TYPE (decl)), - expr_tree_cons (NULL_TREE, - get_eh_type (), - expr_tree_cons (NULL_TREE, exp, NULL_TREE))); - exp = build_function_call (CatchMatch, exp); - call_rtx = expand_call (exp, NULL_RTX, 0); - - return_value_rtx = hard_function_value (ptr_type_node, exp); - - /* did the throw type match function return TRUE? */ - emit_cmp_insn (return_value_rtx, const0_rtx, EQ, NULL_RTX, - GET_MODE (return_value_rtx), 0, 0); - - /* if it returned FALSE, jump over the catch block, else fall into it */ - emit_jump_insn (gen_beq (false_label_rtx)); - - push_eh_cleanup (); - - /* Create a binding level for the parm. */ - pushlevel (0); - expand_start_bindings (0); - - init = convert_from_reference (make_tree (init_type, call_rtx)); - - /* If the constructor for the catch parm exits via an exception, we - must call terminate. See eh23.C. */ - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - { - /* Generate the copy constructor call directly so we can wrap it. - See also expand_default_init. */ - init = ocp_convert (TREE_TYPE (decl), init, - CONV_IMPLICIT|CONV_FORCE_TEMP, 0); - init = build (TRY_CATCH_EXPR, TREE_TYPE (init), init, - build_terminate_handler ()); - } - - /* Let `cp_finish_decl' know that this initializer is ok. */ - DECL_INITIAL (decl) = init; - decl = pushdecl (decl); - - start_decl_1 (decl); - cp_finish_decl (decl, DECL_INITIAL (decl), - NULL_TREE, 0, LOOKUP_ONLYCONVERTING); - } - else - { - push_eh_cleanup (); - - /* Create a binding level for the parm. */ - pushlevel (0); - expand_start_bindings (0); - - /* Fall into the catch all section. */ - } - - init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node); - expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL); - - emit_line_note (input_filename, lineno); -} - -/* This function performs the expand_start_catch_block functionality for exceptions implemented in the new style. __throw determines whether a handler needs to be called or not, so the handler itself has to do - nothing additionaal. */ + nothing additional. */ static void process_start_catch_block (declspecs, declarator) @@ -806,7 +685,9 @@ process_start_catch_block (declspecs, declarator) DECL_INITIAL (decl) = init; decl = pushdecl (decl); - cp_finish_decl (decl, init, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); + start_decl_1 (decl); + cp_finish_decl (decl, init, NULL_TREE, 0, + LOOKUP_ONLYCONVERTING|DIRECT_BIND); } else { @@ -819,14 +700,10 @@ process_start_catch_block (declspecs, declarator) /* Fall into the catch all section. */ } - init = build_modify_expr (get_eh_caught (), NOP_EXPR, integer_one_node); - expand_expr (init, const0_rtx, VOIDmode, EXPAND_NORMAL); - emit_line_note (input_filename, lineno); } - /* Call this to end a catch block. Its responsible for emitting the code to handle jumping back to the correct place, and for emitting the label to jump to if this catch block didn't match. */ @@ -850,10 +727,7 @@ expand_end_catch_block () documentation. */ expand_goto (top_label_entry (&caught_return_label_stack)); - /* label we emit to jump to if this catch block didn't match. */ - /* This the closing } in the `if (eq) {' of the documentation. */ - if (! flag_new_exceptions) - emit_label (pop_label_entry (&false_label_stack)); + end_catch_handler (); } /* An exception spec is implemented more or less like: @@ -895,7 +769,7 @@ expand_end_eh_spec (raises) TREE_HAS_CONSTRUCTOR (types) = 1; /* We can't pass the CONSTRUCTOR directly, so stick it in a variable. */ - tmp = build_array_type (const_ptr_type_node, NULL_TREE); + tmp = build_cplus_array_type (const_ptr_type_node, NULL_TREE); decl = build_decl (VAR_DECL, NULL_TREE, tmp); DECL_ARTIFICIAL (decl) = 1; DECL_INITIAL (decl) = types; @@ -923,10 +797,10 @@ expand_end_eh_spec (raises) TREE_THIS_VOLATILE (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); tmp = expr_tree_cons (NULL_TREE, build_int_2 (count, 0), expr_tree_cons (NULL_TREE, decl, NULL_TREE)); tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp); @@ -1065,10 +939,10 @@ alloc_eh_object (type) DECL_ARTIFICIAL (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); exp = build_function_call (fn, expr_tree_cons (NULL_TREE, size_in_bytes (type), NULL_TREE)); exp = build1 (NOP_EXPR, build_pointer_type (type), exp); @@ -1118,11 +992,8 @@ expand_throw (exp) pop_obstacks (); } - if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE) - { - throw_type = build_eh_type (exp); - exp = build_reinterpret_cast (ptr_type_node, exp); - } + if (TYPE_PTR_P (TREE_TYPE (exp))) + throw_type = build_eh_type (exp); else { tree object, ptr; @@ -1153,13 +1024,11 @@ expand_throw (exp) ourselves into expand_call. */ if (TREE_SIDE_EFFECTS (exp)) { - tree temp = build (VAR_DECL, TREE_TYPE (exp)); + tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); DECL_ARTIFICIAL (temp) = 1; - layout_decl (temp, 0); DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1); - expand_expr (build (INIT_EXPR, TREE_TYPE (exp), temp, exp), - NULL_RTX, VOIDmode, 0); - expand_decl_cleanup (NULL_TREE, maybe_build_cleanup (temp)); + DECL_INITIAL (temp) = exp; + cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); exp = temp; } #endif @@ -1196,6 +1065,10 @@ expand_throw (exp) exp = ptr; } + /* Cast EXP to `void *' so that it will match the prototype for + __cp_push_exception. */ + exp = convert (ptr_type_node, exp); + if (cleanup == NULL_TREE) { cleanup = build_int_2 (0, 0); @@ -1223,10 +1096,10 @@ expand_throw (exp) DECL_ARTIFICIAL (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); e = expr_tree_cons (NULL_TREE, exp, expr_tree_cons (NULL_TREE, throw_type, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE))); @@ -1254,10 +1127,10 @@ expand_throw (exp) DECL_ARTIFICIAL (fn) = 1; pushdecl_top_level (fn); make_function_rtl (fn); - assemble_external (fn); pop_obstacks (); } + mark_used (fn); exp = build_function_call (fn, NULL_TREE); expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL); } @@ -1277,11 +1150,8 @@ build_throw (e) if (processing_template_decl) return build_min (THROW_EXPR, void_type_node, e); - if (! flag_ansi && e == null_node) - { - cp_warning ("throwing NULL"); - e = integer_zero_node; - } + if (e == null_node) + cp_warning ("throwing NULL, which has integral, not pointer type"); e = build1 (THROW_EXPR, void_type_node, e); TREE_SIDE_EFFECTS (e) = 1; diff --git a/contrib/gcc/cp/exception.cc b/contrib/gcc/cp/exception.cc index 4c10404..8e8f35f 100644 --- a/contrib/gcc/cp/exception.cc +++ b/contrib/gcc/cp/exception.cc @@ -1,5 +1,5 @@ // Functions for Exception Support for -*- C++ -*- -// Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation +// Copyright (C) 1994, 95-97, 1998 Free Software Foundation // This file is part of GNU CC. @@ -30,6 +30,7 @@ #include "typeinfo" #include "exception" #include +#include "gansidecl.h" /* Needed to support macros used in eh-common.h. */ #include "eh-common.h" /* Define terminate, unexpected, set_terminate, set_unexpected as @@ -116,13 +117,29 @@ __cp_exception_info (void) return &((*__get_eh_info ())->value); } -/* Compiler hook to return a pointer to the info for the current exception. +#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ()) + +/* Old Compiler hook to return a pointer to the info for the current exception. Used by get_eh_info (). */ extern "C" cp_eh_info * __cp_eh_info (void) { - return *__get_eh_info (); + cp_eh_info *p = CP_EH_INFO; + return p; +} + +/* Compiler hook to return a pointer to the info for the current exception, + Set the caught bit, and increment the number of handlers that are + looking at this exception. This makes handlers smaller. */ + +extern "C" cp_eh_info * +__start_cp_handler (void) +{ + cp_eh_info *p = CP_EH_INFO; + p->caught = 1; + p->handlers++; + return p; } /* Allocate a buffer for a cp_eh_info and an exception object of size SIZE, @@ -157,7 +174,9 @@ __cplus_type_matcher (cp_eh_info *info, rtimetype match_info, { void *ret; - if (exception_table->lang.language != EH_LANG_C_plus_plus) + /* No exception table implies the old style mechanism, so don't check. */ + if (exception_table != NULL + && exception_table->lang.language != EH_LANG_C_plus_plus) return NULL; if (match_info == CATCH_ALL_TYPE) @@ -231,7 +250,7 @@ __cp_pop_exception (cp_eh_info *p) p->cleanup (p->value, 2); if (! __is_pointer (p->type)) - __eh_free (p->value); + __eh_free (p->original_value); // value may have been co-erced. __eh_free (p); } @@ -239,7 +258,7 @@ __cp_pop_exception (cp_eh_info *p) extern "C" void __uncatch_exception (void) { - cp_eh_info *p = __cp_eh_info (); + cp_eh_info *p = CP_EH_INFO; if (p == 0) terminate (); p->caught = false; @@ -260,7 +279,7 @@ __uncatch_exception (void) extern "C" void __check_eh_spec (int n, const void **spec) { - cp_eh_info *p = __cp_eh_info (); + cp_eh_info *p = CP_EH_INFO; for (int i = 0; i < n; ++i) { @@ -313,7 +332,7 @@ __throw_bad_typeid (void) bool std::uncaught_exception () { - cp_eh_info *p = __cp_eh_info (); + cp_eh_info *p = CP_EH_INFO; return p && ! p->caught; } diff --git a/contrib/gcc/cp/expr.c b/contrib/gcc/cp/expr.c index 4c3d8b6..83bdff9 100644 --- a/contrib/gcc/cp/expr.c +++ b/contrib/gcc/cp/expr.c @@ -1,6 +1,6 @@ /* Convert language-specific tree expression to rtl instructions, for GNU compiler. - Copyright (C) 1988, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -36,6 +36,62 @@ static tree extract_scalar_init PROTO((tree, tree)); static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode, enum expand_modifier)); +/* Hook used by output_constant to expand language-specific + constants. */ + +static tree +cplus_expand_constant (cst) + tree cst; +{ + switch (TREE_CODE (cst)) + { + case PTRMEM_CST: + { + tree type = TREE_TYPE (cst); + tree member; + tree offset; + + /* Find the member. */ + member = PTRMEM_CST_MEMBER (cst); + + if (TREE_CODE (member) == FIELD_DECL) + { + /* Find the offset for the field. */ + offset = convert (sizetype, + size_binop (EASY_DIV_EXPR, + DECL_FIELD_BITPOS (member), + size_int (BITS_PER_UNIT))); + + /* We offset all pointer to data members by 1 so that we + can distinguish between a null pointer to data member + and the first data member of a structure. */ + offset = size_binop (PLUS_EXPR, offset, size_int (1)); + + cst = cp_convert (type, offset); + } + else + { + tree delta; + tree idx; + tree pfn; + tree delta2; + + expand_ptrmemfunc_cst (cst, &delta, &idx, &pfn, &delta2); + + cst = build_ptrmemfunc1 (type, delta, idx, + pfn, delta2); + } + } + break; + + default: + /* There's nothing to do. */ + break; + } + + return cst; +} + /* Hook used by expand_expr to expand language-specific tree codes. */ static rtx @@ -148,7 +204,7 @@ cplus_expand_expr (exp, target, tmode, modifier) init = convert_from_reference (init); flag_access_control = 0; - expand_aggr_init (slot, init, 0, LOOKUP_ONLYCONVERTING); + expand_aggr_init (slot, init, LOOKUP_ONLYCONVERTING); flag_access_control = old_ac; if (TYPE_NEEDS_DESTRUCTOR (type)) @@ -162,19 +218,14 @@ cplus_expand_expr (exp, target, tmode, modifier) return DECL_RTL (slot); } + case PTRMEM_CST: + return expand_expr (cplus_expand_constant (exp), + target, tmode, modifier); + case OFFSET_REF: { -#if 1 return expand_expr (default_conversion (resolve_offset_ref (exp)), target, tmode, EXPAND_NORMAL); -#else - /* This is old crusty code, and does not handle all that the - resolve_offset_ref function does. (mrs) */ - tree base = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 0), 0); - tree offset = build_unary_op (ADDR_EXPR, TREE_OPERAND (exp, 1), 0); - return expand_expr (build (PLUS_EXPR, TREE_TYPE (exp), base, offset), - target, tmode, EXPAND_NORMAL); -#endif } case THUNK_DECL: @@ -189,7 +240,7 @@ cplus_expand_expr (exp, target, tmode, modifier) (expand_vec_init (NULL_TREE, TREE_OPERAND (exp, 0), build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2), - integer_one_node, 1), + integer_one_node), TREE_OPERAND (exp, 1), 0), target, tmode, modifier); case NEW_EXPR: @@ -207,6 +258,7 @@ void init_cplus_expand () { lang_expand_expr = cplus_expand_expr; + lang_expand_constant = cplus_expand_constant; } /* If DECL had its rtl moved from where callers expect it @@ -304,7 +356,7 @@ extract_scalar_init (decl, init) int extract_init (decl, init) - tree decl, init; + tree decl ATTRIBUTE_UNUSED, init ATTRIBUTE_UNUSED; { return 0; @@ -405,8 +457,5 @@ do_case (start, end) cp_error ("case label `%E' within scope of cleanup or variable array", start); } } - if (start) - define_case_label (label); - else - define_case_label (NULL_TREE); + define_case_label (); } diff --git a/contrib/gcc/cp/friend.c b/contrib/gcc/cp/friend.c index 58747ef..5085ebc 100644 --- a/contrib/gcc/cp/friend.c +++ b/contrib/gcc/cp/friend.c @@ -1,5 +1,5 @@ /* Help friends in C++. - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -27,11 +27,10 @@ Boston, MA 02111-1307, USA. */ #include "output.h" #include "toplev.h" -static void add_friend PROTO((tree, tree)); -static void add_friends PROTO((tree, tree, tree)); - /* Friend data structures are described in cp-tree.h. */ +/* Returns non-zero if SUPPLICANT is a friend of TYPE. */ + int is_friend (type, supplicant) tree type, supplicant; @@ -59,32 +58,40 @@ is_friend (type, supplicant) for (; list ; list = TREE_CHAIN (list)) { - if (name == TREE_PURPOSE (list)) + if (name == FRIEND_NAME (list)) { - tree friends = TREE_VALUE (list); + tree friends = FRIEND_DECLS (list); for (; friends ; friends = TREE_CHAIN (friends)) { - if (comptypes (ctype, TREE_PURPOSE (friends), 1)) + if (same_type_p (ctype, TREE_PURPOSE (friends))) return 1; if (TREE_VALUE (friends) == NULL_TREE) continue; - if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL) - { - if (is_specialization_of (supplicant, - TREE_VALUE (friends))) - return 1; - - continue; - } - - /* FIXME: The use of comptypes here is bogus, since - two specializations of a template with non-type - parameters may have the same type, but be - different. */ - if (comptypes (TREE_TYPE (supplicant), - TREE_TYPE (TREE_VALUE (friends)), 1)) + if (supplicant == TREE_VALUE (friends)) + return 1; + + /* With -fguiding-decls we are more lenient about + friendship. This is bogus in general since two + specializations of a template with non-type + template parameters may have the same type, but + be different. + + Temporarily, we are also 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, the + FUNCTION_MEMBER_P bit can go. */ + if ((flag_guiding_decls + || DECL_FUNCTION_MEMBER_P (supplicant)) + && same_type_p (TREE_TYPE (supplicant), + TREE_TYPE (TREE_VALUE (friends)))) + return 1; + + if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL + && is_specialization_of (supplicant, + TREE_VALUE (friends))) return 1; } break; @@ -104,7 +111,7 @@ is_friend (type, supplicant) if (TREE_CODE (t) == TEMPLATE_DECL ? is_specialization_of (TYPE_MAIN_DECL (supplicant), t) : - comptypes (supplicant, t, 1)) + same_type_p (supplicant, t)) return 1; } } @@ -130,19 +137,27 @@ 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. */ -static void +void add_friend (type, decl) tree type, decl; { - tree typedecl = TYPE_MAIN_DECL (type); - tree list = DECL_FRIENDLIST (typedecl); - tree name = DECL_NAME (decl); + tree typedecl; + tree list; + tree name; + + if (decl == error_mark_node) + return; + + typedecl = TYPE_MAIN_DECL (type); + list = DECL_FRIENDLIST (typedecl); + name = DECL_NAME (decl); + type = TREE_TYPE (typedecl); while (list) { - if (name == TREE_PURPOSE (list)) + if (name == FRIEND_NAME (list)) { - tree friends = TREE_VALUE (list); + tree friends = FRIEND_DECLS (list); for (; friends ; friends = TREE_CHAIN (friends)) { if (decl == TREE_VALUE (friends)) @@ -160,27 +175,20 @@ add_friend (type, decl) } list = TREE_CHAIN (list); } + DECL_FRIENDLIST (typedecl) = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), DECL_FRIENDLIST (typedecl)); - if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - if (parmtypes && TREE_CHAIN (parmtypes)) - { - tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes)); - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl)) - TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; - } - } + if (!uses_template_parms (type)) + DECL_BEFRIENDING_CLASSES (decl) + = tree_cons (NULL_TREE, type, + DECL_BEFRIENDING_CLASSES (decl)); } /* Declare that every member function NAME in FRIEND_TYPE (which may be NULL_TREE) is a friend of type TYPE. */ -static void +void add_friends (type, name, friend_type) tree type, name, friend_type; { @@ -189,9 +197,9 @@ add_friends (type, name, friend_type) while (list) { - if (name == TREE_PURPOSE (list)) + if (name == FRIEND_NAME (list)) { - tree friends = TREE_VALUE (list); + tree friends = FRIEND_DECLS (list); while (friends && TREE_PURPOSE (friends) != friend_type) friends = TREE_CHAIN (friends); if (friends) @@ -216,13 +224,6 @@ add_friends (type, name, friend_type) = tree_cons (name, build_tree_list (friend_type, NULL_TREE), DECL_FRIENDLIST (typedecl)); - if (! strncmp (IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]), - strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR])))) - { - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists"); - } } /* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already @@ -247,18 +248,31 @@ make_friend_class (type, friend_type) error ("`friend' declaration in signature definition"); return; } - if (IS_SIGNATURE (friend_type)) + if (IS_SIGNATURE (friend_type) || ! IS_AGGR_TYPE (friend_type)) { - error ("signature type `%s' declared `friend'", - IDENTIFIER_POINTER (TYPE_IDENTIFIER (friend_type))); + cp_error ("invalid type `%T' declared `friend'", friend_type); return; } + + if (CLASS_TYPE_P (friend_type) + && CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) + && uses_template_parms (friend_type)) + { + /* [temp.friend] + + Friend declarations shall not declare partial + specializations. */ + cp_error ("partial specialization `%T' declared `friend'", + friend_type); + return; + } + if (processing_template_decl > template_class_depth (type)) /* If the TYPE is a template then it makes sense for it to be friends with itself; this means that each instantiation is friends with all other instantiations. */ is_template_friend = 1; - else if (comptypes (type, friend_type, 1)) + else if (same_type_p (type, friend_type)) { pedwarn ("class `%s' is implicitly friends with itself", TYPE_NAME_STRING (type)); @@ -277,7 +291,7 @@ make_friend_class (type, friend_type) /* Stop if we find the same type on the list. */ && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ? friend_type == TREE_VALUE (classes) : - comptypes (TREE_VALUE (classes), friend_type, 1))) + same_type_p (TREE_VALUE (classes), friend_type))) classes = TREE_CHAIN (classes); if (classes) cp_warning ("`%T' is already a friend of `%T'", @@ -286,6 +300,12 @@ make_friend_class (type, friend_type) { CLASSTYPE_FRIEND_CLASSES (type) = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); + if (is_template_friend) + friend_type = TREE_TYPE (friend_type); + if (!uses_template_parms (type)) + CLASSTYPE_BEFRIENDING_CLASSES (friend_type) + = tree_cons (NULL_TREE, type, + CLASSTYPE_BEFRIENDING_CLASSES (friend_type)); } } @@ -310,13 +330,15 @@ make_friend_class (type, friend_type) pointed to by `this'. */ tree -do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) - tree ctype, declarator, decl, parmdecls; +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; { int is_friend_template = 0; + tree prefix_attributes, attributes; /* Every decl that gets here is a friend of something. */ DECL_FRIEND_P (decl) = 1; @@ -330,9 +352,10 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) declarator = DECL_NAME (get_first_fn (declarator)); } - if (TREE_CODE (decl) == FUNCTION_DECL) - is_friend_template = processing_template_decl > - template_class_depth (current_class_type); + if (TREE_CODE (decl) != FUNCTION_DECL) + my_friendly_abort (990513); + + is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P (); if (ctype) { @@ -341,62 +364,35 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) cname = DECL_NAME (cname); /* A method friend. */ - if (TREE_CODE (decl) == FUNCTION_DECL) + if (flags == NO_SPECIAL && ctype && 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 (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 (uses_template_parms (ctype)) + add_friend (current_class_type, decl); + /* 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 (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype)) { - if (flags == NO_SPECIAL && ctype && declarator == cname) - DECL_CONSTRUCTOR_P (decl) = 1; + decl = check_classfn (ctype, decl); - /* This will set up DECL_ARGUMENTS for us. */ - grokclassfn (ctype, cname, decl, flags, quals); - - if (is_friend_template) - decl = DECL_TI_TEMPLATE (push_template_decl (decl)); - - if (TYPE_SIZE (ctype) != 0 && template_class_depth (ctype) == 0) - decl = check_classfn (ctype, decl); - - /* TYPE_BEING_DEFINED is a hack for nested classes having - member functions of the enclosing class as friends. Will - go away as parsing of classes gets rewritten. */ - if (TREE_TYPE (decl) != error_mark_node) - { - if (TYPE_BEING_DEFINED (ctype) || - TYPE_SIZE (ctype) || template_class_depth (ctype) > 0) - add_friend (current_class_type, decl); - else - cp_error ("member `%D' declared as friend before type `%T' defined", - decl, ctype); - } + if (decl) + add_friend (current_class_type, decl); } else - { - /* Possibly a bunch of method friends. */ - - /* Get the class they belong to. */ - tree ctype = IDENTIFIER_TYPE_VALUE (cname); - tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0); - - if (fields) - add_friends (current_class_type, declarator, ctype); - else - cp_error ("method `%D' is not a member of class `%T'", - declarator, ctype); - decl = void_type_node; - } - } - else if (TREE_CODE (decl) == FUNCTION_DECL - && (MAIN_NAME_P (declarator) - || (IDENTIFIER_LENGTH (declarator) > 10 - && IDENTIFIER_POINTER (declarator)[0] == '_' - && IDENTIFIER_POINTER (declarator)[1] == '_' - && strncmp (IDENTIFIER_POINTER (declarator)+2, - "builtin_", 8) == 0))) - { - /* raw "main", and builtin functions never gets overloaded, - but they can become friends. */ - add_friend (current_class_type, decl); - DECL_FRIEND_P (decl) = 1; - decl = void_type_node; + cp_error ("member `%D' declared as friend before type `%T' defined", + decl, ctype); } /* A global friend. @@ or possibly a friend from a base class ?!? */ @@ -407,9 +403,6 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) Note that because classes all wind up being top-level in their scope, their friend wind up in top-level scope as well. */ - DECL_ASSEMBLER_NAME (decl) - = build_decl_overload (declarator, TYPE_ARG_TYPES (TREE_TYPE (decl)), - TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); DECL_ARGUMENTS (decl) = parmdecls; if (funcdef_flag) DECL_CLASS_CONTEXT (decl) = current_class_type; @@ -417,22 +410,20 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) if (! DECL_USE_TEMPLATE (decl)) { /* We can call pushdecl here, because the TREE_CHAIN of this - FUNCTION_DECL is not needed for other purposes. Don't do this - for a template instantiation. */ - if (!is_friend_template) - { - /* However, we don't call pushdecl() for a friend - function of a template class, since in general, - such a declaration depends on template - parameters. Instead, we call pushdecl when the - class is instantiated. */ - if (template_class_depth (current_class_type) == 0) - decl = pushdecl (decl); - } + FUNCTION_DECL is not needed for other purposes. Don't do + this for a template instantiation. However, we don't + call pushdecl() for a friend function of a template + class, since in general, such a declaration depends on + template parameters. Instead, we call pushdecl when the + class is instantiated. */ + if (!is_friend_template + && template_class_depth (current_class_type) == 0) + decl = pushdecl (decl); else - decl = push_template_decl (decl); + decl = push_template_decl_real (decl, /*is_friend=*/1); - if (! funcdef_flag && ! flag_guiding_decls && ! is_friend_template + if (warn_nontemplate_friend + && ! funcdef_flag && ! flag_guiding_decls && ! is_friend_template && current_template_parms && uses_template_parms (decl)) { static int explained; @@ -443,6 +434,7 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) warning (" (if this is not what you intended, make sure"); warning (" the function template has already been declared,"); warning (" and add <> after the function name here)"); + warning (" -Wno-non-template-friend disables this warning."); explained = 1; } } @@ -453,32 +445,28 @@ do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) is_friend_template ? DECL_TI_TEMPLATE (decl) : decl); DECL_FRIEND_P (decl) = 1; } + + /* Unfortunately, we have to handle attributes here. Normally we would + handle them in start_decl_1, but since this is a friend decl start_decl_1 + never gets to see it. */ + + if (attrlist) + { + attributes = TREE_PURPOSE (attrlist); + prefix_attributes = TREE_VALUE (attrlist); + } else { - /* @@ Should be able to ingest later definitions of this function - before use. */ - tree decl = lookup_name_nonclass (declarator); - if (decl == NULL_TREE) - { - cp_warning ("implicitly declaring `%T' as struct", declarator); - decl = xref_tag (record_type_node, declarator, NULL_TREE, 1); - decl = TYPE_MAIN_DECL (decl); - } + attributes = NULL_TREE; + prefix_attributes = NULL_TREE; + } - /* Allow abbreviated declarations of overloaded functions, - but not if those functions are really class names. */ - if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl))) - { - cp_warning ("`friend %T' archaic, use `friend class %T' instead", - declarator, declarator); - decl = TREE_TYPE (TREE_PURPOSE (decl)); - } +#ifdef SET_DEFAULT_DECL_ATTRIBUTES + SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes); +#endif + + /* Set attributes here so if duplicate decl, will have proper attributes. */ + cplus_decl_attributes (decl, attributes, prefix_attributes); - if (TREE_CODE (decl) == TREE_LIST) - add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE); - else - make_friend_class (current_class_type, TREE_TYPE (decl)); - decl = void_type_node; - } return decl; } diff --git a/contrib/gcc/cp/g++spec.c b/contrib/gcc/cp/g++spec.c index 542ca06..806b90e 100644 --- a/contrib/gcc/cp/g++spec.c +++ b/contrib/gcc/cp/g++spec.c @@ -1,5 +1,5 @@ /* Specific flags and argument handling of the C++ front-end. - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -19,11 +19,8 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "config.h" - #include "system.h" -#include "gansidecl.h" - /* This bit is set if we saw a `-xfoo' language specification. */ #define LANGSPEC (1<<1) /* This bit is set if they did `-lm' or `-lmath'. */ @@ -34,11 +31,10 @@ Boston, MA 02111-1307, USA. */ #ifndef MATH_LIBRARY #define MATH_LIBRARY "-lm" #endif -#ifndef NEED_MATH_LIBRARY -#define NEED_MATH_LIBRARY 1 /* Default is pass MATH_LIBRARY to linker */ -#endif -extern char *xmalloc PROTO((size_t)); +#ifndef LIBSTDCXX +#define LIBSTDCXX "-lstdc++" +#endif void lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) @@ -83,8 +79,8 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) LANGSPEC, MATHLIB, or WITHLIBC. */ int *args; - /* By default, we throw on the math library. */ - int need_math = NEED_MATH_LIBRARY; + /* By default, we throw on the math library if we have one. */ + int need_math = (MATH_LIBRARY[0] != '\0'); /* The total number of arguments with the new stuff. */ int argc; @@ -128,6 +124,7 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) } 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 @@ -239,7 +236,7 @@ lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) /* Add `-lstdc++' if we haven't already done so. */ if (library) { - arglist[j++] = "-lstdc++"; + arglist[j++] = LIBSTDCXX; added_libraries++; } if (saw_math) diff --git a/contrib/gcc/cp/gxx.gperf b/contrib/gcc/cp/gxx.gperf index 71538567..1e621c4 100644 --- a/contrib/gcc/cp/gxx.gperf +++ b/contrib/gcc/cp/gxx.gperf @@ -1,7 +1,7 @@ %{ -/* Command-line: gperf -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ +/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ %} -struct resword { char *name; short token; enum rid rid;}; +struct resword { const char *name; short token; enum rid rid;}; %% __alignof, ALIGNOF, NORID __alignof__, ALIGNOF, NORID @@ -22,6 +22,8 @@ __label__, LABEL, NORID __null, CONSTANT, RID_NULL __real, REALPART, NORID __real__, REALPART, NORID +__restrict, CV_QUALIFIER, RID_RESTRICT +__restrict__, CV_QUALIFIER, RID_RESTRICT __signature__, AGGR, RID_SIGNATURE /* Extension */, __signed, TYPESPEC, RID_SIGNED __signed__, TYPESPEC, RID_SIGNED @@ -55,6 +57,7 @@ dynamic_cast, DYNAMIC_CAST, NORID, else, ELSE, NORID, enum, ENUM, NORID, explicit, SCSPEC, RID_EXPLICIT, +export, SCSPEC, RID_EXPORT, extern, SCSPEC, RID_EXTERN, false, CXX_FALSE, NORID, float, TYPESPEC, RID_FLOAT, @@ -78,7 +81,7 @@ protected, VISSPEC, RID_PROTECTED, public, VISSPEC, RID_PUBLIC, register, SCSPEC, RID_REGISTER, reinterpret_cast, REINTERPRET_CAST, NORID, -return, RETURN, NORID, +return, RETURN_KEYWORD, NORID, short, TYPESPEC, RID_SHORT, signature, AGGR, RID_SIGNATURE /* Extension */, signed, TYPESPEC, RID_SIGNED, diff --git a/contrib/gcc/cp/gxxint.texi b/contrib/gcc/cp/gxxint.texi index 7cb57f2..05f1373 100644 --- a/contrib/gcc/cp/gxxint.texi +++ b/contrib/gcc/cp/gxxint.texi @@ -23,7 +23,6 @@ Questions and comments to Benjamin Kosnik @code{}. * Access Control:: * Error Reporting:: * Parser:: -* Copying Objects:: * Exception Handling:: * Free Store:: * Mangling:: Function name mangling for C++ and Java @@ -167,77 +166,6 @@ class foo @{ public: int b; int a; foo (); @}; Thus, @samp{b} will be initialized with 2 first, then @samp{a} will be initialized with 1, regardless of how they're listed in the mem-initializer. -@item Argument Matching - -In early 1993, the argument matching scheme in @sc{gnu} C++ changed -significantly. The original code was completely replaced with a new -method that will, hopefully, be easier to understand and make fixing -specific cases much easier. - -The @samp{-fansi-overloading} option is used to enable the new code; at -some point in the future, it will become the default behavior of the -compiler. - -The file @file{cp-call.c} contains all of the new work, in the functions -@code{rank_for_overload}, @code{compute_harshness}, -@code{compute_conversion_costs}, and @code{ideal_candidate}. - -Instead of using obscure numerical values, the quality of an argument -match is now represented by clear, individual codes. The new data -structure @code{struct harshness} (it used to be an @code{unsigned} -number) contains: - -@enumerate a -@item the @samp{code} field, to signify what was involved in matching two -arguments; -@item the @samp{distance} field, used in situations where inheritance -decides which function should be called (one is ``closer'' than -another); -@item and the @samp{int_penalty} field, used by some codes as a tie-breaker. -@end enumerate - -The @samp{code} field is a number with a given bit set for each type of -code, OR'd together. The new codes are: - -@itemize @bullet -@item @code{EVIL_CODE} -The argument was not a permissible match. - -@item @code{CONST_CODE} -Currently, this is only used by @code{compute_conversion_costs}, to -distinguish when a non-@code{const} member function is called from a -@code{const} member function. - -@item @code{ELLIPSIS_CODE} -A match against an ellipsis @samp{...} is considered worse than all others. - -@item @code{USER_CODE} -Used for a match involving a user-defined conversion. - -@item @code{STD_CODE} -A match involving a standard conversion. - -@item @code{PROMO_CODE} -A match involving an integral promotion. For these, the -@code{int_penalty} field is used to handle the ARM's rule (XXX cite) -that a smaller @code{unsigned} type should promote to a @code{int}, not -to an @code{unsigned int}. - -@item @code{QUAL_CODE} -Used to mark use of qualifiers like @code{const} and @code{volatile}. - -@item @code{TRIVIAL_CODE} -Used for trivial conversions. The @samp{int_penalty} field is used by -@code{convert_harshness} to communicate further penalty information back -to @code{build_overload_call_real} when deciding which function should -be call. -@end itemize - -The functions @code{convert_to_aggr} and @code{build_method_call} use -@code{compute_conversion_costs} to rate each argument's suitability for -a given candidate function (that's how we get the list of candidates for -@code{ideal_candidate}). - @item The Explicit Keyword The use of @code{explicit} on a constructor is used by @code{grokdeclarator} @@ -1002,7 +930,7 @@ To have the line number on the error message indicate the line of the DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want, use @code{%+D}, or it will default to the first. -@node Parser, Copying Objects, Error Reporting, Top +@node Parser, Exception Handling, Error Reporting, Top @section Parser Some comments on the parser: @@ -1093,33 +1021,7 @@ conflicts. Unlike the others, this ambiguity is not recognized by the Working Paper. -@node Copying Objects, Exception Handling, Parser, Top -@section Copying Objects - -The generated copy assignment operator in g++ does not currently do the -right thing for multiple inheritance involving virtual bases; it just -calls the copy assignment operators for its direct bases. What it -should probably do is: - -1) Split up the copy assignment operator for all classes that have -vbases into "copy my vbases" and "copy everything else" parts. Or do -the trickiness that the constructors do to ensure that vbases don't get -initialized by intermediate bases. - -2) Wander through the class lattice, find all vbases for which no -intermediate base has a user-defined copy assignment operator, and call -their "copy everything else" routines. If not all of my vbases satisfy -this criterion, warn, because this may be surprising behavior. - -3) Call the "copy everything else" routine for my direct bases. - -If we only have one direct base, we can just foist everything off onto -them. - -This issue is currently under discussion in the core reflector -(2/28/94). - -@node Exception Handling, Free Store, Copying Objects, Top +@node Exception Handling, Free Store, Parser, Top @section Exception Handling Note, exception handling in g++ is still under development. @@ -1666,18 +1568,18 @@ as @samp{P} followed by the mangling of the class name. @subsection Squangled type compression -Squangling (enabled with the @samp{-fsquangle} option), utilizes -the @samp{B} code to indicate reuse of a previously -seen type within an indentifier. Types are recognized in a left to -right manner and given increasing values, which are -appended to the code in the standard manner. Ie, multiple digit numbers -are delimited by @samp{_} characters. A type is considered to be any -non primitive type, regardless of whether its a parameter, template -parameter, or entire template. Certain codes are considered modifiers -of a type, and are not included as part of the type. These are the -@samp{C}, @samp{V}, @samp{P}, @samp{A}, @samp{R}, and @samp{U} codes, -denoting constant, volatile, pointer, array, reference, and unsigned. -These codes may precede a @samp{B} type in order to make the required +Squangling (enabled with the @samp{-fsquangle} option), utilizes the +@samp{B} code to indicate reuse of a previously seen type within an +indentifier. Types are recognized in a left to right manner and given +increasing values, which are appended to the code in the standard +manner. Ie, multiple digit numbers are delimited by @samp{_} +characters. A type is considered to be any non primitive type, +regardless of whether its a parameter, template parameter, or entire +template. Certain codes are considered modifiers of a type, and are not +included as part of the type. These are the @samp{C}, @samp{V}, +@samp{P}, @samp{A}, @samp{R}, @samp{U} and @samp{u} codes, denoting +constant, volatile, pointer, array, reference, unsigned, and restrict. +These codes may precede a @samp{B} type in order to make the required modifications to the type. For example: @@ -1845,6 +1747,14 @@ Used to indicate a template function. @item i Encodes the C++ and Java @code{int} types. +@item I +Encodes typedef names of the form @code{int@var{n}_t}, where @var{n} is a +positive decimal number. The @samp{I} is followed by either two +hexidecimal digits, which encode the value of @var{n}, or by an +arbitrary number of hexidecimal digits between underscores. For +example, @samp{I40} encodes the type @code{int64_t}, and @samp{I_200_} +encodes the type @code{int512_t}. + @item J Indicates a complex type. @@ -1854,12 +1764,21 @@ Used by squangling to compress qualified names. @item l Encodes the C++ @code{long} type. +@item n +Immediate repeated type. Followed by the repeat count. + +@item N +Repeated type. Followed by the repeat count of the repeated type, +followed by the type index of the repeated type. Due to a bug in +g++ 2.7.2, this is only generated if index is 0. Superceded by +@samp{n} when squangling. + @item P Indicates a pointer type. Followed by the type pointed to. @item Q Used to mangle qualified names, which arise from nested classes. -Should also be used for namespaces (?). +Also used for namespaces. In Java used to mangle package-qualified names, and inner classes. @item r @@ -1888,11 +1807,14 @@ A modifier that indicates that the following integer type is unsigned. Also used to indicate that the following class or namespace name is encoded using Unicode-mangling. +@item u +The @code{restrict} type qualifier. + @item v Encodes the C++ and Java @code{void} types. @item V -A modified for a @code{const} type or method. +A modifier for a @code{volatile} type or method. @item w Encodes the C++ @code{wchar_t} type, and the Java @code{char} types. diff --git a/contrib/gcc/cp/inc/exception b/contrib/gcc/cp/inc/exception index 9954146..32efb9f 100644 --- a/contrib/gcc/cp/inc/exception +++ b/contrib/gcc/cp/inc/exception @@ -1,5 +1,5 @@ // Exception Handling support header for -*- C++ -*- -// Copyright (C) 1995, 1996 Free Software Foundation +// Copyright (C) 1995, 96-97, 1998 Free Software Foundation #ifndef __EXCEPTION__ #define __EXCEPTION__ @@ -8,9 +8,7 @@ extern "C++" { -#ifdef __HONOR_STD namespace std { -#endif class exception { public: @@ -34,9 +32,7 @@ unexpected_handler set_unexpected (unexpected_handler); void unexpected () __attribute__ ((__noreturn__)); bool uncaught_exception (); -#ifdef __HONOR_STD } // namespace std -#endif } // extern "C++" diff --git a/contrib/gcc/cp/inc/new b/contrib/gcc/cp/inc/new index 0f25a5c..b66673d 100644 --- a/contrib/gcc/cp/inc/new +++ b/contrib/gcc/cp/inc/new @@ -1,5 +1,5 @@ // The -*- C++ -*- dynamic memory management header. -// Copyright (C) 1994, 1996 Free Software Foundation +// Copyright (C) 1994, 96-97, 1998 Free Software Foundation #ifndef __NEW__ #define __NEW__ @@ -10,9 +10,7 @@ extern "C++" { -#ifdef __HONOR_STD namespace std { -#endif class bad_alloc : public exception { public: @@ -24,9 +22,7 @@ namespace std { typedef void (*new_handler)(); new_handler set_new_handler (new_handler); -#ifdef __HONOR_STD } // namespace std -#endif // replaceable signatures void *operator new (size_t) throw (std::bad_alloc); diff --git a/contrib/gcc/cp/inc/new.h b/contrib/gcc/cp/inc/new.h index 799db7e..006be7e 100644 --- a/contrib/gcc/cp/inc/new.h +++ b/contrib/gcc/cp/inc/new.h @@ -5,9 +5,7 @@ #include -#ifdef __HONOR_STD using std::new_handler; using std::set_new_handler; -#endif #endif // __NEW_H__ diff --git a/contrib/gcc/cp/inc/typeinfo b/contrib/gcc/cp/inc/typeinfo index e46acb9..9347849 100644 --- a/contrib/gcc/cp/inc/typeinfo +++ b/contrib/gcc/cp/inc/typeinfo @@ -1,5 +1,5 @@ // RTTI support for -*- C++ -*- -// Copyright (C) 1994, 1995, 1996 Free Software Foundation +// Copyright (C) 1994, 95-97, 1998 Free Software Foundation #ifndef __TYPEINFO__ #define __TYPEINFO__ @@ -10,9 +10,7 @@ extern "C++" { -#ifdef __HONOR_STD namespace std { -#endif class type_info { private: @@ -21,7 +19,7 @@ private: type_info (const type_info&); protected: - type_info (const char *n): _name (n) { } + explicit type_info (const char *n): _name (n) { } const char *_name; @@ -54,9 +52,7 @@ class bad_typeid : public exception { virtual ~bad_typeid () { } }; -#ifdef __HONOR_STD } // namespace std -#endif } // extern "C++" #endif diff --git a/contrib/gcc/cp/init.c b/contrib/gcc/cp/init.c index 931d033..38bf248 100644 --- a/contrib/gcc/cp/init.c +++ b/contrib/gcc/cp/init.c @@ -1,5 +1,5 @@ /* Handle initialization things in C++. - Copyright (C) 1987, 89, 92-96, 1997 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -32,8 +32,6 @@ Boston, MA 02111-1307, USA. */ #include "expr.h" #include "toplev.h" -extern void compiler_error (); - /* In C++, structures with well-defined constructors are initialized by those constructors, unasked. CURRENT_BASE_INIT_LIST holds a list of stmts for a BASE_INIT term in the grammar. @@ -46,25 +44,22 @@ extern void compiler_error (); tree current_base_init_list, current_member_init_list; static void expand_aggr_vbase_init_1 PROTO((tree, tree, tree, tree)); -static void expand_aggr_vbase_init PROTO((tree, tree, tree, tree)); -static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int, - int)); -static void expand_default_init PROTO((tree, tree, tree, tree, int, - int)); +static void construct_virtual_bases PROTO((tree, tree, tree, tree, tree)); +static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int)); +static void expand_default_init PROTO((tree, tree, tree, tree, int)); static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree, int)); static void perform_member_init PROTO((tree, tree, tree, int)); static void sort_base_init PROTO((tree, tree *, tree *)); -static tree build_builtin_call PROTO((tree, tree, tree)); -static tree build_array_eh_cleanup PROTO((tree, tree, tree)); -static int member_init_ok_or_else PROTO((tree, tree, char *)); +static tree build_builtin_delete_call PROTO((tree)); +static int member_init_ok_or_else PROTO((tree, tree, const char *)); static void expand_virtual_init PROTO((tree, tree)); static tree sort_member_init PROTO((tree)); -static tree build_partial_cleanup_for PROTO((tree)); static tree initializing_context PROTO((tree)); - -/* Cache _builtin_new and _builtin_delete exprs. */ -static tree BIN, BID, BIVN, BIVD; +static void expand_vec_init_try_block PROTO((tree)); +static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree)); +static tree build_java_class_ref PROTO((tree)); +static void expand_cleanup_for_base PROTO((tree, tree)); /* Cache the identifier nodes for the magic field of a new cookie. */ static tree nc_nelts_field_id; @@ -80,15 +75,6 @@ void init_init_processing () { tree fields[1]; - /* Define implicit `operator new' and `operator delete' functions. */ - BIN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) NEW_EXPR]))); - TREE_USED (TREE_OPERAND (BIN, 0)) = 0; - BID = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) DELETE_EXPR]))); - TREE_USED (TREE_OPERAND (BID, 0)) = 0; - BIVN = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_NEW_EXPR]))); - TREE_USED (TREE_OPERAND (BIVN, 0)) = 0; - BIVD = default_conversion (get_first_fn (IDENTIFIER_GLOBAL_VALUE (ansi_opname[(int) VEC_DELETE_EXPR]))); - TREE_USED (TREE_OPERAND (BIVD, 0)) = 0; minus_one = build_int_2 (-1, -1); /* Define the structure that holds header information for @@ -189,7 +175,7 @@ perform_member_init (member, name, init, explicit) array_type_nelts (type), TREE_VALUE (init), 1); } else - expand_aggr_init (decl, init, 0, 0); + expand_aggr_init (decl, init, 0); } else { @@ -492,17 +478,6 @@ sort_base_init (t, rbase_ptr, vbase_ptr) *vbase_ptr = vbases; } -/* Perform partial cleanups for a base for exception handling. */ - -static tree -build_partial_cleanup_for (binfo) - tree binfo; -{ - return build_scoped_method_call - (current_class_ref, binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node)); -} - /* Perform whatever initializations have yet to be done on the base class of the class variable. These actions are in the global variable CURRENT_BASE_INIT_LIST. Such an action could be @@ -562,14 +537,13 @@ emit_base_init (t, immediately) sort_base_init (t, &rbase_init_list, &vbase_init_list); current_base_init_list = NULL_TREE; + /* First, initialize the virtual base classes, if we are + constructing the most-derived object. */ if (TYPE_USES_VIRTUAL_BASECLASSES (t)) { tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); - - expand_start_cond (first_arg, 0); - expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr, - vbase_init_list); - expand_end_cond (); + construct_virtual_bases (t, current_class_ref, current_class_ptr, + vbase_init_list, first_arg); } /* Now, perform initialization of non-virtual base classes. */ @@ -581,11 +555,8 @@ emit_base_init (t, immediately) if (TREE_VIA_VIRTUAL (base_binfo)) continue; -#if 0 /* Once unsharing happens soon enough. */ - my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, 999); -#else - BINFO_INHERITANCE_CHAIN (base_binfo) = t_binfo; -#endif + my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, + 999); if (TREE_PURPOSE (rbase_init_list)) init = TREE_VALUE (rbase_init_list); @@ -604,24 +575,13 @@ emit_base_init (t, immediately) member = convert_pointer_to_real (base_binfo, current_class_ptr); expand_aggr_init_1 (base_binfo, NULL_TREE, build_indirect_ref (member, NULL_PTR), init, - BINFO_OFFSET_ZEROP (base_binfo), LOOKUP_NORMAL); + LOOKUP_NORMAL); expand_end_target_temps (); free_temp_slots (); } - if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - tree expr; - - /* All cleanups must be on the function_obstack. */ - push_obstacks_nochange (); - resume_temporary_allocation (); - expr = build_partial_cleanup_for (base_binfo); - pop_obstacks (); - add_partial_entry (expr); - } - + expand_cleanup_for_base (base_binfo, NULL_TREE); rbase_init_list = TREE_CHAIN (rbase_init_list); } @@ -783,6 +743,39 @@ expand_virtual_init (binfo, decl) expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl)); } +/* If an exception is thrown in a constructor, those base classes already + constructed must be destroyed. This function creates the cleanup + for BINFO, which has just been constructed. If FLAG is non-NULL, + it is a DECL which is non-zero when this base needs to be + destroyed. */ + +static void +expand_cleanup_for_base (binfo, flag) + tree binfo; + tree flag; +{ + tree expr; + + if (!TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo))) + return; + + /* All cleanups must be on the function_obstack. */ + push_obstacks_nochange (); + resume_temporary_allocation (); + + /* Call the destructor. */ + expr = (build_scoped_method_call + (current_class_ref, binfo, dtor_identifier, + build_expr_list (NULL_TREE, integer_zero_node))); + if (flag) + expr = fold (build (COND_EXPR, void_type_node, + truthvalue_conversion (flag), + expr, integer_zero_node)); + + pop_obstacks (); + add_partial_entry (expr); +} + /* Subroutine of `expand_aggr_vbase_init'. BINFO is the binfo of the type that is being initialized. INIT_LIST is the list of initializers for the virtual baseclass. */ @@ -799,42 +792,66 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) if (init) init = TREE_VALUE (init); /* Call constructors, but don't set up vtables. */ - expand_aggr_init_1 (binfo, exp, ref, init, 0, LOOKUP_COMPLAIN); + expand_aggr_init_1 (binfo, exp, ref, init, LOOKUP_COMPLAIN); expand_end_target_temps (); free_temp_slots (); } -/* Initialize this object's virtual base class pointers. This must be - done only at the top-level of the object being constructed. - - INIT_LIST is list of initialization for constructor to perform. */ +/* Construct the virtual base-classes of THIS_REF (whose address is + THIS_PTR). The object has the indicated TYPE. The construction + actually takes place only if FLAG is non-zero. INIT_LIST is list + of initialization for constructor to perform. */ static void -expand_aggr_vbase_init (binfo, exp, addr, init_list) - tree binfo; - tree exp; - tree addr; +construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) + tree type; + tree this_ref; + tree this_ptr; tree init_list; + tree flag; { - tree type = BINFO_TYPE (binfo); + tree vbases; + tree result; - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - tree result = init_vbase_pointers (type, addr); - tree vbases; + /* If there are no virtual baseclasses, we shouldn't even be here. */ + my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621); - if (result) - expand_expr_stmt (build_compound_expr (result)); + /* First set the pointers in our object that tell us where to find + our virtual baseclasses. */ + expand_start_cond (flag, 0); + result = init_vbase_pointers (type, this_ptr); + if (result) + expand_expr_stmt (build_compound_expr (result)); + expand_end_cond (); - for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; - vbases = TREE_CHAIN (vbases)) - { - tree tmp = purpose_member (vbases, result); - expand_aggr_vbase_init_1 (vbases, exp, - TREE_OPERAND (TREE_VALUE (tmp), 0), - init_list); - } + /* Now, run through the baseclasses, initializing each. */ + for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; + vbases = TREE_CHAIN (vbases)) + { + tree tmp = purpose_member (vbases, result); + + /* If there are virtual base classes with destructors, we need to + emit cleanups to destroy them if an exception is thrown during + the construction process. These exception regions (i.e., the + period during which the cleanups must occur) begin from the time + the construction is complete to the end of the function. If we + create a conditional block in which to initialize the + base-classes, then the cleanup region for the virtual base begins + inside a block, and ends outside of that block. This situation + confuses the sjlj exception-handling code. Therefore, we do not + create a single conditional block, but one for each + initialization. (That way the cleanup regions always begin + in the outer block.) We trust the back-end to figure out + that the FLAG will not change across initializations, and + avoid doing multiple tests. */ + expand_start_cond (flag, 0); + expand_aggr_vbase_init_1 (vbases, this_ref, + TREE_OPERAND (TREE_VALUE (tmp), 0), + init_list); + expand_end_cond (); + + expand_cleanup_for_base (vbases, flag); } } @@ -864,7 +881,7 @@ static int member_init_ok_or_else (field, type, member_name) tree field; tree type; - char *member_name; + const char *member_name; { if (field == error_mark_node) return 0; @@ -914,7 +931,7 @@ expand_member_init (exp, name, init) if (name && TREE_CODE (name) == TYPE_DECL) { - basetype = TREE_TYPE (name); + basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); name = DECL_NAME (name); } @@ -1052,9 +1069,8 @@ expand_member_init (exp, name, init) perform the initialization, but not both, as it would be ambiguous. */ void -expand_aggr_init (exp, init, alias_this, flags) +expand_aggr_init (exp, init, flags) tree exp, init; - int alias_this; int flags; { tree type = TREE_TYPE (exp); @@ -1075,7 +1091,7 @@ expand_aggr_init (exp, init, alias_this, flags) /* Must arrange to initialize each element of EXP from elements of INIT. */ tree itype = init ? TREE_TYPE (init) : NULL_TREE; - if (TYPE_READONLY (TREE_TYPE (type)) || TYPE_VOLATILE (TREE_TYPE (type))) + if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED) { TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); if (init) @@ -1099,7 +1115,8 @@ expand_aggr_init (exp, init, alias_this, flags) return; } expand_vec_init (exp, exp, array_type_nelts (type), init, - init && comptypes (TREE_TYPE (init), TREE_TYPE (exp), 1)); + init && same_type_p (TREE_TYPE (init), + TREE_TYPE (exp))); TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; TREE_TYPE (exp) = type; @@ -1123,18 +1140,17 @@ expand_aggr_init (exp, init, alias_this, flags) TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, - init, alias_this, LOOKUP_NORMAL|flags); + init, LOOKUP_NORMAL|flags); TREE_TYPE (exp) = type; TREE_READONLY (exp) = was_const; TREE_THIS_VOLATILE (exp) = was_volatile; } static void -expand_default_init (binfo, true_exp, exp, init, alias_this, flags) +expand_default_init (binfo, true_exp, exp, init, flags) tree binfo; tree true_exp, exp; tree init; - int alias_this; int flags; { tree type = TREE_TYPE (exp); @@ -1155,14 +1171,13 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) if (true_exp != exp) abort (); - /* We special-case TARGET_EXPRs here to avoid an error about - private copy constructors for temporaries bound to reference vars. - If the TARGET_EXPR represents a call to a function that has - permission to create such objects, a reference can bind directly - to the return value. An object variable must be initialized - via the copy constructor, even if the call is elided. */ - if (! (TREE_CODE (exp) == VAR_DECL && DECL_ARTIFICIAL (exp) - && TREE_CODE (init) == TARGET_EXPR && TREE_TYPE (init) == type)) + if (flags & DIRECT_BIND) + /* Do nothing. We hit this in two cases: Reference initialization, + where we aren't initializing a real variable, so we don't want + to run a new constructor; and catching an exception, where we + have already built up the constructor call so we could wrap it + in an exception region. */; + else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); if (TREE_CODE (init) == TRY_CATCH_EXPR) @@ -1227,11 +1242,10 @@ expand_default_init (binfo, true_exp, exp, init, alias_this, flags) its description. */ static void -expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) +expand_aggr_init_1 (binfo, true_exp, exp, init, flags) tree binfo; tree true_exp, exp; tree init; - int alias_this; int flags; { tree type = TREE_TYPE (exp); @@ -1262,7 +1276,7 @@ expand_aggr_init_1 (binfo, true_exp, exp, init, alias_this, flags) /* We know that expand_default_init can handle everything we want at this point. */ - expand_default_init (binfo, true_exp, exp, init, alias_this, flags); + expand_default_init (binfo, true_exp, exp, init, flags); } /* Report an error if NAME is not the name of a user-defined, @@ -1379,7 +1393,6 @@ build_member_call (type, name, parmlist) tree t; tree method_name; int dtor = 0; - int dont_use_this = 0; tree basetype_path, decl; if (TREE_CODE (name) == TEMPLATE_ID_EXPR @@ -1387,7 +1400,18 @@ build_member_call (type, name, parmlist) { /* 'name' already refers to the decls from the namespace, since we hit do_identifier for template_ids. */ - my_friendly_assert (is_overloaded_fn (TREE_OPERAND (name, 0)), 980519); + 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 build_x_function_call (name, parmlist, current_class_ref); } @@ -1398,10 +1422,17 @@ build_member_call (type, name, parmlist) return build_x_function_call (lookup_namespace_name (type, name), parmlist, current_class_ref); - if (TREE_CODE (name) != TEMPLATE_ID_EXPR) - method_name = name; + 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 = TREE_OPERAND (name, 0); + method_name = name; if (TREE_CODE (method_name) == BIT_NOT_EXPR) { @@ -1435,42 +1466,29 @@ build_member_call (type, name, parmlist) return error_mark_node; } - /* No object? Then just fake one up, and let build_method_call - figure out what to do. */ - if (current_class_type == 0 - || get_base_distance (type, current_class_type, 0, &basetype_path) == -1) - dont_use_this = 1; + decl = maybe_dummy_object (type, &basetype_path); - if (dont_use_this) - { - basetype_path = TYPE_BINFO (type); - decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node); - } - else if (current_class_ptr == 0) - { - dont_use_this = 1; - decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node); - } - else + /* Convert 'this' to the specified type to disambiguate conversion + to the function's context. Apparently Standard C++ says that we + shouldn't do this. */ + if (decl == current_class_ref + && ! pedantic + && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) { tree olddecl = current_class_ptr; tree oldtype = TREE_TYPE (TREE_TYPE (olddecl)); if (oldtype != type) { - tree newtype = build_type_variant (type, TYPE_READONLY (oldtype), - TYPE_VOLATILE (oldtype)); + tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype)); decl = convert_force (build_pointer_type (newtype), olddecl, 0); + decl = build_indirect_ref (decl, NULL_PTR); } - else - decl = olddecl; } - decl = build_indirect_ref (decl, NULL_PTR); - if (method_name == constructor_name (type) || method_name == constructor_name_full (type)) return build_functional_cast (type, parmlist); - if ((t = lookup_fnfields (basetype_path, method_name, 0))) + if (lookup_fnfields (basetype_path, method_name, 0)) return build_method_call (decl, TREE_CODE (name) == TEMPLATE_ID_EXPR ? name : method_name, @@ -1483,7 +1501,7 @@ build_member_call (type, name, parmlist) return error_mark_node; if (TREE_CODE (t) == FIELD_DECL) { - if (dont_use_this) + if (is_dummy_object (decl)) { cp_error ("invalid use of non-static field `%D'", t); return error_mark_node; @@ -1523,7 +1541,8 @@ tree build_offset_ref (type, name) tree type, name; { - tree decl, fnfields, fields, t = error_mark_node; + tree decl, t = error_mark_node; + tree member; tree basebinfo = NULL_TREE; tree orig_name = name; @@ -1541,7 +1560,7 @@ build_offset_ref (type, name) if (TREE_CODE (type) == NAMESPACE_DECL) { t = lookup_namespace_name (type, name); - if (! type_unknown_p (t)) + if (t != error_mark_node && ! type_unknown_p (t)) { mark_used (t); t = convert_from_reference (t); @@ -1559,6 +1578,11 @@ build_offset_ref (type, name) part, we treat this just like a.f. We do remember, however, the template-id that was used. */ name = TREE_OPERAND (orig_name, 0); + + if (TREE_CODE (name) == LOOKUP_EXPR) + /* This can happen during tsubst'ing. */ + name = TREE_OPERAND (name, 0); + my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); } @@ -1576,57 +1600,27 @@ build_offset_ref (type, name) name = ctor_identifier; #endif - if (TYPE_SIZE (complete_type (type)) == 0) + if (TYPE_SIZE (complete_type (type)) == 0 + && !TYPE_BEING_DEFINED (type)) { - if (type == current_class_type) - t = IDENTIFIER_CLASS_VALUE (name); - else - t = NULL_TREE; - if (t == 0) - { - cp_error ("incomplete type `%T' does not have member `%D'", type, - name); - return error_mark_node; - } - if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == VAR_DECL - || TREE_CODE (t) == CONST_DECL) - { - mark_used (t); - return t; - } - if (TREE_CODE (t) == FIELD_DECL) - sorry ("use of member in incomplete aggregate type"); - else if (TREE_CODE (t) == FUNCTION_DECL) - sorry ("use of member function in incomplete aggregate type"); - else - my_friendly_abort (52); + cp_error ("incomplete type `%T' does not have member `%D'", type, + name); return error_mark_node; } - if (current_class_type == 0 - || get_base_distance (type, current_class_type, 0, &basebinfo) == -1) - { - basebinfo = TYPE_BINFO (type); - decl = build1 (NOP_EXPR, type, error_mark_node); - } - else if (current_class_ptr == 0) - decl = build1 (NOP_EXPR, type, error_mark_node); - else - decl = current_class_ref; + decl = maybe_dummy_object (type, &basebinfo); - fnfields = lookup_fnfields (basebinfo, name, 1); - fields = lookup_field (basebinfo, name, 0, 0); + member = lookup_member (basebinfo, name, 1, 0); - if (fields == error_mark_node || fnfields == error_mark_node) + if (member == error_mark_node) return error_mark_node; /* A lot of this logic is now handled in lookup_field and lookup_fnfield. */ - if (fnfields) + if (member && BASELINK_P (member)) { - extern int flag_save_memoized_contexts; - /* Go from the TREE_BASELINK to the member function info. */ + tree fnfields = member; t = TREE_VALUE (fnfields); if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) @@ -1644,7 +1638,7 @@ build_offset_ref (type, name) t = ovl_cons (t, NULL_TREE); return build (OFFSET_REF, - build_offset_type (type, unknown_type_node), + unknown_type_node, decl, build (TEMPLATE_ID_EXPR, TREE_TYPE (t), @@ -1654,56 +1648,35 @@ build_offset_ref (type, name) if (!really_overloaded_fn (t)) { - tree access; - /* Get rid of a potential OVERLOAD around it */ t = OVL_CURRENT (t); /* unique functions are handled easily. */ basebinfo = TREE_PURPOSE (fnfields); - access = compute_access (basebinfo, t); - if (access == access_protected_node) - { - cp_error_at ("member function `%#D' is protected", t); - error ("in this context"); - return error_mark_node; - } - if (access == access_private_node) - { - cp_error_at ("member function `%#D' is private", t); - error ("in this context"); - return error_mark_node; - } + if (!enforce_access (basebinfo, t)) + return error_mark_node; mark_used (t); + if (DECL_STATIC_FUNCTION_P (t)) + return t; return build (OFFSET_REF, TREE_TYPE (t), decl, t); } /* FNFIELDS is most likely allocated on the search_obstack, which will go away after this class scope. If we need - to save this value for later (either for memoization - or for use as an initializer for a static variable), then - do so here. + to save this value for later (i.e. for use as an initializer + for a static variable), then do so here. ??? The smart thing to do for the case of saving initializers is to resolve them before we're done with this scope. */ if (!TREE_PERMANENT (fnfields) - && ((flag_save_memoized_contexts && toplevel_bindings_p ()) - || ! allocation_temporary_p ())) + && ! allocation_temporary_p ()) fnfields = copy_list (fnfields); - t = build_tree_list (error_mark_node, fnfields); - TREE_TYPE (t) = build_offset_type (type, unknown_type_node); - return t; + TREE_TYPE (fnfields) = unknown_type_node; + return build (OFFSET_REF, unknown_type_node, decl, fnfields); } - /* Now that we know we are looking for a field, see if we - have access to that field. Lookup_field will give us the - error message. */ - - t = lookup_field (basebinfo, name, 1, 0); - - if (t == error_mark_node) - return error_mark_node; + t = member; if (t == NULL_TREE) { @@ -1724,7 +1697,7 @@ build_offset_ref (type, name) return convert_from_reference (t); } - if (TREE_CODE (t) == FIELD_DECL && DECL_BIT_FIELD (t)) + if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) { cp_error ("illegal pointer to bit field `%D'", t); return error_mark_node; @@ -1753,12 +1726,6 @@ resolve_offset_ref (exp) tree member; tree basetype, addr; - if (TREE_CODE (exp) == TREE_LIST) - { - cp_pedwarn ("assuming & on overloaded member function"); - return build_unary_op (ADDR_EXPR, exp, 0); - } - if (TREE_CODE (exp) == OFFSET_REF) { member = TREE_OPERAND (exp, 1); @@ -1777,10 +1744,22 @@ resolve_offset_ref (exp) base = current_class_ref; } + if (BASELINK_P (member)) + { + cp_pedwarn ("assuming & on overloaded member function"); + return build_unary_op (ADDR_EXPR, exp, 0); + } + + if (TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) + { + cp_pedwarn ("assuming & on `%E'", member); + return build_unary_op (ADDR_EXPR, exp, 0); + } + if ((TREE_CODE (member) == VAR_DECL - && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) - || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) + && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)) + && ! TYPE_PTRMEM_P (TREE_TYPE (member))) + || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE) { /* These were static members. */ if (mark_addressable (member) == 0) @@ -1808,11 +1787,10 @@ resolve_offset_ref (exp) /* The first case is really just a reference to a member of `this'. */ if (TREE_CODE (member) == FIELD_DECL - && (base == current_class_ref - || (TREE_CODE (base) == NOP_EXPR - && TREE_OPERAND (base, 0) == error_mark_node))) + && (base == current_class_ref || is_dummy_object (base))) { - tree basetype_path, access; + tree basetype_path; + tree expr; if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) basetype = TYPE_OFFSET_BASETYPE (type); @@ -1828,40 +1806,28 @@ resolve_offset_ref (exp) } /* Kludge: we need to use basetype_path now, because convert_pointer_to will bash it. */ - access = compute_access (basetype_path, member); + enforce_access (basetype_path, member); addr = convert_pointer_to (basetype, base); - if (access == access_public_node) - return build (COMPONENT_REF, TREE_TYPE (member), - build_indirect_ref (addr, NULL_PTR), member); - if (access == access_protected_node) - { - cp_error_at ("member `%D' is protected", member); - error ("in this context"); - return error_mark_node; - } - if (access == access_private_node) - { - cp_error_at ("member `%D' is private", member); - error ("in this context"); - return error_mark_node; - } - my_friendly_abort (55); + + /* Even in the case of illegal access, we form the + COMPONENT_REF; that will allow better error recovery than + just feeding back error_mark_node. */ + expr = build (COMPONENT_REF, TREE_TYPE (member), + build_indirect_ref (addr, NULL_PTR), member); + return convert_from_reference (expr); } /* Ensure that we have an object. */ - if (TREE_CODE (base) == NOP_EXPR - && TREE_OPERAND (base, 0) == error_mark_node) + 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); - } + /* 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); - if (TREE_CODE (TREE_TYPE (member)) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (TREE_TYPE (member))) { if (addr == error_mark_node) { @@ -1869,17 +1835,15 @@ resolve_offset_ref (exp) return error_mark_node; } - basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (member)); + basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member))); addr = convert_pointer_to (basetype, addr); - member = cp_convert (ptrdiff_type_node, - build_unary_op (ADDR_EXPR, member, 0)); + member = cp_convert (ptrdiff_type_node, member); /* Pointer to data members are offset by one, so that a null pointer with a real value of 0 is distinguishable from an offset of the first member of a structure. */ member = build_binary_op (MINUS_EXPR, member, - cp_convert (ptrdiff_type_node, integer_one_node), - 0); + cp_convert (ptrdiff_type_node, integer_one_node)); return build1 (INDIRECT_REF, type, build (PLUS_EXPR, build_pointer_type (type), @@ -1901,48 +1865,29 @@ decl_constant_value (decl) tree decl; { if (! TREE_THIS_VOLATILE (decl) -#if 0 - /* These may be necessary for C, but they break C++. */ - ! TREE_PUBLIC (decl) - /* Don't change a variable array bound or initial value to a constant - in a place where a variable is invalid. */ - && ! pedantic -#endif /* 0 */ - && DECL_INITIAL (decl) != 0 + && DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node /* This is invalid if initial value is not constant. If it has either a function call, a memory reference, or a variable, then re-evaluating it could give different results. */ && TREE_CONSTANT (DECL_INITIAL (decl)) /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR -#if 0 - /* We must allow this to work outside of functions so that - static constants can be used for array sizes. */ - && current_function_decl != 0 - && DECL_MODE (decl) != BLKmode -#endif - ) + && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) return DECL_INITIAL (decl); return decl; } /* Common subroutines of build_new and build_vec_delete. */ -/* Common interface for calling "builtin" functions that are not - really builtin. */ +/* Call the global __builtin_delete to delete ADDR. */ static tree -build_builtin_call (type, node, arglist) - tree type; - tree node; - tree arglist; +build_builtin_delete_call (addr) + tree addr; { - tree rval = build (CALL_EXPR, type, node, arglist, NULL_TREE); - TREE_SIDE_EFFECTS (rval) = 1; - assemble_external (TREE_OPERAND (node, 0)); - TREE_USED (TREE_OPERAND (node, 0)) = 1; - return rval; + mark_used (global_delete_fndecl); + return build_call (global_delete_fndecl, + void_type_node, build_expr_list (NULL_TREE, addr)); } /* Generate a C++ "new" expression. DECL is either a TREE_LIST @@ -2036,6 +1981,11 @@ build_new (placement, decl, init, use_global_new) } else { + int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM); + if (build_expr_type_conversion (flags, this_nelts, 0) + == NULL_TREE) + pedwarn ("size in array new must have integral type"); + this_nelts = save_expr (cp_convert (sizetype, this_nelts)); absdcl = TREE_OPERAND (absdcl, 0); if (this_nelts == integer_zero_node) @@ -2044,7 +1994,7 @@ build_new (placement, decl, init, use_global_new) nelts = integer_zero_node; } else - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); + nelts = build_binary_op (MULT_EXPR, nelts, this_nelts); } } else @@ -2155,6 +2105,46 @@ build_new (placement, decl, init, use_global_new) return rval; } +/* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ + +static tree jclass_node = NULL_TREE; + +/* Given a Java class, return a decl for the corresponding java.lang.Class. */ + +static tree +build_java_class_ref (type) + tree type; +{ + tree name, class_decl; + static tree CL_prefix = NULL_TREE; + if (CL_prefix == NULL_TREE) + CL_prefix = get_identifier("_CL_"); + if (jclass_node == NULL_TREE) + { + jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier("jclass")); + if (jclass_node == NULL_TREE) + fatal("call to Java constructor, while `jclass' undefined"); + jclass_node = TREE_TYPE (jclass_node); + } + name = build_overload_with_type (CL_prefix, type); + class_decl = IDENTIFIER_GLOBAL_VALUE (name); + if (class_decl == NULL_TREE) + { + push_obstacks_nochange (); + end_temporary_allocation (); + class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node)); + TREE_STATIC (class_decl) = 1; + DECL_EXTERNAL (class_decl) = 1; + TREE_PUBLIC (class_decl) = 1; + DECL_ARTIFICIAL (class_decl) = 1; + DECL_IGNORED_P (class_decl) = 1; + pushdecl_top_level (class_decl); + make_decl_rtl (class_decl, NULL_PTR, 1); + pop_obstacks (); + } + return class_decl; +} + /* Called from cplus_expand_expr when expanding a NEW_EXPR. The return value is immediately handed to expand_expr. */ @@ -2170,6 +2160,7 @@ build_new_1 (exp) enum tree_code code = NEW_EXPR; int use_cookie, nothrow, check_new; int use_global_new; + int use_java_new = 0; placement = TREE_OPERAND (exp, 0); type = TREE_OPERAND (exp, 1); @@ -2184,7 +2175,7 @@ build_new_1 (exp) } true_type = type; - if (TYPE_READONLY (type) || TYPE_VOLATILE (type)) + if (CP_TYPE_QUALS (type)) type = TYPE_MAIN_VARIANT (type); /* If our base type is an array, then make sure we know how many elements @@ -2192,16 +2183,16 @@ build_new_1 (exp) while (TREE_CODE (true_type) == ARRAY_TYPE) { tree this_nelts = array_type_nelts_top (true_type); - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); + nelts = build_binary_op (MULT_EXPR, nelts, this_nelts); true_type = TREE_TYPE (true_type); } - if (!complete_type_or_else (true_type)) + if (!complete_type_or_else (true_type, exp)) return error_mark_node; if (has_array) size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type), - nelts, 1)); + nelts)); else size = size_in_bytes (type); @@ -2223,21 +2214,21 @@ build_new_1 (exp) signature_error (NULL_TREE, true_type); return error_mark_node; } + + /* When we allocate an array, and the corresponding deallocation + function takes a second argument of type size_t, and that's the + "usual deallocation function", we allocate some extra space at + the beginning of the array to store the size of the array. -#if 1 - /* Get a little extra space to store a couple of things before the new'ed - array, if this isn't the default placement new. */ + Well, that's what we should do. For backwards compatibility, we + have to do this whenever there's a two-argument array-delete + operator. + FIXME: For -fnew-abi, we don't have to maintain backwards + compatibility and we should fix this. */ use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) && ! (placement && ! TREE_CHAIN (placement) && TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node)); -#else - /* Get a little extra space to store a couple of things before the new'ed - array, if this is either non-placement new or new (nothrow). */ - - use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) - && (! placement || nothrow)); -#endif if (use_cookie) { @@ -2267,9 +2258,26 @@ build_new_1 (exp) return error_mark_node; } } + else if (! placement && TYPE_FOR_JAVA (true_type)) + { + tree class_addr, alloc_decl; + tree class_decl = build_java_class_ref (true_type); + tree class_size = size_in_bytes (true_type); + static char alloc_name[] = "_Jv_AllocObject"; + use_java_new = 1; + alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name)); + if (alloc_decl == NULL_TREE) + fatal("call to Java constructor, while `%s' undefined", alloc_name); + class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); + rval = build_function_call (alloc_decl, + tree_cons (NULL_TREE, class_addr, + build_tree_list (NULL_TREE, + class_size))); + rval = cp_convert (build_pointer_type (true_type), rval); + } else { - int susp; + int susp = 0; if (flag_exceptions) /* We will use RVAL when generating an exception handler for @@ -2302,12 +2310,9 @@ build_new_1 (exp) tree t = TREE_OPERAND (rval, 0); /* The function. */ t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); - t = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t)); - - if (t && TREE_VALUE (t) == NULL_TREE) - nothrow = 1; + nothrow = TYPE_NOTHROW_P (TREE_TYPE (t)); } - check_new = flag_check_new || nothrow; + check_new = (flag_check_new || nothrow) && ! use_java_new; if ((check_new || flag_exceptions) && rval) { @@ -2326,7 +2331,7 @@ build_new_1 (exp) tree extra = BI_header_size; tree cookie, exp1; rval = convert (string_type_node, rval); /* for ptr arithmetic */ - rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1)); + rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra)); /* Store header info. */ cookie = build_indirect_ref (build (MINUS_EXPR, build_pointer_type (BI_header_type), @@ -2354,12 +2359,26 @@ build_new_1 (exp) if (! TYPE_NEEDS_CONSTRUCTING (type) && ! IS_AGGR_TYPE (type) && ! has_array) { - /* New 2.0 interpretation: `new int (10)' means - allocate an int, and initialize it with 10. */ + /* We are processing something like `new int (10)', which + means allocate an int, and initialize it with 10. */ tree deref; + tree deref_type; + /* At present RVAL is a temporary variable, created to hold + the value from the call to `operator new'. We transform + it to (*RVAL = INIT, RVAL). */ rval = save_expr (rval); deref = build_indirect_ref (rval, NULL_PTR); + + /* Even for something like `new const int (10)' we must + allow the expression to be non-const while we do the + initialization. */ + deref_type = TREE_TYPE (deref); + if (CP_TYPE_CONST_P (deref_type)) + TREE_TYPE (deref) + = cp_build_qualified_type (deref_type, + CP_TYPE_QUALS (deref_type) + & ~TYPE_QUAL_CONST); TREE_READONLY (deref) = 0; if (TREE_CHAIN (init) != NULL_TREE) @@ -2393,6 +2412,8 @@ build_new_1 (exp) flags |= LOOKUP_HAS_IN_CHARGE; } + if (use_java_new) + rval = save_expr (rval); newrval = rval; if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE) @@ -2404,6 +2425,10 @@ build_new_1 (exp) if (newrval == NULL_TREE || newrval == error_mark_node) return error_mark_node; + /* Java constructors compiled by jc1 do not return this. */ + if (use_java_new) + newrval = build (COMPOUND_EXPR, TREE_TYPE (newrval), + newrval, rval); rval = newrval; TREE_HAS_CONSTRUCTOR (rval) = 1; } @@ -2411,11 +2436,15 @@ build_new_1 (exp) rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), save_expr (rval), init, nelts); - /* If any part of the object initialization terminates by throwing - an exception and the new-expression does not contain a - new-placement, then the deallocation function is called to free - the memory in which the object was being constructed. */ - if (flag_exceptions && alloc_expr) + /* If any part of the object initialization terminates by throwing an + exception and a suitable deallocation function can be found, the + deallocation function is called to free the memory in which the + object was being constructed, after which the exception continues + to propagate in the context of the new-expression. If no + unambiguous matching deallocation function can be found, + propagating the exception does not cause the object's memory to be + freed. */ + if (flag_exceptions && alloc_expr && ! use_java_new) { enum tree_code dcode = has_array ? VEC_DELETE_EXPR : DELETE_EXPR; tree cleanup, fn = NULL_TREE; @@ -2435,7 +2464,7 @@ build_new_1 (exp) } /* Copy size to the saveable obstack. */ - size = copy_node (size); + size = mapcar (size, permanent_p); cleanup = build_op_delete_call (dcode, alloc_node, size, flags, fn); @@ -2448,9 +2477,6 @@ build_new_1 (exp) if (cleanup) { -#if 0 - /* Disable this until flow is fixed so that it doesn't - think the initialization of sentry is a dead write. */ tree end, sentry, begin, buf, t = TREE_TYPE (rval); begin = get_target_expr (boolean_true_node); @@ -2473,18 +2499,10 @@ build_new_1 (exp) rval = build (COMPOUND_EXPR, t, begin, build (COMPOUND_EXPR, t, rval, build (COMPOUND_EXPR, t, end, buf))); -#else - /* FIXME: this is a workaround for a crash due to overlapping - exception regions. Cleanups shouldn't really happen here. */ - rval = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (rval), rval); - - rval = build (TRY_CATCH_EXPR, TREE_TYPE (rval), rval, cleanup); - rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval); -#endif } } } - else if (TYPE_READONLY (true_type)) + else if (CP_TYPE_CONST_P (true_type)) cp_error ("uninitialized const in `new' of `%#T'", true_type); done: @@ -2499,7 +2517,7 @@ build_new_1 (exp) { /* Did we modify the storage? */ tree ifexp = build_binary_op (NE_EXPR, alloc_node, - integer_zero_node, 1); + integer_zero_node); rval = build_conditional_expr (ifexp, rval, alloc_node); } @@ -2569,12 +2587,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, tree base_tbd = cp_convert (ptype, build_binary_op (MINUS_EXPR, cp_convert (ptr_type_node, base), - BI_header_size, - 1)); + BI_header_size)); /* This is the real size */ virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); body = build_expr_list (NULL_TREE, - build_x_delete (ptype, base_tbd, + build_x_delete (base_tbd, 2 | use_global_delete, virtual_size)); body = build (COND_EXPR, void_type_node, @@ -2608,8 +2625,7 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, no_destructor: /* If the delete flag is one, or anything else with the low bit set, delete the storage. */ - if (auto_delete_vec == integer_zero_node - || auto_delete_vec == integer_two_node) + if (auto_delete_vec == integer_zero_node) deallocate_expr = integer_zero_node; else { @@ -2626,12 +2642,11 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, base_tbd = cp_convert (ptype, build_binary_op (MINUS_EXPR, cp_convert (string_type_node, base), - BI_header_size, - 1)); + BI_header_size)); /* True size with header. */ virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); } - deallocate_expr = build_x_delete (ptype, base_tbd, + deallocate_expr = build_x_delete (base_tbd, 2 | use_global_delete, virtual_size); if (auto_delete_vec != integer_one_node) @@ -2665,18 +2680,80 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, return cp_convert (void_type_node, body); } -/* Build a tree to cleanup partially built arrays. - BASE is that starting address of the array. - COUNT is the count of objects that have been built, that need destroying. - TYPE is the type of elements in the array. */ +/* Protect the vector initialization with a try-block so that we can + destroy the first few elements if constructing a later element + causes an exception to be thrown. TYPE is the type of the array + elements. */ -static tree -build_array_eh_cleanup (base, count, type) - tree base, count, type; +static void +expand_vec_init_try_block (type) + tree type; +{ + if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) + return; + + /* The code we generate looks like: + + try { + // Initialize the vector. + } catch (...) { + // Destory the elements that need destroying. + throw; + } + + Here we're just beginning the `try'. */ + + expand_eh_region_start (); +} + +/* Add code to destroy the array elements constructed so far if the + construction of some element in the array causes an exception to be + thrown. RVAL is the address of the last element in the array. + TYPE is the type of the array elements. MAXINDEX is the maximum + allowable index into the array. ITERATOR is an integer variable + indicating how many elements remain to be constructed. */ + +static void +expand_vec_init_catch_clause (rval, type, maxindex, iterator) + tree rval; + tree type; + tree maxindex; + tree iterator; { - tree expr = build_vec_delete_1 (base, count, type, integer_two_node, - integer_zero_node, 0); - return expr; + tree e; + tree cleanup; + + if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) + return; + + /* We have to ensure that this can live to the cleanup expansion + time, since we know it is only ever needed once, generate code + now. */ + push_obstacks_nochange (); + resume_temporary_allocation (); + + cleanup = make_node (RTL_EXPR); + TREE_TYPE (cleanup) = void_type_node; + RTL_EXPR_RTL (cleanup) = const0_rtx; + TREE_SIDE_EFFECTS (cleanup) = 1; + do_pending_stack_adjust (); + start_sequence_for_rtl_expr (cleanup); + + e = build_vec_delete_1 (rval, + build_binary_op (MINUS_EXPR, maxindex, + iterator), + type, + /*auto_delete_vec=*/integer_zero_node, + /*auto_delete=*/integer_zero_node, + /*use_global_delete=*/0); + expand_expr (e, const0_rtx, VOIDmode, EXPAND_NORMAL); + + do_pending_stack_adjust (); + RTL_EXPR_SEQUENCE (cleanup) = get_insns (); + end_sequence (); + cleanup = protect_with_terminate (cleanup); + expand_eh_region_end (cleanup); + pop_obstacks (); } /* `expand_vec_init' performs initialization of a vector of aggregate @@ -2702,9 +2779,12 @@ expand_vec_init (decl, base, maxindex, init, from_array) int from_array; { tree rval; - tree iterator, base2 = NULL_TREE; + tree base2 = NULL_TREE; tree type = TREE_TYPE (TREE_TYPE (base)); tree size; + tree itype = NULL_TREE; + tree iterator; + int num_initialized_elts = 0; maxindex = cp_convert (ptrdiff_type_node, maxindex); if (maxindex == error_mark_node) @@ -2721,104 +2801,100 @@ expand_vec_init (decl, base, maxindex, init, from_array) size = size_in_bytes (type); - /* Set to zero in case size is <= 0. Optimizer will delete this if - it is not needed. */ - rval = get_temp_regvar (build_pointer_type (type), - cp_convert (build_pointer_type (type), null_pointer_node)); base = default_conversion (base); base = cp_convert (build_pointer_type (type), base); - expand_assignment (rval, base, 0, 0); + rval = get_temp_regvar (build_pointer_type (type), base); base = get_temp_regvar (build_pointer_type (type), base); + iterator = get_temp_regvar (ptrdiff_type_node, maxindex); - if (init != NULL_TREE - && TREE_CODE (init) == CONSTRUCTOR - && (! decl || TREE_TYPE (init) == TREE_TYPE (decl))) + /* Protect the entire array initialization so that we can destroy + the partially constructed array if an exception is thrown. */ + expand_vec_init_try_block (type); + + if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR + && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl)))) { - /* Initialization of array from {...}. */ - tree elts = CONSTRUCTOR_ELTS (init); + /* Do non-default initialization resulting from brace-enclosed + initializers. */ + + tree elts; tree baseref = build1 (INDIRECT_REF, type, base); - tree baseinc = build (PLUS_EXPR, build_pointer_type (type), base, size); - int host_i = TREE_INT_CST_LOW (maxindex); - if (IS_AGGR_TYPE (type)) + from_array = 0; + + for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts)) { - while (elts) - { - host_i -= 1; - expand_aggr_init (baseref, TREE_VALUE (elts), 0, 0); + tree elt = TREE_VALUE (elts); - expand_assignment (base, baseinc, 0, 0); - elts = TREE_CHAIN (elts); - } - /* Initialize any elements by default if possible. */ - if (host_i >= 0) - { - if (TYPE_NEEDS_CONSTRUCTING (type) == 0) - { - if (obey_regdecls) - use_variable (DECL_RTL (base)); - goto done_init; - } + num_initialized_elts++; - iterator = get_temp_regvar (ptrdiff_type_node, - build_int_2 (host_i, 0)); - init = NULL_TREE; - goto init_by_default; - } + if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE) + expand_aggr_init (baseref, elt, 0); + else + expand_assignment (baseref, elt, 0, 0); + + expand_assignment (base, + build (PLUS_EXPR, build_pointer_type (type), + base, size), + 0, 0); + expand_assignment (iterator, + build (MINUS_EXPR, ptrdiff_type_node, + iterator, integer_one_node), + 0, 0); } - else - while (elts) - { - expand_assignment (baseref, TREE_VALUE (elts), 0, 0); - expand_assignment (base, baseinc, 0, 0); - elts = TREE_CHAIN (elts); - } + /* Clear out INIT so that we don't get confused below. */ + init = NULL_TREE; if (obey_regdecls) use_variable (DECL_RTL (base)); } - else + else if (from_array) { - tree itype; + /* If initializing one array from another, initialize element by + element. We rely upon the below calls the do argument + checking. */ + if (decl == NULL_TREE) + { + sorry ("initialization of array from dissimilar array type"); + return error_mark_node; + } + if (init) + { + base2 = default_conversion (init); + itype = TREE_TYPE (base2); + base2 = get_temp_regvar (itype, base2); + itype = TREE_TYPE (itype); + } + else if (TYPE_LANG_SPECIFIC (type) + && TYPE_NEEDS_CONSTRUCTING (type) + && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) + { + error ("initializer ends prematurely"); + return error_mark_node; + } + } - iterator = get_temp_regvar (ptrdiff_type_node, maxindex); + /* Now, default-initialize any remaining elements. We don't need to + do that if a) the type does not need constructing, or b) we've + already initialized all the elements. - init_by_default: - itype = NULL_TREE; + We do need to keep going if we're copying an array. */ - /* If initializing one array from another, - initialize element by element. */ - if (from_array) - { - /* We rely upon the below calls the do argument checking */ - if (decl == NULL_TREE) - { - sorry ("initialization of array from dissimilar array type"); - return error_mark_node; - } - if (init) - { - base2 = default_conversion (init); - itype = TREE_TYPE (base2); - base2 = get_temp_regvar (itype, base2); - itype = TREE_TYPE (itype); - } - else if (TYPE_LANG_SPECIFIC (type) - && TYPE_NEEDS_CONSTRUCTING (type) - && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) - { - error ("initializer ends prematurely"); - return error_mark_node; - } - } + if (from_array + || (TYPE_NEEDS_CONSTRUCTING (type) + && !(TREE_CODE (maxindex) == INTEGER_CST + && num_initialized_elts == TREE_INT_CST_LOW (maxindex) + 1))) + { + /* If the ITERATOR is equal to -1, then we don't have to loop; + we've already initialized all the elements. */ + expand_start_cond (build (NE_EXPR, boolean_type_node, + iterator, minus_one), + 0); - expand_start_cond (build (GE_EXPR, boolean_type_node, - iterator, integer_zero_node), 0); - if (TYPE_NEEDS_DESTRUCTOR (type)) - expand_eh_region_start (); + /* Otherwise, loop through the elements. */ expand_start_loop_continue_elsewhere (1); - + /* The initialization of each array element is a full-expression. */ expand_start_target_temps (); @@ -2835,7 +2911,7 @@ expand_vec_init (decl, base, maxindex, init, from_array) if (from_array == 2) expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from)); else if (TYPE_NEEDS_CONSTRUCTING (type)) - expand_aggr_init (to, from, 0, 0); + expand_aggr_init (to, from, 0); else if (from) expand_assignment (to, from, 0, 0); else @@ -2845,70 +2921,55 @@ expand_vec_init (decl, base, maxindex, init, from_array) { if (init != 0) sorry ("cannot initialize multi-dimensional array with initializer"); - expand_vec_init (decl, build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), base), + expand_vec_init (decl, + build1 (NOP_EXPR, + build_pointer_type (TREE_TYPE + (type)), + base), array_type_nelts (type), 0, 0); } else - expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0, 0); + expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0); expand_assignment (base, - build (PLUS_EXPR, build_pointer_type (type), base, size), - 0, 0); + build (PLUS_EXPR, build_pointer_type (type), + base, size), 0, 0); if (base2) expand_assignment (base2, - build (PLUS_EXPR, build_pointer_type (type), base2, size), 0, 0); + build (PLUS_EXPR, build_pointer_type (type), + base2, size), 0, 0); /* Cleanup any temporaries needed for the initial value. */ expand_end_target_temps (); - + expand_loop_continue_here (); expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node, - build (PREDECREMENT_EXPR, ptrdiff_type_node, iterator, integer_one_node), minus_one)); - + build (PREDECREMENT_EXPR, + ptrdiff_type_node, + iterator, + integer_one_node), + minus_one)); + if (obey_regdecls) { use_variable (DECL_RTL (base)); if (base2) use_variable (DECL_RTL (base2)); } + expand_end_loop (); - if (TYPE_NEEDS_DESTRUCTOR (type) && flag_exceptions) - { - /* We have to ensure that this can live to the cleanup - expansion time, since we know it is only ever needed - once, generate code now. */ - push_obstacks_nochange (); - resume_temporary_allocation (); - { - tree e1, cleanup = make_node (RTL_EXPR); - TREE_TYPE (cleanup) = void_type_node; - RTL_EXPR_RTL (cleanup) = const0_rtx; - TREE_SIDE_EFFECTS (cleanup) = 1; - do_pending_stack_adjust (); - start_sequence_for_rtl_expr (cleanup); - - e1 = build_array_eh_cleanup - (rval, - build_binary_op (MINUS_EXPR, maxindex, iterator, 1), - type); - expand_expr (e1, const0_rtx, VOIDmode, EXPAND_NORMAL); - do_pending_stack_adjust (); - RTL_EXPR_SEQUENCE (cleanup) = get_insns (); - end_sequence (); - - cleanup = protect_with_terminate (cleanup); - expand_eh_region_end (cleanup); - } - pop_obstacks (); - } expand_end_cond (); - if (obey_regdecls) - use_variable (DECL_RTL (iterator)); } - done_init: + + /* Make sure to cleanup any partially constructed elements. */ + expand_vec_init_catch_clause (rval, type, maxindex, iterator); if (obey_regdecls) - use_variable (DECL_RTL (rval)); + { + use_variable (DECL_RTL (iterator)); + use_variable (DECL_RTL (rval)); + } + return rval; } @@ -2927,8 +2988,8 @@ expand_vec_init (decl, base, maxindex, init, from_array) This does not call any destructors. */ tree -build_x_delete (type, addr, which_delete, virtual_size) - tree type, addr; +build_x_delete (addr, which_delete, virtual_size) + tree addr; int which_delete; tree virtual_size; { @@ -2976,15 +3037,14 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) if (TREE_CODE (type) == POINTER_TYPE) { type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if (!complete_type_or_else (type)) + if (type != void_type_node && !complete_type_or_else (type, addr)) return error_mark_node; if (TREE_CODE (type) == ARRAY_TYPE) goto handle_array; if (! IS_AGGR_TYPE (type)) { /* Call the builtin operator delete. */ - return build_builtin_call (void_type_node, BID, - build_expr_list (NULL_TREE, addr)); + return build_builtin_delete_call (addr); } if (TREE_SIDE_EFFECTS (addr)) addr = save_expr (addr); @@ -3004,7 +3064,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) return error_mark_node; } return build_vec_delete (addr, array_type_nelts (type), - auto_delete, integer_two_node, + auto_delete, integer_zero_node, use_global_delete); } else @@ -3050,8 +3110,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) { tree cond = fold (build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node)); - tree call = build_builtin_call - (void_type_node, BID, build_expr_list (NULL_TREE, addr)); + tree call = build_builtin_delete_call (addr); cond = fold (build (COND_EXPR, void_type_node, cond, call, void_zero_node)); @@ -3076,7 +3135,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) ifexp = integer_one_node; else /* Handle deleting a null pointer. */ - ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node, 1)); + ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node)); if (ifexp != integer_one_node) expr = build (COND_EXPR, void_type_node, @@ -3094,6 +3153,10 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) tree parent_auto_delete = auto_delete; tree cond; + /* Set this again before we call anything, as we might get called + recursively. */ + TYPE_HAS_DESTRUCTOR (type) = 1; + /* If we have member delete or vbases, we call delete in finish_function. */ if (auto_delete == integer_zero_node) @@ -3103,8 +3166,7 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) { cond = build (COND_EXPR, void_type_node, build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), - build_builtin_call (void_type_node, BID, - build_expr_list (NULL_TREE, addr)), + build_builtin_delete_call (addr), void_zero_node); } else diff --git a/contrib/gcc/cp/input.c b/contrib/gcc/cp/input.c index 5a73fea..9148c86 100644 --- a/contrib/gcc/cp/input.c +++ b/contrib/gcc/cp/input.c @@ -1,5 +1,5 @@ /* Input handling for G++. - Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. This file is part of GNU CC. @@ -53,12 +53,6 @@ static struct input_source *input, *free_inputs; extern char *input_filename; extern int lineno; -#ifdef __GNUC__ -#define inline __inline__ -#else -#define inline -#endif - #if USE_CPPLIB extern unsigned char *yy_cur, *yy_lim; extern int yy_get_token (); diff --git a/contrib/gcc/cp/lang-options.h b/contrib/gcc/cp/lang-options.h index 5c50332..cfc6456 100644 --- a/contrib/gcc/cp/lang-options.h +++ b/contrib/gcc/cp/lang-options.h @@ -1,5 +1,5 @@ /* Definitions for switches for C++. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc. This file is part of GNU CC. @@ -23,9 +23,6 @@ DEFINE_LANG_NAME ("C++") /* This is the contribution to the `lang_options' array in gcc.c for g++. */ - { "-+e0", "" }, /* gcc.c tacks the `-' on the front. */ - { "-+e1", "" }, - { "-+e2", "" }, { "-faccess-control", "" }, { "-fno-access-control", "Do not obey access control semantics" }, { "-fall-virtual", "Make all member functions virtual" }, @@ -38,8 +35,10 @@ DEFINE_LANG_NAME ("C++") { "-fno-check-new", "" }, { "-fconserve-space", "Reduce size of object files" }, { "-fno-conserve-space", "" }, + { "-fconst-strings", "" }, + { "-fno-const-strings", "Make string literals `char[]' instead of `const char[]'" }, { "-fdefault-inline", "" }, - { "-fno-default-inline", "Do not inline mmeber functions be default"}, + { "-fno-default-inline", "Do not inline member functions by default"}, { "-frtti", "" }, { "-fno-rtti", "Do not generate run time type descriptor information" }, { "-felide-constructors", "" }, @@ -54,23 +53,27 @@ DEFINE_LANG_NAME ("C++") { "-fno-guiding-decls", "" }, { "-fgnu-keywords", "" }, { "-fno-gnu-keywords", "Do not recognise GNU defined keywords" }, - { "-fhandle-exceptions", "Enable exception handling" }, + { "-fhandle-exceptions", "" }, { "-fno-handle-exceptions", "" }, { "-fhandle-signatures", "Handle signature language constructs" }, { "-fno-handle-signatures", "" }, - { "-fhonor-std", "Do not ignore the namespace standard" }, + { "-fhonor-std", "Treat the namespace `std' as a normal namespace" }, { "-fno-honor-std", "" }, { "-fhuge-objects", "Enable support for huge objects" }, { "-fno-huge-objects", "" }, { "-fimplement-inlines", "" }, { "-fno-implement-inlines", "Export functions even if they can be inlined" }, - { "-fimplicit-templates", "Emit implicit instatiations if needed" }, - { "-fno-implicit-templates", "" }, + { "-fimplicit-templates", "" }, + { "-fno-implicit-templates", "Only emit explicit template instatiations" }, + { "-fimplicit-inline-templates", "" }, + { "-fno-implicit-inline-templates", "Only emit explicit instatiations of inline templates" }, + { "-finit-priority", "Handle the init_priority attribute" }, + { "-fno-init-priority", "" }, { "-flabels-ok", "Labels can be used as first class objects" }, { "-fno-labels-ok", "" }, - { "-fmemoize-lookups", "Enable caching of member function resolutions" }, + { "-fmemoize-lookups", "" }, { "-fno-memoize-lookups", "" }, - { "-fname-mangling-version-", "Set the version of name mangling to use" }, + { "-fname-mangling-version-", "" }, { "-fnew-abi", "Enable experimental ABI changes" }, { "-fno-new-abi", "" }, { "-fnonnull-objects", "" }, @@ -79,9 +82,11 @@ DEFINE_LANG_NAME ("C++") { "-fno-operator-names", "" }, { "-foptional-diags", "" }, { "-fno-optional-diags", "Disable optional diagnostics" }, + { "-fpermissive", "Downgrade conformance errors to warnings" }, + { "-fno-permissive", "" }, { "-frepo", "Enable automatic template instantiation" }, { "-fno-repo", "" }, - { "-fsave-memoized", "Save cache of member function resolutions" }, + { "-fsave-memoized", "" }, { "-fno-save-memoized", "" }, { "-fsquangle", "Enable squashed name mangling" }, { "-fno-squangle", "" }, @@ -92,6 +97,8 @@ DEFINE_LANG_NAME ("C++") { "-ftemplate-depth-", "Specify maximum template instantiation depth"}, { "-fthis-is-variable", "Make 'this' not be type '* const'" }, { "-fno-this-is-variable", "" }, + { "-fvtable-gc", "Discard unused virtual functions" }, + { "-fno-vtable-gc", "" }, { "-fvtable-thunks", "Implement vtables using thunks" }, { "-fno-vtable-thunks", "" }, { "-fweak", "Emit common-like symbols as weak symbols" }, @@ -103,8 +110,8 @@ DEFINE_LANG_NAME ("C++") { "-Wno-return-type", "" }, { "-Woverloaded-virtual", "Warn about overloaded virtual function names" }, { "-Wno-overloaded-virtual", "" }, - { "-Wctor-dtor-privacy", "Warn when all ctors/dtors are private" }, - { "-Wno-ctor-dtor-privacy", "" }, + { "-Wctor-dtor-privacy", "" }, + { "-Wno-ctor-dtor-privacy", "Don't warn when all ctors/dtors are private" }, { "-Wnon-virtual-dtor", "Warn about non virtual destructors" }, { "-Wno-non-virtual-dtor", "" }, { "-Wextern-inline", "Warn when a function is declared extern, then inline" }, @@ -113,11 +120,15 @@ DEFINE_LANG_NAME ("C++") { "-Wno-reorder", "" }, { "-Wsynth", "Warn when synthesis behaviour differs from Cfront" }, { "-Wno-synth", "" }, - { "-Wpmf-conversions", "Warn when type converting pointers to member functions" }, - { "-Wno-pmf-conversions", "" }, + { "-Wpmf-conversions", "" }, + { "-Wno-pmf-conversions", "Don't warn when type converting pointers to member functions" }, { "-Weffc++", "Warn about violations of Effective C++ style rules" }, { "-Wno-effc++", "" }, { "-Wsign-promo", "Warn when overload promotes from unsigned to signed" }, { "-Wno-sign-promo", "" }, { "-Wold-style-cast", "Warn if a C style cast is used in a program" }, { "-Wno-old-style-cast", "" }, + { "-Wnon-template-friend", "" }, + { "-Wno-non-template-friend", "Don't warn when non-templatized friend functions are declared within a template" }, + { "-Wdeprecated", "" }, + { "-Wno-deprecated", "Don't announce deprecation of compiler features" }, diff --git a/contrib/gcc/cp/lang-specs.h b/contrib/gcc/cp/lang-specs.h index b208ca1..648bc1f 100644 --- a/contrib/gcc/cp/lang-specs.h +++ b/contrib/gcc/cp/lang-specs.h @@ -1,5 +1,5 @@ /* Definitions for specs for C++. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 96-98, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -30,51 +30,54 @@ Boston, MA 02111-1307, USA. */ {"@c++", #if USE_CPPLIB { - "%{E|M|MM:cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + "%{E|M|MM:cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\ %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\ + %{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\ + -D__cplusplus\ %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fhonor-std:-D__HONOR_STD} %{fnew-abi:-D__HONOR_STD}\ %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\ + %{ffast-math:-D__FAST_MATH__}\ %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ %i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}\ %{!E:%{!M:%{!MM:cc1plus %i %1 %2\ - -lang-c++ %{nostdinc*} %{C} %{A*} %{I*} %{P} %I\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus\ - -D__GNUC_MINOR__=%v2\ + -lang-c++ %{nostdinc*} %{C} %{A*} %{I*} %{P} %{$} %I\ + %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ + %{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1\ + -D__GNUC_MINOR__=%v2} -D__cplusplus\ %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fhonor-std:-D__HONOR_STD} %{fnew-abi:-D__HONOR_STD}\ %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ + %{ffast-math:-D__FAST_MATH__}\ %{trigraphs}\ %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ + %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\ %{!S:as %a %Y\ %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ %{!pipe:%g.s} %A\n }}}}"}}, #else /* ! USE_CPPLIB */ - {"cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ + {"cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %{$} %I\ %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\ + %{!no-gcc:-D__GNUC__=%v1 -D__GNUG__=%v1 -D__GNUC_MINOR__=%v2}\ + -D__cplusplus\ %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fhonor-std:-D__HONOR_STD} %{fnew-abi:-D__HONOR_STD}\ %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\ + %{ffast-math:-D__FAST_MATH__}\ %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ %i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.ii} %1 %2\ %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ + %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\ %{!S:as %a %Y\ @@ -86,7 +89,7 @@ Boston, MA 02111-1307, USA. */ {"%{!M:%{!MM:%{!E:cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ + %{f*} %{+e*} %{aux-info*} %{Qn:-fno-ident}\ %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ %{!S:as %a %Y\ diff --git a/contrib/gcc/cp/lex.c b/contrib/gcc/cp/lex.c index 57639ad..d9f2262 100644 --- a/contrib/gcc/cp/lex.c +++ b/contrib/gcc/cp/lex.c @@ -1,5 +1,5 @@ /* Separate lexical analyzer for GNU C++. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -27,7 +27,6 @@ Boston, MA 02111-1307, USA. */ #include "config.h" #include "system.h" -#include #include "input.h" #include "tree.h" #include "lex.h" @@ -39,14 +38,8 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "output.h" -/* MULTIBYTE_CHARS support only works for native compilers. - ??? Ideally what we want is to model widechar support after - the current floating point support. */ -#ifdef CROSS_COMPILE -#undef MULTIBYTE_CHARS -#endif - #ifdef MULTIBYTE_CHARS +#include "mbchar.h" #include #endif @@ -61,28 +54,26 @@ extern struct obstack permanent_obstack; extern struct obstack *current_obstack, *saveable_obstack; extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern void compiler_error PROTO((char *, HOST_WIDE_INT, - HOST_WIDE_INT)); -static tree get_time_identifier PROTO((char *)); +static tree get_time_identifier PROTO((const char *)); static int check_newline PROTO((void)); static int skip_white_space PROTO((int)); static void finish_defarg PROTO((void)); static int my_get_run_time PROTO((void)); static int get_last_nonwhite_on_line PROTO((void)); -static int interface_strcmp PROTO((char *)); +static int interface_strcmp PROTO((const char *)); static int readescape PROTO((int *)); -static char *extend_token_buffer PROTO((char *)); +static char *extend_token_buffer PROTO((const char *)); static void consume_string PROTO((struct obstack *, int)); -static void set_typedecl_interface_info PROTO((tree, tree)); +static int set_typedecl_interface_info PROTO((tree *, void *)); static void feed_defarg PROTO((tree, tree)); -static int set_vardecl_interface_info PROTO((tree, tree)); +static int set_vardecl_interface_info PROTO((tree *, void *)); static void store_pending_inline PROTO((tree, struct pending_inline *)); static void reinit_parse_for_expr PROTO((struct obstack *)); static int *init_cpp_parse PROTO((void)); -static int handle_cp_pragma PROTO((char *)); -#ifdef HANDLE_SYSV_PRAGMA -static int handle_sysv_pragma PROTO((int)); +static int handle_cp_pragma PROTO((const char *)); +#ifdef HANDLE_GENERIC_PRAGMAS +static int handle_generic_pragma PROTO((int)); #endif #ifdef GATHER_STATISTICS #ifdef REDUCE_LENGTH @@ -90,12 +81,16 @@ static int reduce_cmp PROTO((int *, int *)); static int token_cmp PROTO((int *, int *)); #endif #endif +static void begin_definition_of_inclass_inline PROTO((struct pending_inline*)); +static void parse_float PROTO((PTR)); +static int is_global PROTO((tree)); +static void init_filename_times PROTO((void)); /* Given a file name X, return the nondirectory portion. Keep in mind that X can be computed more than once. */ char * file_name_nondirectory (x) - char *x; + const char *x; { char *tmp = (char *) rindex (x, '/'); if (DIR_SEPARATOR != '/' && ! tmp) @@ -103,7 +98,7 @@ file_name_nondirectory (x) if (tmp) return (char *) (tmp + 1); else - return x; + return (char *) x; } /* This obstack is needed to hold text. It is not safe to use @@ -319,7 +314,7 @@ static int ignore_escape_flag = 0; static tree get_time_identifier (name) - char *name; + const char *name; { tree time_identifier; int len = strlen (name); @@ -328,12 +323,13 @@ get_time_identifier (name) bcopy (name, buf+5, len); buf[len+5] = '\0'; time_identifier = get_identifier (buf); - if (IDENTIFIER_LOCAL_VALUE (time_identifier) == NULL_TREE) + if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE) { push_obstacks_nochange (); end_temporary_allocation (); - IDENTIFIER_LOCAL_VALUE (time_identifier) = build_int_2 (0, 0); - IDENTIFIER_CLASS_VALUE (time_identifier) = build_int_2 (0, 1); + TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0); + TIME_IDENTIFIER_FILEINFO (time_identifier) + = build_int_2 (0, 1); SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); filename_times = time_identifier; pop_obstacks (); @@ -383,7 +379,7 @@ int cplus_tree_code_length[] = { Used for printing out the tree and error messages. */ #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, -char *cplus_tree_code_name[] = { +const char *cplus_tree_code_name[] = { "@@dummy", #include "cp-tree.def" }; @@ -394,6 +390,12 @@ char *cplus_tree_code_name[] = { void lang_init_options () { +#if USE_CPPLIB + cpp_reader_init (&parse_in); + parse_in.opts = &parse_options; + cpp_options_init (&parse_options); +#endif + /* Default exceptions on. */ flag_exceptions = 1; } @@ -401,11 +403,14 @@ lang_init_options () void lang_init () { -#if ! USE_CPPLIB /* the beginning of the file is a new line; check for # */ /* With luck, we discover the real source file's name from that and put it in input_filename. */ +#if ! USE_CPPLIB put_back (check_newline ()); +#else + check_newline (); + yy_cur--; #endif if (flag_gnu_xref) GNU_xref_begin (input_filename); init_repo (input_filename); @@ -424,7 +429,7 @@ lang_identify () return "cplusplus"; } -void +static void init_filename_times () { this_filename_time = get_time_identifier (""); @@ -432,7 +437,8 @@ init_filename_times () { header_time = 0; body_time = my_get_run_time (); - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) = body_time; + TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) + = body_time; } } @@ -474,13 +480,22 @@ init_parse (filename) int i; -#if USE_CPPLIB - yy_cur = "\n"; - yy_lim = yy_cur + 1; +#ifdef MULTIBYTE_CHARS + /* Change to the native locale for multibyte conversions. */ + setlocale (LC_CTYPE, ""); + literal_codeset = getenv ("LANG"); +#endif +#if USE_CPPLIB parse_in.show_column = 1; if (! cpp_start_read (&parse_in, filename)) abort (); + + /* cpp_start_read always puts at least one line directive into the + token buffer. We must arrange to read it out here. */ + yy_cur = parse_in.token_buffer; + yy_lim = CPP_PWRITTEN (&parse_in); + #else /* Open input file. */ if (filename == 0 || !strcmp (filename, "-")) @@ -635,7 +650,7 @@ init_parse (filename) IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1; ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd"); IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1; - ansi_opname[(int) TYPE_EXPR] = get_identifier ("__op"); + ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT); IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; /* This is not true: these operators are not defined in ANSI, @@ -664,67 +679,28 @@ init_parse (filename) token_buffer = (char *) xmalloc (maxtoken + 2); ridpointers[(int) RID_INT] = get_identifier ("int"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INT])); ridpointers[(int) RID_BOOL] = get_identifier ("bool"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL])); ridpointers[(int) RID_CHAR] = get_identifier ("char"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR])); ridpointers[(int) RID_VOID] = get_identifier ("void"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID])); ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT])); ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE])); ridpointers[(int) RID_SHORT] = get_identifier ("short"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT])); ridpointers[(int) RID_LONG] = get_identifier ("long"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG], - build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG])); ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED])); ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED])); ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE])); ridpointers[(int) RID_CONST] = get_identifier ("const"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST])); ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE])); + ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict"); ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO], - build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO])); ridpointers[(int) RID_STATIC] = get_identifier ("static"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN])); ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF])); ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], - build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX], - build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX])); /* C++ extensions. These are probably not correctly named. */ ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR])); class_type_node = build_int_2 (class_type, 0); TREE_TYPE (class_type_node) = class_type_node; ridpointers[(int) RID_CLASS] = class_type_node; @@ -742,37 +718,26 @@ init_parse (filename) ridpointers[(int) RID_ENUM] = enum_type_node; ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT])); + ridpointers[(int) RID_EXPORT] = get_identifier ("export"); ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC])); ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE])); ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE])); /* This is for ANSI C++. */ ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE])); /* Signature handling extensions. */ signature_type_node = build_int_2 (signature_type, 0); TREE_TYPE (signature_type_node) = signature_type_node; ridpointers[(int) RID_SIGNATURE] = signature_type_node; + /* Create the built-in __null node. Note that we can't yet call for + type_for_size here because integer_type_node and so forth are not + set up. Therefore, we don't set the type of these nodes until + init_decl_processing. */ null_node = build_int_2 (0, 0); ridpointers[RID_NULL] = null_node; @@ -1123,7 +1088,7 @@ extract_interface_info () } if (!fileinfo) fileinfo = get_time_identifier (input_filename); - fileinfo = IDENTIFIER_CLASS_VALUE (fileinfo); + fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo); interface_only = TREE_INT_CST_LOW (fileinfo); interface_unknown = TREE_INT_CST_HIGH (fileinfo); } @@ -1133,15 +1098,15 @@ extract_interface_info () static int interface_strcmp (s) - char *s; + const char *s; { /* Set the interface/implementation bits for this scope. */ struct impl_files *ifiles; - char *s1; + const char *s1; for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) { - char *t1 = ifiles->filename; + const char *t1 = ifiles->filename; s1 = s; if (*s1 != *t1 || *s1 == 0) @@ -1169,37 +1134,71 @@ interface_strcmp (s) return 1; } -static void -set_typedecl_interface_info (prev, vars) - tree prev, vars; +static int +set_typedecl_interface_info (t, data) + tree *t; + void *data ATTRIBUTE_UNUSED; { - tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); - tree fileinfo = IDENTIFIER_CLASS_VALUE (id); - tree type = TREE_TYPE (vars); + tree id = get_time_identifier (DECL_SOURCE_FILE (*t)); + tree fileinfo = TIME_IDENTIFIER_FILEINFO (id); + tree type = TREE_TYPE (*t); CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) - = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars))); + = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (*t))); + return 0; } static int -set_vardecl_interface_info (prev, vars) - tree prev, vars; +set_vardecl_interface_info (t, data) + tree *t; + void *data ATTRIBUTE_UNUSED; { - tree type = DECL_CONTEXT (vars); + tree type = DECL_CONTEXT (*t); if (CLASSTYPE_INTERFACE_KNOWN (type)) { if (CLASSTYPE_INTERFACE_ONLY (type)) - set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type)); + set_typedecl_interface_info (&TYPE_MAIN_DECL (type), data); else CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; - DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); - TREE_PUBLIC (vars) = 1; + DECL_EXTERNAL (*t) = CLASSTYPE_INTERFACE_ONLY (type); + TREE_PUBLIC (*t) = 1; return 1; } return 0; } +/* Set up the state required to correctly handle the definition of the + inline function whose preparsed state has been saved in PI. */ + +static void +begin_definition_of_inclass_inline (pi) + struct pending_inline* pi; +{ + tree context; + + if (!pi->fndecl) + return; + + /* If this is an inline function in a local class, we must make sure + that we save all pertinent information about the function + surrounding the local class. */ + context = hack_decl_function_context (pi->fndecl); + if (context) + push_cp_function_context (context); + + feed_input (pi->buf, pi->len); + lineno = pi->lineno; + input_filename = pi->filename; + yychar = PRE_PARSED_FUNCTION_DECL; + yylval.ttype = build_tree_list ((tree) pi, pi->fndecl); + /* Pass back a handle to the rest of the inline functions, so that they + can be processed later. */ + DECL_PENDING_INLINE_INFO (pi->fndecl) = 0; + interface_unknown = pi->interface == 1; + interface_only = pi->interface == 0; +} + /* Called from the top level: if there are any pending inlines to do, set up to process them now. This function sets up the first function to be parsed; after it has been, the rule for fndef in parse.y will @@ -1209,7 +1208,6 @@ void do_pending_inlines () { struct pending_inline *t; - tree context; /* Oops, we're still dealing with the last batch. */ if (yychar == PRE_PARSED_FUNCTION_DECL) @@ -1236,32 +1234,7 @@ do_pending_inlines () return; /* Now start processing the first inline function. */ - context = hack_decl_function_context (t->fndecl); - if (context) - push_cp_function_context (context); - maybe_begin_member_template_processing (t->fndecl); - if (t->len > 0) - { - feed_input (t->buf, t->len); - lineno = t->lineno; -#if 0 - if (input_filename != t->filename) - { - input_filename = t->filename; - /* Get interface/implementation back in sync. */ - extract_interface_info (); - } -#else - input_filename = t->filename; - interface_unknown = t->interface == 1; - interface_only = t->interface == 0; -#endif - yychar = PRE_PARSED_FUNCTION_DECL; - } - /* Pass back a handle on the rest of the inline functions, so that they - can be processed later. */ - yylval.ttype = build_tree_list ((tree) t, t->fndecl); - DECL_PENDING_INLINE_INFO (t->fndecl) = 0; + begin_definition_of_inclass_inline (t); } static int nextchar = -1; @@ -1277,7 +1250,6 @@ process_next_inline (t) tree context; struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); context = hack_decl_function_context (i->fndecl); - maybe_end_member_template_processing (i->fndecl); if (context) pop_cp_function_context (context); i = i->next; @@ -1295,24 +1267,8 @@ process_next_inline (t) } yychar = YYEMPTY; end_input (); - if (i && i->fndecl != NULL_TREE) - { - context = hack_decl_function_context (i->fndecl); - if (context) - push_cp_function_context (context); - maybe_begin_member_template_processing (i->fndecl); - feed_input (i->buf, i->len); - lineno = i->lineno; - input_filename = i->filename; - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.ttype = build_tree_list ((tree) i, i->fndecl); - DECL_PENDING_INLINE_INFO (i->fndecl) = 0; - } if (i) - { - interface_unknown = i->interface == 1; - interface_only = i->interface == 0; - } + begin_definition_of_inclass_inline (i); else extract_interface_info (); } @@ -1538,10 +1494,12 @@ reinit_parse_for_block (pyychar, obstackp) else if (pyychar == ':') { obstack_1grow (obstackp, pyychar); + /* Add a space so we don't get confused by ': ::A(20)'. */ + obstack_1grow (obstackp, ' '); look_for_lbrac = 1; blev = 0; } - else if (pyychar == RETURN) + else if (pyychar == RETURN_KEYWORD) { obstack_grow (obstackp, "return", 6); look_for_lbrac = 1; @@ -1928,12 +1886,12 @@ do_pending_defargs () if (TREE_CODE (defarg_fn) == FUNCTION_DECL) { - maybe_end_member_template_processing (defarg_fn); + maybe_end_member_template_processing (); check_default_args (defarg_fn); } poplevel (0, 0, 0); - pop_nested_class (1); + pop_nested_class (); } } @@ -1977,7 +1935,7 @@ cons_up_default_function (type, full_name, kind) break; case 3: - type = build_type_variant (type, 1, 0); + type = build_qualified_type (type, TYPE_QUAL_CONST); /* Fall through... */ case 4: /* According to ARM $12.8, the default copy ctor will be declared, but @@ -1995,7 +1953,7 @@ cons_up_default_function (type, full_name, kind) declspecs = build_decl_list (NULL_TREE, type); if (kind == 5) - type = build_type_variant (type, 1, 0); + type = build_qualified_type (type, TYPE_QUAL_CONST); name = ansi_opname [(int) MODIFY_EXPR]; @@ -2113,7 +2071,7 @@ note_got_semicolon (type) { if (TREE_CODE_CLASS (TREE_CODE (type)) != 't') my_friendly_abort (60); - if (IS_AGGR_TYPE (type)) + if (CLASS_TYPE_P (type)) CLASSTYPE_GOT_SEMICOLON (type) = 1; } @@ -2182,7 +2140,7 @@ skip_white_space (c) static char * extend_token_buffer (p) - char *p; + const char *p; { int offset = p - token_buffer; @@ -2208,6 +2166,32 @@ get_last_nonwhite_on_line () return c; } +#if defined HANDLE_PRAGMA +/* Local versions of these macros, that can be passed as function pointers. */ +static int +pragma_getc () +{ + int c; + + if (nextchar != EOF) + { + c = nextchar; + nextchar = EOF; + } + else + c = getch (); + + return c; +} + +static void +pragma_ungetc (arg) + int arg; +{ + yyungetc (arg, 0); +} +#endif /* HANDLE_PRAGMA */ + /* At the beginning of a line, increment the line number and process any #-directive on this line. If the line is a #-directive, read the entire line and return a newline. @@ -2215,13 +2199,12 @@ get_last_nonwhite_on_line () int linemode; -static int handle_cp_pragma PROTO((char *)); - static int check_newline () { register int c; register int token; + int saw_line = 0; /* Read first nonwhite char on the line. Do this before incrementing the line number, in case we're at the end of saved text. */ @@ -2251,7 +2234,7 @@ check_newline () it and ignore it; otherwise, ignore the line, with an error if the word isn't `pragma'. */ - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) + if (ISALPHA (c)) { if (c == 'p') { @@ -2274,21 +2257,29 @@ check_newline () else if (token == END_OF_LINE) goto skipline; -#ifdef HANDLE_SYSV_PRAGMA - if (handle_sysv_pragma (token)) - goto skipline; -#else #ifdef HANDLE_PRAGMA -#if USE_CPPLIB - /* TODO: ??? */ - goto skipline; -#else - if (HANDLE_PRAGMA (finput, yylval.ttype)) - goto skipline; -#endif /* !USE_CPPLIB */ -#endif -#endif + /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS + (if both are defined), in order to give the back + end a chance to override the interpretation of + SYSV style pragmas. */ + if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, + IDENTIFIER_POINTER (yylval.ttype))) + goto skipline; +#endif /* HANDLE_PRAGMA */ + +#ifdef HANDLE_GENERIC_PRAGMAS + if (handle_generic_pragma (token)) + 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); } + goto skipline; } else if (c == 'd') @@ -2322,7 +2313,10 @@ check_newline () && getch () == 'n' && getch () == 'e' && ((c = getch ()) == ' ' || c == '\t')) - goto linenum; + { + saw_line = 1; + goto linenum; + } } else if (c == 'i') { @@ -2419,9 +2413,16 @@ linenum: /* More follows: it must be a string constant (filename). */ - /* Read the string constant, but don't treat \ as special. */ - ignore_escape_flag = 1; + if (saw_line) + { + /* Don't treat \ as special if we are processing #line 1 "...". + If you want it to be treated specially, use # 1 "...". */ + ignore_escape_flag = 1; + } + + /* Read the string constant. */ token = real_yylex (); + ignore_escape_flag = 0; if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) @@ -2438,7 +2439,7 @@ linenum: int this_time = my_get_run_time (); tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); header_time += this_time - body_time; - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) + TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) += this_time - body_time; this_filename_time = time_identifier; body_time = this_time; @@ -2463,7 +2464,14 @@ linenum: main_input_filename = input_filename; if (write_virtuals == 3) - walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); + { + walk_globals (vtable_decl_p, + set_vardecl_interface_info, + /*data=*/0); + walk_globals (vtype_decl_p, + set_typedecl_interface_info, + /*data=*/0); + } } extract_interface_info (); @@ -2662,7 +2670,8 @@ readescape (ignore_ptr) ; else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) + && (((unsigned)1 << + (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) <= firstdig))) pedwarn ("hex escape out of range"); return code; @@ -2727,7 +2736,7 @@ readescape (ignore_ptr) pedwarn ("unknown escape sequence `\\%c'", c); return c; } - if (c >= 040 && c < 0177) + if (ISGRAPH (c)) pedwarn ("unknown escape sequence `\\%c'", c); else pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); @@ -2746,6 +2755,7 @@ int identifier_type (decl) tree decl; { + tree t; if (TREE_CODE (decl) == TEMPLATE_DECL) { if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL) @@ -2755,7 +2765,10 @@ identifier_type (decl) } if (looking_for_template && really_overloaded_fn (decl)) { - tree t; + /* See through a baselink. */ + if (TREE_CODE (decl) == TREE_LIST) + decl = TREE_VALUE (decl); + for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) return PFUNCNAME; @@ -2764,10 +2777,20 @@ identifier_type (decl) return NSNAME; if (TREE_CODE (decl) != TYPE_DECL) return IDENTIFIER; - if (((got_scope && TREE_TYPE (decl) == got_scope) - || TREE_TYPE (decl) == current_class_type) - && DECL_ARTIFICIAL (decl)) + if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) return SELFNAME; + + /* A constructor declarator for a template type will get here as an + implicit typename, a TYPENAME_TYPE with a type. */ + t = got_scope; + if (t && TREE_CODE (t) == TYPENAME_TYPE) + t = TREE_TYPE (t); + decl = TREE_TYPE (decl); + if (TREE_CODE (decl) == TYPENAME_TYPE) + decl = TREE_TYPE (decl); + if (t && t == decl) + return SELFNAME; + return TYPENAME; } @@ -2801,6 +2824,9 @@ is_global (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: @@ -2843,12 +2869,19 @@ do_identifier (token, parsing, args) || TREE_CODE (field) == CONST_DECL || TREE_CODE (field) == TEMPLATE_DECL) id = field; + else if (TREE_CODE (field) == TYPE_DECL + && DECL_ARTIFICIAL (field) + && IMPLICIT_TYPENAME_P (TREE_TYPE (field))) + /* When we did name-lookup before, we will have eschewed + implicit typenames in favor of global bindings. Therefore, + if lookup_field returns an implicit typename, but ID is not + an implicit typename, then we should skip this one, too. */ + ; else if (TREE_CODE (field) != FIELD_DECL) my_friendly_abort (61); else { - cp_error ("invalid use of member `%D' from base class `%T'", field, - DECL_FIELD_CONTEXT (field)); + cp_error ("invalid use of member `%D'", field); id = error_mark_node; return id; } @@ -2857,44 +2890,41 @@ do_identifier (token, parsing, args) /* Do Koenig lookup if appropriate (inside templates we build lookup expressions instead). */ if (args && !current_template_parms && (!id || is_global (id))) - { - /* If we have arguments and we only found global names, - do Koenig lookup. */ - id = lookup_arg_dependent (token, id, args); - } + /* If we have arguments and we only found global names, do Koenig + lookup. */ + id = lookup_arg_dependent (token, id, args); /* Remember that this name has been used in the class definition, as per [class.scope0] */ - if (id && current_class_type && parsing - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE (token) + if (id && parsing /* Avoid breaking if we get called for a default argument that refers to an overloaded method. Eventually this will not be necessary, since default arguments shouldn't be parsed until after the class is complete. (jason 3/12/97) */ && TREE_CODE (id) != OVERLOAD) - pushdecl_class_level (id); - - if (!id || id == error_mark_node) - { - if (id == error_mark_node && current_class_type != NULL_TREE) - { - id = lookup_nested_field (token, 1); - /* In lookup_nested_field(), we marked this so we can gracefully - leave this whole mess. */ - if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) - return id; - } + 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); + return error_mark_node; + } + + if (!id) + { if (current_template_parms) - return build_min_nt (LOOKUP_EXPR, token, NULL_TREE); + return build_min_nt (LOOKUP_EXPR, token); else if (IDENTIFIER_OPNAME_P (token)) { if (token != ansi_opname[ERROR_MARK]) cp_error ("`%D' not defined", token); id = error_mark_node; } - else if (in_call) + else if (in_call && ! flag_strict_prototype) { id = implicitly_declare (token); } @@ -2968,37 +2998,39 @@ do_identifier (token, parsing, args) /* TREE_USED is set in `hack_identifier'. */ if (TREE_CODE (id) == CONST_DECL) { + /* Check access. */ if (IDENTIFIER_CLASS_VALUE (token) == id) - { - /* Check access. */ - tree access = compute_access (TYPE_BINFO (current_class_type), id); - if (access == access_private_node) - cp_error ("enum `%D' is private", id); - /* protected is OK, since it's an enum of `this'. */ - } - if (! processing_template_decl - || (DECL_INITIAL (id) - && TREE_CODE (DECL_INITIAL (id)) == TEMPLATE_PARM_INDEX)) + enforce_access (DECL_REAL_CONTEXT(id), id); + if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) id = DECL_INITIAL (id); } else id = hack_identifier (id, token); - if (current_template_parms) - { - if (is_overloaded_fn (id)) - { - tree t = build_min (LOOKUP_EXPR, unknown_type_node, - token, get_first_fn (id)); - if (id != IDENTIFIER_NAMESPACE_VALUE (token)) - TREE_OPERAND (t, 1) = error_mark_node; - id = t; - } - else if (! TREE_PERMANENT (id) || TREE_CODE (id) == PARM_DECL - || TREE_CODE (id) == USING_DECL) - id = build_min (LOOKUP_EXPR, TREE_TYPE (id), token, error_mark_node); - /* else just use the decl */ - } + /* 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) + /* If it's not going to be around at instantiation time, we + look it up then. This is a hack, and should go when we + really get dependent/independent name lookup right. */ + || !TREE_PERMANENT (id) + /* Some local VAR_DECLs (such as those for local variables + in member functions of local classes) are built on the + permanent obstack. */ + || (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); return id; } @@ -3027,17 +3059,17 @@ do_scoped_id (token, parsing) { if (processing_template_decl) { - id = build_min_nt (LOOKUP_EXPR, token, NULL_TREE); + id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; return id; } - if (parsing && (yychar == '(' || yychar == LEFT_RIGHT)) + if (parsing && (yychar == '(' || yychar == LEFT_RIGHT) + && ! flag_strict_prototype) id = implicitly_declare (token); else { if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) - error ("undeclared variable `%s' (first use here)", - IDENTIFIER_POINTER (token)); + cp_error ("`::%D' undeclared (first use here)", token); id = error_mark_node; /* Prevent repeated error messages. */ SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); @@ -3064,9 +3096,9 @@ do_scoped_id (token, parsing) { if (is_overloaded_fn (id)) { - id = build_min (LOOKUP_EXPR, unknown_type_node, - token, get_first_fn (id)); + id = build_min_nt (LOOKUP_EXPR, token); LOOKUP_EXPR_GLOBAL (id) = 1; + return id; } /* else just use the decl */ } @@ -3081,16 +3113,20 @@ identifier_typedecl_value (node) type = IDENTIFIER_TYPE_VALUE (node); if (type == NULL_TREE) return NULL_TREE; -#define do(X) \ - { \ - t = (X); \ - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) \ - return t; \ - } - do (IDENTIFIER_LOCAL_VALUE (node)); - do (IDENTIFIER_CLASS_VALUE (node)); - do (IDENTIFIER_NAMESPACE_VALUE (node)); -#undef do + + 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; + } + /* Will this one ever happen? */ if (TYPE_MAIN_DECL (type)) return TYPE_MAIN_DECL (type); @@ -3100,6 +3136,103 @@ identifier_typedecl_value (node) return NULL_TREE; } +struct pf_args +{ + /* Input */ + /* I/O */ + char *p; + int c; + int imag; + tree type; + /* Output */ + REAL_VALUE_TYPE value; +}; + +static void +parse_float (data) + PTR data; +{ + struct pf_args * args = (struct pf_args *) data; + int fflag = 0, lflag = 0; + /* Copy token_buffer now, while it has just the number + and not the suffixes; once we add `f' or `i', + REAL_VALUE_ATOF may not work any more. */ + char *copy = (char *) alloca (args->p - token_buffer + 1); + bcopy (token_buffer, copy, args->p - token_buffer + 1); + + while (1) + { + int lose = 0; + + /* Read the suffixes to choose a data type. */ + switch (args->c) + { + case 'f': case 'F': + if (fflag) + error ("more than one `f' in numeric constant"); + fflag = 1; + break; + + case 'l': case 'L': + if (lflag) + error ("more than one `l' in numeric constant"); + lflag = 1; + break; + + case 'i': case 'I': + if (args->imag) + error ("more than one `i' or `j' in numeric constant"); + else if (pedantic) + pedwarn ("ANSI C++ forbids imaginary numeric constants"); + args->imag = 1; + break; + + default: + lose = 1; + } + + if (lose) + break; + + if (args->p >= token_buffer + maxtoken - 3) + args->p = extend_token_buffer (args->p); + *(args->p++) = args->c; + *(args->p) = 0; + args->c = getch (); + } + + /* The second argument, machine_mode, of REAL_VALUE_ATOF + tells the desired precision of the binary result + of decimal-to-binary conversion. */ + + if (fflag) + { + if (lflag) + error ("both `f' and `l' in floating constant"); + + args->type = float_type_node; + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + /* A diagnostic is required here by some ANSI C testsuites. + This is not pedwarn, become some people don't want + an error for this. */ + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `float'"); + } + else if (lflag) + { + args->type = long_double_type_node; + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `long double'"); + } + else + { + args->value = REAL_VALUE_ATOF (copy, TYPE_MODE (args->type)); + if (REAL_VALUE_ISINF (args->value) && pedantic) + warning ("floating point number exceeds range of `double'"); + } +} + int real_yylex () { @@ -3635,7 +3768,7 @@ real_yylex () int exceeds_double = 0; int imag = 0; REAL_VALUE_TYPE value; - jmp_buf handler; + struct pf_args args; /* Read explicit exponent if any, and put it in tokenbuf. */ @@ -3664,97 +3797,31 @@ real_yylex () *p = 0; errno = 0; + /* Setup input for parse_float() */ + args.p = p; + args.c = c; + args.imag = imag; + args.type = type; + /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) + if (do_float_handler (parse_float, (PTR) &args)) { - error ("floating constant out of range"); - value = dconst0; + /* Receive output from parse_float() */ + value = args.value; } else { - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (p - token_buffer + 1); - bcopy (token_buffer, copy, p - token_buffer + 1); - - set_float_handler (handler); - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids imaginary numeric constants"); - imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - *p = 0; - c = getch (); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - type = float_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, become some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - type = long_double_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } - - set_float_handler (NULL_PTR); + /* We got an exception from parse_float() */ + error ("floating constant out of range"); + value = dconst0; } + + /* Receive output from parse_float() */ + p = args.p; + c = args.c; + imag = args.imag; + type = args.type; + #ifdef ERANGE if (errno == ERANGE && pedantic) { @@ -3808,7 +3875,7 @@ real_yylex () { if (spec_long_long) error ("three `l's in integer constant"); - else if (pedantic) + else if (pedantic && ! in_system_header && warn_long_long) pedwarn ("ANSI C++ forbids long long integer constants"); spec_long_long = 1; } @@ -3922,30 +3989,27 @@ real_yylex () { register int result = 0; register int num_chars = 0; + int chars_seen = 0; unsigned width = TYPE_PRECISION (char_type_node); int max_chars; - - if (wide_flag) - { - width = WCHAR_TYPE_SIZE; #ifdef MULTIBYTE_CHARS - max_chars = MB_CUR_MAX; -#else - max_chars = 1; + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); #endif - } - else - max_chars = TYPE_PRECISION (integer_type_node) / width; + + max_chars = TYPE_PRECISION (integer_type_node) / width; + if (wide_flag) + width = WCHAR_TYPE_SIZE; while (1) { tryagain: - c = getch (); if (c == '\'' || c == EOF) break; + ++chars_seen; if (c == '\\') { int ignore = 0; @@ -3953,8 +4017,8 @@ real_yylex () if (ignore) goto tryagain; if (width < HOST_BITS_PER_INT - && (unsigned) c >= (1 << width)) - warning ("escape sequence out of range for character"); + && (unsigned) c >= ((unsigned)1 << width)) + pedwarn ("escape sequence out of range for character"); #ifdef MAP_CHARACTER if (ISPRINT (c)) c = MAP_CHARACTER (c); @@ -3963,21 +4027,79 @@ real_yylex () else if (c == '\n') { if (pedantic) - pedwarn ("ANSI C++ forbids newline in character constant"); + pedwarn ("ANSI C forbids newline in character constant"); lineno++; } -#ifdef MAP_CHARACTER else - c = MAP_CHARACTER (c); + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 1; i <= longest_char; ++i) + { + if (i > maxtoken - 4) + extend_token_buffer (token_buffer); + + token_buffer[i] = c; + char_len = local_mbtowc (& wc, + token_buffer + 1, + i); + if (char_len != -1) + break; + c = getch (); + } + if (char_len > 1) + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len < i) + put_back (c); + if (! wide_flag) + { + /* Merge character into result; ignore excess chars. */ + for (i = 1; i <= char_len; ++i) + { + if (i > max_chars) + break; + if (width < HOST_BITS_PER_INT) + result = (result << width) + | (token_buffer[i] + & ((1 << width) - 1)); + else + result = token_buffer[i]; + } + num_chars += char_len; + goto tryagain; + } + c = wc; + } + else + { + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + if (wide_flag) + c = wc; +#ifdef MAP_CHARACTER + else + c = MAP_CHARACTER (c); #endif + } +#else /* ! MULTIBYTE_CHARS */ +#ifdef MAP_CHARACTER + c = MAP_CHARACTER (c); +#endif +#endif /* ! MULTIBYTE_CHARS */ + } - num_chars++; - if (num_chars > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[num_chars] = c; + if (wide_flag) + { + if (chars_seen == 1) /* only keep the first one */ + result = c; + goto tryagain; + } /* Merge character into result; ignore excess chars. */ + num_chars++; if (num_chars < max_chars + 1) { if (width < HOST_BITS_PER_INT) @@ -3987,19 +4109,16 @@ real_yylex () } } - token_buffer[num_chars + 1] = '\''; - token_buffer[num_chars + 2] = 0; - if (c != '\'') error ("malformatted character constant"); - else if (num_chars == 0) + else if (chars_seen == 0) error ("empty character constant"); else if (num_chars > max_chars) { num_chars = max_chars; error ("character constant too long"); } - else if (num_chars != 1 && warn_multichar) + else if (chars_seen != 1 && warn_multichar) warning ("multi-character character constant"); /* If char type is signed, sign-extend the constant. */ @@ -4012,37 +4131,21 @@ real_yylex () else if (TREE_UNSIGNED (char_type_node) || ((result >> (num_bits - 1)) & 1) == 0) yylval.ttype - = build_int_2 (result & ((unsigned HOST_WIDE_INT) ~0 + = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 >> (HOST_BITS_PER_WIDE_INT - num_bits)), 0); else yylval.ttype - = build_int_2 (result | ~((unsigned HOST_WIDE_INT) ~0 + = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 >> (HOST_BITS_PER_WIDE_INT - num_bits)), -1); - if (num_chars<=1) + if (chars_seen <= 1) TREE_TYPE (yylval.ttype) = char_type_node; else TREE_TYPE (yylval.ttype) = integer_type_node; } else { -#ifdef MULTIBYTE_CHARS - /* Set the initial shift state and convert the next sequence. */ - result = 0; - /* In all locales L'\0' is zero and mbtowc will return zero, - so don't use it. */ - if (num_chars > 1 - || (num_chars == 1 && token_buffer[1] != '\0')) - { - wchar_t wc; - (void) mbtowc (NULL, NULL, 0); - if (mbtowc (& wc, token_buffer + 1, num_chars) == num_chars) - result = wc; - else - warning ("Ignoring invalid multibyte character"); - } -#endif yylval.ttype = build_int_2 (result, 0); TREE_TYPE (yylval.ttype) = wchar_type_node; } @@ -4055,6 +4158,12 @@ real_yylex () string_constant: { register char *p; + unsigned width = wide_flag ? WCHAR_TYPE_SIZE + : TYPE_PRECISION (char_type_node); +#ifdef MULTIBYTE_CHARS + int longest_char = local_mb_cur_max (); + (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); +#endif c = getch (); p = token_buffer + 1; @@ -4068,9 +4177,8 @@ real_yylex () c = readescape (&ignore); if (ignore) goto skipnewline; - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && c >= ((unsigned) 1 << TYPE_PRECISION (char_type_node))) + if (width < HOST_BITS_PER_INT + && (unsigned) c >= ((unsigned)1 << width)) warning ("escape sequence out of range for character"); } else if (c == '\n') @@ -4079,10 +4187,72 @@ real_yylex () pedwarn ("ANSI C++ forbids newline in string constant"); lineno++; } + else + { +#ifdef MULTIBYTE_CHARS + wchar_t wc; + int i; + int char_len = -1; + for (i = 0; i < longest_char; ++i) + { + if (p + i >= token_buffer + maxtoken) + p = extend_token_buffer (p); + p[i] = c; - if (p == token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; + char_len = local_mbtowc (& wc, p, i + 1); + if (char_len != -1) + break; + c = getch (); + } + if (char_len == -1) + warning ("Ignoring invalid multibyte character"); + else + { + /* mbtowc sometimes needs an extra char before accepting */ + if (char_len <= i) + put_back (c); + if (! wide_flag) + { + p += (i + 1); + c = getch (); + continue; + } + c = wc; + } +#endif /* MULTIBYTE_CHARS */ + } + + /* Add this single character into the buffer either as a wchar_t + or as a single byte. */ + if (wide_flag) + { + unsigned width = TYPE_PRECISION (char_type_node); + unsigned bytemask = (1 << width) - 1; + int byte; + + if (p + WCHAR_BYTES > token_buffer + maxtoken) + p = extend_token_buffer (p); + + for (byte = 0; byte < WCHAR_BYTES; ++byte) + { + int value; + if (byte >= (int) sizeof(c)) + value = 0; + else + value = (c >> (byte * width)) & bytemask; + if (BYTES_BIG_ENDIAN) + p[WCHAR_BYTES - byte - 1] = value; + else + p[byte] = value; + } + p += WCHAR_BYTES; + } + else + { + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); + *p++ = c; + } skipnewline: c = getch (); @@ -4091,56 +4261,36 @@ real_yylex () break; } } - *p = 0; - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ + /* Terminate the string value, either with a single byte zero + or with a wide zero. */ if (wide_flag) { - /* If this is a L"..." wide-string, convert the multibyte string - to a wide character string. */ - char *widep = (char *) alloca ((p - token_buffer) * WCHAR_BYTES); - int len; - -#ifdef MULTIBYTE_CHARS - len = mbstowcs ((wchar_t *) widep, token_buffer + 1, p - token_buffer); - if (len < 0 || len >= (p - token_buffer)) - { - warning ("Ignoring invalid multibyte string"); - len = 0; - } - bzero (widep + (len * WCHAR_BYTES), WCHAR_BYTES); -#else - { - char *wp, *cp; - - wp = widep + (BYTES_BIG_ENDIAN ? WCHAR_BYTES - 1 : 0); - bzero (widep, (p - token_buffer) * WCHAR_BYTES); - for (cp = token_buffer + 1; cp < p; cp++) - *wp = *cp, wp += WCHAR_BYTES; - len = p - token_buffer - 1; - } -#endif - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - yylval.ttype = build_string ((len + 1) * WCHAR_BYTES, widep); - if (processing_template_decl) - pop_obstacks (); - TREE_TYPE (yylval.ttype) = wchar_array_type_node; + if (p + WCHAR_BYTES > token_buffer + maxtoken) + p = extend_token_buffer (p); + bzero (p, WCHAR_BYTES); + p += WCHAR_BYTES; } else { - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - yylval.ttype = build_string (p - token_buffer, token_buffer + 1); - if (processing_template_decl) - pop_obstacks (); - TREE_TYPE (yylval.ttype) = char_array_type_node; + if (p >= token_buffer + maxtoken) + p = extend_token_buffer (p); + *p++ = 0; } - *p++ = '"'; - *p = 0; + /* We have read the entire constant. + Construct a STRING_CST for the result. */ + + if (processing_template_decl) + push_obstacks (&permanent_obstack, &permanent_obstack); + yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); + if (processing_template_decl) + pop_obstacks (); + + if (wide_flag) + TREE_TYPE (yylval.ttype) = wchar_array_type_node; + else + TREE_TYPE (yylval.ttype) = char_array_type_node; value = STRING; break; } @@ -4392,6 +4542,17 @@ build_lang_decl (code, name, type) tree type; { register tree t = build_decl (code, name, type); + retrofit_lang_decl (t); + return t; +} + +/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl + and pushdecl (for functions generated by the backend). */ + +void +retrofit_lang_decl (t) + tree t; +{ struct obstack *obstack = current_obstack; register int i = sizeof (struct lang_decl) / sizeof (int); register int *pi; @@ -4440,8 +4601,6 @@ build_lang_decl (code, name, type) tree_node_counts[(int)lang_decl] += 1; tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl); #endif - - return t; } tree @@ -4503,39 +4662,49 @@ make_lang_type (code) { extern struct obstack *current_obstack, *saveable_obstack; register tree t = make_node (code); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_type) / sizeof (int); - register int *pi; /* Set up some flags that give proper default behavior. */ - IS_AGGR_TYPE (t) = 1; + if (IS_AGGR_TYPE_CODE (code)) + { + struct obstack *obstack = current_obstack; + struct lang_type *pi; - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 236); + SET_IS_AGGR_TYPE (t, 1); - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_type)); - while (i > 0) - pi[--i] = 0; + if (! TREE_PERMANENT (t)) + obstack = saveable_obstack; + else + my_friendly_assert (obstack == &permanent_obstack, 236); + + pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type)); + bzero ((char *) pi, (int) sizeof (struct lang_type)); - TYPE_LANG_SPECIFIC (t) = (struct lang_type *) pi; - CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t); - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE, - NULL_TREE); - CLASSTYPE_BINFO_AS_LIST (t) = build_tree_list (NULL_TREE, TYPE_BINFO (t)); + TYPE_LANG_SPECIFIC (t) = pi; + SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); + CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - /* Make sure this is laid out, for ease of use later. - In the presence of parse errors, the normal was of assuring - this might not ever get executed, so we lay it out *immediately*. */ - build_pointer_type (t); + /* Make sure this is laid out, for ease of use later. In the + presence of parse errors, the normal was of assuring this + might not ever get executed, so we lay it out *immediately*. */ + build_pointer_type (t); #ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); + tree_node_counts[(int)lang_type] += 1; + tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); #endif + } + else + /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, + TYPE_ALIAS_SET is initialized to -1 by default, so we must + clear it here. */ + TYPE_ALIAS_SET (t) = 0; + + /* We need to allocate a TYPE_BINFO even for TEMPALTE_TYPE_PARMs + since they can be virtual base types, and we then need a + canonical binfo for them. Ideally, this would be done lazily for + all types. */ + if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM) + TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE); return t; } @@ -4545,7 +4714,7 @@ dump_time_statistics () { register tree prev = 0, decl, next; int this_time = my_get_run_time (); - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (this_filename_time)) + TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) += this_time - body_time; fprintf (stderr, "\n******\n"); @@ -4564,22 +4733,31 @@ dump_time_statistics () for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (IDENTIFIER_LOCAL_VALUE (decl))); + TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl))); } void -compiler_error (s, v, v2) - char *s; - HOST_WIDE_INT v, v2; /* @@also used as pointer */ +compiler_error VPROTO ((const char *msg, ...)) { +#ifndef ANSI_PROTOTYPES + const char *msg; +#endif char buf[1024]; - sprintf (buf, s, v, v2); + va_list ap; + + VA_START (ap, msg); + +#ifndef ANSI_PROTOTYPES + msg = va_arg (ap, const char *); +#endif + + vsprintf (buf, msg, ap); error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); } void yyerror (string) - char *string; + const char *string; { extern int end_of_file; char buf[200]; @@ -4598,7 +4776,7 @@ yyerror (string) strcat (buf, " before string constant"); else if (token_buffer[0] == '\'') strcat (buf, " before character constant"); - else if (token_buffer[0] < 040 || (unsigned char) token_buffer[0] >= 0177) + else if (!ISGRAPH ((unsigned char)token_buffer[0])) sprintf (buf + strlen (buf), " before character 0%o", (unsigned char) token_buffer[0]); else @@ -4609,7 +4787,7 @@ yyerror (string) static int handle_cp_pragma (pname) - char *pname; + const char *pname; { register int token; @@ -4655,7 +4833,8 @@ handle_cp_pragma (pname) } else if (! strcmp (pname, "interface")) { - tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); + tree fileinfo + = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); char *main_filename = input_filename; main_filename = file_name_nondirectory (main_filename); @@ -4677,7 +4856,6 @@ handle_cp_pragma (pname) if (token != END_OF_LINE) warning ("garbage after `#pragma interface' ignored"); -#ifndef NO_LINKAGE_HEURISTICS write_virtuals = 3; if (impl_file_chain == 0) @@ -4690,7 +4868,7 @@ handle_cp_pragma (pname) #ifdef AUTO_IMPLEMENT filename = file_name_nondirectory (main_input_filename); fi = get_time_identifier (filename); - fi = IDENTIFIER_CLASS_VALUE (fi); + fi = TIME_IDENTIFIER_FILEINFO (fi); TREE_INT_CST_LOW (fi) = 0; TREE_INT_CST_HIGH (fi) = 1; /* Get default. */ @@ -4701,16 +4879,21 @@ handle_cp_pragma (pname) } interface_only = interface_strcmp (main_filename); +#ifdef MULTIPLE_SYMBOL_SPACES + if (! interface_only) + interface_unknown = 0; +#else /* MULTIPLE_SYMBOL_SPACES */ interface_unknown = 0; +#endif /* MULTIPLE_SYMBOL_SPACES */ TREE_INT_CST_LOW (fileinfo) = interface_only; TREE_INT_CST_HIGH (fileinfo) = interface_unknown; -#endif /* NO_LINKAGE_HEURISTICS */ return 1; } else if (! strcmp (pname, "implementation")) { - tree fileinfo = IDENTIFIER_CLASS_VALUE (get_time_identifier (input_filename)); + tree fileinfo + = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); char *main_filename = main_input_filename ? main_input_filename : input_filename; main_filename = file_name_nondirectory (main_filename); @@ -4730,7 +4913,6 @@ handle_cp_pragma (pname) if (token != END_OF_LINE) warning ("garbage after `#pragma implementation' ignored"); -#ifndef NO_LINKAGE_HEURISTICS if (write_virtuals == 3) { struct impl_files *ifiles = impl_file_chain; @@ -4775,25 +4957,43 @@ handle_cp_pragma (pname) #endif TREE_INT_CST_LOW (fileinfo) = interface_only; TREE_INT_CST_HIGH (fileinfo) = interface_unknown; -#endif /* NO_LINKAGE_HEURISTICS */ return 1; } return 0; } + +/* Return the type-qualifier corresponding to the identifier given by + RID. */ + +int +cp_type_qual_from_rid (rid) + tree rid; +{ + if (rid == ridpointers[(int) RID_CONST]) + return TYPE_QUAL_CONST; + else if (rid == ridpointers[(int) RID_VOLATILE]) + return TYPE_QUAL_VOLATILE; + else if (rid == ridpointers[(int) RID_RESTRICT]) + return TYPE_QUAL_RESTRICT; + + my_friendly_abort (0); + return TYPE_UNQUALIFIED; +} + -#ifdef HANDLE_SYSV_PRAGMA +#ifdef HANDLE_GENERIC_PRAGMAS -/* Handle a #pragma directive. INPUT is the current input stream, - and C is a character to reread. Processes the entire input line - and returns a character for the caller to reread: either \n or EOF. */ +/* Handle a #pragma directive. TOKEN is the type of the word following + the #pragma directive on the line. Process the entire input line and + return non-zero iff the directive successfully parsed. */ /* This function has to be in this file, in order to get at the token types. */ static int -handle_sysv_pragma (token) +handle_generic_pragma (token) register int token; { for (;;) @@ -4802,32 +5002,24 @@ handle_sysv_pragma (token) { case IDENTIFIER: case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token ("ignored", yylval.ttype); - break; - case '(': - handle_pragma_token ("(", NULL_TREE); - break; - case ')': - handle_pragma_token (")", NULL_TREE); - break; - case ',': - handle_pragma_token (",", NULL_TREE); - break; - case '=': - handle_pragma_token ("=", NULL_TREE); + case STRING: + case CONSTANT: + handle_pragma_token (token_buffer, yylval.ttype); break; + case LEFT_RIGHT: handle_pragma_token ("(", NULL_TREE); handle_pragma_token (")", NULL_TREE); break; + case END_OF_LINE: + return handle_pragma_token (NULL_PTR, NULL_TREE); + default: - handle_pragma_token (NULL_PTR, NULL_TREE); - return 1; + handle_pragma_token (token_buffer, NULL_TREE); } + token = real_yylex (); } } -#endif /* HANDLE_SYSV_PRAGMA */ +#endif /* HANDLE_GENERIC_PRAGMAS */ diff --git a/contrib/gcc/cp/lex.h b/contrib/gcc/cp/lex.h index 8df6b76..249eef9 100644 --- a/contrib/gcc/cp/lex.h +++ b/contrib/gcc/cp/lex.h @@ -1,5 +1,5 @@ /* Define constants and variables for communication with parse.y. - Copyright (C) 1987, 1992, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) and by Brendan Kehoe (brendan@cygnus.com). @@ -59,10 +59,12 @@ enum rid RID_FRIEND, RID_VIRTUAL, RID_EXPLICIT, + RID_EXPORT, RID_SIGNED, RID_AUTO, RID_MUTABLE, RID_COMPLEX, + RID_RESTRICT, /* This is where grokdeclarator ends its search when setting the specbits. */ diff --git a/contrib/gcc/cp/method.c b/contrib/gcc/cp/method.c index 29b31c4..d4a667b 100644 --- a/contrib/gcc/cp/method.c +++ b/contrib/gcc/cp/method.c @@ -1,6 +1,6 @@ /* Handle the hair of processing (but not expanding) inline functions. Also manage function and variable name overloading. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. + Copyright (C) 1987, 89, 92-97, 1998, 1999 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -57,7 +57,8 @@ static char *scratch_firstobj; static void icat PROTO((HOST_WIDE_INT)); static void dicat PROTO((HOST_WIDE_INT, HOST_WIDE_INT)); -static void flush_repeats PROTO((int, tree)); +static int old_backref_index PROTO((tree)); +static int flush_repeats PROTO((int, tree)); static void build_overload_identifier PROTO((tree)); static void build_overload_nested_name PROTO((tree)); static void build_overload_int PROTO((tree, int)); @@ -71,8 +72,6 @@ static void process_overload_item PROTO((tree,int)); static void do_build_assign_ref PROTO((tree)); static void do_build_copy_constructor PROTO((tree)); static tree largest_union_member PROTO((tree)); -static tree build_decl_overload_real PROTO((tree, tree, tree, tree, - tree, int)); static void build_template_template_parm_names PROTO((tree)); static void build_template_parm_names PROTO((tree, tree)); static void build_underscore_int PROTO((int)); @@ -82,6 +81,9 @@ static int check_ktype PROTO((tree, int)); static int issue_ktype PROTO((tree)); static void build_overload_scope_ref PROTO((tree)); static void build_mangled_template_parm_index PROTO((char *, tree)); +#if HOST_BITS_PER_WIDE_INT >= 64 +static void build_mangled_C9x_name PROTO((int)); +#endif static int is_back_referenceable_type PROTO((tree)); static int check_btype PROTO((tree)); static void build_mangled_name_for_type PROTO((tree)); @@ -298,15 +300,48 @@ dicat (lo, hi) OB_PUTC ('0' + ulo); } -static __inline void +/* Returns the index of TYPE in the typevec, or -1 if it's not there. */ + +static __inline int +old_backref_index (type) + tree type; +{ + int tindex = 0; + + if (! is_back_referenceable_type (type)) + return -1; + + /* The entry for this parm is at maxtype-1, so don't look there for + something to repeat. */ + for (tindex = 0; tindex < maxtype - 1; ++tindex) + if (same_type_p (typevec[tindex], type)) + break; + + if (tindex == maxtype - 1) + return -1; + + return tindex; +} + +/* Old mangling style: If TYPE has already been used in the parameter list, + emit a backward reference and return non-zero; otherwise, return 0. + + NREPEATS is the number of repeats we've recorded of this type, or 0 if + this is the first time we've seen it and we're just looking to see if + it had been used before. */ + +static __inline int flush_repeats (nrepeats, type) int nrepeats; tree type; { - int tindex = 0; + int tindex = old_backref_index (type); - while (typevec[tindex] != type) - tindex++; + if (tindex == -1) + { + my_friendly_assert (nrepeats == 0, 990316); + return 0; + } if (nrepeats > 1) { @@ -320,25 +355,33 @@ flush_repeats (nrepeats, type) icat (tindex); if (tindex > 9) OB_PUTC ('_'); + + return 1; } /* Returns nonzero iff this is a type to which we will want to make back-references (using the `B' code). */ -int +static int is_back_referenceable_type (type) tree type; { - if (btypelist == NULL) - /* We're not generating any back-references. */ + /* For some reason, the Java folks don't want back refs on these. */ + if (TYPE_FOR_JAVA (type)) return 0; switch (TREE_CODE (type)) { + case BOOLEAN_TYPE: + if (!flag_do_squangling) + /* Even though the mangling of this is just `b', we did + historically generate back-references for it. */ + return 1; + /* Fall through. */ + case INTEGER_TYPE: case REAL_TYPE: case VOID_TYPE: - case BOOLEAN_TYPE: /* These types have single-character manglings, so there's no point in generating back-references. */ return 0; @@ -376,8 +419,10 @@ issue_nrepeats (nrepeats, type) } } -/* Check to see if a tree node has been entered into the Kcode typelist */ -/* if not, add it. Return -1 if it isn't found, otherwise return the index */ +/* Check to see if a tree node has been entered into the Kcode typelist. + If not, add it. Returns -1 if it isn't found, otherwise returns the + index. */ + static int check_ktype (node, add) tree node; @@ -394,10 +439,10 @@ check_ktype (node, add) for (x=0; x < maxktype; x++) { - if (localnode == ktypelist[x]) - return x ; + if (same_type_p (localnode, ktypelist[x])) + return x; } - /* Didn't find it, so add it here */ + /* Didn't find it, so add it here. */ if (add) { if (maxksize <= maxktype) @@ -625,20 +670,53 @@ build_mangled_template_parm_index (s, index) } +/* Mangling for C9X integer types (and Cygnus extensions for 128-bit + and other types) is based on the letter "I" followed by the hex + representations of the bitsize for the type in question. For + encodings that result in larger than two digits, a leading and + trailing underscore is added. + + Thus: + int1_t = 001 = I01 + int8_t = 008 = I08 + int16_t = 010 = I10 + int24_t = 018 = I18 + int32_t = 020 = I20 + int64_t = 040 = I40 + int80_t = 050 = I50 + int128_t = 080 = I80 + int256_t = 100 = I_100_ + int512_t = 200 = I_200_ + + Given an integer in decimal format, mangle according to this scheme. */ + +#if HOST_BITS_PER_WIDE_INT >= 64 +static void +build_mangled_C9x_name (bits) + int bits; +{ + char mangled[10] = ""; + + if (bits > 255) + sprintf (mangled, "I_%x_", bits); + else + sprintf (mangled, "I%.2x", bits); + + OB_PUTCP (mangled); +} +#endif + static void build_overload_value (type, value, in_template) tree type, value; int in_template; { + my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); + while (TREE_CODE (value) == NON_LVALUE_EXPR || TREE_CODE (value) == NOP_EXPR) value = TREE_OPERAND (value, 0); - if (TREE_CODE (type) == PARM_DECL) - type = TREE_TYPE (type); - - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); - if (numeric_output_need_bar) { OB_PUTC ('_'); @@ -651,21 +729,21 @@ build_overload_value (type, value, in_template) return; } - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE) + if (TYPE_PTRMEM_P (type)) { - /* Handle a pointer to data member as a template instantiation - parameter, boy, what fun! */ - type = integer_type_node; - if (TREE_CODE (value) != INTEGER_CST) - { - sorry ("unknown pointer to member constant"); - return; - } - } + if (TREE_CODE (value) != PTRMEM_CST) + /* We should have already rejected this pointer to member, + since it is not a constant. */ + my_friendly_abort (0); - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); + /* Get the actual FIELD_DECL. */ + value = PTRMEM_CST_MEMBER (value); + my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0); + + /* Output the name of the field. */ + build_overload_identifier (DECL_NAME (value)); + return; + } switch (TREE_CODE (type)) { @@ -743,46 +821,6 @@ build_overload_value (type, value, in_template) return; } case POINTER_TYPE: - if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE - && TREE_CODE (value) != ADDR_EXPR) - { - if (TREE_CODE (value) == CONSTRUCTOR) - { - /* This is dangerous code, crack built up pointer to members. */ - tree args = CONSTRUCTOR_ELTS (value); - tree a1 = TREE_VALUE (args); - tree a2 = TREE_VALUE (TREE_CHAIN (args)); - tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)))); - a3 = TREE_VALUE (a3); - STRIP_NOPS (a3); - if (TREE_CODE (a1) == INTEGER_CST - && TREE_CODE (a2) == INTEGER_CST) - { - build_overload_int (a1, in_template); - OB_PUTC ('_'); - build_overload_int (a2, in_template); - OB_PUTC ('_'); - if (TREE_CODE (a3) == ADDR_EXPR) - { - a3 = TREE_OPERAND (a3, 0); - if (TREE_CODE (a3) == FUNCTION_DECL) - { - numeric_output_need_bar = 0; - build_overload_identifier (DECL_ASSEMBLER_NAME (a3)); - return; - } - } - else if (TREE_CODE (a3) == INTEGER_CST) - { - OB_PUTC ('i'); - build_overload_int (a3, in_template); - return; - } - } - } - sorry ("template instantiation with pointer to method that is too complex"); - return; - } if (TREE_CODE (value) == INTEGER_CST) { build_overload_int (value, in_template); @@ -796,6 +834,10 @@ build_overload_value (type, value, in_template) } value = TREE_OPERAND (value, 0); + + /* Fall through. */ + + case REFERENCE_TYPE: if (TREE_CODE (value) == VAR_DECL) { my_friendly_assert (DECL_NAME (value) != 0, 245); @@ -814,6 +856,51 @@ build_overload_value (type, value, in_template) my_friendly_abort (71); break; /* not really needed */ + case RECORD_TYPE: + { + tree delta; + tree idx; + tree pfn; + tree delta2; + + my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 0); + + /* We'll get a ADDR_EXPR of a SCOPE_REF here if we're + mangling, an instantiation of something like: + + template class C {}; + template C x(); + + We mangle the return type of the function, and that + contains template parameters. */ + if (TREE_CODE (value) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (value, 0)) == SCOPE_REF) + { + build_overload_scope_ref (TREE_OPERAND (value, 0)); + break; + } + + my_friendly_assert (TREE_CODE (value) == PTRMEM_CST, 0); + + expand_ptrmemfunc_cst (value, &delta, &idx, &pfn, &delta2); + build_overload_int (delta, in_template); + OB_PUTC ('_'); + build_overload_int (idx, in_template); + OB_PUTC ('_'); + if (pfn) + { + numeric_output_need_bar = 0; + build_overload_identifier (DECL_ASSEMBLER_NAME + (PTRMEM_CST_MEMBER (value))); + } + else + { + OB_PUTC ('i'); + build_overload_int (delta2, in_template); + } + } + break; + default: sorry ("conversion of %s as template parameter", tree_code_name [(int) TREE_CODE (type)]); @@ -823,7 +910,7 @@ build_overload_value (type, value, in_template) /* Add encodings for the declaration of template template parameters. - PARMLIST must be a TREE_VEC */ + PARMLIST must be a TREE_VEC. */ static void build_template_template_parm_names (parmlist) @@ -864,13 +951,14 @@ build_template_parm_names (parmlist, arglist) tree arglist; { int i, nparms; - + tree inner_args = innermost_args (arglist); + nparms = TREE_VEC_LENGTH (parmlist); icat (nparms); for (i = 0; i < nparms; i++) { tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); - tree arg = TREE_VEC_ELT (arglist, i); + tree arg = TREE_VEC_ELT (inner_args, i); if (TREE_CODE (parm) == TYPE_DECL) { /* This parameter is a type. */ @@ -879,9 +967,9 @@ build_template_parm_names (parmlist, arglist) } else if (TREE_CODE (parm) == TEMPLATE_DECL) { - /* This parameter is a template. */ + /* This parameter is a template. */ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - /* Output parameter declaration, argument index and level */ + /* Output parameter declaration, argument index and level. */ build_mangled_name_for_type (arg); else { @@ -889,17 +977,19 @@ build_template_parm_names (parmlist, arglist) and template name */ OB_PUTC ('z'); - build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); + build_template_template_parm_names + (DECL_INNERMOST_TEMPLATE_PARMS (parm)); icat (IDENTIFIER_LENGTH (DECL_NAME (arg))); OB_PUTID (DECL_NAME (arg)); } } else { - parm = tsubst (parm, arglist, NULL_TREE); + parm = tsubst (parm, arglist, /*complain=*/1, NULL_TREE); /* It's a PARM_DECL. */ build_mangled_name_for_type (TREE_TYPE (parm)); - build_overload_value (parm, arg, uses_template_parms (arglist)); + build_overload_value (TREE_TYPE (parm), arg, + uses_template_parms (arglist)); } } } @@ -912,7 +1002,7 @@ build_overload_identifier (name) tree name; { if (TREE_CODE (name) == TYPE_DECL - && IS_AGGR_TYPE (TREE_TYPE (name)) + && CLASS_TYPE_P (TREE_TYPE (name)) && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE @@ -921,9 +1011,8 @@ build_overload_identifier (name) { /* NAME is the TYPE_DECL for a template specialization. */ tree template, parmlist, arglist, tname; - template = CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)); - arglist = innermost_args (TREE_VALUE (template), 0); - template = TREE_PURPOSE (template); + template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)); + arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name)); tname = DECL_NAME (template); parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); OB_PUTC ('t'); @@ -970,15 +1059,18 @@ build_qualified_name (decl) } context = decl; - /* if we can't find a Ktype, do it the hard way */ + /* If we can't find a Ktype, do it the hard way. */ if (check_ktype (context, FALSE) == -1) { - /* count type and namespace scopes */ - while (DECL_CONTEXT (context) && DECL_CONTEXT (context) != global_namespace) + /* Count type and namespace scopes. */ + while (1) { + context = CP_DECL_CONTEXT (context); + if (context == global_namespace) + break; i += 1; - context = DECL_CONTEXT (context); - if (check_ktype (context, FALSE) != -1) /* found it! */ + if (check_ktype (context, FALSE) != -1) + /* Found one! */ break; if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') context = TYPE_NAME (context); @@ -998,14 +1090,13 @@ build_qualified_name (decl) non-zero, mangled names for structure/union types are intentionally mangled differently from the method described in the ARM. */ -void +static void build_mangled_name_for_type_with_Gcode (type, extra_Gcode) tree type; int extra_Gcode; { if (TYPE_PTRMEMFUNC_P (type)) type = TYPE_PTRMEMFUNC_FN_TYPE (type); - type = canonical_type_variant (type); process_modifiers (type); process_overload_item (type, extra_Gcode); } @@ -1013,7 +1104,7 @@ build_mangled_name_for_type_with_Gcode (type, extra_Gcode) /* Like build_mangled_name_for_type_with_Gcode, but never outputs the `G'. */ -void +static void build_mangled_name_for_type (type) tree type; { @@ -1069,7 +1160,11 @@ build_mangled_name (parmtypes, begin, end) for (; parmtypes && parmtypes != void_list_node; parmtypes = TREE_CHAIN (parmtypes)) { - tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes)); + /* We used to call canonical_type_variant here, but that isn't + good enough; it doesn't handle pointers to typedef types. So + we can't just set TREE_USED to say we've seen a type already; + we have to check each of the earlier types with same_type_p. */ + tree parmtype = TREE_VALUE (parmtypes); if (old_style_repeats) { @@ -1078,11 +1173,11 @@ build_mangled_name (parmtypes, begin, end) typevec[maxtype++] = parmtype; } - if (parmtype == last_type) + if (last_type && same_type_p (parmtype, last_type)) { if (flag_do_squangling - || (old_style_repeats && TREE_USED (parmtype) - && !TYPE_FOR_JAVA (parmtype))) + || (old_style_repeats + && is_back_referenceable_type (parmtype))) { /* The next type is the same as this one. Keep track of the repetition, and output the repeat @@ -1104,35 +1199,11 @@ build_mangled_name (parmtypes, begin, end) last_type = parmtype; - if (old_style_repeats) - { - if (nrepeats) - { - flush_repeats (nrepeats, last_type); - nrepeats = 0; - } - - if (TREE_USED (parmtype)) - { -#if 0 - /* We can turn this on at some point when we want - improved symbol mangling. */ - nrepeats++; -#else - /* This is bug compatible with 2.7.x */ - flush_repeats (nrepeats, parmtype); -#endif - nrepeats = 0; - continue; - } - - /* Only cache types which take more than one character. */ - if ((parmtype != TYPE_MAIN_VARIANT (parmtype) - || (TREE_CODE (parmtype) != INTEGER_TYPE - && TREE_CODE (parmtype) != REAL_TYPE)) - && ! TYPE_FOR_JAVA (parmtype)) - TREE_USED (parmtype) = 1; - } + /* Note that for bug-compatibility with 2.7.2, we can't build up + repeats of types other than the most recent one. So we call + flush_repeats every round, if we get this far. */ + if (old_style_repeats && flush_repeats (0, parmtype)) + continue; /* Output the PARMTYPE. */ build_mangled_name_for_type_with_Gcode (parmtype, 1); @@ -1159,27 +1230,37 @@ build_mangled_name (parmtypes, begin, end) return (char *)obstack_base (&scratch_obstack); } -/* handles emitting modifiers such as Constant, read-only, and volatile */ -void +/* Emit modifiers such as constant, read-only, and volatile. */ + +static void process_modifiers (parmtype) tree parmtype; { - if (TREE_READONLY (parmtype)) + /* Note that here we do not use CP_TYPE_CONST_P and friends because + we describe types recursively; we will get the `const' in + `const int ()[10]' when processing the `const int' part. */ + if (TYPE_READONLY (parmtype)) OB_PUTC ('C'); if (TREE_CODE (parmtype) == INTEGER_TYPE + && parmtype != char_type_node + && parmtype != wchar_type_node && (TYPE_MAIN_VARIANT (parmtype) == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) && ! TYPE_FOR_JAVA (parmtype)) OB_PUTC ('U'); if (TYPE_VOLATILE (parmtype)) OB_PUTC ('V'); + /* It would be better to use `R' for `restrict', but that's already + used for reference types. And `r' is used for `long double'. */ + if (TYPE_RESTRICT (parmtype)) + OB_PUTC ('u'); } /* Check to see if TYPE has been entered into the Bcode typelist. If so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE to the list of back-referenceable types and return 0. */ -int +static int check_btype (type) tree type; { @@ -1191,12 +1272,8 @@ check_btype (type) if (!is_back_referenceable_type (type)) return 0; - /* We assume that our caller has put out any necessary - qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - for (x = 0; x < maxbtype; x++) - if (type == btypelist[x]) + if (same_type_p (type, btypelist[x])) { OB_PUTC ('B'); icat (x); @@ -1218,7 +1295,8 @@ check_btype (type) return 0; } -/* handle emitting the correct code for various node types */ +/* Emit the correct code for various node types. */ + static void process_overload_item (parmtype, extra_Gcode) tree parmtype; @@ -1226,9 +1304,17 @@ process_overload_item (parmtype, extra_Gcode) { numeric_output_need_bar = 0; - /* These tree types are considered modifiers for B code squangling , */ - /* and therefore should not get entries in the Btypelist */ - /* they are, however, repeatable types */ + /* Our caller should have already handed any qualifiers, so pull out the + TYPE_MAIN_VARIANT to avoid typedef confusion. Except we can't do that + for arrays, because they are transparent to qualifiers. Sigh. */ + if (TREE_CODE (parmtype) == ARRAY_TYPE) + parmtype = canonical_type_variant (parmtype); + else + parmtype = TYPE_MAIN_VARIANT (parmtype); + + /* These tree types are considered modifiers for B code squangling, + and therefore should not get entries in the Btypelist. They are, + however, repeatable types. */ switch (TREE_CODE (parmtype)) { @@ -1239,11 +1325,9 @@ process_overload_item (parmtype, extra_Gcode) case ARRAY_TYPE: #if PARM_CAN_BE_ARRAY_TYPE { - tree length; - OB_PUTC ('A'); if (TYPE_DOMAIN (parmtype) == NULL_TREE) - error("pointer/reference to array of unknown bound in parm type"); + OB_PUTC ('_'); else { tree length = array_type_nelts (parmtype); @@ -1331,7 +1415,6 @@ process_overload_item (parmtype, extra_Gcode) } case INTEGER_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == integer_type_node || parmtype == unsigned_type_node || parmtype == java_int_type_node) @@ -1359,15 +1442,18 @@ process_overload_item (parmtype, extra_Gcode) || parmtype == long_long_unsigned_type_node || parmtype == java_long_type_node) OB_PUTC ('x'); -#if 0 - /* it would seem there is no way to enter these in source code, - yet. (mrs) */ - else if (parmtype == long_long_long_integer_type_node - || parmtype == long_long_long_unsigned_type_node) - OB_PUTC ('q'); -#endif else if (parmtype == java_boolean_type_node) OB_PUTC ('b'); +#if HOST_BITS_PER_WIDE_INT >= 64 + else if (parmtype == intTI_type_node + || parmtype == unsigned_intTI_type_node) + { + /* Should just check a flag here instead of specific + *_type_nodes, because all C9x types could use this. */ + int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype)); + build_mangled_C9x_name (bits); + } +#endif else my_friendly_abort (73); break; @@ -1377,7 +1463,6 @@ process_overload_item (parmtype, extra_Gcode) break; case REAL_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); if (parmtype == long_double_type_node) OB_PUTC ('r'); else if (parmtype == double_type_node @@ -1413,11 +1498,6 @@ process_overload_item (parmtype, extra_Gcode) { tree name = TYPE_NAME (parmtype); - if (TREE_CODE (name) == IDENTIFIER_NODE) - { - build_overload_identifier (TYPE_NAME (parmtype)); - break; - } my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248); build_qualified_name (name); @@ -1432,14 +1512,14 @@ process_overload_item (parmtype, extra_Gcode) case TEMPLATE_TEMPLATE_PARM: /* Find and output the original template parameter declaration. */ - if (CLASSTYPE_TEMPLATE_INFO (parmtype)) + if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype)) { build_mangled_template_parm_index ("tzX", TEMPLATE_TYPE_PARM_INDEX (parmtype)); build_template_parm_names - (DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (parmtype)), - CLASSTYPE_TI_ARGS (parmtype)); + (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)), + TYPE_TI_ARGS (parmtype)); } else { @@ -1499,7 +1579,10 @@ build_static_name (context, name) return get_identifier ((char *)obstack_base (&scratch_obstack)); } -static tree +/* FOR_METHOD should be 1 if the declaration in question is for a member + of a class (including a static member) and 2 if the declaration is + for a constructor. */ +tree build_decl_overload_real (dname, parms, ret_type, tparms, targs, for_method) tree dname; @@ -1557,12 +1640,13 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, OB_PUTC ('v'); else { - if (!flag_do_squangling) /* Allocate typevec array. */ + if (!flag_do_squangling) { + /* Allocate typevec array. */ maxtype = 0; typevec_size = list_length (parms); if (!for_method && current_namespace != global_namespace) - /* the namespace of a global function needs one slot */ + /* The namespace of a global function needs one slot. */ typevec_size++; typevec = (tree *)alloca (typevec_size * sizeof (tree)); } @@ -1583,12 +1667,6 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, { my_friendly_assert (maxtype < typevec_size, 387); typevec[maxtype++] = this_type; - TREE_USED (this_type) = 1; - - /* By setting up PARMS in this way, the loop below will - automatically clear TREE_USED on THIS_TYPE. */ - parms = temp_tree_cons (NULL_TREE, this_type, - TREE_CHAIN (parms)); } if (TREE_CHAIN (parms)) @@ -1609,20 +1687,9 @@ build_decl_overload_real (dname, parms, ret_type, tparms, targs, build_mangled_name (parms, 0, 0); } - if (!flag_do_squangling) /* Deallocate typevec array */ - { - tree t = parms; - typevec = NULL; - while (t) - { - tree temp = TREE_VALUE (t); - TREE_USED (temp) = 0; - /* clear out the type variant in case we used it */ - temp = canonical_type_variant (temp); - TREE_USED (temp) = 0; - t = TREE_CHAIN (t); - } - } + if (!flag_do_squangling) + /* Deallocate typevec array. */ + typevec = NULL; } if (ret_type != NULL_TREE && for_method != 2) @@ -1661,38 +1728,38 @@ build_decl_overload (dname, parms, for_method) NULL_TREE, for_method); } +/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */ -/* Like build_decl_overload, but for template functions. */ - -tree -build_template_decl_overload (decl, parms, ret_type, tparms, targs, - for_method) +void +set_mangled_name_for_decl (decl) tree decl; - tree parms; - tree ret_type; - tree tparms; - tree targs; - int for_method; { - tree res, saved_ctx; - - /* If the template is in a namespace, we need to put that into the - mangled name. Unfortunately, build_decl_overload_real does not - get the decl to mangle, so it relies on the current - namespace. Therefore, we set that here temporarily. */ + tree parm_types; - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 980702); - saved_ctx = current_namespace; - current_namespace = CP_DECL_CONTEXT (decl); + if (processing_template_decl) + /* There's no need to mangle the name of a template function. */ + return; - res = build_decl_overload_real (DECL_NAME (decl), parms, ret_type, - tparms, targs, for_method); + parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - current_namespace = saved_ctx; - return res; + if (DECL_STATIC_FUNCTION_P (decl)) + parm_types = + hash_tree_chain (build_pointer_type (DECL_CLASS_CONTEXT (decl)), + parm_types); + else + /* The only member functions whose type is a FUNCTION_TYPE, rather + than a METHOD_TYPE, should be static members. */ + my_friendly_assert (!DECL_CONTEXT (decl) + || !IS_AGGR_TYPE_CODE (TREE_CODE (DECL_CONTEXT (decl))) + || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE, + 0); + + DECL_ASSEMBLER_NAME (decl) + = build_decl_overload (DECL_NAME (decl), parm_types, + DECL_FUNCTION_MEMBER_P (decl) + + DECL_CONSTRUCTOR_P (decl)); } - /* Build an overload name for the type expression TYPE. */ tree @@ -1851,8 +1918,16 @@ hack_identifier (value, name) { if (current_class_ptr == NULL_TREE) { - error ("request for member `%s' in static member function", - IDENTIFIER_POINTER (DECL_NAME (value))); + if (current_function_decl + && DECL_STATIC_FUNCTION_P (current_function_decl)) + cp_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); } */ + cp_error ("invalid use of member `%D'", value); + return error_mark_node; } TREE_USED (current_class_ptr) = 1; @@ -1863,24 +1938,24 @@ hack_identifier (value, name) TREE_USED (value) = 1; value = build_component_ref (current_class_ref, name, NULL_TREE, 1); } - else if (TREE_CODE (value) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (value)) - /* This is a placeholder; don't mark it used. */ - return value; - else if (really_overloaded_fn (value)) + else if ((TREE_CODE (value) == FUNCTION_DECL + && DECL_FUNCTION_MEMBER_P (value)) + || (TREE_CODE (value) == OVERLOAD + && DECL_FUNCTION_MEMBER_P (OVL_CURRENT (value)))) { -#if 0 - tree t = get_first_fn (value); - for (; t; t = DECL_CHAIN (t)) - { - if (TREE_CODE (t) == TEMPLATE_DECL) - continue; + tree decl; - assemble_external (t); - TREE_USED (t) = 1; - } -#endif + if (TREE_CODE (value) == OVERLOAD) + value = OVL_CURRENT (value); + + if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value))) + return value; + + decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0); + value = build_component_ref (decl, name, NULL_TREE, 1); } + else if (really_overloaded_fn (value)) + ; else if (TREE_CODE (value) == OVERLOAD) /* not really overloaded function */ mark_used (OVL_FUNCTION (value)); @@ -1907,7 +1982,8 @@ hack_identifier (value, name) else mark_used (value); - if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL) + 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 @@ -1926,44 +2002,27 @@ hack_identifier (value, name) if (DECL_LANG_SPECIFIC (value) && DECL_CLASS_CONTEXT (value) != current_class_type) { - tree path, access; + tree path; register tree context = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) ? DECL_CLASS_CONTEXT (value) : DECL_CONTEXT (value); get_base_distance (context, current_class_type, 0, &path); - if (path) - { - access = compute_access (path, value); - if (access != access_public_node) - { - if (TREE_CODE (value) == VAR_DECL) - error ("static member `%s' is %s", - IDENTIFIER_POINTER (name), - TREE_PRIVATE (value) ? "private" - : "from a private base class"); - else - error ("enum `%s' is from private base class", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - } + if (path && !enforce_access (current_class_type, value)) + return error_mark_node; } } - else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) + else if (TREE_CODE (value) == TREE_LIST + && TREE_TYPE (value) == error_mark_node) { - if (type == 0) - { - error ("request for member `%s' is ambiguous in multiple inheritance lattice", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - - return value; + error ("request for member `%s' is ambiguous in multiple inheritance lattice", + IDENTIFIER_POINTER (name)); + print_candidates (value); + return error_mark_node; } - if (TREE_CODE (type) == REFERENCE_TYPE && ! processing_template_decl) + if (! processing_template_decl) value = convert_from_reference (value); return value; } @@ -2172,42 +2231,21 @@ do_build_copy_constructor (fndecl) tree binfos = TYPE_BINFO_BASETYPES (current_class_type); int i; + /* Initialize all the base-classes. */ for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; t = TREE_CHAIN (t)) - { - tree basetype = BINFO_TYPE (t); - tree p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - p = convert_from_reference (p); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } - + current_base_init_list + = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); for (i = 0; i < n_bases; ++i) { - tree p, basetype = TREE_VEC_ELT (binfos, i); - if (TREE_VIA_VIRTUAL (basetype)) + t = TREE_VEC_ELT (binfos, i); + if (TREE_VIA_VIRTUAL (t)) continue; - basetype = BINFO_TYPE (basetype); - p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - { - p = convert_from_reference (p); - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } + current_base_init_list + = tree_cons (BINFO_TYPE (t), parm, current_base_init_list); } + for (; fields; fields = TREE_CHAIN (fields)) { tree init, t; @@ -2305,7 +2343,7 @@ do_build_assign_ref (fndecl) if (TREE_CODE (field) != FIELD_DECL) continue; - if (TREE_READONLY (field)) + if (CP_TYPE_CONST_P (TREE_TYPE (field))) { if (DECL_NAME (field)) cp_error ("non-static const member `%#D', can't use default assignment operator", field); diff --git a/contrib/gcc/cp/new.cc b/contrib/gcc/cp/new.cc index 28187a4..3197012 100644 --- a/contrib/gcc/cp/new.cc +++ b/contrib/gcc/cp/new.cc @@ -1,5 +1,5 @@ // Implementation file for the -*- C++ -*- dynamic memory management header. -// Copyright (C) 1996 Free Software Foundation +// Copyright (C) 1996, 1997, 1998 Free Software Foundation // This file is part of GNU CC. diff --git a/contrib/gcc/cp/new1.cc b/contrib/gcc/cp/new1.cc index 5bb85c9..73fbcd2 100644 --- a/contrib/gcc/cp/new1.cc +++ b/contrib/gcc/cp/new1.cc @@ -1,5 +1,5 @@ // Support routines for the -*- C++ -*- dynamic memory management. -// Copyright (C) 1997 Free Software Foundation +// Copyright (C) 1997, 1998 Free Software Foundation // This file is part of GNU CC. diff --git a/contrib/gcc/cp/new2.cc b/contrib/gcc/cp/new2.cc index 0be1c0d..2833ea2 100644 --- a/contrib/gcc/cp/new2.cc +++ b/contrib/gcc/cp/new2.cc @@ -1,5 +1,5 @@ // Boilerplate support routines for -*- C++ -*- dynamic memory management. -// Copyright (C) 1997 Free Software Foundation +// Copyright (C) 1997, 1998 Free Software Foundation // This file is part of GNU CC. diff --git a/contrib/gcc/cp/parse.y b/contrib/gcc/cp/parse.y index 279cec3..7b5d3bd 100644 --- a/contrib/gcc/cp/parse.y +++ b/contrib/gcc/cp/parse.y @@ -1,5 +1,5 @@ /* YACC parser for C++ syntax. - Copyright (C) 1988, 89, 93, 94, 95, 1996 Free Software Foundation, Inc. + Copyright (C) 1988, 89, 93-98, 1999 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GNU CC. @@ -60,9 +60,10 @@ extern int end_of_file; /* Contains the statement keyword (if/while/do) to include in an error message if the user supplies an empty conditional expression. */ -static char *cond_stmt_keyword; +static const char *cond_stmt_keyword; static tree empty_parms PROTO((void)); +static int parse_decl PROTO((tree, tree, tree, int, tree *)); /* Nonzero if we have an `extern "C"' acting as an extern specifier. */ int have_extern_spec; @@ -130,7 +131,7 @@ empty_parms () /* the reserved words */ /* SCO include files test "ASM", so use something else. */ %token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT -%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF +%token BREAK CONTINUE RETURN_KEYWORD GOTO ASM_KEYWORD TYPEOF ALIGNOF %token SIGOF %token ATTRIBUTE EXTENSION LABEL %token REALPART IMAGPART @@ -203,11 +204,12 @@ empty_parms () %type compstmt implicitly_scoped_stmt %type declarator notype_declarator after_type_declarator +%type notype_declarator_intern absdcl_intern +%type after_type_declarator_intern %type direct_notype_declarator direct_after_type_declarator - -%type opt.component_decl_list component_decl_list -%type component_decl component_decl_1 components notype_components -%type component_declarator component_declarator0 self_reference +%type components notype_components +%type component_decl component_decl_1 +%type component_declarator component_declarator0 %type notype_component_declarator notype_component_declarator0 %type after_type_component_declarator after_type_component_declarator0 %type enumlist enumerator @@ -217,7 +219,8 @@ empty_parms () %type xexpr parmlist parms bad_parm %type identifiers_or_typenames %type fcast_or_absdcl regcast_or_absdcl -%type expr_or_declarator complex_notype_declarator +%type expr_or_declarator expr_or_declarator_intern +%type complex_notype_declarator %type notype_unqualified_id unqualified_id qualified_id %type template_id do_id object_template_id notype_template_declarator %type overqualified_id notype_qualified_id any_id @@ -235,11 +238,12 @@ empty_parms () %token PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER %type component_constructor_declarator %type fn.def2 return_id fn.defpen constructor_declarator -%type ctor_initializer_opt -%type named_class_head named_class_head_sans_basetype -%type named_complex_class_head_sans_basetype +%type ctor_initializer_opt function_try_block +%type named_class_head_sans_basetype +%type class_head named_class_head +%type named_complex_class_head_sans_basetype %type unnamed_class_head -%type class_head base_class_list +%type base_class_list %type base_class_access_list %type base_class maybe_base_class_list base_class.1 %type exception_specification_opt ansi_raise_identifier ansi_raise_identifiers @@ -252,6 +256,7 @@ empty_parms () %type template_header template_parm_list template_parm %type template_type_parm template_template_parm %type template_close_bracket +%type apparent_template_type %type template_type template_arg_list template_arg_list_opt %type template_arg %type condition xcond paren_cond_or_null @@ -267,7 +272,7 @@ empty_parms () %type named_class_head_sans_basetype_defn %type identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN -%type self_template_type +%type self_template_type .finish_template_type %token NSNAME %type NSNAME @@ -290,9 +295,13 @@ static tree current_declspecs; a declspec list have been updated. */ static tree prefix_attributes; -/* When defining an aggregate, this is the most recent one being defined. */ +/* When defining an aggregate, this is the kind of the most recent one + being defined. (For example, this might be class_type_node.) */ static tree current_aggr; +/* When defining an enumeration, this is the type of the enumeration. */ +static tree current_enum_type; + /* Tell yyparse how to print a token's value, if yydebug is set. */ #define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) @@ -312,7 +321,7 @@ parse_decl(declarator, specs_attrs, attributes, initialized, decl) split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); if (current_declspecs && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = get_decl_list (current_declspecs); + current_declspecs = build_decl_list (NULL_TREE, current_declspecs); if (have_extern_spec && !used_extern_spec) { current_declspecs = decl_tree_cons (NULL_TREE, @@ -556,22 +565,38 @@ template_parm: ; template_def: - template_header - extdef - { - if ($1) - end_template_decl (); - else - end_specialization (); - } - | template_header - error %prec EMPTY - { - if ($1) - end_template_decl (); - else - end_specialization (); - } + template_header template_extdef + { finish_template_decl ($1); } + | template_header error %prec EMPTY + { finish_template_decl ($1); } + ; + +template_extdef: + fndef eat_saved_input + { if (pending_inlines) do_pending_inlines (); } + | template_datadef + { if (pending_inlines) do_pending_inlines (); } + | template_def + { if (pending_inlines) do_pending_inlines (); } + | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input + { if (pending_inlines) do_pending_inlines (); + pop_lang_context (); } + | extern_lang_string .hush_warning template_datadef .warning_ok + { if (pending_inlines) do_pending_inlines (); + pop_lang_context (); } + | extension template_extdef + { pedantic = $1; } + ; + +template_datadef: + nomods_initdecls ';' + | declmods notype_initdecls ';' + {} + | typed_declspecs initdecls ';' + { note_list_got_semicolon ($1.t); } + | structsp ';' + { maybe_process_partial_specialization ($1.t); + note_got_semicolon ($1.t); } ; datadef: @@ -579,9 +604,7 @@ datadef: | declmods notype_initdecls ';' {} | typed_declspecs initdecls ';' - { - note_list_got_semicolon ($1.t); - } + { note_list_got_semicolon ($1.t); } | declmods ';' { pedwarn ("empty declaration"); } | explicit_instantiation ';' @@ -619,7 +642,11 @@ fndef: fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error { finish_function (lineno, (int)$3, 0); } | fn.def1 maybe_return_init function_try_block - { } + { + int nested = (hack_decl_function_context + (current_function_decl) != NULL_TREE); + finish_function (lineno, (int)$3, nested); + } | fn.def1 maybe_return_init error { } ; @@ -692,8 +719,10 @@ component_constructor_declarator: reduce/reduce conflict introduced by these rules. */ fn.def2: declmods component_constructor_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); rest_of_mdef: if (! $$) YYERROR1; @@ -701,24 +730,33 @@ fn.def2: yychar = YYLEX; reinit_parse_for_method (yychar, $$); } | component_constructor_declarator - { $$ = start_method (NULL_TREE, $1); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $1, NULL_TREE); + goto rest_of_mdef; } | typed_declspecs declarator - { tree specs = strip_attrs ($1.t); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1.t, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | declmods notype_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | notype_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $$, NULL_TREE); + goto rest_of_mdef; } | declmods constructor_declarator - { tree specs = strip_attrs ($1); - $$ = start_method (specs, $2); goto rest_of_mdef; } + { tree specs, attrs; + split_specs_attrs ($1, &specs, &attrs); + attrs = build_tree_list (attrs, NULL_TREE); + $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } | constructor_declarator - { $$ = start_method (NULL_TREE, $$); goto rest_of_mdef; } + { $$ = start_method (NULL_TREE, $$, NULL_TREE); + goto rest_of_mdef; } ; return_id: - RETURN IDENTIFIER + RETURN_KEYWORD IDENTIFIER { if (! current_function_parms_stored) store_parm_decls (); @@ -870,29 +908,35 @@ end_explicit_instantiation: template_type: PTYPENAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } | TYPENAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } | self_template_type ; +apparent_template_type: + template_type + | identifier '<' template_arg_list_opt '>' + .finish_template_type + { $$ = $5; } + self_template_type: SELFNAME '<' template_arg_list_opt template_close_bracket - { - $$ = lookup_template_class ($1, $3, NULL_TREE, NULL_TREE); - if ($$ != error_mark_node) - $$ = TYPE_STUB_DECL ($$); - } + .finish_template_type + { $$ = $5; } ; +.finish_template_type: + { + if (yychar == YYEMPTY) + yychar = YYLEX; + + $$ = finish_template_type ($-3, $-1, + yychar == SCOPE); + } + template_close_bracket: '>' | RSHIFT @@ -1056,7 +1100,8 @@ unary_expr: | SIZEOF unary_expr %prec UNARY { $$ = expr_sizeof ($2); } | SIZEOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_sizeof (groktypename ($3.t)); } + { $$ = c_sizeof (groktypename ($3.t)); + check_for_new_type ("sizeof", $3); } | ALIGNOF unary_expr %prec UNARY { $$ = grok_alignof ($2); } | ALIGNOF '(' type_id ')' %prec HYPERUNARY @@ -1265,6 +1310,8 @@ expr_no_commas: notype_unqualified_id: '~' see_typename identifier { $$ = build_parse_node (BIT_NOT_EXPR, $3); } + | '~' see_typename template_type + { $$ = build_parse_node (BIT_NOT_EXPR, $3); } | template_id | operator_name | IDENTIFIER @@ -1273,7 +1320,16 @@ notype_unqualified_id: ; do_id: - { $$ = do_identifier ($-1, 1, NULL_TREE); } + { + /* If lastiddecl is a TREE_LIST, it's a baselink, which + means that we're in an expression like S::f, so + don't do_identifier; we only do that for unqualified + identifiers. */ + if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) + $$ = do_identifier ($-1, 1, NULL_TREE); + else + $$ = $-1; + } template_id: PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket @@ -1298,13 +1354,23 @@ unqualified_id: | SELFNAME ; +expr_or_declarator_intern: + expr_or_declarator + | attributes expr_or_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + expr_or_declarator: notype_unqualified_id - | '*' expr_or_declarator %prec UNARY + | '*' expr_or_declarator_intern %prec UNARY { $$ = build_parse_node (INDIRECT_REF, $2); } - | '&' expr_or_declarator %prec UNARY + | '&' expr_or_declarator_intern %prec UNARY { $$ = build_parse_node (ADDR_EXPR, $2); } - | '(' expr_or_declarator ')' + | '(' expr_or_declarator_intern ')' { $$ = $2; } ; @@ -1321,8 +1387,8 @@ direct_notype_declarator: to the Koenig lookup shift in primary, below. I hate yacc. */ | notype_unqualified_id %prec '(' | notype_template_declarator - | '(' expr_or_declarator ')' - { $$ = finish_decl_parsing ($2); } + | '(' expr_or_declarator_intern ')' + { $$ = finish_decl_parsing ($2); } ; primary: @@ -1340,18 +1406,25 @@ primary: if (processing_template_decl) push_obstacks (&permanent_obstack, &permanent_obstack); $$ = combine_strings ($$); + /* combine_strings doesn't set up TYPE_MAIN_VARIANT of + a const array the way we want, so fix it. */ + if (flag_const_strings) + TREE_TYPE ($$) = build_cplus_array_type + (TREE_TYPE (TREE_TYPE ($$)), + TYPE_DOMAIN (TREE_TYPE ($$))); if (processing_template_decl) pop_obstacks (); } | '(' expr ')' { $$ = finish_parenthesized_expr ($2); } - | '(' expr_or_declarator ')' + | '(' expr_or_declarator_intern ')' { $2 = reparse_decl_as_expr (NULL_TREE, $2); $$ = finish_parenthesized_expr ($2); } | '(' error ')' { $$ = error_mark_node; } | '(' - { if (current_function_decl == 0) + { tree scope = current_scope (); + if (!scope || TREE_CODE (scope) != FUNCTION_DECL) { error ("braced-group within expression allowed only inside a function"); YYERROR; @@ -1384,47 +1457,20 @@ primary: { $$ = finish_this_expr (); } | CV_QUALIFIER '(' nonnull_exprlist ')' { - tree type = NULL_TREE; - tree id = $$; + /* This is a C cast in C++'s `functional' notation + using the "implicit int" extension so that: + `const (3)' is equivalent to `const int (3)'. */ + tree type; - /* This is a C cast in C++'s `functional' notation. */ if ($3 == error_mark_node) { $$ = error_mark_node; break; } -#if 0 - if ($3 == NULL_TREE) - { - error ("cannot cast null list to type `%s'", - IDENTIFIER_POINTER (TYPE_NAME (id))); - $$ = error_mark_node; - break; - } -#endif -#if 0 - /* type is not set! (mrs) */ - if (type == error_mark_node) - $$ = error_mark_node; - else -#endif - { - if (id == ridpointers[(int) RID_CONST]) - type = build_type_variant (integer_type_node, 1, 0); - else if (id == ridpointers[(int) RID_VOLATILE]) - type = build_type_variant (integer_type_node, 0, 1); -#if 0 - /* should not be able to get here (mrs) */ - else if (id == ridpointers[(int) RID_FRIEND]) - { - error ("cannot cast expression to `friend' type"); - $$ = error_mark_node; - break; - } -#endif - else my_friendly_abort (79); - $$ = build_c_cast (type, build_compound_expr ($3)); - } + + type = cp_build_qualified_type (integer_type_node, + cp_type_qual_from_rid ($1)); + $$ = build_c_cast (type, build_compound_expr ($3)); } | functional_cast | DYNAMIC_CAST '<' type_id '>' '(' expr ')' @@ -1464,9 +1510,9 @@ primary: | overqualified_id %prec HYPERUNARY { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } | overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_globally_qualified_member_call_expr ($1, $3); } + { $$ = finish_qualified_call_expr ($1, $3); } | overqualified_id LEFT_RIGHT - { $$ = finish_globally_qualified_member_call_expr ($1, NULL_TREE); } + { $$ = finish_qualified_call_expr ($1, NULL_TREE); } | object object_template_id %prec UNARY { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); @@ -1642,7 +1688,8 @@ type_id: { $$.t = build_decl_list ($1.t, $2); $$.new_type_flag = $1.new_type_flag; } | typespec absdcl - { $$.t = build_decl_list (get_decl_list ($1.t), $2); + { $$.t = build_decl_list (build_decl_list (NULL_TREE, $1.t), + $2); $$.new_type_flag = $1.new_type_flag; } | typed_typespecs %prec EMPTY { $$.t = build_decl_list ($1.t, NULL_TREE); @@ -1708,24 +1755,33 @@ reserved_declspecs: to redeclare a typedef-name. In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ +/* We use hash_tree_cons for lists of typeless declspecs so that they end + up on a persistent obstack. Otherwise, they could appear at the + beginning of something like + + static const struct { int foo () { } } b; + + and would be discarded after we finish compiling foo. We don't need to + worry once we see a type. */ + declmods: nonempty_cv_qualifiers %prec EMPTY { $$ = $1.t; TREE_STATIC ($$) = 1; } | SCSPEC - { $$ = IDENTIFIER_AS_LIST ($$); } + { $$ = hash_tree_cons (NULL_TREE, $$, NULL_TREE); } | declmods CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); + { $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = 1; } | declmods SCSPEC { if (extra_warnings && TREE_STATIC ($$)) warning ("`%s' is not at beginning of declaration", IDENTIFIER_POINTER ($2)); - $$ = decl_tree_cons (NULL_TREE, $2, $$); + $$ = hash_tree_cons (NULL_TREE, $2, $$); TREE_STATIC ($$) = TREE_STATIC ($1); } | declmods attributes - { $$ = decl_tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } + { $$ = hash_tree_cons ($2, NULL_TREE, $1); } + | attributes %prec EMPTY + { $$ = hash_tree_cons ($1, NULL_TREE, NULL_TREE); } ; /* Used instead of declspecs where storage classes are not allowed @@ -1736,7 +1792,7 @@ declmods: typed_typespecs: typespec %prec EMPTY - { $$.t = get_decl_list ($1.t); + { $$.t = build_decl_list (NULL_TREE, $1.t); $$.new_type_flag = $1.new_type_flag; } | nonempty_cv_qualifiers typespec { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1.t); @@ -1767,7 +1823,7 @@ typespec: | complete_type_name { $$.t = $1; $$.new_type_flag = 0; } | TYPEOF '(' expr ')' - { $$.t = TREE_TYPE ($3); + { $$.t = finish_typeof ($3); $$.new_type_flag = 0; } | TYPEOF '(' type_id ')' { $$.t = groktypename ($3.t); @@ -1817,16 +1873,19 @@ typespecqual_reserved: initdecls: initdcl0 | initdecls ',' initdcl + { check_multiple_declarators (); } ; notype_initdecls: notype_initdcl0 | notype_initdecls ',' initdcl + { check_multiple_declarators (); } ; nomods_initdecls: nomods_initdcl0 | nomods_initdecls ',' initdcl + { check_multiple_declarators (); } ; maybeasm: @@ -1995,7 +2054,7 @@ initlist: fn.defpen: PRE_PARSED_FUNCTION_DECL { start_function (NULL_TREE, TREE_VALUE ($1), - NULL_TREE, 1); + NULL_TREE, 2); reinit_parse_for_function (); } pending_inline: @@ -2003,11 +2062,16 @@ pending_inline: { int nested = (hack_decl_function_context (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3, nested); + finish_function (lineno, (int)$3 | 2, nested); process_next_inline ($1); } | fn.defpen maybe_return_init function_try_block - { process_next_inline ($1); } + { + int nested = (hack_decl_function_context + (current_function_decl) != NULL_TREE); + finish_function (lineno, (int)$3 | 2, nested); + process_next_inline ($1); + } | fn.defpen maybe_return_init error { process_next_inline ($1); } ; @@ -2036,39 +2100,48 @@ pending_defargs: structsp: ENUM identifier '{' { $3 = suspend_momentary (); - $$ = start_enum ($2); } + $$ = current_enum_type; + current_enum_type = start_enum ($2); } enumlist maybecomma_warn '}' - { $$.t = finish_enum ($4, $5); + { TYPE_VALUES (current_enum_type) = $5; + $$.t = finish_enum (current_enum_type); $$.new_type_flag = 1; + current_enum_type = $4; resume_momentary ((int) $3); - check_for_missing_semicolon ($4); } + check_for_missing_semicolon ($$.t); } | ENUM identifier '{' '}' - { $$.t = finish_enum (start_enum ($2), NULL_TREE); + { $$.t = finish_enum (start_enum ($2)); $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM '{' { $2 = suspend_momentary (); - $$ = start_enum (make_anon_name ()); } + $$ = current_enum_type; + current_enum_type = start_enum (make_anon_name ()); } enumlist maybecomma_warn '}' - { $$.t = finish_enum ($3, $4); + { TYPE_VALUES (current_enum_type) = $4; + $$.t = finish_enum (current_enum_type); + $$.new_type_flag = 1; + current_enum_type = $3; resume_momentary ((int) $1); - check_for_missing_semicolon ($3); - $$.new_type_flag = 1; } + check_for_missing_semicolon ($$.t); } | ENUM '{' '}' - { $$.t = finish_enum (start_enum (make_anon_name()), NULL_TREE); + { $$.t = finish_enum (start_enum (make_anon_name())); $$.new_type_flag = 1; check_for_missing_semicolon ($$.t); } | ENUM identifier - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | ENUM complex_type_name - { $$.t = xref_tag (enum_type_node, $2, NULL_TREE, 1); + { $$.t = xref_tag (enum_type_node, $2, 1); $$.new_type_flag = 0; } | TYPENAME_KEYWORD typename_sub { $$.t = $2; - $$.new_type_flag = 0; } + $$.new_type_flag = 0; + if (!processing_template_decl) + cp_pedwarn ("using `typename' outside of template"); } /* C++ extensions, merged with C to avoid shift/reduce conflicts */ - | class_head left_curly + | class_head '{' + { $1.t = begin_class_definition ($1.t); } opt.component_decl_list '}' maybe_attribute { int semi; @@ -2077,25 +2150,32 @@ structsp: yychar = YYLEX; semi = yychar == ';'; - $$ = finish_class_definition ($1, $3, $5, semi); + $$ = finish_class_definition ($1.t, $6, semi, + $1.new_type_flag); } pending_defargs - { finish_default_args (); } + { + begin_inline_definitions (); + } pending_inlines - { $$.t = $6; + { + finish_inline_definitions (); + $$.t = $7; $$.new_type_flag = 1; - begin_inline_definitions (); } + } | class_head %prec EMPTY { + if ($1.new_type_flag) + pop_scope (CP_DECL_CONTEXT (TYPE_MAIN_DECL ($1.t))); $$.new_type_flag = 0; - if (TYPE_BINFO ($1) == NULL_TREE) + if (TYPE_BINFO ($1.t) == NULL_TREE) { - cp_error ("%T is not a class type", $1); + cp_error ("%T is not a class type", $1.t); $$.t = error_mark_node; } else { - $$.t = $1; + $$.t = $1.t; /* struct B: public A; is not accepted by the WP grammar. */ if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t) && ! TYPE_BEING_DEFINED ($$.t)) @@ -2133,7 +2213,10 @@ aggr: named_class_head_sans_basetype: aggr identifier - { current_aggr = $$; $$ = $2; } + { + current_aggr = $1; + $$ = $2; + } ; named_class_head_sans_basetype_defn: @@ -2149,75 +2232,98 @@ named_complex_class_head_sans_basetype: aggr nested_name_specifier identifier { current_aggr = $1; - $$ = handle_class_head ($1, $2, $3); + $$.t = handle_class_head ($1, $2, $3); + $$.new_type_flag = 1; } | aggr global_scope nested_name_specifier identifier { current_aggr = $1; - $$ = handle_class_head ($1, $3, $4); + $$.t = handle_class_head ($1, $3, $4); + $$.new_type_flag = 1; } | aggr global_scope identifier { current_aggr = $1; - $$ = handle_class_head ($1, NULL_TREE, $3); + $$.t = handle_class_head ($1, NULL_TREE, $3); + $$.new_type_flag = 1; + } + | aggr apparent_template_type + { + current_aggr = $1; + $$.t = $2; + $$.new_type_flag = 0; + } + | aggr nested_name_specifier apparent_template_type + { + current_aggr = $1; + $$.t = $3; + if (CP_DECL_CONTEXT ($$.t)) + push_scope (CP_DECL_CONTEXT ($$.t)); + $$.new_type_flag = 1; } - | aggr template_type - { current_aggr = $$; $$ = $2; } - | aggr nested_name_specifier template_type - { current_aggr = $$; $$ = $3; } - ; - -do_xref_defn: - /* empty */ %prec EMPTY - { $$ = xref_tag (current_aggr, $0, NULL_TREE, 0); } ; named_class_head: named_class_head_sans_basetype %prec EMPTY - { $$ = xref_tag (current_aggr, $1, NULL_TREE, 1); } - | named_class_head_sans_basetype_defn do_xref_defn + { + $$.t = xref_tag (current_aggr, $1, 1); + $$.new_type_flag = 0; + } + | named_class_head_sans_basetype_defn + { $$ = xref_tag (current_aggr, $1, 0); } + /* Class name is unqualified, so we look for base classes + in the current scope. */ maybe_base_class_list %prec EMPTY { - $$ = $2; + $$.t = $2; + $$.new_type_flag = 0; if ($3) xref_basetypes (current_aggr, $1, $2, $3); } - | named_complex_class_head_sans_basetype maybe_base_class_list + | named_complex_class_head_sans_basetype + maybe_base_class_list { - $$ = TREE_TYPE ($1); - if (TREE_INT_CST_LOW (current_aggr) == union_type - && TREE_CODE ($$) != UNION_TYPE) - cp_pedwarn ("`union' tag used in declaring `%#T'", $$); - else if (TREE_CODE ($$) == UNION_TYPE - && TREE_INT_CST_LOW (current_aggr) != union_type) - cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$); - if ($2) + if ($1.t != error_mark_node) { - if (IS_AGGR_TYPE ($$) && CLASSTYPE_USE_TEMPLATE ($$)) - { - if (CLASSTYPE_IMPLICIT_INSTANTIATION ($$) - && TYPE_SIZE ($$) == NULL_TREE) - { - SET_CLASSTYPE_TEMPLATE_SPECIALIZATION ($$); - if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL ($$)); - } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION ($$)) - cp_error ("specialization after instantiation of `%T'", $$); + $$.t = TREE_TYPE ($1.t); + $$.new_type_flag = $1.new_type_flag; + if (current_aggr == union_type_node + && TREE_CODE ($$.t) != UNION_TYPE) + cp_pedwarn ("`union' tag used in declaring `%#T'", + $$.t); + else if (TREE_CODE ($$.t) == UNION_TYPE + && current_aggr != union_type_node) + cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$); + else if (TREE_CODE ($$.t) == RECORD_TYPE) + /* We might be specializing a template with a different + class-key; deal. */ + CLASSTYPE_DECLARED_CLASS ($$.t) + = (current_aggr == class_type_node); + if ($2) + { + maybe_process_partial_specialization ($$.t); + xref_basetypes (current_aggr, $1.t, $$.t, $2); } - xref_basetypes (current_aggr, $1, $$, $2); } } ; unnamed_class_head: aggr '{' - { $$ = xref_tag ($$, make_anon_name (), NULL_TREE, 0); + { $$ = xref_tag ($$, make_anon_name (), 0); yyungetc ('{', 1); } ; +/* The tree output of this nonterminal a declarationf or the type + named. If NEW_TYPE_FLAG is set, then the name used in this + class-head was explicitly qualified, e.g.: `struct X::Y'. We have + already called push_scope for X. */ class_head: unnamed_class_head + { + $$.t = $1; + $$.new_type_flag = 0; + } | named_class_head ; @@ -2238,76 +2344,18 @@ base_class_list: base_class: base_class.1 - { - tree type; - if ($1 == NULL_TREE) - { - error ("invalid base class"); - type = error_mark_node; - } - else - type = TREE_TYPE ($1); - if (! is_aggr_type (type, 1)) - $$ = NULL_TREE; - else if (current_aggr == signature_type_node - && (! type) && (! IS_SIGNATURE (type))) - { - error ("class name not allowed as base signature"); - $$ = NULL_TREE; - } - else if (current_aggr == signature_type_node) - { - sorry ("signature inheritance, base type `%s' ignored", - IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, type); - } - else if (type && IS_SIGNATURE (type)) - { - error ("signature name not allowed as base class"); - $$ = NULL_TREE; - } - else - $$ = build_tree_list (access_default_node, type); - } + { $$ = finish_base_specifier (access_default_node, $1, + current_aggr + == signature_type_node); } | base_class_access_list see_typename base_class.1 - { - tree type; - if ($3 == NULL_TREE) - { - error ("invalid base class"); - type = error_mark_node; - } - else - type = TREE_TYPE ($3); - if (current_aggr == signature_type_node) - error ("access and source specifiers not allowed in signature"); - if (! is_aggr_type (type, 1)) - $$ = NULL_TREE; - else if (current_aggr == signature_type_node - && (! type) && (! IS_SIGNATURE (type))) - { - error ("class name not allowed as base signature"); - $$ = NULL_TREE; - } - else if (current_aggr == signature_type_node) - { - sorry ("signature inheritance, base type `%s' ignored", - IDENTIFIER_POINTER ($$)); - $$ = build_tree_list (access_public_node, type); - } - else if (type && IS_SIGNATURE (type)) - { - error ("signature name not allowed as base class"); - $$ = NULL_TREE; - } - else - $$ = build_tree_list ($$, type); - } + { $$ = finish_base_specifier ($1, $3, + current_aggr + == signature_type_node); } ; base_class.1: typename_sub - { $$ = TYPE_MAIN_DECL ($1); } + { if ($$ != error_mark_node) $$ = TYPE_MAIN_DECL ($1); } | nonnested_type | SIGOF '(' expr ')' { @@ -2384,71 +2432,40 @@ base_class_access_list: } ; -left_curly: - '{' - { $0 = begin_class_definition ($0); } - ; - -self_reference: - /* empty */ - { - $$ = build_self_reference (); - } - ; - opt.component_decl_list: - self_reference - { if ($$) $$ = build_tree_list (access_public_node, $$); } - | self_reference component_decl_list - { - if (current_aggr == signature_type_node) - $$ = build_tree_list (access_public_node, $2); - else - $$ = build_tree_list (access_default_node, $2); - if ($1) $$ = tree_cons (access_public_node, $1, $$); - } - | opt.component_decl_list VISSPEC ':' component_decl_list - { - tree visspec = $2; + | component_decl_list + | opt.component_decl_list access_specifier component_decl_list + | opt.component_decl_list access_specifier + ; +access_specifier: + VISSPEC ':' + { if (current_aggr == signature_type_node) { error ("access specifier not allowed in signature"); - visspec = access_public_node; + $1 = access_public_node; } - $$ = chainon ($$, build_tree_list (visspec, $4)); - } - | opt.component_decl_list VISSPEC ':' - { - if (current_aggr == signature_type_node) - error ("access specifier not allowed in signature"); - } + + current_access_specifier = $1; + } ; /* Note: we no longer warn about the semicolon after a component_decl_list. ARM $9.2 says that the semicolon is optional, and therefore allowed. */ component_decl_list: component_decl - { if ($$ == void_type_node) $$ = NULL_TREE; + { + finish_member_declaration ($1); } | component_decl_list component_decl - { /* In pushdecl, we created a reverse list of names - in this binding level. Make sure that the chain - of what we're trying to add isn't the item itself - (which can happen with what pushdecl's doing). */ - if ($2 != NULL_TREE && $2 != void_type_node) - { - if (TREE_CHAIN ($2) != $$) - $$ = chainon ($$, $2); - else - $$ = $2; - } + { + finish_member_declaration ($2); } ; component_decl: component_decl_1 ';' - { } | component_decl_1 '}' { error ("missing ';' before right brace"); yyungetc ('}', 0); } @@ -2458,7 +2475,7 @@ component_decl: { $$ = finish_method ($$); } | fn.def2 TRY /* base_init compstmt */ { $$ = finish_method ($$); } - | fn.def2 RETURN /* base_init compstmt */ + | fn.def2 RETURN_KEYWORD /* base_init compstmt */ { $$ = finish_method ($$); } | fn.def2 '{' /* nodecls compstmt */ { $$ = finish_method ($$); } @@ -2468,9 +2485,20 @@ component_decl: { $$ = $2; pedantic = $1; } | template_header component_decl - { $$ = finish_member_template_decl ($1, $2); } + { + if ($2) + $$ = finish_member_template_decl ($2); + else + /* The component was already processed. */ + $$ = NULL_TREE; + + finish_template_decl ($1); + } | template_header typed_declspecs ';' - { $$ = finish_member_class_template ($1, $2.t); } + { + $$ = finish_member_class_template ($2.t); + finish_template_decl ($1); + } ; component_decl_1: @@ -2478,9 +2506,32 @@ component_decl_1: speed; we need to call grok_x_components for enums, so the speedup would be insignificant. */ typed_declspecs components - { $$ = grok_x_components ($1.t, $2); } + { + /* Most of the productions for component_decl only + allow the creation of one new member, so we call + finish_member_declaration in component_decl_list. + For this rule and the next, however, there can be + more than one member, e.g.: + + int i, j; + + and we need the first member to be fully + registered before the second is processed. + Therefore, the rules for components take care of + this processing. To avoid registering the + components more than once, we send NULL_TREE up + here; that lets finish_member_declaration know + that there is nothing to do. */ + if (!$2) + grok_x_components ($1.t); + $$ = NULL_TREE; + } | declmods notype_components - { $$ = grok_x_components ($1, $2); } + { + if (!$2) + grok_x_components ($1); + $$ = NULL_TREE; + } | notype_declarator maybeasm maybe_attribute maybe_init { $$ = grokfield ($$, NULL_TREE, $4, $2, build_tree_list ($3, NULL_TREE)); } @@ -2515,31 +2566,41 @@ component_decl_1: /* ??? Huh? ^^^ */ components: /* empty: possibly anonymous */ - { $$ = NULL_TREE; } + { $$ = 0; } | component_declarator0 + { + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $1 = finish_member_template_decl ($1); + finish_member_declaration ($1); + $$ = 1; + } | components ',' component_declarator - { - /* In this context, void_type_node encodes - friends. They have been recorded elsewhere. */ - if ($$ == void_type_node) - $$ = $3; - else - $$ = chainon ($$, $3); + { + check_multiple_declarators (); + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $3 = finish_member_template_decl ($3); + finish_member_declaration ($3); + $$ = 2; } ; notype_components: /* empty: possibly anonymous */ - { $$ = NULL_TREE; } + { $$ = 0; } | notype_component_declarator0 + { + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $1 = finish_member_template_decl ($1); + finish_member_declaration ($1); + $$ = 1; + } | notype_components ',' notype_component_declarator - { - /* In this context, void_type_node encodes - friends. They have been recorded elsewhere. */ - if ($$ == void_type_node) - $$ = $3; - else - $$ = chainon ($$, $3); + { + check_multiple_declarators (); + if (PROCESSING_REAL_TEMPLATE_DECL_P ()) + $3 = finish_member_template_decl ($3); + finish_member_declaration ($3); + $$ = 2; } ; @@ -2628,9 +2689,9 @@ enumlist: enumerator: identifier - { $$ = build_enumerator ($$, NULL_TREE); } + { $$ = build_enumerator ($$, NULL_TREE, current_enum_type); } | identifier '=' expr_no_commas - { $$ = build_enumerator ($$, $3); } + { $$ = build_enumerator ($$, $3, current_enum_type); } ; /* ANSI new-type-id (5.3.4) */ @@ -2664,10 +2725,10 @@ cv_qualifiers: nonempty_cv_qualifiers: CV_QUALIFIER - { $$.t = IDENTIFIER_AS_LIST ($1); + { $$.t = hash_tree_cons (NULL_TREE, $1, NULL_TREE); $$.new_type_flag = 0; } | nonempty_cv_qualifiers CV_QUALIFIER - { $$.t = decl_tree_cons (NULL_TREE, $2, $1.t); + { $$.t = hash_tree_cons (NULL_TREE, $2, $1.t); $$.new_type_flag = $1.new_type_flag; } ; @@ -2697,37 +2758,57 @@ maybe_parmlist: ; /* A declarator that is allowed only after an explicit typespec. */ + +after_type_declarator_intern: + after_type_declarator + | attributes after_type_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + /* may all be followed by prec '.' */ after_type_declarator: - '*' nonempty_cv_qualifiers after_type_declarator %prec UNARY + '*' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers after_type_declarator %prec UNARY + | '&' nonempty_cv_qualifiers after_type_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } - | '*' after_type_declarator %prec UNARY + | '*' after_type_declarator_intern %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' after_type_declarator %prec UNARY + | '&' after_type_declarator_intern %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers after_type_declarator + | ptr_to_mem cv_qualifiers after_type_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } | direct_after_type_declarator ; +direct_after_type_declarator: + direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' + { $$ = make_call_declarator ($$, $2, $3, $4); } + | direct_after_type_declarator '[' nonmomentary_expr ']' + { $$ = build_parse_node (ARRAY_REF, $$, $3); } + | direct_after_type_declarator '[' ']' + { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } + | '(' after_type_declarator_intern ')' + { $$ = $2; } + | nested_name_specifier type_name %prec EMPTY + { push_nested_class ($1, 3); + $$ = build_parse_node (SCOPE_REF, $$, $2); + TREE_COMPLEXITY ($$) = current_class_depth; } + | type_name %prec EMPTY + ; + nonnested_type: type_name %prec EMPTY { if (TREE_CODE ($1) == IDENTIFIER_NODE) { $$ = lookup_name ($1, 1); - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - { - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - pushdecl_class_level ($$); - } + maybe_note_name_used_in_class ($1, $$); } else $$ = $1; @@ -2754,35 +2835,29 @@ nested_type: { $$ = get_type_decl ($2); } ; -direct_after_type_declarator: - direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | direct_after_type_declarator '[' nonmomentary_expr ']' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_after_type_declarator '[' ']' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | '(' after_type_declarator ')' - { $$ = $2; } - | nested_name_specifier type_name %prec EMPTY - { push_nested_class ($1, 3); - $$ = build_parse_node (SCOPE_REF, $$, $2); - TREE_COMPLEXITY ($$) = current_class_depth; } - | type_name %prec EMPTY - ; - /* A declarator allowed whether or not there has been an explicit typespec. These cannot redeclare a typedef-name. */ +notype_declarator_intern: + notype_declarator + | attributes notype_declarator + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator %prec UNARY + '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY + | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } - | '*' notype_declarator %prec UNARY + | '*' notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' notype_declarator %prec UNARY + | '&' notype_declarator_intern %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator + | ptr_to_mem cv_qualifiers notype_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } @@ -2790,15 +2865,15 @@ notype_declarator: ; complex_notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator %prec UNARY + '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator %prec UNARY + | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY { $$ = make_reference_declarator ($2.t, $3); } | '*' complex_notype_declarator %prec UNARY { $$ = make_pointer_declarator (NULL_TREE, $2); } | '&' complex_notype_declarator %prec UNARY { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator + | ptr_to_mem cv_qualifiers notype_declarator_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } @@ -2815,25 +2890,11 @@ complex_direct_notype_declarator: | direct_notype_declarator '[' ']' { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } | notype_qualified_id - { if (TREE_CODE (OP0 ($1)) == NAMESPACE_DECL) - { - push_decl_namespace (OP0 ($1)); - TREE_COMPLEXITY ($1) = -1; - } - else if (OP0 ($1) != current_class_type) - { - push_nested_class (OP0 ($1), 3); - TREE_COMPLEXITY ($1) = current_class_depth; - } - } + { enter_scope_of ($1); } | nested_name_specifier notype_template_declarator { got_scope = NULL_TREE; $$ = build_parse_node (SCOPE_REF, $1, $2); - if ($1 != current_class_type) - { - push_nested_class ($1, 3); - TREE_COMPLEXITY ($$) = current_class_depth; - } + enter_scope_of ($$); } ; @@ -2864,12 +2925,11 @@ overqualified_id: functional_cast: typespec '(' nonnull_exprlist ')' { $$ = build_functional_cast ($1.t, $3); } - | typespec '(' expr_or_declarator ')' + | typespec '(' expr_or_declarator_intern ')' { $$ = reparse_decl_as_expr ($1.t, $3); } | typespec fcast_or_absdcl %prec EMPTY { $$ = reparse_absdcl_as_expr ($1.t, $2); } ; - type_name: TYPENAME | SELFNAME @@ -2892,14 +2952,10 @@ nested_name_specifier_1: if (TREE_CODE ($1) == IDENTIFIER_NODE) { $$ = lastiddecl; - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - pushdecl_class_level ($$); + maybe_note_name_used_in_class ($1, $$); } - got_scope = $$ = TYPE_MAIN_VARIANT (TREE_TYPE ($$)); + got_scope = $$ = + complete_type (TYPE_MAIN_VARIANT (TREE_TYPE ($$))); } | SELFNAME SCOPE { @@ -3073,19 +3129,29 @@ direct_new_declarator: { $$ = build_parse_node (ARRAY_REF, $$, $3); } ; +absdcl_intern: + absdcl + | attributes absdcl + { + /* Provide support for '(' attributes '*' declarator ')' + etc */ + $$ = decl_tree_cons ($1, $2, NULL_TREE); + } + ; + /* ANSI abstract-declarator (8.1) */ absdcl: - '*' nonempty_cv_qualifiers absdcl + '*' nonempty_cv_qualifiers absdcl_intern { $$ = make_pointer_declarator ($2.t, $3); } - | '*' absdcl + | '*' absdcl_intern { $$ = make_pointer_declarator (NULL_TREE, $2); } | '*' nonempty_cv_qualifiers %prec EMPTY { $$ = make_pointer_declarator ($2.t, NULL_TREE); } | '*' %prec EMPTY { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); } - | '&' nonempty_cv_qualifiers absdcl + | '&' nonempty_cv_qualifiers absdcl_intern { $$ = make_reference_declarator ($2.t, $3); } - | '&' absdcl + | '&' absdcl_intern { $$ = make_reference_declarator (NULL_TREE, $2); } | '&' nonempty_cv_qualifiers %prec EMPTY { $$ = make_reference_declarator ($2.t, NULL_TREE); } @@ -3095,7 +3161,7 @@ absdcl: { tree arg = make_pointer_declarator ($2, NULL_TREE); $$ = build_parse_node (SCOPE_REF, $1, arg); } - | ptr_to_mem cv_qualifiers absdcl + | ptr_to_mem cv_qualifiers absdcl_intern { tree arg = make_pointer_declarator ($2, $3); $$ = build_parse_node (SCOPE_REF, $1, arg); } @@ -3104,7 +3170,7 @@ absdcl: /* ANSI direct-abstract-declarator (8.1) */ direct_abstract_declarator: - '(' absdcl ')' + '(' absdcl_intern ')' { $$ = $2; } /* `(typedef)1' is `int'. */ | PAREN_STAR_PAREN @@ -3270,9 +3336,9 @@ simple_stmt: { finish_break_stmt (); } | CONTINUE ';' { finish_continue_stmt (); } - | RETURN ';' + | RETURN_KEYWORD ';' { finish_return_stmt (NULL_TREE); } - | RETURN expr ';' + | RETURN_KEYWORD expr ';' { finish_return_stmt ($2); } | asm_keyword maybe_cv_qualifier '(' string ')' ';' { @@ -3324,14 +3390,13 @@ function_try_block: } ctor_initializer_opt compstmt { + end_protect_partials (); expand_start_all_catch (); } handler_seq { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); expand_end_all_catch (); - finish_function (lineno, (int)$3, nested); + $$ = $3; } ; @@ -3561,7 +3626,8 @@ named_parm: { $$.t = build_tree_list ($1.t, $2); $$.new_type_flag = $1.new_type_flag; } | typespec declarator - { $$.t = build_tree_list (get_decl_list ($1.t), $2); + { $$.t = build_tree_list (build_decl_list (NULL_TREE, $1.t), + $2); $$.new_type_flag = $1.new_type_flag; } | typed_declspecs1 absdcl { tree specs = strip_attrs ($1.t); diff --git a/contrib/gcc/cp/pt.c b/contrib/gcc/cp/pt.c index 556b761..47fa99a 100644 --- a/contrib/gcc/cp/pt.c +++ b/contrib/gcc/cp/pt.c @@ -1,5 +1,5 @@ /* Handle parameterized types (templates) for GNU C++. - Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. + Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc. Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. Rewritten by Jason Merrill (jason@cygnus.com). @@ -39,6 +39,8 @@ Boston, MA 02111-1307, USA. */ #include "defaults.h" #include "except.h" #include "toplev.h" +#include "rtl.h" +#include "varray.h" /* The type of functions taking a tree, and some additional data, and returning an int. */ @@ -48,15 +50,21 @@ extern struct obstack permanent_obstack; extern int lineno; extern char *input_filename; -struct pending_inline *pending_template_expansions; tree current_template_parms; HOST_WIDE_INT processing_template_decl; -tree pending_templates; +/* 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 a either a DECL + (for a function or static data member), or a TYPE (for a class) + indicating what we are hoping to instantiate. */ +static tree pending_templates; static tree *template_tail = &pending_templates; -tree maybe_templates; +static tree maybe_templates; static tree *maybe_template_tail = &maybe_templates; int minimal_parse_mode; @@ -67,6 +75,8 @@ int processing_template_parmlist; static int template_header_count; static tree saved_trees; +static varray_type inline_parm_levels; +static size_t inline_parm_levels_used; #define obstack_chunk_alloc xmalloc #define obstack_chunk_free free @@ -75,35 +85,47 @@ static tree saved_trees; #define UNIFY_ALLOW_MORE_CV_QUAL 1 #define UNIFY_ALLOW_LESS_CV_QUAL 2 #define UNIFY_ALLOW_DERIVED 4 - -static int unify PROTO((tree, tree, tree, tree, int, int*)); +#define UNIFY_ALLOW_INTEGER 8 + +#define GTB_VIA_VIRTUAL 1 /* The base class we are examining is + virtual, or a base class of a virtual + base. */ +#define GTB_IGNORE_TYPE 2 /* We don't need to try to unify the current + type with the desired type. */ + +static int resolve_overloaded_unification PROTO((tree, tree, tree, tree, + unification_kind_t, int)); +static int try_one_overload PROTO((tree, tree, tree, tree, tree, + unification_kind_t, int)); +static int unify PROTO((tree, tree, tree, tree, int)); static void add_pending_template PROTO((tree)); static int push_tinst_level PROTO((tree)); static tree classtype_mangled_name PROTO((tree)); -static char *mangle_class_name_for_template PROTO((char *, tree, tree, tree)); +static char *mangle_class_name_for_template PROTO((char *, tree, tree)); static tree tsubst_expr_values PROTO((tree, tree)); static int list_eq PROTO((tree, tree)); -static tree get_class_bindings PROTO((tree, tree, tree, tree)); +static tree get_class_bindings PROTO((tree, tree, tree)); static tree coerce_template_parms PROTO((tree, tree, tree, int, int)); -static tree tsubst_enum PROTO((tree, tree, tree *)); +static void tsubst_enum PROTO((tree, tree, tree)); static tree add_to_template_args PROTO((tree, tree)); +static tree add_outermost_template_args PROTO((tree, tree)); static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*, tree*)); static int type_unification_real PROTO((tree, tree, tree, tree, - int, unification_kind_t, int, int*)); -static tree complete_template_args PROTO((tree, tree, int)); + int, unification_kind_t, int)); static void note_template_header PROTO((int)); static tree maybe_fold_nontype_arg PROTO((tree)); static tree convert_nontype_argument PROTO((tree, tree)); +static tree convert_template_argument PROTO ((tree, tree, tree, int, + int , tree)); static tree get_bindings_overload PROTO((tree, tree, tree)); static int for_each_template_parm PROTO((tree, tree_fn_t, void*)); static tree build_template_parm_index PROTO((int, int, int, tree, tree)); -static tree original_template PROTO((tree)); static int inline_needs_template_parms PROTO((tree)); static void push_inline_template_parms_recursive PROTO((tree, int)); static tree retrieve_specialization PROTO((tree, tree)); -static void register_specialization PROTO((tree, tree, tree)); -static void print_candidates PROTO((tree)); +static tree register_specialization PROTO((tree, tree, tree)); +static int unregister_specialization PROTO((tree, tree)); static tree reduce_template_parm_level PROTO((tree, tree, int)); static tree build_template_decl PROTO((tree, tree)); static int mark_template_parm PROTO((tree, void *)); @@ -113,35 +135,108 @@ static tree get_bindings_real PROTO((tree, tree, tree, int)); static int template_decl_level PROTO((tree)); static tree maybe_get_template_decl_from_type_decl PROTO((tree)); static int check_cv_quals_for_unify PROTO((int, tree, tree)); -static tree tsubst_template_arg_vector PROTO((tree, tree)); +static tree tsubst_template_arg_vector PROTO((tree, tree, int)); +static tree tsubst_template_parms PROTO((tree, tree, int)); static void regenerate_decl_from_template PROTO((tree, tree)); -static int is_member_template_class PROTO((tree)); - -/* Nonzero if ARGVEC contains multiple levels of template arguments. */ -#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 \ +static tree most_specialized PROTO((tree, tree, tree)); +static tree most_specialized_class PROTO((tree, tree)); +static tree most_general_template PROTO((tree)); +static void set_mangled_name_for_template_decl PROTO((tree)); +static int template_class_depth_real PROTO((tree, int)); +static tree tsubst_aggr_type PROTO((tree, tree, int, tree, int)); +static tree tsubst_decl PROTO((tree, tree, tree, tree)); +static tree tsubst_arg_types PROTO((tree, tree, int, tree)); +static tree tsubst_function_type PROTO((tree, tree, int, tree)); +static void check_specialization_scope PROTO((void)); +static tree process_partial_specialization PROTO((tree)); +static void set_current_access_from_decl PROTO((tree)); +static void check_default_tmpl_args PROTO((tree, tree, int, int)); +static tree tsubst_call_declarator_parms PROTO((tree, tree, int, tree)); +static tree get_template_base_recursive PROTO((tree, tree, + tree, tree, tree, int)); +static tree get_template_base PROTO((tree, tree, tree, tree)); +static tree try_class_unification PROTO((tree, tree, tree, tree)); +static int coerce_template_template_parms PROTO((tree, tree, int, + tree, tree)); +static tree determine_specialization PROTO((tree, tree, tree *, int)); +static int template_args_equal PROTO((tree, tree)); +static void print_template_context PROTO((int)); + +/* We use TREE_VECs to hold template arguments. If there is only one + level of template arguments, then the TREE_VEC contains the + arguments directly. If there is more than one level of template + arguments, then each entry in the TREE_VEC is itself a TREE_VEC, + containing the template arguments for a single level. The first + entry in the outer TREE_VEC is the outermost level of template + parameters; the last is the innermost. + + It is incorrect to ever form a template argument vector containing + only one level of arguments, but which is a TREE_VEC containing as + its only entry the TREE_VEC for that level. */ + +/* Non-zero 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 \ && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) +/* The depth of a template argument vector. When called directly by + the parser, we use a TREE_LIST rather than a TREE_VEC to represent + template arguments. In fact, we may even see NULL_TREE if there + are no template arguments. In both of those cases, there is only + one level of template arguments. */ +#define TMPL_ARGS_DEPTH(NODE) \ + (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) + +/* The LEVELth level of the template ARGS. Note that template + parameter levels are indexed from 1, not from 0. */ +#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ + (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ + ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS) + +/* Set the LEVELth level of the template ARGS to VAL. This macro does + not work with single-level argument vectors. */ +#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \ + (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL)) + +/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */ +#define TMPL_ARG(ARGS, LEVEL, IDX) \ + (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX)) + +/* Set the IDXth element in the LEVELth level of ARGS to VAL. This + macro does not work with single-level argument vectors. */ +#define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL) \ + (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL)) + +/* 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))) + +/* The number of levels of template parameters given by NODE. */ +#define TMPL_PARMS_DEPTH(NODE) \ + (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE))) + /* 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. */ tree -finish_member_template_decl (template_parameters, decl) - tree template_parameters; +finish_member_template_decl (decl) tree decl; { - if (template_parameters) - end_template_decl (); - else - end_specialization (); - 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) { /* Assume that the class is the only declspec. */ @@ -167,7 +262,6 @@ finish_member_template_decl (template_parameters, decl) } else cp_error ("invalid member template declaration `%D'", decl); - return error_mark_node; } @@ -182,37 +276,59 @@ finish_member_template_decl (template_parameters, decl) struct B {}; }; - A::B has depth two, while A has depth one. Also, - both A::B and A::B have depth one. */ + A::B has depth two, while A has depth one. + Both A::B and A::B have depth one, if + COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not + specializations. -int -template_class_depth (type) + This function is guaranteed to return 0 if passed NULL_TREE so + that, for example, `template_class_depth (current_class_type)' is + always safe. */ + +static int +template_class_depth_real (type, count_specializations) tree type; + int count_specializations; { int depth; for (depth = 0; - type && TREE_CODE (type) != FUNCTION_DECL - && TREE_CODE (type) != NAMESPACE_DECL; - type = TYPE_CONTEXT (type)) - if (CLASSTYPE_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) - && uses_template_parms (CLASSTYPE_TI_ARGS (type))) - ++depth; + type && TREE_CODE (type) != NAMESPACE_DECL; + type = (TREE_CODE (type) == FUNCTION_DECL) + ? DECL_REAL_CONTEXT (type) : TYPE_CONTEXT (type)) + { + if (TREE_CODE (type) != FUNCTION_DECL) + { + if (CLASSTYPE_TEMPLATE_INFO (type) + && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) + && ((count_specializations + && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) + || uses_template_parms (CLASSTYPE_TI_ARGS (type)))) + ++depth; + } + else + { + if (DECL_TEMPLATE_INFO (type) + && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) + && ((count_specializations + && DECL_TEMPLATE_SPECIALIZATION (type)) + || uses_template_parms (DECL_TI_ARGS (type)))) + ++depth; + } + } return depth; } -/* Return the original template for this decl, disregarding any - specializations. */ +/* Returns the template nesting level of the indicated class TYPE. + Like template_class_depth_real, but instantiations do not count in + the depth. */ -static tree -original_template (decl) - tree decl; +int +template_class_depth (type) + tree type; { - while (DECL_TEMPLATE_INFO (decl)) - decl = DECL_TI_TEMPLATE (decl); - return decl; + return template_class_depth_real (type, /*count_specializations=*/0); } /* Returns 1 if processing DECL as part of do_pending_inlines @@ -225,7 +341,7 @@ inline_needs_template_parms (decl) if (! DECL_TEMPLATE_INFO (decl)) return 0; - return (list_length (DECL_TEMPLATE_PARMS (original_template (decl))) + return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl))) > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl))); } @@ -266,10 +382,15 @@ push_inline_template_parms_recursive (parmlist, levels) case PARM_DECL: { - /* Make a CONST_DECL as is done in process_template_parm. */ + /* Make a CONST_DECL as is done in process_template_parm. + It is ugly that we recreate this here; the original + version built in process_template_parm is no longer + available. */ tree decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); + SET_DECL_ARTIFICIAL (decl); DECL_INITIAL (decl) = DECL_INITIAL (parm); + DECL_TEMPLATE_PARM_P (decl) = 1; pushdecl (decl); } break; @@ -288,35 +409,46 @@ maybe_begin_member_template_processing (decl) tree decl; { tree parms; - int levels; - - if (! inline_needs_template_parms (decl)) - return; + int levels = 0; - parms = DECL_TEMPLATE_PARMS (original_template (decl)); + if (inline_needs_template_parms (decl)) + { + parms = DECL_TEMPLATE_PARMS (most_general_template (decl)); + levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl; - levels = list_length (parms) - processing_template_decl; + if (DECL_TEMPLATE_SPECIALIZATION (decl)) + { + --levels; + parms = TREE_CHAIN (parms); + } - if (DECL_TEMPLATE_SPECIALIZATION (decl)) - { - --levels; - parms = TREE_CHAIN (parms); + push_inline_template_parms_recursive (parms, levels); } - push_inline_template_parms_recursive (parms, levels); + /* Remember how many levels of template parameters we pushed so that + we can pop them later. */ + if (!inline_parm_levels) + VARRAY_INT_INIT (inline_parm_levels, 4, "inline_parm_levels"); + if (inline_parm_levels_used == inline_parm_levels->num_elements) + VARRAY_GROW (inline_parm_levels, 2 * inline_parm_levels_used); + VARRAY_INT (inline_parm_levels, inline_parm_levels_used) = levels; + ++inline_parm_levels_used; } /* Undo the effects of begin_member_template_processing. */ void -maybe_end_member_template_processing (decl) - tree decl; +maybe_end_member_template_processing () { - if (! processing_template_decl) + int i; + + if (!inline_parm_levels_used) return; - while (current_template_parms - && TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) + --inline_parm_levels_used; + for (i = 0; + i < VARRAY_INT (inline_parm_levels, inline_parm_levels_used); + ++i) { --processing_template_decl; current_template_parms = TREE_CHAIN (current_template_parms); @@ -336,14 +468,14 @@ maybe_end_member_template_processing (decl) template class C { template void f(U); } then neither C::f nor C::f is considered - to be a member template. */ + to be a member template. But, `template void + C::f(U)' is considered a member template. */ int is_member_template (t) tree t; { - if (TREE_CODE (t) != FUNCTION_DECL - && !DECL_FUNCTION_TEMPLATE_P (t)) + if (!DECL_FUNCTION_TEMPLATE_P (t)) /* Anything that isn't a function or a template function is certainly not a member template. */ return 0; @@ -352,33 +484,15 @@ is_member_template (t) if (hack_decl_function_context (t)) return 0; - if ((DECL_FUNCTION_MEMBER_P (t) - && !DECL_TEMPLATE_SPECIALIZATION (t)) - || (TREE_CODE (t) == TEMPLATE_DECL - && DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)))) - { - tree tmpl; - - if (DECL_FUNCTION_TEMPLATE_P (t)) - tmpl = t; - else if (DECL_TEMPLATE_INFO (t) - && DECL_FUNCTION_TEMPLATE_P (DECL_TI_TEMPLATE (t))) - tmpl = DECL_TI_TEMPLATE (t); - else - tmpl = NULL_TREE; - - if (tmpl + return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)) /* If there are more levels of template parameters than there are template classes surrounding the declaration, then we have a member template. */ - && (list_length (DECL_TEMPLATE_PARMS (tmpl)) > - template_class_depth (DECL_CLASS_CONTEXT (t)))) - return 1; - } - - return 0; + && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > + template_class_depth (DECL_CLASS_CONTEXT (t)))); } +#if 0 /* UNUSED */ /* Returns non-zero iff T is a member template class. See is_member_template for a description of what precisely constitutes a member template. */ @@ -400,146 +514,69 @@ is_member_template_class (t) /* If there are more levels of template parameters than there are template classes surrounding the declaration, then we have a member template. */ - return (list_length (DECL_TEMPLATE_PARMS (t)) > + return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > template_class_depth (DECL_CONTEXT (t))); } +#endif -/* Return a new template argument vector which contains all of ARGS - for all outer templates TMPL is contained in, but has as its - innermost set of arguments the EXTRA_ARGS. If UNBOUND_ONLY, we - are only interested in unbound template arguments, not arguments from - enclosing templates that have been instantiated already. */ +/* Return a new template argument vector which contains all of ARGS, + but has as its innermost set of arguments the EXTRA_ARGS. The + resulting vector will be built on a temporary obstack, and so must + be explicitly copied to the permanent obstack, if required. */ static tree -complete_template_args (tmpl, extra_args, unbound_only) - tree tmpl, extra_args; - int unbound_only; +add_to_template_args (args, extra_args) + tree args; + tree extra_args; { - /* depth is the number of levels of enclosing args we're adding. */ - int depth, i; - tree args, new_args, spec_args = NULL_TREE; - int extra_arg_depth; - - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); - my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0); - - if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (extra_args)) - extra_arg_depth = TREE_VEC_LENGTH (extra_args); - else - extra_arg_depth = 1; - - if (DECL_TEMPLATE_INFO (tmpl) && !unbound_only) - { - /* A specialization of a member template of a template class shows up - as a TEMPLATE_DECL with DECL_TEMPLATE_SPECIALIZATION set. - DECL_TI_ARGS is the specialization args, and DECL_TI_TEMPLATE - is the template being specialized. */ - if (DECL_TEMPLATE_SPECIALIZATION (tmpl)) - { - spec_args = DECL_TI_ARGS (tmpl); - tmpl = DECL_TI_TEMPLATE (tmpl); - } - - if (DECL_TEMPLATE_INFO (tmpl)) - { - /* A partial instantiation of a member template shows up as a - TEMPLATE_DECL with DECL_TEMPLATE_INFO. DECL_TI_ARGS is - all the bound template arguments. */ - args = DECL_TI_ARGS (tmpl); - if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) - depth = 1; - else - depth = TREE_VEC_LENGTH (args); - } - else - /* If we are a specialization, we might have no previously bound - template args. */ - depth = 0; - - new_args = make_tree_vec (depth + extra_arg_depth + (!!spec_args)); - - if (depth == 1) - TREE_VEC_ELT (new_args, 0) = args; - else - for (i = 0; i < depth; ++i) - TREE_VEC_ELT (new_args, i) = TREE_VEC_ELT (args, i); - } - else - { - tree type; - int skip; - - /* For unbound args, we have to do more work. We are getting bindings - for the innermost args from extra_args, so we start from our - context and work out until we've seen all the args. We need to - do it this way to handle partial specialization. */ - - depth = list_length (DECL_TEMPLATE_PARMS (tmpl)) - 1; - if (depth == 0) - return extra_args; - - new_args = make_tree_vec (depth + extra_arg_depth); - - /* If this isn't a member template, extra_args is for the innermost - template class, so skip over it. */ - skip = (! is_member_template (tmpl)); - - if (depth > skip) - { - type = DECL_REAL_CONTEXT (tmpl); - for (i = depth; i; type = TYPE_CONTEXT (type)) - if (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type))) - { - if (skip) - skip = 0; - else - { - --i; - TREE_VEC_ELT (new_args, i) = CLASSTYPE_TI_ARGS (type); - } - } - } - } + tree new_args; + int extra_depth; + int i; + int j; - if (extra_arg_depth == 1) - TREE_VEC_ELT (new_args, depth++) = extra_args; - else - for (i = 0; i < extra_arg_depth; ++i) - TREE_VEC_ELT (new_args, depth++) = TREE_VEC_ELT (extra_args, i); + extra_depth = TMPL_ARGS_DEPTH (extra_args); + new_args = make_temp_vec (TMPL_ARGS_DEPTH (args) + extra_depth); - if (spec_args) - TREE_VEC_ELT (new_args, depth) = spec_args; + for (i = 1; i <= TMPL_ARGS_DEPTH (args); ++i) + SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (args, i)); + for (j = 1; j <= extra_depth; ++j, ++i) + SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (extra_args, j)); + return new_args; } -/* Return a new template argument vector which contains all of ARGS, - but has as its innermost set of arguments the EXTRA_ARGS. */ +/* Like add_to_template_args, but only the outermost ARGS are added to + the EXTRA_ARGS. In particular, all but TMPL_ARGS_DEPTH + (EXTRA_ARGS) levels are added. This function is used to combine + the template arguments from a partial instantiation with the + template arguments used to attain the full instantiation from the + partial instantiation. */ static tree -add_to_template_args (args, extra_args) +add_outermost_template_args (args, extra_args) tree args; tree extra_args; { tree new_args; - if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) - { - new_args = make_tree_vec (2); - TREE_VEC_ELT (new_args, 0) = args; - } - else - { - int i; + /* If there are more levels of EXTRA_ARGS than there are ARGS, + something very fishy is going on. */ + my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args), + 0); - new_args = make_tree_vec (TREE_VEC_LENGTH (args) + 1); + /* If *all* the new arguments will be the EXTRA_ARGS, just return + them. */ + if (TMPL_ARGS_DEPTH (args) == TMPL_ARGS_DEPTH (extra_args)) + return extra_args; - for (i = 0; i < TREE_VEC_LENGTH (args); ++i) - TREE_VEC_ELT (new_args, i) = TREE_VEC_ELT (args, i); - } - - TREE_VEC_ELT (new_args, - TREE_VEC_LENGTH (new_args) - 1) = extra_args; + /* For the moment, we make ARGS look like it contains fewer levels. */ + TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH (extra_args); + + new_args = add_to_template_args (args, extra_args); + + /* Now, we restore ARGS to its full dimensions. */ + TREE_VEC_LENGTH (args) += TMPL_ARGS_DEPTH (extra_args); return new_args; } @@ -571,12 +608,46 @@ begin_template_parm_list () note_template_header (0); } +/* This routine is called when a specialization is declared. If it is + illegal to declare a specialization here, an error is reported. */ + +static void +check_specialization_scope () +{ + tree scope = current_scope (); + + /* [temp.expl.spec] + + An explicit specialization shall be declared in the namespace of + which the template is a member, or, for member templates, in the + namespace of which the enclosing class or enclosing class + template is a member. An explicit specialization of a member + function, member class or static data member of a class template + shall be declared in the namespace of which the class template + is a member. */ + if (scope && TREE_CODE (scope) != NAMESPACE_DECL) + cp_error ("explicit specialization in non-namespace scope `%D'", + scope); + + /* [temp.expl.spec] + + In an explicit specialization declaration for a member of a class + template or a member template that appears in namespace scope, + the member template and some of its enclosing class templates may + remain unspecialized, except that the declaration shall not + explicitly specialize a class member template if its enclosing + class templates are not explicitly specialized as well. */ + if (current_template_parms) + cp_error ("enclosing class templates are not explicitly specialized"); +} + /* We've just seen template <>. */ void begin_specialization () { note_template_header (1); + check_specialization_scope (); } /* Called at then end of processing a declaration preceeded by @@ -625,6 +696,36 @@ end_explicit_instantiation () --processing_explicit_instantiation; } +/* 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; +{ + if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type)) + { + if (CLASSTYPE_IMPLICIT_INSTANTIATION (type) + && TYPE_SIZE (type) == NULL_TREE) + { + if (current_namespace + != decl_namespace_context (CLASSTYPE_TI_TEMPLATE (type))) + { + cp_pedwarn ("specializing `%#T' in different namespace", type); + cp_pedwarn_at (" from definition of `%#D'", + CLASSTYPE_TI_TEMPLATE (type)); + } + SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); + if (processing_template_decl) + push_template_decl (TYPE_MAIN_DECL (type)); + } + else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) + cp_error ("specialization of `%T' after instantiation", type); + } + else if (processing_specialization) + cp_error ("explicit specialization of non-template `%T'", type); +} + /* Retrieve the specialization (in the sense of [temp.spec] - a specialization is either an instantiation or an explicit specialization) of TMPL for the given template ARGS. If there is @@ -641,6 +742,12 @@ retrieve_specialization (tmpl, args) my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); + /* There should be as many levels of arguments as there are + levels of parameters. */ + my_friendly_assert (TMPL_ARGS_DEPTH (args) + == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), + 0); + for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); s != NULL_TREE; s = TREE_CHAIN (s)) @@ -675,8 +782,8 @@ is_specialization_of (decl, tmpl) t != NULL_TREE; t = CLASSTYPE_USE_TEMPLATE (t) ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE) - if (comptypes (TYPE_MAIN_VARIANT (t), - TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)), 1)) + if (same_type_p (TYPE_MAIN_VARIANT (t), + TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)))) return 1; } @@ -684,9 +791,10 @@ is_specialization_of (decl, tmpl) } /* Register the specialization SPEC as a specialization of TMPL with - the indicated ARGS. */ + the indicated ARGS. Returns SPEC, or an equivalent prior + declaration, if available. */ -static void +static tree register_specialization (spec, tmpl, args) tree spec; tree tmpl; @@ -696,14 +804,27 @@ register_specialization (spec, tmpl, args) my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); - if (TREE_CODE (spec) != TEMPLATE_DECL - && list_length (DECL_TEMPLATE_PARMS (tmpl)) > 1) - /* Avoid registering function declarations as - specializations of member templates, as would otherwise - happen with out-of-class specializations of member - templates. */ - return; + if (TREE_CODE (spec) == FUNCTION_DECL + && uses_template_parms (DECL_TI_ARGS (spec))) + /* This is the FUNCTION_DECL for a partial instantiation. Don't + register it; we want the corresponding TEMPLATE_DECL instead. + We use `uses_template_parms (DECL_TI_ARGS (spec))' rather than + the more obvious `uses_template_parms (spec)' to avoid problems + with default function arguments. In particular, given + something like this: + + template void f(T t1, T t = T()) + + 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) + == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), + 0); + for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); s != NULL_TREE; s = TREE_CHAIN (s)) @@ -720,7 +841,7 @@ register_specialization (spec, tmpl, args) { cp_error ("specialization of %D after instantiation", fn); - return; + return spec; } else { @@ -729,68 +850,117 @@ register_specialization (spec, tmpl, args) the second is an explicit specialization, and the implicit instantiation has not yet been used. That situation can occur if we have - implicitly instantiated a member function of - class type, and then specialized it later. */ - TREE_VALUE (s) = spec; - return; + implicitly instantiated a member function and + then specialized it later. + + We can also wind up here if a friend + declaration that looked like an instantiation + turns out to be a specialization: + + template void foo(T); + class S { friend void foo<>(int) }; + template <> void foo(int); + + We transform the existing DECL in place so that + any pointers to it become pointers to the + updated declaration. + + If there was a definition for the template, but + not for the specialization, we want this to + look as if there is no definition, and vice + versa. */ + DECL_INITIAL (fn) = NULL_TREE; + duplicate_decls (spec, fn); + + return fn; } } else if (DECL_TEMPLATE_SPECIALIZATION (fn)) { - if (DECL_INITIAL (fn)) - cp_error ("duplicate specialization of %D", fn); - - TREE_VALUE (s) = spec; - return; + duplicate_decls (spec, fn); + return fn; } } } DECL_TEMPLATE_SPECIALIZATIONS (tmpl) = perm_tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); + + return spec; +} + +/* Unregister the specialization SPEC as a specialization of TMPL. + Returns nonzero if the SPEC was listed as a specialization of + TMPL. */ + +static int +unregister_specialization (spec, tmpl) + tree spec; + tree tmpl; +{ + tree* s; + + for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); + *s != NULL_TREE; + s = &TREE_CHAIN (*s)) + if (TREE_VALUE (*s) == spec) + { + *s = TREE_CHAIN (*s); + return 1; + } + + return 0; } /* Print the list of candidate FNS in an error message. */ -static void +void print_candidates (fns) tree fns; { tree fn; - char* str = "candidates are:"; + const char *str = "candidates are:"; for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn)) { - cp_error_at ("%s %+#D", str, TREE_VALUE (fn)); + tree f; + + for (f = TREE_VALUE (fn); f; f = OVL_NEXT (f)) + cp_error_at ("%s %+#D", str, OVL_CURRENT (f)); str = " "; } } /* Returns the template (one of the functions given by TEMPLATE_ID) which can be specialized to match the indicated DECL with the - explicit template args given in TEMPLATE_ID. If - NEED_MEMBER_TEMPLATE is true the function is a specialization of a - member template. The template args (those explicitly specified and - those deduced) are output in a newly created vector *TARGS_OUT. If - it is impossible to determine the result, an error message is - issued, unless COMPLAIN is 0. The DECL may be NULL_TREE if none is - available. */ + explicit template args given in TEMPLATE_ID. The DECL may be + NULL_TREE if none is available. In that case, the functions in + TEMPLATE_ID are non-members. -tree + If NEED_MEMBER_TEMPLATE is non-zero the function is known to be a + specialization of a member template. + + The template args (those explicitly specified and those deduced) + are output in a newly created vector *TARGS_OUT. + + If it is impossible to determine the result, an error message is + issued. The error_mark_node is returned to indicate failure. */ + +static tree determine_specialization (template_id, decl, targs_out, - need_member_template, - complain) + need_member_template) tree template_id; tree decl; tree* targs_out; int need_member_template; - int complain; { - tree fns, targs_in; - tree templates = NULL_TREE; tree fn; - int i; + tree fns; + tree targs; + tree explicit_targs; + tree candidates = NULL_TREE; + tree templates = NULL_TREE; *targs_out = NULL_TREE; @@ -798,7 +968,7 @@ determine_specialization (template_id, decl, targs_out, return error_mark_node; fns = TREE_OPERAND (template_id, 0); - targs_in = TREE_OPERAND (template_id, 1); + explicit_targs = TREE_OPERAND (template_id, 1); if (fns == error_mark_node) return error_mark_node; @@ -812,86 +982,146 @@ determine_specialization (template_id, decl, targs_out, tree tmpl; fn = OVL_CURRENT (fns); - if (!need_member_template - && TREE_CODE (fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (fn) - && DECL_USE_TEMPLATE (fn) - && DECL_TI_TEMPLATE (fn)) - /* We can get here when processing something like: - template class X { void f(); } - template <> void X::f() {} - We're specializing a member function, but not a member - template. */ - tmpl = DECL_TI_TEMPLATE (fn); - else if (TREE_CODE (fn) != TEMPLATE_DECL - || (need_member_template && !is_member_template (fn))) + + if (TREE_CODE (fn) == TEMPLATE_DECL) + /* DECL might be a specialization of FN. */ + tmpl = fn; + else if (need_member_template) + /* FN is an ordinary member function, and we need a + specialization of a member template. */ + continue; + else if (TREE_CODE (fn) != FUNCTION_DECL) + /* We can get IDENTIFIER_NODEs here in certain erroneous + cases. */ + continue; + else if (!DECL_FUNCTION_MEMBER_P (fn)) + /* This is just an ordinary non-member function. Nothing can + be a specialization of that. */ continue; else - tmpl = fn; + { + tree decl_arg_types; - if (list_length (targs_in) > DECL_NTPARMS (tmpl)) - continue; + /* This is an ordinary member function. However, since + we're here, we can assume it's enclosing class is a + template class. For example, + + template struct S { void f(); }; + template <> void S::f() {} - if (decl == NULL_TREE) - { - tree targs = make_scratch_vec (DECL_NTPARMS (tmpl)); - - /* We allow incomplete unification here, because we are going to - check all the functions. */ - i = type_unification (DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - targs, - NULL_TREE, - NULL_TREE, - targs_in, - DEDUCE_EXACT, 1); - - if (i == 0) - /* Unification was successful. */ - templates = scratch_tree_cons (targs, tmpl, templates); + Here, S::f is a non-template, but S is a + template class. If FN has the same type as DECL, we + might be in business. */ + if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)), + TREE_TYPE (TREE_TYPE (fn)))) + /* The return types differ. */ + continue; + + /* Adjust the type of DECL in case FN is a static member. */ + decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); + if (DECL_STATIC_FUNCTION_P (fn) + && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + decl_arg_types = TREE_CHAIN (decl_arg_types); + + if (compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), + decl_arg_types)) + /* They match! */ + candidates = tree_cons (NULL_TREE, fn, candidates); + + continue; } - else - templates = scratch_tree_cons (NULL_TREE, tmpl, templates); - } - - if (decl != NULL_TREE) - { - tree tmpl = most_specialized (templates, decl, targs_in); - if (tmpl == error_mark_node) - goto ambiguous; - else if (tmpl == NULL_TREE) - goto no_match; + /* See whether this function might be a specialization of this + template. */ + targs = get_bindings (tmpl, decl, explicit_targs); + + if (!targs) + /* We cannot deduce template arguments that when used to + specialize TMPL will produce DECL. */ + continue; - *targs_out = get_bindings (tmpl, decl, targs_in); - return tmpl; + /* Save this template, and the arguments deduced. */ + templates = scratch_tree_cons (targs, tmpl, templates); } - if (templates == NULL_TREE) + if (templates && TREE_CHAIN (templates)) { - no_match: - if (complain) - { - cp_error_at ("template-id `%D' for `%+D' does not match any template declaration", - template_id, decl); - return error_mark_node; - } - return NULL_TREE; + /* We have: + + [temp.expl.spec] + + It is possible for a specialization with a given function + signature to be instantiated from more than one function + template. In such cases, explicit specification of the + template arguments must be used to uniquely identify the + function template specialization being specialized. + + Note that here, there's no suggestion that we're supposed to + determine which of the candidate templates is most + specialized. However, we, also have: + + [temp.func.order] + + Partial ordering of overloaded function template + declarations is used in the following contexts to select + the function template to which a function template + specialization refers: + + -- when an explicit specialization refers to a function + template. + + So, we do use the partial ordering rules, at least for now. + This extension can only serve to make illegal programs legal, + so it's safe. And, there is strong anecdotal evidence that + the committee intended the partial ordering rules to apply; + the EDG front-end has that behavior, and John Spicer claims + that the committee simply forgot to delete the wording in + [temp.expl.spec]. */ + tree tmpl = most_specialized (templates, decl, explicit_targs); + if (tmpl && tmpl != error_mark_node) + { + targs = get_bindings (tmpl, decl, explicit_targs); + templates = scratch_tree_cons (targs, tmpl, NULL_TREE); + } + } + + if (templates == NULL_TREE && candidates == NULL_TREE) + { + cp_error_at ("template-id `%D' for `%+D' does not match any template declaration", + template_id, decl); + return error_mark_node; } - else if (TREE_CHAIN (templates) != NULL_TREE) + else if ((templates && TREE_CHAIN (templates)) + || (candidates && TREE_CHAIN (candidates)) + || (templates && candidates)) { - ambiguous: - if (complain) - { - cp_error_at ("ambiguous template specialization `%D' for `%+D'", - template_id, decl); - print_candidates (templates); - return error_mark_node; - } - return NULL_TREE; + cp_error_at ("ambiguous template specialization `%D' for `%+D'", + template_id, decl); + chainon (candidates, templates); + print_candidates (candidates); + return error_mark_node; } /* We have one, and exactly one, match. */ - *targs_out = TREE_PURPOSE (templates); + if (candidates) + { + /* It was a specialization of an ordinary member function in a + template class. */ + *targs_out = copy_node (DECL_TI_ARGS (TREE_VALUE (candidates))); + return DECL_TI_TEMPLATE (TREE_VALUE (candidates)); + } + + /* It was a specialization of a template. */ + targs = DECL_TI_ARGS (DECL_RESULT (TREE_VALUE (templates))); + if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs)) + { + *targs_out = copy_node (targs); + SET_TMPL_ARGS_LEVEL (*targs_out, + TMPL_ARGS_DEPTH (*targs_out), + TREE_PURPOSE (templates)); + } + else + *targs_out = TREE_PURPOSE (templates); return TREE_VALUE (templates); } @@ -901,19 +1131,14 @@ determine_specialization (template_id, decl, targs_out, instantiation at this point. Returns DECL, or an equivalent declaration that should be used - instead. + instead if all goes well. Issues an error message if something is + amiss. Returns error_mark_node if the error is not easily + recoverable. FLAGS is a bitmask consisting of the following flags: - 1: We are being called by finish_struct. (We are unable to - determine what template is specialized by an in-class - declaration until the class definition is complete, so - finish_struct_methods calls this function again later to finish - the job.) 2: The function has a definition. 4: The function is a friend. - 8: The function is known to be a specialization of a member - template. The TEMPLATE_COUNT is the number of references to qualifying template classes that appeared in the name of the function. For @@ -927,8 +1152,7 @@ determine_specialization (template_id, decl, targs_out, template struct S {}; template <> struct S { void f(); } - template <> - void S::f(); + template <> void S::f(); the TEMPLATE_COUNT would be 0. (Note that this declaration is illegal; there should be no template <>.) @@ -945,113 +1169,117 @@ check_explicit_specialization (declarator, decl, template_count, flags) int template_count; int flags; { - int finish_member = flags & 1; int have_def = flags & 2; int is_friend = flags & 4; int specialization = 0; int explicit_instantiation = 0; - int member_specialization = flags & 8; + int member_specialization = 0; tree ctype = DECL_CLASS_CONTEXT (decl); tree dname = DECL_NAME (decl); - if (!finish_member) + if (processing_specialization) { - if (processing_specialization) - { - /* The last template header was of the form template <>. */ + /* The last template header was of the form template <>. */ - if (template_header_count > template_count) - { - /* There were more template headers than qualifying template - classes. */ - if (template_header_count - template_count > 1) - /* There shouldn't be that many template parameter - lists. There can be at most one parameter list for - every qualifying class, plus one for the function - itself. */ - cp_error ("too many template parameter lists in declaration of `%D'", decl); - - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - if (ctype) - member_specialization = 1; - else - specialization = 1; - } - else if (template_header_count == template_count) - { - /* The counts are equal. So, this might be a - specialization, but it is not a specialization of a - member template. It might be something like - - template struct S { - void f(int i); - }; - template <> - void S::f(int i) {} */ - specialization = 1; - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - } - else - { - /* This cannot be an explicit specialization. There are not - enough headers for all of the qualifying classes. For - example, we might have: - - template <> - void S::T::f(); + if (template_header_count > template_count) + { + /* There were more template headers than qualifying template + classes. */ + if (template_header_count - template_count > 1) + /* There shouldn't be that many template parameter lists. + There can be at most one parameter list for every + qualifying class, plus one for the function itself. */ + cp_error ("too many template parameter lists in declaration of `%D'", decl); - But, we're missing another template <>. */ - cp_error("too few template parameter lists in declaration of `%D'", decl); - return decl; - } + SET_DECL_TEMPLATE_SPECIALIZATION (decl); + if (ctype) + member_specialization = 1; + else + specialization = 1; } - else if (processing_explicit_instantiation) + else if (template_header_count == template_count) { - if (template_header_count) - cp_error ("template parameter list used in explicit instantiation"); - - if (have_def) - cp_error ("definition provided for explicit instantiation"); - - explicit_instantiation = 1; + /* The counts are equal. So, this might be a + specialization, but it is not a specialization of a + member template. It might be something like + + template struct S { + void f(int i); + }; + template <> + void S::f(int i) {} */ + specialization = 1; + SET_DECL_TEMPLATE_SPECIALIZATION (decl); } - else if (ctype != NULL_TREE - && !TYPE_BEING_DEFINED (ctype) - && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) + else { - /* This case catches outdated code that looks like this: + /* This cannot be an explicit specialization. There are not + enough headers for all of the qualifying classes. For + example, we might have: + + template <> + void S::T::f(); + + But, we're missing another template <>. */ + cp_error("too few template parameter lists in declaration of `%D'", decl); + return decl; + } + } + else if (processing_explicit_instantiation) + { + if (template_header_count) + cp_error ("template parameter list used in explicit instantiation"); + + if (have_def) + cp_error ("definition provided for explicit instantiation"); + + explicit_instantiation = 1; + } + else if (ctype != NULL_TREE + && !TYPE_BEING_DEFINED (ctype) + && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype) + && !is_friend) + { + /* This case catches outdated code that looks like this: - template struct S { void f(); }; - void S::f() {} // Missing template <> + template struct S { void f(); }; + void S::f() {} // Missing template <> - We disable this check when the type is being defined to - avoid complaining about default compiler-generated - constructors, destructors, and assignment operators. - Since the type is an instantiation, not a specialization, - these are the only functions that can be defined before - the class is complete. */ + We disable this check when the type is being defined to + avoid complaining about default compiler-generated + constructors, destructors, and assignment operators. + Since the type is an instantiation, not a specialization, + these are the only functions that can be defined before + the class is complete. */ /* If they said template void S::f() {} that's bogus. */ - if (template_header_count) - { - cp_error ("template parameters specified in specialization"); - return decl; - } - - if (pedantic) - cp_pedwarn - ("explicit specialization not preceded by `template <>'"); - specialization = 1; - SET_DECL_TEMPLATE_SPECIALIZATION (decl); + if (template_header_count) + { + cp_error ("template parameters specified in specialization"); + return decl; } - else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) + + if (pedantic) + cp_pedwarn + ("explicit specialization not preceded by `template <>'"); + specialization = 1; + SET_DECL_TEMPLATE_SPECIALIZATION (decl); + } + else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) + { + if (is_friend) + /* This could be something like: + + template void f(T); + class S { friend void f<>(int); } */ + specialization = 1; + else { - /* This case handles bogus declarations like - template <> template - void f(); */ + /* This case handles bogus declarations like template <> + template void f(); */ cp_error ("template-id `%D' in declaration of primary template", declarator); @@ -1069,6 +1297,8 @@ check_explicit_specialization (declarator, decl, template_count, flags) ("default argument specified in explicit specialization"); break; } + if (current_lang_name == lang_name_c) + cp_error ("template specialization with C linkage"); } if (specialization || member_specialization || explicit_instantiation) @@ -1095,47 +1325,41 @@ check_explicit_specialization (declarator, decl, template_count, flags) if (declarator == error_mark_node) return error_mark_node; - 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; - } - if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype)) { if (!explicit_instantiation) - { - /* Since finish_struct_1 has not been called yet, we - can't call lookup_fnfields. We note that this - template is a specialization, and proceed, letting - finish_struct fix this up later. */ - tree ti = perm_tree_cons (NULL_TREE, - TREE_OPERAND (declarator, 1), - NULL_TREE); - TI_PENDING_SPECIALIZATION_FLAG (ti) = 1; - DECL_TEMPLATE_INFO (decl) = ti; - } + /* A specialization in class scope. This is illegal, + but the error will already have been flagged by + check_specialization_scope. */ + return error_mark_node; else - /* It's not legal to write an explicit instantiation in - class scope, e.g.: + { + /* It's not legal to write an explicit instantiation in + class scope, e.g.: - class C { template void f(); } + class C { template void f(); } - This case is caught by the parser. However, on - something like: + This case is caught by the parser. However, on + something like: - template class C { void f(); }; + template class C { void f(); }; - (which is illegal) we can get here. The error will be - issued later. */ - ; + (which is illegal) we can get here. The error will be + issued later. */ + ; + } 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)) @@ -1143,8 +1367,9 @@ check_explicit_specialization (declarator, decl, template_count, flags) /* Find the list of functions in ctype that have the same name as the declared function. */ tree name = TREE_OPERAND (declarator, 0); - tree fns; - + tree fns = NULL_TREE; + int idx; + if (name == constructor_name (ctype) || name == constructor_name_full (ctype)) { @@ -1162,21 +1387,51 @@ check_explicit_specialization (declarator, decl, template_count, flags) Similar language is found in [temp.explicit]. */ cp_error ("specialization of implicitly-declared special member function"); - - return decl; + return error_mark_node; } name = is_constructor ? ctor_identifier : dtor_identifier; } - fns = lookup_fnfields (TYPE_BINFO (ctype), name, 1); - + if (!IDENTIFIER_TYPENAME_P (name)) + { + idx = lookup_fnfields_1 (ctype, name); + if (idx >= 0) + fns = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (ctype), idx); + } + else + { + tree methods; + + /* For a type-conversion operator, we cannot do a + name-based lookup. We might be looking for `operator + int' which will be a specialization of `operator T'. + So, we find *all* the conversion operators, and then + select from them. */ + fns = NULL_TREE; + + methods = CLASSTYPE_METHOD_VEC (ctype); + if (methods) + for (idx = 2; idx < TREE_VEC_LENGTH (methods); ++idx) + { + tree ovl = TREE_VEC_ELT (methods, idx); + + if (!ovl || !DECL_CONV_FN_P (OVL_CURRENT (ovl))) + /* There are no more conversion functions. */ + break; + + /* Glue all these conversion functions together + with those we already have. */ + for (; ovl; ovl = OVL_NEXT (ovl)) + fns = ovl_cons (OVL_CURRENT (ovl), fns); + } + } + if (fns == NULL_TREE) { - cp_error ("no member function `%s' declared in `%T'", - IDENTIFIER_POINTER (name), - ctype); - return decl; + cp_error ("no member function `%D' declared in `%T'", + name, ctype); + return error_mark_node; } else TREE_OPERAND (declarator, 0) = fns; @@ -1186,100 +1441,141 @@ check_explicit_specialization (declarator, decl, template_count, flags) Note that for an explicit instantiation, even one for a member function, we cannot tell apriori whether the instantiation is for a member template, or just a member - function of a template class. In particular, even in if the - instantiation is for a member template, the template - arguments could be deduced from the declaration. */ + function of a template class. Even if a member template is + being instantiated, the member template arguments may be + elided if they can be deduced from the rest of the + declaration. */ tmpl = determine_specialization (declarator, decl, &targs, - member_specialization, - 1); + member_specialization); - if (tmpl && tmpl != error_mark_node) + if (!tmpl || tmpl == error_mark_node) + /* We couldn't figure out what this declaration was + specializing. */ + return error_mark_node; + else { + tree gen_tmpl = most_general_template (tmpl); + if (explicit_instantiation) { + /* We don't set DECL_EXPLICIT_INSTANTIATION here; that + is done by do_decl_instantiation later. */ + + int arg_depth = TMPL_ARGS_DEPTH (targs); + int parm_depth = TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)); + + if (arg_depth > parm_depth) + { + /* If TMPL is not the most general template (for + example, if TMPL is a friend template that is + injected into namespace scope), then there will + be too many levels fo TARGS. Remove some of them + here. */ + int i; + tree new_targs; + + new_targs = make_temp_vec (parm_depth); + for (i = arg_depth - parm_depth; i < arg_depth; ++i) + TREE_VEC_ELT (new_targs, i - (arg_depth - parm_depth)) + = TREE_VEC_ELT (targs, i); + targs = new_targs; + } + decl = instantiate_template (tmpl, targs); - if (!DECL_TEMPLATE_SPECIALIZATION (decl)) - /* There doesn't seem to be anything in the draft to - prevent a specialization from being explicitly - instantiated. We're careful not to destroy the - information indicating that this is a - specialization here. */ - SET_DECL_EXPLICIT_INSTANTIATION (decl); return decl; } - else if (DECL_STATIC_FUNCTION_P (tmpl) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) + + /* If we though 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. */ + if (DECL_STATIC_FUNCTION_P (tmpl) + && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) { revert_static_member_fn (&decl, 0, 0); last_function_parms = TREE_CHAIN (last_function_parms); } + /* Set up the DECL_TEMPLATE_INFO for DECL. */ + DECL_TEMPLATE_INFO (decl) + = perm_tree_cons (tmpl, targs, NULL_TREE); + /* Mangle the function name appropriately. Note that we do not mangle specializations of non-template member functions of template classes, e.g. with + template struct S { void f(); } + and given the specialization + template <> void S::f() {} + we do not mangle S::f() here. That's because it's just an ordinary member function and doesn't need special - treatment. */ + treatment. We do this here so that the ordinary, + non-template, name-mangling algorith will not be used + later. */ if ((is_member_template (tmpl) || ctype == NULL_TREE) && name_mangling_version >= 1) - { - tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (tmpl)); - - if (ctype - && TREE_CODE (TREE_TYPE (tmpl)) == FUNCTION_TYPE) - arg_types = - hash_tree_chain (build_pointer_type (ctype), - arg_types); - - DECL_ASSEMBLER_NAME (decl) - = build_template_decl_overload - (decl, arg_types, TREE_TYPE (TREE_TYPE (tmpl)), - DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - targs, ctype != NULL_TREE); - } + set_mangled_name_for_template_decl (decl); if (is_friend && !have_def) - { - /* This is not really a declaration of a specialization. - It's just the name of an instantiation. But, it's not - a request for an instantiation, either. */ - SET_DECL_IMPLICIT_INSTANTIATION (decl); - DECL_TEMPLATE_INFO (decl) - = perm_tree_cons (tmpl, targs, NULL_TREE); - return decl; - } + /* This is not really a declaration of a specialization. + It's just the name of an instantiation. But, it's not + a request for an instantiation, either. */ + SET_DECL_IMPLICIT_INSTANTIATION (decl); + + /* Register this specialization so that we can find it + again. */ + decl = register_specialization (decl, gen_tmpl, targs); + } + } + + return decl; +} + +/* TYPE is being declared. Verify that the use of template headers + and such is reasonable. Issue error messages if not. */ - /* If DECL_TI_TEMPLATE (decl), the decl is an - instantiation of a specialization of a member template. - (In other words, there was a member template, in a - class template. That member template was specialized. - We then instantiated the class, so there is now an - instance of that specialization.) +void +maybe_check_template_type (type) + tree type; +{ + if (template_header_count) + { + /* We are in the scope of some `template <...>' header. */ - According to the CD2, + int context_depth + = template_class_depth_real (TYPE_CONTEXT (type), + /*count_specializations=*/1); - 14.7.3.13 [tmpl.expl.spec] - - A specialization of a member function template or - member class template of a non-specialized class - template is itself a template. + if (template_header_count <= context_depth) + /* This is OK; the template headers are for the context. We + are actually too lenient here; like + check_explicit_specialization we should consider the number + of template types included in the actual declaration. For + example, - So, we just leave the template info alone in this case. */ - if (!(DECL_TEMPLATE_INFO (decl) && DECL_TI_TEMPLATE (decl))) - DECL_TEMPLATE_INFO (decl) - = perm_tree_cons (tmpl, targs, NULL_TREE); + template struct S { + template template + struct I {}; + }; - register_specialization (decl, tmpl, targs); + is illegal, but: - return decl; - } + template struct S { + template struct I; + }; + + template template ::I {}; + + is not. */ + ; + else if (template_header_count > context_depth + 1) + /* There are two many template parameter lists. */ + cp_error ("too many template parameter lists in declaration of `%T'", type); } - - return decl; } /* Returns 1 iff PARMS1 and PARMS2 are identical sets of template @@ -1320,8 +1616,7 @@ int comp_template_parms (parms1, parms2) if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM) continue; - else if (!comptypes (TREE_TYPE (parm1), - TREE_TYPE (parm2), 1)) + else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2))) return 0; } } @@ -1334,6 +1629,51 @@ int comp_template_parms (parms1, parms2) return 1; } +/* Complain if DECL shadows a template parameter. + + [temp.local]: A template-parameter shall not be redeclared within its + scope (including nested scopes). */ + +void +check_template_shadow (decl) + tree decl; +{ + tree olddecl; + + /* If we're not in a template, we can't possibly shadow a template + parameter. */ + if (!current_template_parms) + return; + + /* Figure out what we're shadowing. */ + if (TREE_CODE (decl) == OVERLOAD) + decl = OVL_CURRENT (decl); + olddecl = IDENTIFIER_VALUE (DECL_NAME (decl)); + + /* If there's no previous binding for this name, we're not shadowing + anything, let alone a template parameter. */ + if (!olddecl) + return; + + /* If we're not shadowing a template parameter, we're done. Note + that OLDDECL might be an OVERLOAD (or perhaps even an + ERROR_MARK), so we can't just blithely assume it to be a _DECL + node. */ + if (TREE_CODE_CLASS (TREE_CODE (olddecl)) != 'd' + || !DECL_TEMPLATE_PARM_P (olddecl)) + return; + + /* We check for decl != olddecl to avoid bogus errors for using a + name inside a class. We check TPFI to avoid duplicate errors for + inline member templates. */ + if (decl == olddecl + || TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) + return; + + cp_error_at ("declaration of `%#D'", decl); + cp_error_at (" shadows template parm `%#D'", olddecl); +} + /* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, ORIG_LEVEL, DECL, and TYPE. */ @@ -1428,6 +1768,13 @@ process_template_parm (list, next) /* is a const-param */ parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), PARM, 0, NULL_TREE); + + /* [temp.param] + + The top-level cv-qualifiers on the template-parameter are + ignored when determining its type. */ + TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); + /* A template parameter is not modifiable. */ TREE_READONLY (parm) = 1; if (IS_AGGR_TYPE (TREE_TYPE (parm)) @@ -1477,7 +1824,6 @@ process_template_parm (list, next) decl = build_decl (TYPE_DECL, parm, t); } - CLASSTYPE_GOT_SEMICOLON (t) = 1; TYPE_NAME (t) = decl; TYPE_STUB_DECL (t) = decl; parm = decl; @@ -1487,6 +1833,7 @@ process_template_parm (list, next) decl, TREE_TYPE (parm)); } SET_DECL_ARTIFICIAL (decl); + DECL_TEMPLATE_PARM_P (decl) = 1; pushdecl (decl); parm = build_tree_list (defval, parm); return chainon (list, parm); @@ -1535,26 +1882,34 @@ end_template_decl () (void) get_pending_sizes (); /* Why? */ } -/* Generate a valid set of template args from current_template_parms. */ +/* Given a template argument vector containing the template PARMS. + The innermost PARMS are given first. */ tree current_template_args () { - tree header = current_template_parms; - int length = list_length (header); - tree args = make_tree_vec (length); + tree header; + tree args = NULL_TREE; + int length = TMPL_PARMS_DEPTH (current_template_parms); int l = length; - while (header) + /* If there is only one level of template parameters, we do not + create a TREE_VEC of TREE_VECs. Instead, we return a single + TREE_VEC containing the arguments. */ + if (length > 1) + args = make_tree_vec (length); + + for (header = current_template_parms; header; header = TREE_CHAIN (header)) { tree a = copy_node (TREE_VALUE (header)); - int i = TREE_VEC_LENGTH (a); + int i; + TREE_TYPE (a) = NULL_TREE; - while (i--) + for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i) { tree t = TREE_VEC_ELT (a, i); - /* t will be a list if we are called from within a + /* T will be a list if we are called from within a begin/end_template_parm_list pair, but a vector directly if within a begin/end_member_template_processing pair. */ if (TREE_CODE (t) == TREE_LIST) @@ -1566,18 +1921,19 @@ current_template_args () t = TREE_TYPE (t); else t = DECL_INITIAL (t); + TREE_VEC_ELT (a, i) = t; } - - TREE_VEC_ELT (a, i) = t; } - TREE_VEC_ELT (args, --l) = a; - header = TREE_CHAIN (header); + + if (length > 1) + TREE_VEC_ELT (args, --l) = a; + else + args = a; } return args; } - /* Return a TEMPLATE_DECL corresponding to DECL, using the indicated template PARMS. Used by push_template_decl below. */ @@ -1592,8 +1948,8 @@ build_template_decl (decl, parms) if (DECL_LANG_SPECIFIC (decl)) { DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (tmpl) = - DECL_STATIC_FUNCTION_P (decl); + DECL_STATIC_FUNCTION_P (tmpl) = DECL_STATIC_FUNCTION_P (decl); + DECL_CONSTRUCTOR_P (tmpl) = DECL_CONSTRUCTOR_P (decl); } return tmpl; @@ -1601,8 +1957,23 @@ build_template_decl (decl, parms) struct template_parm_data { + /* The level of the template parameters we are currently + processing. */ int level; + + /* The index of the specialization argument we are currently + processing. */ + int current_arg; + + /* An array whose size is the number of template parameters. The + elements are non-zero if the parameter has been used in any one + of the arguments processed so far. */ int* parms; + + /* An array whose size is the number of template arguments. The + elements are non-zero if the argument makes use of template + parameters of this level. */ + int* arg_uses_template_parms; }; /* Subroutine of push_template_decl used to see if each template @@ -1632,13 +2003,296 @@ mark_template_parm (t, data) } if (level == tpd->level) - tpd->parms[idx] = 1; + { + tpd->parms[idx] = 1; + tpd->arg_uses_template_parms[tpd->current_arg] = 1; + } /* Return zero so that for_each_template_parm will continue the traversal of the tree; we want to mark *every* template parm. */ return 0; } +/* Process the partial specialization DECL. */ + +static tree +process_partial_specialization (decl) + tree decl; +{ + tree type = TREE_TYPE (decl); + tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); + tree specargs = CLASSTYPE_TI_ARGS (type); + tree inner_args = innermost_args (specargs); + tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); + tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); + int nargs = TREE_VEC_LENGTH (inner_args); + int ntparms = TREE_VEC_LENGTH (inner_parms); + int i; + int did_error_intro = 0; + struct template_parm_data tpd; + struct template_parm_data tpd2; + + /* We check that each of the template parameters given in the + partial specialization is used in the argument list to the + specialization. For example: + + template struct S; + template struct S; + + The second declaration is OK because `T*' uses the template + parameter T, whereas + + template struct S; + + is no good. Even trickier is: + + template + struct S1 + { + template + struct S2; + template + struct S2; + }; + + The S2 declaration is actually illegal; it is a + full-specialization. Of course, + + template + struct S2; + + or some such would have been OK. */ + tpd.level = TMPL_PARMS_DEPTH (current_template_parms); + tpd.parms = alloca (sizeof (int) * ntparms); + bzero ((PTR) tpd.parms, sizeof (int) * ntparms); + + tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs); + bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs); + for (i = 0; i < nargs; ++i) + { + tpd.current_arg = i; + for_each_template_parm (TREE_VEC_ELT (inner_args, i), + &mark_template_parm, + &tpd); + } + for (i = 0; i < ntparms; ++i) + if (tpd.parms[i] == 0) + { + /* One of the template parms was not used in the + specialization. */ + if (!did_error_intro) + { + cp_error ("template parameters not used in partial specialization:"); + did_error_intro = 1; + } + + cp_error (" `%D'", + TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); + } + + /* [temp.class.spec] + + The argument list of the specialization shall not be identical to + the implicit argument list of the primary template. */ + if (comp_template_args (inner_args, + innermost_args (CLASSTYPE_TI_ARGS (TREE_TYPE + (maintmpl))))) + cp_error ("partial specialization `%T' does not specialize any template arguments", type); + + /* [temp.class.spec] + + A partially specialized non-type argument expression shall not + involve template parameters of the partial specialization except + when the argument expression is a simple identifier. + + The type of a template parameter corresponding to a specialized + non-type argument shall not be dependent on a parameter of the + specialization. */ + my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0); + tpd2.parms = 0; + for (i = 0; i < nargs; ++i) + { + tree arg = TREE_VEC_ELT (inner_args, i); + if (/* These first two lines are the `non-type' bit. */ + TREE_CODE_CLASS (TREE_CODE (arg)) != 't' + && TREE_CODE (arg) != TEMPLATE_DECL + /* This next line is the `argument expression is not just a + simple identifier' condition and also the `specialized + non-type argument' bit. */ + && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) + { + if (tpd.arg_uses_template_parms[i]) + cp_error ("template argument `%E' involves template parameter(s)", arg); + else + { + /* Look at the corresponding template parameter, + marking which template parameters its type depends + upon. */ + tree type = + TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms, + i))); + + if (!tpd2.parms) + { + /* We haven't yet initialized TPD2. Do so now. */ + tpd2.arg_uses_template_parms + = (int*) 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.level = + TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); + } + + /* Mark the template parameters. But this time, we're + looking for the template parameters of the main + template, not in the specialization. */ + tpd2.current_arg = i; + tpd2.arg_uses_template_parms[i] = 0; + bzero ((PTR) tpd2.parms, sizeof (int) * nargs); + for_each_template_parm (type, + &mark_template_parm, + &tpd2); + + if (tpd2.arg_uses_template_parms [i]) + { + /* The type depended on some template parameters. + If they are fully specialized in the + specialization, that's OK. */ + int j; + for (j = 0; j < nargs; ++j) + if (tpd2.parms[j] != 0 + && tpd.arg_uses_template_parms [j]) + { + cp_error ("type `%T' of template argument `%E' depends on template parameter(s)", + type, + arg); + break; + } + } + } + } + } + + if (retrieve_specialization (maintmpl, specargs)) + /* We've already got this specialization. */ + return decl; + + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type) + = perm_tree_cons (inner_args, inner_parms, + DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); + TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; + return decl; +} + +/* Check that a template declaration's use of default arguments is not + invalid. Here, PARMS are the template parameters. IS_PRIMARY is + non-zero if DECL is the thing declared by a primary template. + IS_PARTIAL is non-zero 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; +{ + const char *msg; + int last_level_to_check; + + /* [temp.param] + + A default template-argument shall not be specified in a + function template declaration or a function template definition, nor + in the template-parameter-list of the definition of a member of a + class template. */ + + if (current_class_type + && !TYPE_BEING_DEFINED (current_class_type) + && DECL_LANG_SPECIFIC (decl) + /* If this is either a friend defined in the scope of the class + or a member function. */ + && DECL_CLASS_CONTEXT (decl) == current_class_type + /* And, if it was a member function, it really was defined in + the scope of the class. */ + && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_DEFINED_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 + that the class is complete. */ + return; + + if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) + /* For an ordinary class template, default template arguments are + allowed at the innermost level, e.g.: + template + struct S {}; + but, in a partial specialization, they're not allowed even + there, as we have in [temp.class.spec]: + + The template parameter list of a specialization shall not + contain default template argument values. + + So, for a partial specialization, or for a function template, + we look at all of them. */ + ; + else + /* But, for a primary class template that is not a partial + specialization we look at all template parameters except the + innermost ones. */ + parms = TREE_CHAIN (parms); + + /* Figure out what error message to issue. */ + if (TREE_CODE (decl) == FUNCTION_DECL) + msg = "default argument for template parameter in function template `%D'"; + else if (is_partial) + msg = "default argument in partial specialization `%D'"; + else + msg = "default argument for template parameter for class enclosing `%D'"; + + if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) + /* If we're inside a class definition, there's no need to + examine the parameters to the class itself. On the one + hand, they will be checked when the class is defined, and, + on the other, default arguments are legal in things like: + template + struct S { template void f(U); }; + Here the default argument for `S' has no bearing on the + declaration of `f'. */ + last_level_to_check = template_class_depth (current_class_type) + 1; + else + /* Check everything. */ + last_level_to_check = 0; + + for (; parms && TMPL_PARMS_DEPTH (parms) >= last_level_to_check; + parms = TREE_CHAIN (parms)) + { + tree inner_parms = TREE_VALUE (parms); + int i, ntparms; + + ntparms = TREE_VEC_LENGTH (inner_parms); + for (i = 0; i < ntparms; ++i) + if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) + { + if (msg) + { + cp_error (msg, decl); + msg = 0; + } + + /* Clear out the default argument so that we are not + confused later. */ + TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; + } + + /* At this point, if we're still interested in issuing messages, + they must apply to classes surrounding the object declared. */ + if (msg) + msg = "default argument for template parameter for class enclosing `%D'"; + } +} + /* Creates a TEMPLATE_DECL for the indicated DECL using the template parameters given by current_template_args, or reuses a previously existing one, if appropriate. Returns the DECL, or an @@ -1656,6 +2310,12 @@ push_template_decl_real (decl, is_friend) tree info; tree ctx; int primary; + int is_partial; + + /* See if this is a partial specialization. */ + is_partial = (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) + && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE + && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))); is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)); @@ -1682,12 +2342,11 @@ push_template_decl_real (decl, is_friend) /* For determining whether this is a primary template or not, we're really interested in the lexical context, not the true context. */ if (is_friend) - /* For a TYPE_DECL, there is no DECL_CLASS_CONTEXT. */ - info = TREE_CODE (decl) == FUNCTION_DECL - ? DECL_CLASS_CONTEXT (decl) : current_class_type; + info = current_class_type; else info = ctx; + /* See if this is a primary template. */ if (info && TREE_CODE (info) == FUNCTION_DECL) primary = 0; /* Note that template_class_depth returns 0 if given NULL_TREE, so @@ -1703,91 +2362,18 @@ push_template_decl_real (decl, is_friend) cp_error ("template with C linkage"); if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) cp_error ("template class without a name"); + if (TREE_CODE (decl) == TYPE_DECL + && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) + cp_error ("template declaration of `%#T'", TREE_TYPE (decl)); } - /* Partial specialization. */ - if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) - && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))) - { - tree type = TREE_TYPE (decl); - tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); - tree mainargs = CLASSTYPE_TI_ARGS (type); - tree spec = DECL_TEMPLATE_SPECIALIZATIONS (maintmpl); - - /* We check that each of the template parameters given in the - partial specialization is used in the argument list to the - specialization. For example: - - template struct S; - template struct S; - - The second declaration is OK because `T*' uses the template - parameter T, whereas - - template struct S; - - is no good. Even trickier is: - - template - struct S1 - { - template - struct S2; - template - struct S2; - }; - - The S2 declaration is actually illegal; it is a - full-specialization. Of course, - - template - struct S2; - - or some such would have been OK. */ - int i; - struct template_parm_data tpd; - int ntparms = TREE_VEC_LENGTH (TREE_VALUE (current_template_parms)); - int did_error_intro = 0; - - tpd.level = TREE_INT_CST_HIGH (TREE_PURPOSE (current_template_parms)); - tpd.parms = alloca (sizeof (int) * ntparms); - for (i = 0; i < ntparms; ++i) - tpd.parms[i] = 0; - for (i = 0; i < TREE_VEC_LENGTH (mainargs); ++i) - for_each_template_parm (TREE_VEC_ELT (mainargs, i), - &mark_template_parm, - &tpd); - for (i = 0; i < ntparms; ++i) - if (tpd.parms[i] == 0) - { - /* One of the template parms was not used in the - specialization. */ - if (!did_error_intro) - { - cp_error ("template parameters not used in partial specialization:"); - did_error_intro = 1; - } - - cp_error (" `%D'", - TREE_VALUE (TREE_VEC_ELT - (TREE_VALUE (current_template_parms), - i))); - } - - for (; spec; spec = TREE_CHAIN (spec)) - { - /* purpose: args to main template - value: spec template */ - if (comp_template_args (TREE_PURPOSE (spec), mainargs)) - return decl; - } + /* Check to see that the rules regarding the use of default + arguments are not being violated. */ + check_default_tmpl_args (decl, current_template_parms, + primary, is_partial); - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type) - = perm_tree_cons (mainargs, TREE_VALUE (current_template_parms), - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); - TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; - return decl; - } + if (is_partial) + return process_partial_specialization (decl); args = current_template_args (); @@ -1817,18 +2403,19 @@ push_template_decl_real (decl, is_friend) } else { - tree t; - tree a; + tree a, t, current, parms; + int i; if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) cp_error ("must specialize `%#T' before defining member `%#D'", ctx, decl); if (TREE_CODE (decl) == TYPE_DECL) { - if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl)) - && CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl))) - tmpl = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)); + if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) + || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) + && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) + && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) + tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); else { cp_error ("`%D' does not declare a template type", decl); @@ -1843,93 +2430,78 @@ push_template_decl_real (decl, is_friend) else tmpl = DECL_TI_TEMPLATE (decl); - if (is_member_template (tmpl) || is_member_template_class (tmpl)) + if (is_member_template (tmpl) + && DECL_FUNCTION_TEMPLATE_P (tmpl) + && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) + && DECL_TEMPLATE_SPECIALIZATION (decl)) { - if (DECL_FUNCTION_TEMPLATE_P (tmpl) - && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) - && DECL_TEMPLATE_SPECIALIZATION (decl)) - { - tree new_tmpl; - - /* The declaration is a specialization of a member - template, declared outside the class. Therefore, the - innermost template arguments will be NULL, so we - replace them with the arguments determined by the - earlier call to check_explicit_specialization. */ - args = DECL_TI_ARGS (decl); - - new_tmpl - = build_template_decl (decl, current_template_parms); - DECL_TEMPLATE_RESULT (new_tmpl) = decl; - TREE_TYPE (new_tmpl) = TREE_TYPE (decl); - DECL_TI_TEMPLATE (decl) = new_tmpl; - SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl); - DECL_TEMPLATE_INFO (new_tmpl) = - perm_tree_cons (tmpl, args, NULL_TREE); - - register_specialization (new_tmpl, tmpl, args); - return decl; - } - - a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); - t = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); - if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) - { - cp_error ("got %d template parameters for `%#D'", - TREE_VEC_LENGTH (a), decl); - cp_error (" but %d required", TREE_VEC_LENGTH (t)); - } - if (TREE_VEC_LENGTH (args) > 1) - /* Get the template parameters for the enclosing template - class. */ - a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 2); - else - a = NULL_TREE; + tree new_tmpl; + + /* The declaration is a specialization of a member + template, declared outside the class. Therefore, the + innermost template arguments will be NULL, so we + replace them with the arguments determined by the + earlier call to check_explicit_specialization. */ + args = DECL_TI_ARGS (decl); + + new_tmpl + = build_template_decl (decl, current_template_parms); + DECL_TEMPLATE_RESULT (new_tmpl) = decl; + TREE_TYPE (new_tmpl) = TREE_TYPE (decl); + DECL_TI_TEMPLATE (decl) = new_tmpl; + SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl); + DECL_TEMPLATE_INFO (new_tmpl) = + perm_tree_cons (tmpl, args, NULL_TREE); + + register_specialization (new_tmpl, tmpl, args); + return decl; } - else - a = TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1); - t = NULL_TREE; + /* Make sure the template headers we got make sense. */ - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (ctx)) + parms = DECL_TEMPLATE_PARMS (tmpl); + i = TMPL_PARMS_DEPTH (parms); + if (TMPL_ARGS_DEPTH (args) != i) { - /* When processing an inline member template of a - specialized class, there is no CLASSTYPE_TI_SPEC_INFO. */ - if (CLASSTYPE_TI_SPEC_INFO (ctx)) - t = TREE_VALUE (CLASSTYPE_TI_SPEC_INFO (ctx)); + cp_error ("expected %d levels of template parms for `%#D', got %d", + i, decl, TMPL_ARGS_DEPTH (args)); } - else if (CLASSTYPE_TEMPLATE_INFO (ctx)) - t = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (ctx)); + else + for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms)) + { + a = TMPL_ARGS_LEVEL (args, i); + t = INNERMOST_TEMPLATE_PARMS (parms); - /* There should be template arguments if and only if there is a - template class. */ - my_friendly_assert((a != NULL_TREE) == (t != NULL_TREE), 0); + if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) + { + if (current == decl) + cp_error ("got %d template parameters for `%#D'", + TREE_VEC_LENGTH (a), decl); + else + cp_error ("got %d template parameters for `%#T'", + TREE_VEC_LENGTH (a), current); + cp_error (" but %d required", TREE_VEC_LENGTH (t)); + } - if (t != NULL_TREE - && TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) - { - cp_error ("got %d template parameters for `%#D'", - TREE_VEC_LENGTH (a), decl); - cp_error (" but `%#T' has %d", ctx, TREE_VEC_LENGTH (t)); - } + /* Perhaps we should also check that the parms are used in the + appropriate qualifying scopes in the declarator? */ + + if (current == decl) + current = ctx; + else + current = TYPE_CONTEXT (current); + } } - /* Get the innermost set of template arguments. We don't do this - for a non-template member function of a nested template class - because there we will never get a `partial instantiation' of the - function containing the outer arguments, and so we must save all - of the arguments here. */ - if (TREE_CODE (decl) != FUNCTION_DECL - || template_class_depth (ctx) <= 1 - || primary) - args = innermost_args (args, 0); DECL_TEMPLATE_RESULT (tmpl) = decl; TREE_TYPE (tmpl) = TREE_TYPE (decl); - if (! ctx && !(is_friend && template_class_depth (info) > 0)) - /* Note that we do not try to push a global template friend - declared in a template class; such a thing may well depend on - the template parameters of the class. */ + /* Push template declarations for global functions and types. Note + that we do not try to push a global template friend declared in a + template class; such a thing may well depend on the template + parameters of the class. */ + if (! ctx + && !(is_friend && template_class_depth (current_class_type) > 0)) tmpl = pushdecl_namespace_level (tmpl); if (primary) @@ -1939,8 +2511,9 @@ push_template_decl_real (decl, is_friend) if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) { - CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (tmpl)) = info; - if (!ctx || TREE_CODE (ctx) != FUNCTION_DECL) + SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); + if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL) + && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE) DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); } else if (! DECL_LANG_SPECIFIC (decl)) @@ -1969,10 +2542,17 @@ redeclare_class_template (type, parms) tree type; tree parms; { - tree tmpl = CLASSTYPE_TI_TEMPLATE (type); + tree tmpl; tree tmpl_parms; int i; + if (!TYPE_TEMPLATE_INFO (type)) + { + cp_error ("`%T' is not a template type", type); + return; + } + + tmpl = TYPE_TI_TEMPLATE (type); if (!PRIMARY_TEMPLATE_P (tmpl)) /* The type is nested in some template class. Nothing to worry about here; there are no new template parameters for the nested @@ -2072,22 +2652,16 @@ convert_nontype_argument (type, expr) Check this first since if expr_type is the unknown_type_node we would otherwise complain below. */ ; - else if (INTEGRAL_TYPE_P (expr_type) - || TYPE_PTRMEM_P (expr_type) - || TYPE_PTRMEMFUNC_P (expr_type) - /* The next two are g++ extensions. */ - || TREE_CODE (expr_type) == REAL_TYPE - || TREE_CODE (expr_type) == COMPLEX_TYPE) + else if (TYPE_PTRMEM_P (expr_type) + || TYPE_PTRMEMFUNC_P (expr_type)) { - if (! TREE_CONSTANT (expr)) - { - non_constant: - cp_error ("non-constant `%E' cannot be used as template argument", - expr); - return NULL_TREE; - } + if (TREE_CODE (expr) != PTRMEM_CST) + goto bad_argument; } - else if (TYPE_PTR_P (expr_type) + 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 will get the unknown_type_node at this point. */ || expr_type == unknown_type_node) @@ -2096,21 +2670,33 @@ convert_nontype_argument (type, expr) tree e = expr; STRIP_NOPS (e); - if (TREE_CODE (e) != ADDR_EXPR) + if (TREE_CODE (type) == REFERENCE_TYPE + || TREE_CODE (expr_type) == ARRAY_TYPE) + referent = e; + else { - bad_argument: - cp_error ("`%E' is not a valid template argument", expr); - error ("it must be %s%s with external linkage", - TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE - ? "a pointer to " : "", - TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == FUNCTION_TYPE - ? "a function" : "an object"); - return NULL_TREE; + if (TREE_CODE (e) != ADDR_EXPR) + { + bad_argument: + cp_error ("`%E' is not a valid template argument", expr); + if (TYPE_PTR_P (expr_type)) + { + if (TREE_CODE (TREE_TYPE (expr_type)) == FUNCTION_TYPE) + cp_error ("it must be the address of a function with external linkage"); + else + cp_error ("it must be the address of an object with external linkage"); + } + else if (TYPE_PTRMEM_P (expr_type) + || TYPE_PTRMEMFUNC_P (expr_type)) + cp_error ("it must be a pointer-to-member of the form `&X::Y'"); + + return NULL_TREE; + } + + referent = TREE_OPERAND (e, 0); + STRIP_NOPS (referent); } - referent = TREE_OPERAND (e, 0); - STRIP_NOPS (referent); - if (TREE_CODE (referent) == STRING_CST) { cp_error ("string literal %E is not a valid template argument", @@ -2130,10 +2716,20 @@ convert_nontype_argument (type, expr) return error_mark_node; } } - else if (TREE_CODE (expr) == VAR_DECL) + else if (INTEGRAL_TYPE_P (expr_type) + || TYPE_PTRMEM_P (expr_type) + || TYPE_PTRMEMFUNC_P (expr_type) + /* The next two are g++ extensions. */ + || TREE_CODE (expr_type) == REAL_TYPE + || TREE_CODE (expr_type) == COMPLEX_TYPE) { - if (!TREE_PUBLIC (expr)) - goto bad_argument; + if (! TREE_CONSTANT (expr)) + { + non_constant: + cp_error ("non-constant `%E' cannot be used as template argument", + expr); + return NULL_TREE; + } } else { @@ -2157,7 +2753,7 @@ convert_nontype_argument (type, expr) expr = digest_init (type, expr, (tree*) 0); if (TREE_CODE (expr) != INTEGER_CST) - /* Curiously, some TREE_CONSTNAT integral expressions do not + /* Curiously, some TREE_CONSTANT integral expressions do not simplify to integer constants. For example, `3 % 0', remains a TRUNC_MOD_EXPR. */ goto non_constant; @@ -2182,10 +2778,24 @@ convert_nontype_argument (type, expr) tree type_pointed_to = TREE_TYPE (type); if (TYPE_PTRMEM_P (type)) - /* For a non-type template-parameter of type pointer to data - member, qualification conversions (_conv.qual_) are - applied. */ - return perform_qualification_conversions (type, expr); + { + 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) { /* For a non-type template-parameter of type pointer to @@ -2217,7 +2827,7 @@ convert_nontype_argument (type, expr) expr = build_unary_op (ADDR_EXPR, fn, 0); - my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1), + my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } @@ -2252,15 +2862,18 @@ convert_nontype_argument (type, expr) if (TREE_CODE (type_referred_to) == FUNCTION_TYPE) { /* For a non-type template-parameter of type reference to - function, no conversions apply. If the - template-argument represents a set of overloaded - functions, the matching function is selected from the - set (_over.over_). */ + function, no conversions apply. If the + template-argument represents a set of overloaded + functions, the matching function is selected from the + set (_over.over_). */ tree fns = expr; tree fn; fn = instantiate_type (type_referred_to, fns, 0); + if (fn == error_mark_node) + return error_mark_node; + if (!TREE_PUBLIC (fn)) { if (really_overloaded_fn (fns)) @@ -2272,10 +2885,8 @@ convert_nontype_argument (type, expr) goto bad_argument; } - if (fn == error_mark_node) - return error_mark_node; - - my_friendly_assert (comptypes (type, TREE_TYPE (fn), 1), + my_friendly_assert (same_type_p (type_referred_to, + TREE_TYPE (fn)), 0); return fn; @@ -2288,12 +2899,10 @@ convert_nontype_argument (type, expr) identical) type of the template-argument. The template-parameter is bound directly to the template-argument, which must be an lvalue. */ - if (!comptypes (TYPE_MAIN_VARIANT (expr_type), - TYPE_MAIN_VARIANT (type), 1) - || (TYPE_READONLY (expr_type) > - TYPE_READONLY (type_referred_to)) - || (TYPE_VOLATILE (expr_type) > - TYPE_VOLATILE (type_referred_to)) + if ((TYPE_MAIN_VARIANT (expr_type) + != TYPE_MAIN_VARIANT (type_referred_to)) + || !at_least_as_qualified_p (type_referred_to, + expr_type) || !real_lvalue_p (expr)) return error_mark_node; else @@ -2304,9 +2913,6 @@ convert_nontype_argument (type, expr) case RECORD_TYPE: { - tree fns; - tree fn; - if (!TYPE_PTRMEMFUNC_P (type)) /* This handles templates like template void f(); @@ -2325,10 +2931,10 @@ convert_nontype_argument (type, expr) expr_type != unknown_type_node) return error_mark_node; - if (TREE_CODE (expr) == CONSTRUCTOR) + if (TREE_CODE (expr) == PTRMEM_CST) { /* A ptr-to-member constant. */ - if (!comptypes (type, expr_type, 1)) + if (!same_type_p (type, expr_type)) return error_mark_node; else return expr; @@ -2337,17 +2943,12 @@ convert_nontype_argument (type, expr) if (TREE_CODE (expr) != ADDR_EXPR) return error_mark_node; - fns = TREE_OPERAND (expr, 0); - - fn = instantiate_type (TREE_TYPE (TREE_TYPE (type)), - fns, 0); + expr = instantiate_type (type, expr, 0); - if (fn == error_mark_node) + if (expr == error_mark_node) return error_mark_node; - expr = build_unary_op (ADDR_EXPR, fn, 0); - - my_friendly_assert (comptypes (type, TREE_TYPE (expr), 1), + my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), 0); return expr; } @@ -2380,8 +2981,11 @@ convert_nontype_argument (type, expr) substitute the TT parameter. */ static int -coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args) - tree parm_parms, arg_parms, in_decl, outer_args; +coerce_template_template_parms (parm_parms, arg_parms, complain, + in_decl, outer_args) + tree parm_parms, arg_parms; + int complain; + tree in_decl, outer_args; { int nparms, nargs, i; tree parm, arg; @@ -2419,15 +3023,24 @@ coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args) /* We encounter instantiations of templates like template