aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2000-04-08 13:35:53 +0000
committerRichard Earnshaw <rearnsha@arm.com>2000-04-08 13:35:53 +0000
commita8aec5d453f43d7cb393600b826f519d0ce015a0 (patch)
tree41674a640d14edc21fe187daedda3a01a0434f25
parent4c2a925528228f220f8da3c30fb71114669aedb4 (diff)
* Merge trunk code from tag merged-arm-thumb-backend-merge_20000408
into branch. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/merged-arm-thumb-backend-branch@33027 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog21
-rw-r--r--MAINTAINERS3
-rw-r--r--Makefile.in7
-rw-r--r--config.if11
-rwxr-xr-xconfig.sub2
-rw-r--r--configure.in30
-rw-r--r--gcc/ChangeLog1726
-rw-r--r--gcc/Makefile.in196
-rw-r--r--gcc/acconfig.h9
-rw-r--r--gcc/alias.c62
-rw-r--r--gcc/basic-block.h41
-rw-r--r--gcc/bb-reorder.c7
-rw-r--r--gcc/builtins.c89
-rw-r--r--gcc/c-common.c34
-rw-r--r--gcc/c-convert.c4
-rw-r--r--gcc/c-decl.c65
-rw-r--r--gcc/c-typeck.c112
-rw-r--r--gcc/calls.c1442
-rw-r--r--gcc/ch/ChangeLog14
-rw-r--r--gcc/ch/actions.c3
-rw-r--r--gcc/ch/expr.c2
-rw-r--r--gcc/ch/lang-specs.h1
-rw-r--r--gcc/ch/typeck.c4
-rw-r--r--gcc/combine.c348
-rw-r--r--gcc/config.in9
-rw-r--r--gcc/config/a29k/a29k.h2
-rw-r--r--gcc/config/alpha/alpha.c229
-rw-r--r--gcc/config/alpha/alpha.h6
-rw-r--r--gcc/config/alpha/alpha.md14
-rw-r--r--gcc/config/arc/arc.h2
-rw-r--r--gcc/config/arm/arm.c217
-rw-r--r--gcc/config/arm/arm.h5
-rw-r--r--gcc/config/arm/linux-elf.h4
-rw-r--r--gcc/config/c4x/c4x.c8
-rw-r--r--gcc/config/clipper/clipper.h2
-rw-r--r--gcc/config/convex/fixinc.convex10
-rw-r--r--gcc/config/dsp16xx/dsp16xx.h2
-rw-r--r--gcc/config/fr30/fr30.h2
-rw-r--r--gcc/config/i370/i370.h2
-rw-r--r--gcc/config/i386/att.h8
-rw-r--r--gcc/config/i386/djgpp.h2
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c205
-rw-r--r--gcc/config/i386/i386.h41
-rw-r--r--gcc/config/i386/i386.md773
-rw-r--r--gcc/config/i960/i960.h2
-rw-r--r--gcc/config/ia64/ia64.c2
-rw-r--r--gcc/config/ia64/ia64.h21
-rw-r--r--gcc/config/m32r/m32r.h2
-rw-r--r--gcc/config/m68k/m68k-protos.h4
-rw-r--r--gcc/config/m88k/m88k.h2
-rw-r--r--gcc/config/mcore/mcore.h2
-rw-r--r--gcc/config/mips/abi64.h16
-rw-r--r--gcc/config/mips/mips.c35
-rw-r--r--gcc/config/mips/mips.h50
-rw-r--r--gcc/config/mn10200/mn10200.h2
-rw-r--r--gcc/config/mn10300/mn10300.h2
-rw-r--r--gcc/config/pa/pa.c4
-rw-r--r--gcc/config/pa/pa.h2
-rw-r--r--gcc/config/romp/romp.h2
-rw-r--r--gcc/config/rs6000/aix.h7
-rw-r--r--gcc/config/rs6000/aix41.h1
-rw-r--r--gcc/config/rs6000/aix43.h1
-rw-r--r--gcc/config/rs6000/eabi.h5
-rw-r--r--gcc/config/rs6000/eabiaix.h4
-rw-r--r--gcc/config/rs6000/eabile.h49
-rw-r--r--gcc/config/rs6000/eabilesim.h46
-rw-r--r--gcc/config/rs6000/eabisim.h4
-rw-r--r--gcc/config/rs6000/linux.h19
-rw-r--r--gcc/config/rs6000/rs6000.c20
-rw-r--r--gcc/config/rs6000/rs6000.h9
-rw-r--r--gcc/config/rs6000/rs6000.md2
-rw-r--r--gcc/config/rs6000/rtems.h2
-rw-r--r--gcc/config/rs6000/sol2.h2
-rw-r--r--gcc/config/rs6000/sysv4.h8
-rw-r--r--gcc/config/rs6000/sysv4le.h2
-rw-r--r--gcc/config/rs6000/t-aix432
-rw-r--r--gcc/config/rs6000/t-ppc12
-rw-r--r--gcc/config/rs6000/t-ppccomm7
-rw-r--r--gcc/config/rs6000/t-ppcgas3
-rw-r--r--gcc/config/rs6000/t-ppcos18
-rw-r--r--gcc/config/rs6000/vxppc.h2
-rw-r--r--gcc/config/rs6000/vxppcle.h58
-rw-r--r--gcc/config/sh/lib1funcs.asm10
-rw-r--r--gcc/config/sh/sh-protos.h1
-rw-r--r--gcc/config/sh/sh.c76
-rw-r--r--gcc/config/sh/sh.h40
-rw-r--r--gcc/config/sh/sh.md2
-rw-r--r--gcc/config/sparc/sparc.c77
-rw-r--r--gcc/config/sparc/sparc.h36
-rw-r--r--gcc/config/sparc/sparc.md570
-rw-r--r--gcc/config/sparc/t-linux6413
-rw-r--r--gcc/config/v850/v850.h2
-rwxr-xr-xgcc/configure579
-rw-r--r--gcc/configure.in146
-rw-r--r--gcc/convert.c4
-rw-r--r--gcc/cp/ChangeLog404
-rw-r--r--gcc/cp/Make-lang.in5
-rw-r--r--gcc/cp/Makefile.in23
-rw-r--r--gcc/cp/call.c13
-rw-r--r--gcc/cp/cfns.gperf10
-rw-r--r--gcc/cp/cfns.h10
-rw-r--r--gcc/cp/class.c2036
-rw-r--r--gcc/cp/cp-tree.h116
-rw-r--r--gcc/cp/decl.c43
-rw-r--r--gcc/cp/decl2.c58
-rw-r--r--gcc/cp/dump.c4
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/expr.c15
-rw-r--r--gcc/cp/inc/cxxabi.h84
-rw-r--r--gcc/cp/init.c30
-rw-r--r--gcc/cp/lang-specs.h1
-rw-r--r--gcc/cp/lex.c5
-rw-r--r--gcc/cp/method.c2
-rw-r--r--gcc/cp/optimize.c40
-rw-r--r--gcc/cp/pt.c107
-rw-r--r--gcc/cp/repo.c2
-rw-r--r--gcc/cp/rtti.c195
-rw-r--r--gcc/cp/search.c272
-rw-r--r--gcc/cp/semantics.c16
-rw-r--r--gcc/cp/tinfo.cc102
-rw-r--r--gcc/cp/tinfo2.cc2
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/cp/typeck.c31
-rw-r--r--gcc/cpp.texi38
-rw-r--r--gcc/cpperror.c35
-rw-r--r--gcc/cppexp.c591
-rw-r--r--gcc/cppfiles.c86
-rw-r--r--gcc/cpphash.c181
-rw-r--r--gcc/cpphash.h40
-rw-r--r--gcc/cppinit.c704
-rw-r--r--gcc/cpplex.c673
-rw-r--r--gcc/cpplib.c717
-rw-r--r--gcc/cpplib.h430
-rw-r--r--gcc/cppmain.c74
-rw-r--r--gcc/crtstuff.c13
-rw-r--r--gcc/cse.c183
-rw-r--r--gcc/dbxout.c9
-rw-r--r--gcc/dwarf2out.c22
-rw-r--r--gcc/emit-rtl.c126
-rw-r--r--gcc/enquire.c2
-rw-r--r--gcc/except.c20
-rw-r--r--gcc/explow.c28
-rw-r--r--gcc/expmed.c181
-rw-r--r--gcc/expr.c796
-rw-r--r--gcc/expr.h21
-rw-r--r--gcc/f/ChangeLog18
-rw-r--r--gcc/f/Makefile.in4
-rw-r--r--gcc/f/com.c10
-rw-r--r--gcc/f/lang-specs.h1
-rw-r--r--gcc/f/version.c2
-rw-r--r--gcc/final.c39
-rw-r--r--gcc/fix-header.c9
-rwxr-xr-xgcc/fixinc/fixinc.irix4
-rwxr-xr-xgcc/fixinc/fixinc.sco2
-rwxr-xr-xgcc/fixinc/fixinc.wrap6
-rw-r--r--gcc/fixinc/fixincl.x6
-rw-r--r--gcc/fixinc/inclhack.def6
-rwxr-xr-xgcc/fixinc/inclhack.sh6
-rwxr-xr-xgcc/fixinc/mkfixinc.sh2
-rw-r--r--gcc/fixinc/server.c24
-rw-r--r--gcc/flags.h4
-rw-r--r--gcc/flow.c1402
-rw-r--r--gcc/fold-const.c97
-rw-r--r--gcc/function.c82
-rw-r--r--gcc/function.h16
-rw-r--r--gcc/gcc.c80
-rw-r--r--gcc/gcc.texi140
-rwxr-xr-xgcc/gccbug.in30
-rw-r--r--gcc/gcse.c70
-rw-r--r--gcc/genattrtab.c2
-rw-r--r--gcc/genconfig.c30
-rw-r--r--gcc/genrecog.c21
-rw-r--r--gcc/ggc-common.c279
-rw-r--r--gcc/ggc.h43
-rw-r--r--gcc/ginclude/stdarg.h8
-rw-r--r--gcc/ginclude/varargs.h6
-rw-r--r--gcc/global.c8
-rw-r--r--gcc/gsyslimits.h2
-rw-r--r--gcc/haifa-sched.c30
-rw-r--r--gcc/hard-reg-set.h4
-rw-r--r--gcc/integrate.c25
-rw-r--r--gcc/invoke.texi29
-rw-r--r--gcc/java/ChangeLog126
-rw-r--r--gcc/java/boehm.c14
-rw-r--r--gcc/java/class.c53
-rw-r--r--gcc/java/decl.c20
-rw-r--r--gcc/java/expr.c22
-rw-r--r--gcc/java/gjavah.c3
-rw-r--r--gcc/java/java-tree.h10
-rw-r--r--gcc/java/jcf-depend.c2
-rw-r--r--gcc/java/jcf-parse.c2
-rw-r--r--gcc/java/jcf-write.c3
-rw-r--r--gcc/java/jvspec.c9
-rw-r--r--gcc/java/parse-scan.c2128
-rw-r--r--gcc/java/parse-scan.y55
-rw-r--r--gcc/java/parse.c1317
-rw-r--r--gcc/java/parse.h2
-rw-r--r--gcc/java/parse.y63
-rw-r--r--gcc/jump.c18
-rw-r--r--gcc/libgcc2.h12
-rw-r--r--gcc/limity.h2
-rw-r--r--gcc/local-alloc.c7
-rw-r--r--gcc/loop.c25
-rw-r--r--gcc/loop.h6
-rw-r--r--gcc/machmode.h9
-rw-r--r--gcc/md.texi6
-rw-r--r--gcc/objc/lang-specs.h2
-rw-r--r--gcc/objc/objc-act.c9
-rw-r--r--gcc/optabs.c46
-rw-r--r--gcc/po/ChangeLog9
-rw-r--r--gcc/po/POTFILES.in14
-rw-r--r--gcc/print-rtl.c15
-rw-r--r--gcc/print-tree.c45
-rw-r--r--gcc/real.c2
-rw-r--r--gcc/real.h2
-rw-r--r--gcc/regclass.c29
-rw-r--r--gcc/regmove.c20
-rw-r--r--gcc/reload.c84
-rw-r--r--gcc/reload.h7
-rw-r--r--gcc/reload1.c161
-rw-r--r--gcc/reorg.c24
-rw-r--r--gcc/resource.c144
-rw-r--r--gcc/resource.h10
-rw-r--r--gcc/rtl.c112
-rw-r--r--gcc/rtl.def7
-rw-r--r--gcc/rtl.h306
-rw-r--r--gcc/rtl.texi6
-rw-r--r--gcc/rtlanal.c167
-rw-r--r--gcc/sdbout.c5
-rw-r--r--gcc/sibcall.c11
-rw-r--r--gcc/simplify-rtx.c37
-rw-r--r--gcc/ssa.c588
-rw-r--r--gcc/stmt.c181
-rw-r--r--gcc/stor-layout.c830
-rw-r--r--gcc/testsuite/ChangeLog75
-rw-r--r--gcc/testsuite/g++.old-deja/g++.abi/vtable.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/dcast3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/offset2.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/opeq.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators16.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.law/operators17.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net26.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/virt3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/virt6.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/badopt1.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/ChangeLog35
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/981211-1.c43
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/960327-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp-if1.c4
-rw-r--r--gcc/testsuite/gcc.dg/cpp-redef-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp-unc.c1
-rw-r--r--gcc/tlink.c8
-rw-r--r--gcc/tm.texi37
-rw-r--r--gcc/toplev.c1114
-rw-r--r--gcc/toplev.h2
-rw-r--r--gcc/tree.c116
-rw-r--r--gcc/tree.h165
-rw-r--r--gcc/unroll.c62
-rw-r--r--gcc/varasm.c74
-rw-r--r--gcc/varray.h3
-rw-r--r--gcc/version.c2
-rw-r--r--include/ChangeLog10
-rw-r--r--include/hashtab.h11
-rw-r--r--include/splay-tree.h2
-rw-r--r--libchill/ChangeLog4
-rw-r--r--libchill/basicio.c16
-rw-r--r--libf2c/libF77/Version.c2
-rw-r--r--libf2c/libI77/Version.c2
-rw-r--r--libf2c/libU77/Version.c2
-rw-r--r--libiberty/ChangeLog18
-rw-r--r--libiberty/configure.bat14
-rw-r--r--libiberty/hashtab.c40
-rw-r--r--libiberty/makefile.dos29
-rw-r--r--libiberty/splay-tree.c41
-rw-r--r--libio/ChangeLog8
-rw-r--r--libio/configure.in6
-rw-r--r--libobjc/ChangeLog5
-rw-r--r--libobjc/objc/Protocol.h2
-rw-r--r--libobjc/objc/objc-list.h2
-rw-r--r--libstdc++/ChangeLog4
-rw-r--r--libstdc++/configure.in2
283 files changed, 16125 insertions, 11575 deletions
diff --git a/ChangeLog b/ChangeLog
index 336a9336525..e86ec0346a3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Thu Apr 6 16:15:14 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * MAINTAINERS: Added myself.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+ Martin v. Loewis <martin@loewis.home.cs.tu-berlin.de>
+
+ * configure.in (enable_libstdcxx_v3): Add.
+ (target_libs): Add bits here to switch between libstdc++-v2 and
+ libstdc++-v3.
+ * config.if: And this file too.
+ * Makefile.in: Add libstdc++-v3 targets.
+
+2000-04-05 Michael Meissner <meissner@redhat.com>
+
+ * config.sub (d30v): Add d30v as a basic machine type.
+
+2000-03-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * configure.in: -linux-gnu*, not -linux-gnu.
+
Sun Mar 12 17:30:30 2000 Toon Moene <toon@moene.indiv.nluug.nl>
* MAINTAINERS: Add self in write-after-approval section.
diff --git a/MAINTAINERS b/MAINTAINERS
index cf13e8a5497..a59c37154bd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -29,6 +29,7 @@ mn10200 port Jeff Law law@cygnus.com
mn10300 port Jeff Law law@cygnus.com
hppa port Jeff Law law@cygnus.com
m68k port (?) Jeff Law law@cygnus.com
+m68k-motorola-sysv port Philippe De Muyter phdm@macqel.be
rs6000 port Geoff Keating geoffk@cygnus.com
rs6000 port David Edelsohn dje@watson.ibm.com
mips port Gavin Romig-Koch gavin@cygnus.com
@@ -70,7 +71,7 @@ c++ runtime libs Gabriel Dos Reis dosreis@cmla.ens-cachan.fr
*c-torture Torbjorn Granlund tege@swox.com
*f-torture Kate Hedstrom kate@ahab.rutgers.edu
sco5, unixware, sco udk Robert Lipe robertlipe@usa.net
-fixincludes Bruce Korb autogen@linuxbox.com
+fixincludes Bruce Korb bkorb@gnu.org
gcse.c Jeff Law law@cygnus.com
global opt framework Jeff Law law@cygnus.com
jump.c David S. Miller davem@redhat.com
diff --git a/Makefile.in b/Makefile.in
index 0de1a86dea8..40569591fe6 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -772,6 +772,7 @@ INSTALL_X11_MODULES = \
ALL_TARGET_MODULES = \
all-target-libio \
all-target-libstdc++ \
+ all-target-libstdc++-v3 \
all-target-librx \
all-target-libg++ \
all-target-newlib \
@@ -795,6 +796,7 @@ ALL_TARGET_MODULES = \
CONFIGURE_TARGET_MODULES = \
configure-target-libio \
configure-target-libstdc++ \
+ configure-target-libstdc++-v3 \
configure-target-librx \
configure-target-libg++ \
configure-target-newlib \
@@ -818,6 +820,7 @@ CONFIGURE_TARGET_MODULES = \
CHECK_TARGET_MODULES = \
check-target-libio \
check-target-libstdc++ \
+ check-target-libstdc++-v3 \
check-target-libg++ \
check-target-newlib \
check-target-libf2c \
@@ -836,6 +839,7 @@ CHECK_TARGET_MODULES = \
INSTALL_TARGET_MODULES = \
install-target-libio \
install-target-libstdc++ \
+ install-target-libstdc++-v3 \
install-target-libg++ \
install-target-newlib \
install-target-libf2c \
@@ -922,6 +926,7 @@ CLEAN_MODULES = \
CLEAN_TARGET_MODULES = \
clean-target-libio \
clean-target-libstdc++ \
+ clean-target-libstdc++-v3 \
clean-target-librx \
clean-target-libg++ \
clean-target-newlib \
@@ -1634,7 +1639,9 @@ all-target-libjava: configure-target-libjava all-gcc all-zip all-target-newlib a
configure-target-librx: $(ALL_GCC) configure-target-newlib
all-target-librx: configure-target-librx
configure-target-libstdc++: $(ALL_GCC)
+configure-target-libstdc++-v3: $(ALL_GCC)
all-target-libstdc++: configure-target-libstdc++ all-gas all-ld all-gcc all-target-libiberty all-target-newlib all-target-libio
+all-target-libstdc++-v3: configure-target-libstdc++-v3 all-gas all-ld all-gcc all-target-libiberty all-target-newlib
configure-target-libstub: $(ALL_GCC)
all-target-libstub: configure-target-libstub
all-libtool:
diff --git a/config.if b/config.if
index bcc026908d8..f8e086de2a8 100644
--- a/config.if
+++ b/config.if
@@ -21,9 +21,16 @@ else
if_topsrcdir=${top_srcdir}
fi
-if [ -f ${if_topsrcdir}/libstdc++/Makefile.in ]; then
+if [ "${enable_libstdcxx_v3}" = "yes" ] ; then
+ libstdcxx_srcdir=${if_topsrcdir}/libstdc++-v3
+else
+ libstdcxx_srcdir=${if_topsrcdir}/libstdc++
+fi
+
+echo "${libstdcxx_srcdir} is where"
+if [ -f ${libstdcxx_srcdir}/Makefile.in ]; then
# We check libstdc++ for libstdcxx_interface.
-libstdcxx_interface=`grep "^INTERFACE" ${if_topsrcdir}/libstdc++/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
+libstdcxx_interface=`grep "^INTERFACE" ${libstdcxx_srcdir}/Makefile.in | sed 's/INTERFACE[ ]*=[ ]*\(.*\)/\1/'`
else
libstdcxx_interface=
fi
diff --git a/config.sub b/config.sub
index 5d756240452..04eea53c319 100755
--- a/config.sub
+++ b/config.sub
@@ -183,7 +183,7 @@ case $basic_machine in
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
| mips64vr5000 | miprs64vr5000el | mcore \
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
- | thumb | d10v | fr30 | avr)
+ | thumb | d10v | d30v | fr30 | avr)
basic_machine=$basic_machine-unknown
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
diff --git a/configure.in b/configure.in
index e4f2a49e842..c8431d71452 100644
--- a/configure.in
+++ b/configure.in
@@ -47,6 +47,13 @@ if [ "${enable_gdbgui}" = "yes" ] ; then
host_libs="${host_libs} libgui"
fi
+# Set up configure/Makefile variables if libstdc++-v3 is to be built.
+if [ "${enable_libstdcxx_v3}" = "yes" ] ; then
+ libstdcxx_version="target-libstdc++-v3"
+else
+ libstdcxx_version="target-libio target-libstdc++"
+fi
+
# these tools are built for the host environment
# Note, the powerpc-eabi build depends on sim occurring before gdb in order to
# know that we are building the simulator.
@@ -59,9 +66,8 @@ host_tools="texinfo byacc flex bison binutils ld gas gcc sim gdb make patch prms
target_libs="target-libiberty \
target-libgloss \
target-newlib \
- target-libio \
+ ${libstdcxx_version} \
target-librx \
- target-libstdc++ \
target-libg++ \
target-libf2c \
target-libchill \
@@ -337,7 +343,7 @@ case "${target}" in
powerpc-*-netware*)
target_makefile_frag="${target_makefile_frag} config/mt-netware"
;;
- *-*-linux-gnu)
+ *-*-linux-gnu*)
target_makefile_frag="${target_makefile_frag} config/mt-linux"
;;
*-*-aix4.[3456789]* | *-*-aix[56789].*)
@@ -561,7 +567,7 @@ esac
case "${target}" in
*-*-netware)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-librx target-newlib target-libiberty target-libgloss"
+ noconfigdirs="$noconfigdirs target-libg++ ${libstdcxx_version} target-librx target-newlib target-libiberty target-libgloss"
;;
*-*-rtems*)
noconfigdirs="$noconfigdirs target-libgloss"
@@ -598,11 +604,11 @@ case "${target}" in
noconfigdirs="$noconfigdirs tcl tix tk itcl libgui sim"
noconfigdirs="$noconfigdirs expect dejagnu"
# the C++ libraries don't build on top of CE's C libraries
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio"
+ noconfigdirs="$noconfigdirs target-libg++ ${libstdcxx_version}"
skipdirs="$skipdirs target-newlib"
case "${host}" in
*-*-cygwin*) ;; # keep gdb and readline
- *) noconfigdirs="$noconfigdirs gdb readline target-libio target-libstdc++ target-libg++"
+ *) noconfigdirs="$noconfigdirs gdb readline ${libstdcxx_version} target-libg++"
;;
esac
;;
@@ -625,7 +631,7 @@ case "${target}" in
fi
;;
c4x-*-*)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ noconfigdirs="$noconfigdirs target-libg++ ${libstdcxx_version} target-librx target-libgloss"
;;
thumb-*-coff)
noconfigdirs="$noconfigdirs target-libgloss"
@@ -634,7 +640,7 @@ case "${target}" in
noconfigdirs="$noconfigdirs ld target-libgloss"
;;
d10v-*-*)
- noconfigdirs="$noconfigdirs target-librx target-libg++ target-libstdc++ target-libio target-libgloss"
+ noconfigdirs="$noconfigdirs target-librx target-libg++ ${libstdcxx_version} target-libgloss"
;;
fr30-*-elf*)
if [ x${is_cross_compiler} != xno ] ; then
@@ -643,7 +649,7 @@ case "${target}" in
;;
h8300*-*-* | \
h8500-*-*)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ noconfigdirs="$noconfigdirs target-libg++ ${libstdcxx_version} target-librx target-libgloss"
;;
hppa*-*-*elf* | \
hppa*-*-lites*)
@@ -661,7 +667,7 @@ case "${target}" in
;;
i[3456]86-*-go32* | i[3456]-*-msdosdjgpp*)
# but don't build gdb
- noconfigdirs="$noconfigdirs gdb target-libg++ target-libstdc++ target-libio target-librx"
+ noconfigdirs="$noconfigdirs gdb target-libg++ ${libstdcxx_version} target-librx"
;;
*-*-linux*)
# linux has rx in libc
@@ -692,7 +698,7 @@ case "${target}" in
esac
;;
i[3456]86-*-pe)
- noconfigdirs="$noconfigdirs target-libg++ target-libstdc++ target-libio target-librx target-libgloss"
+ noconfigdirs="$noconfigdirs target-libg++ ${libstdcxx_version} target-librx target-libgloss"
;;
i[3456]86-*-sco3.2v5*)
# The linker does not yet know about weak symbols in COFF,
@@ -831,7 +837,7 @@ case "${target}" in
fi
;;
v810-*-*)
- noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libio target-libg++ target-libstdc++ opcodes target-libgloss"
+ noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld ${libstdcxx_version} target-libg++ opcodes target-libgloss"
;;
v850-*-*)
noconfigdirs="$noconfigdirs target-libgloss"
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0a225bd4b86..4acfae746f0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2000-04-08 Richard Earnshaw (rearnsha@arm.com)
+ * Merge trunk code from tag merged-arm-thumb-backend-merge_20000408
+ into branch.
+
* arm.md (nop): Use the standard RTL expression. Don't code as a
define_expand.
(*arm_nop, *thumb_nop): Delete.
@@ -11,19 +14,7 @@
* arm.h (ARM_LEGITIIMIZE_RELOAD_ADDRESS, ARM_SIGN_EXTEND,
MASK_RETURN_ADDDR): Likewise.
-2000-04-03 Richard Earnshaw (rearnsha@arm.com)
-
- Merge Change from trunk:
- Thu Mar 30 13:30:40 2000 Jeffrey A Law (law@cygnus.com)
- * c-parse.in (cast_expr): Move change from March 21 into c-parse.in
- since it is used to generate c-parse.y.
- * objc-parse.c, objc-parse.y: Regenerated.
-
-2000-04-03 Philip Blundell <philb@gnu.org>
-
- * config/arm/linux-elf.h (SUBTARGET_EXTRA_LINK_SPEC): Fix typos.
-
-2000-03-31 Richard Earnshaw (rearnsha@arm.com)
+ 2000-03-31 Richard Earnshaw (rearnsha@arm.com)
* Merge trunk code from tag merged-arm-thumb-backend-merge_20000325
into branch.
@@ -400,6 +391,1673 @@
the code of value stored in the minipool array.
(arm_add_minipool_constant): Likewise.
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * basic-block.h (conflict_graph_enum_fn): K&R fix.
+
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * tree.c (tree_expr_nonnegative_p): New function.
+
+ * tree.h (tree_expr_nonnegative_p): Declare.
+
+ * c-typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to
+ elide some sign_compare warnings.
+ (build_conditional_expr): Likewise.
+
+Sat Apr 8 00:21:51 EDT 2000 John Wehle (john@feith.com)
+
+ * i386.md (ashrsi3, ashrhi3, ashrqi3): Fix typo.
+
+ * 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.
+
+2000-04-08 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c (parse_charconst): Null does not end character
+ constants.
+ * cppinit.c (ISTABLE): Null character handled as whitespace.
+ * cpplex.c (null_warning): new function.
+ (skip_string): Emit warning if nulls encountered.
+ (_cpp_skip_hspace): Emit warning if nulls encountered.
+ (_cpp_lex_token): Emit warning if nulls encountered. Drop
+ them.
+ * cpp.texi: Update.
+
+2000-04-07 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (loop_depth): Remove.
+ (reg_next_use, cc0_live, mem_set_list): Replace with ...
+ (struct propagate_block_info): New.
+ (life_analysis): Don't allocate reg_next_use.
+ (propagate_block_delete_insn): Break out of propagate_block.
+ Use flow_delete_insn to unlink rather than use NOTE_INSN_DELETED.
+ (propagate_block_delete_libcall): Likewise.
+ (propagate_block): Create a propagate_block_info struct to pass
+ to subroutines. Allocate one not two temporary regsets. Don't
+ clobber memory for const calls. Look for clobbers in
+ CALL_INSN_FUNCTION_USAGE.
+ (mark_set_regs): Recognize COND_EXEC.
+ (mark_set_reg): Break out of mark_set_1.
+ (mark_used_reg): Break out of mark_used_regs.
+ (mark_used_regs): Recognize COND_EXEC.
+ (insn_dead_p): Use propagate_block_info struct.
+ (libcall_dead_p, invalidate_mems_from_autoinc): Likewise.
+ (find_auto_inc, try_pre_increment_1): Likewise.
+ (print_rtl_with_bb): Dump regs live at end too.
+ (count_reg_sets_1): Pass in loop_depth.
+ (count_reg_sets, count_reg_references): Likewise.
+ (recompute_reg_usage): Provide it.
+
+2000-04-07 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (conflict.o): Depend on $(RTL_H) and $(BASIC_BLOCK_H)
+ not the raw files.
+
+2000-04-07 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.c (do_elif): Skip the rest of the line if we're
+ not going to bother evaluating it.
+ (skip_if_group): Clear pfile->only_seen_white. Reorder loop
+ to avoid pointless calls to the lexer.
+
+Fri Apr 7 11:50:54 2000 Jim Wilson <wilson@cygnus.com>
+
+ * config/ia64/ia64.c: Delete stdio.h and ctype.h includes.
+
+2000-04-07 Jason Merrill <jason@casey.cygnus.com>
+
+ * calls.c (expand_call): emit_queue if we're trying a sibcall.
+
+2000-04-07 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/t-linux64 (tcrtbeginS.o, tcrtendS.o): Remove.
+
+2000-04-06 Geoff Keating <geoffk@cygnus.com>
+
+ * Makefile.in: Build crtbeginS and crtendS like crtbegin and
+ crtend so they can be multilibbed.
+ (STAGESTUFF): Remove s-crt and s-crtS.
+
+2000-04-07 Richard Henderson <rth@cygnus.com>
+
+ * config/alpha/alpha.c (alpha_emit_conditional_move): Fail
+ if we discover we need a pseudo and no_new_pseudos is true.
+ * config/alpha/alpha.md (ne:DI insn): New.
+ (trunctfsf2, sne): Emit NE instead of non-canonical LTU.
+
+2000-04-07 Richard Henderson <rth@cygnus.com>
+
+ * rtl.def (COND_EXEC): New.
+ * rtl.h (COND_EXEC_TEST, COND_EXEC_CODE): New.
+ * tm.texi (MAX_CONDITIONAL_EXECUTE): Document.
+
+ * genconfig.c (have_cond_arith_flag): Remove.
+ (have_cond_exec_flag): New.
+ (walk_insn_part): Detect COND_EXEC, not arithmetic in IF_THEN_ELSE.
+ (main): Print HAVE_conditional_execution.
+
+ * haifa-sched.c (haifa_classify_insn): Recognize COND_EXEC.
+ (sched_analyze_insn, print_pattern): Likewise.
+ * reload.c (find_equiv_reg): Likewise.
+ * rtlanal.c (reg_referenced_p): Likewise.
+ (note_stores, dead_or_set_regno_p): Likewise.
+ (reg_overlap_mentioned_p): Rewrite to use a switch.
+
+ * ggc.h (struct rtx_def): Forward declare.
+
+ * print-rtl.c (debug_rtx_range): New.
+ * rtl.h (debug_rtx_range): Declare.
+
+ * varray.h (VARRAY_ACTIVE_SIZE, VARRAY_POP_ALL): New.
+
+ * gcse.c (gcse_main): Don't rebuild the CFG here.
+ (delete_null_pointer_checks): Likewise.
+ * ssa.c (convert_to_ssa): Likewise.
+ * toplev.c (rest_of_compilation): Do it here instead. Combine
+ sequential calls to TIMEVAR. Consistently use `insns' instead of
+ `get_insns()'. Always split insns after reload when optimizing.
+
+ * basic-block.h (merge_blocks_nomove): Declare.
+ (tidy_fallthru_edge): Declare.
+ * flow.c (merge_blocks_nomove): Document as merging into previous
+ blocks. Remove cruft from between blocks; remove all edges out of A.
+ (tidy_fallthru_edge): Export.
+
+2000-04-06 Alex Samuel <samuel@codesourcery.com>
+
+ * ssa.c (compute_conservative_reg_partition): Declare with
+ void arguments.
+ * toplev.c (clean_dump_file): Remove previously-deleted function
+ inadvertantly merged back in.
+ * conflict.c (conflict_graph_add): Use a single call to
+ htab_find_slot to look up and insert.
+
+2000-04-06 Richard Henderson <rth@cygnus.com>
+
+ * genrecog.c (*): Rename _last_insn to last_insn.
+ (make_insn_sequence): Set the position of the peephole2 C test
+ to be at the last insn.
+
+2000-04-06 Richard Henderson <rth@cygnus.com>
+
+ * flow.c (compute_flow_dominators): Free worklist.
+
+2000-04-06 Michael Matz <matzmich@cs.tu-berlin.de>
+
+ * flow.c (compute_flow_dominators): Process blocks FIFO not LIFO.
+
+2000-04-06 Alex Samuel <samuel@codesourcery.com>
+
+ * rtl.h (INSN_P): New macro.
+ (successor_phi_fn): New typedef.
+ (for_each_successor_phi): New prototype.
+ (in_ssa_form): New variable.
+ (PHI_NODE_P): Likewise.
+ * flow.c (calculate_global_regs_live): Add to new_live_at_end from
+ phi nodes in successors.
+ (mark_used_regs): Add PHI case.
+ (set_phi_alternative_reg): New function.
+ (life_analysis): Assert that dead code elimination is not selected
+ when in SSA form.
+ * toplev.c (to_ssa_time): New variable.
+ (from_ssa_time): Likewise.
+ (compile_file): Zero to_ssa_time and from_ssa_time.
+ Print time to convert to and from SSA.
+ (rest_of_compilation): Time convert_to_ssa and convert_from_ssa.
+ (print_time): Compute percent fraction as integer.
+ * ssa.c (PHI_NODE_P): Moved to rtl.h.
+ (convert_to_ssa): Check if we're already in SSA.
+ Don't eliminate dead code in life_analysis.
+ Rerun flow and life analysis at bottom.
+ (eliminate_phi): Use canonical regnos when adding nodes.
+ (mark_reg_in_phi): New function.
+ (mark_phi_and_copy_regs): Likewise.
+ (convert_from_ssa): Rerun life analysis at top.
+ Use coalesced partition.
+ Check for removing a phi node at the end of the block.
+ (compute_coalesced_reg_partition): New function.
+ (coalesce_regs_in_copies): Likewise.
+ (coalesce_reg_in_phi): Likewise.
+ (coalesce_regs_in_sucessor_phi_nodes): Likewise.
+ (for_each_successor_phi): Likewise.
+ (rename_context): New struct.
+ (rename_block): Use a rename_context with rename_insn_1. When
+ renaming sets of a subreg, emit a copy of the entire reg first.
+ (rename_insn_1): Treat data as a rename_context *. Save current
+ insn in set_data.
+ (rename_set_data): Add field set_insn.
+ * Makefile.in (HASHTAB_H): Move up in file.
+ (OBSTACK_H): New macro.
+ (collect2.o): Use OBSTACK_H in dependencies.
+ (sdbout.o): Likewise.
+ (emit-rtl.o): Likewise.
+ (simplify-rtx.o): Likewise.
+ (fix-header.o): Likewise.
+ (OBJS): Add conflict.o.
+ (conflict.o): New rule.
+ * basic-block.h: Include partition.h.
+ (conflict_graph): New typedef.
+ (conflict_graph_enum_fn): Likewise.
+ (conflict_graph_new): New prototype.
+ (conflict_graph_delete): Likewise.
+ (conflict_graph_add): Likewise.
+ (conflict_graph_conflict_p): Likewise.
+ (conflict_graph_enum): Likewise.
+ (conflict_graph_merge_regs): Likewise.
+ (conflict_graph_print): Likewise.
+ (conflict_graph_compute): Likewise.
+ * conflict.c: New file.
+
+2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tlink.c (read_repo_files): Don't look for .rpo info for
+ linker flags.
+
+Thu Apr 6 20:39:26 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.h (STRUCT_VALUE, RETURN_IN_MEMORY): Define.
+
+Thu Apr 6 19:34:08 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/sh/lib1funcs.asm (___udivsi3_i4):
+ ( __SH4_SINGLE__ / __SH4_SINGLE_ONLY__ variant): value for fpscr
+ only depends on FMOVD_WORKS.
+
+Thu Apr 6 19:11:47 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * config/sh/lib1funcs.asm (___udivsi3_i4): When using fmovd,
+ make double constant 8-byte aligned.
+
+2000-04-06 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.md (movtf_insn_sp32, movtf_insn_vis_sp32,
+ movtf_no_e_insn_sp32, movtf_insn_hq_sp64, movtf_insn_hq_vis_sp64,
+ movtf_no_e_insn_sp64): Accept loading 0.0 into GENERAL_REGS.
+ (movtf_insn_sp64, movtf_insn_vis_sp64): Likewise.
+ Accept storing GENERAL_REGS into offsetable memory.
+ * config/sparc/sparc.h (PREFERRED_RELOAD_CLASS): Don't allow
+ building a TFmode constant other than 0.0L into GENERAL_REGS.
+
+2000-04-06 Clinton Popetz <cpopetz@cygnus.com>
+
+ * regrename.c (regrename_optimize): Handle no REG_ALLOC_ORDER.
+
+2000-04-06 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpphash.c (CPP_IS_MACRO_BUFFER, FORWARD, PEEKC): Delete.
+ (macro_cleanup): No need to cast pbuf->macro.
+ (collect_expansion): Use _cpp_get_define_token. Goto done if
+ it returns VSPACE. Remove check for trailing space after
+ CPP_COMMENT.
+ (_cpp_create_definition): Don't diddle flags here. Return
+ directly on error.
+ (unsafe_chars): Handle c1 being EOF.
+ (push_macro_expansion): Use unsafe_chars for both accidental-paste
+ checks. Don't push the buffer till after we're done with
+ them.
+ * cpplex.c (PEEKBUF, GETBUF, FORWARDBUF): New.
+ (PEEKN, FORWARD, GETC, PEEKC): Use them.
+ (cpp_push_buffer): Don't set new->alimit. Set new->mark
+ appropriately.
+ (_cpp_parse_assertion): Don't NUL terminate.
+ (_cpp_lex_token): Fix -traditional macro handling. Don't skip
+ hspace before calling _cpp_parse_assertion. Remove all sets
+ of only_seen_white. Treat '\f' as hspace. Don't do anything
+ special with '\n' here.
+ (maybe_macroexpand): Handle T_EMPTY hash entries without
+ pushing a buffer at all.
+ (cpp_get_token): Handle clearing only_seen_white here. Handle
+ incrementing the line number here. Clear
+ potential_control_macro as well as only_seen_white, if
+ appropriate.
+ (cpp_get_non_space_token): Don't eat CPP_POP tokens.
+ (_cpp_get_define_token): New function, basically like
+ _cpp_get_directive_token was but doesn't eat horizontal space.
+ Don't do anything with only_seen_white here.
+ (_cpp_get_directive_token): Just call _cpp_get_define_token
+ repeatedly till it returns non-hspace.
+
+ * cpplib.c (PEEKN, FORWARD, GETC, PEEKC): Delete.
+ (conditional_skip, skip_if_group): Return int.
+ (DIRECTIVE_TABLE): Change origin of all conditional directives
+ to "COND".
+ (TRAD_DIRECT_P): New macro.
+ (_cpp_handle_directive): Use _cpp_get_directive_token. Issue
+ an error for a bogus directive, unless -lang-asm. Use
+ TRAD_DIRECT_P. Loop calling handler functions till one returns
+ zero.
+ (get_macro_name): Don't diddle flags here.
+ (do_define): Diddle flags here. Use _cpp_get_directive_token.
+ Create T_EMPTY nodes for #define macro /* nothing */.
+ (do_undef): Don't copy the name. Use _cpp_get_directive_token.
+ Use hp->name when calling pass_thru_directive.
+ (do_if, do_else, do_elif, do_ifdef, do_ifndef, conditional_skip):
+ Return the result of conditional_skip and/or skip_if_group.
+ Don't call _cpp_output_line_command.
+ (consider_directive_while_skipping): Use _cpp_get_directive_token.
+ Issue -Wtraditional warnings as appropriate. Don't complain
+ about unrecognized directives. If we are to stop skipping,
+ return the number of the directive that ended the skip.
+ (skip_if_group): Use _cpp_get_directive_token. Turn off macro
+ expansion and line commands while skipping. Return the result
+ of consider_directive_while_skipping, if nonzero.
+ (do_endif): Just set potential_control_macro here.
+ (validate_else): Use _cpp_get_directive_token.
+ (do_assert, do_unassert): Don't save pointers into the
+ token_buffer across calls to the lexer. Use
+ _cpp_get_directive_token.
+
+ * cpplib.h (cpp_buffer): Remove alimit and colno. Make mark a
+ pointer, not an offset. Replace 'data', which was a generic
+ pointer, with 'macro', which points to a struct hashnode.
+ (cpp_reader): Add 'potential_control_macro' pointer.
+ * cpphash.h (T_UNUSED): Replace with T_EMPTY.
+ (CPP_BUF_GET, CPP_FORWARD): Delete.
+ (CPP_IN_COLUMN_1, ADJACENT_TO_MARK): New macros.
+ (CPP_IS_MACRO_BUFFER, CPP_SET_BUF_MARK, CPP_GOTO_BUF_MARK,
+ ACTIVE_MARK_P): Update.
+ (_cpp_get_define_token): New internal function.
+ * cppfiles.c (read_include_file): Don't set fp->alimit or fp->colno.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * configure.in: And here.
+ * configure: Regenerate.
+ * acconfig.h: Add ENABLE_STD_NAMESPACE to set flag_honor_std if
+ --enable-libstdcxx-v3 is passed at configure time.
+ * config.h.in: Regenerate.
+
+2000-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * final.c (final): Use xcalloc to allocate line_note_exists.
+ * function.c (free_after_compilation): Free the temp_slots.
+ (assign_stack_temp_for_type): Use xmalloc to allocate temp_slots.
+ (combine_temp_slot): Free temp_slots when they get combined.
+ (purge_addressof): Fix typo in comment.
+ * stmt.c (mark_goto_fixup): Mark the fixup itself.
+ (expand_fixup): Allocate the fixup with ggc_alloc_obj.
+
+ * ggc.h: Include varray.h.
+ (ggc_pending_trees): Declare.
+ (ggc_mark_tree_children): Remove declaration.
+ (ggc_mark_tree): Just push unmarked trees on ggc_pending_trees.
+ * ggc-common.c (ggc_pending_trees): New variable.
+ (ggc_mark_roots): Call ggc_mark_trees.
+ (ggc_mark_tree_children): Rename to ggc_mark_trees. Process all
+ the ggc_pending_trees.
+ * Makefile.in (GGC_H): New variable. Use it throughout in place
+ of ggc.h.
+
+Thu Apr 6 00:30:50 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.h (FUNCTION_ARG_PARTIAL_NREGS): Accomodate an unsigned
+ GET_MODE_SIZE.
+
+Wed Apr 5 23:17:10 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.c (sh_insn_length_adjustment): New function.
+ * sh-protos.h (sh_insn_length_adjustment): Declare.
+ * sh.h (ADJUST_INSN_LENGTH): Use it.
+
+Wed Apr 5 12:35:18 2000 Hans-Peter Nilsson <hp@axis.com>
+
+ * optabs.c (emit_libcall_block): Remove spurious REG_EQUAL notes
+ from the insn where REG_RETVAL is added.
+ (emit_no_conflict_block): Ditto.
+
+ * md.texi (Standard Names): Clarify when movX is needed.
+
+ * combine.c (simplify_comparison) [MINUS]: Do not replace
+ all (op (minus A B) 0) with (op A B).
+
+Wed Apr 5 18:03:31 2000 Toshiyasu Morita (toshi.morita@sega.com)
+ J"orn Rennecke <amylaar@cygnus.co.uk>
+
+ * sh.md (block_lump_real_i4): Add missing clobber of T_REG
+ (block_lump_real): Likewise.
+
+2000-04-05 Chris Demetriou <cgd@netbsd.org>
+
+ * mips.h (MASK_DEBUG_A, MASK_DEBUG_B, MASK_DEBUG_C): Zero the
+ remaining non-zero debugging masks.
+
+Wed Apr 5 09:44:07 2000 Jeffrey A Law (law@cygnus.com)
+
+ * basic-block.h (verify_flow_info): Declare.
+ (flow_loop_outside_edge_p): Declare.
+ * flow.c (verify_flow_info): Remove declaration.
+ (clear_log_links, flow_loop_outside_edge_p): Likewise.
+
+Wed Apr 5 09:34:26 2000 Philippe De Muyter <phdm@macqel.be>
+
+ * m68k/m68k-protos.h (finalize_pic): Turn prototype off using `#if 0',
+ not C++ comments.
+
+2000-04-05 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.md (snedi_zero+1, neg_snedi_zero+1,
+ snedi_zero_trunc+1, seqdi_zero+1, neg_seqdi_zero+1,
+ seqdi_zero_trunc+1): Allow splits only if registers are
+ different.
+
+2000-04-04 Ulrich Drepper <drepper@cygnus.com>
+
+ * acconfig.h: Add HAVE_GAS_HIDDEN.
+ * config.in: Regenerated.
+ * configure.in: Add test for .hidden pseudo-op in gas.
+ * configure: Regenerated.
+ * crtstuff.c: Include auto-host.h.
+ Emit additional .hidden pseudo-op for __dso_handle if the
+ assembler knows about it.
+
+2000-04-04 Philippe De Muyter <phdm@macqel.be>
+
+ * cpphash.c (_cpp_free_definition): Test argnames, not nargs >= 0,
+ before freeing argnames.
+ * cpplib.c (do_ifndef): Cast return value of xstrdup.
+
+2000-04-05 Michael Meissner <meissner@redhat.com>
+
+ * config/rs6000/rs6000.c (print_operand): Patch from Jonathan
+ Walton <jonboy@gordian.com> to make memory references with update
+ work wtih -mregnames.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * regrename.c (regno_first_use_in): Wrap prototype in PARAMS.
+ (regrename_optimize): Rename variables `def_uses' and
+ `ext_basic_blocks' to avoid conflicts with similarly named
+ typedefs in traditional C.
+
+ * calls.c (initialize_argument_information): Fix typo in previous
+ change.
+
+2000-04-04 Richard Henderson <rth@cygnus.com>
+
+ * regrename.c (consider_available): Test fixed_regs not
+ PIC_OFFSET_TABLE_REGNUM.
+
+2000-04-04 Geoff Keating <geoffk@cygnus.com>
+
+ * config/rs6000/t-ppccomm (EXTRA_MULTILIB_PARTS): Add crtbegin,
+ crtend.
+ (CRTSTUFF_T_CFLAGS_S): Delete definition.
+ * config/rs6000/sysv4.h (STARTFILE_LINUX_SPEC): Always use crtbegin.
+ (ENDFILE_LINUX_SPEC): Always use crtend.
+ * configure.in (powerpc-*-linux-gnulibc1): Don't define extra_parts.
+ (powerpc-*-linux-gnu): Likewise.
+ * configure: Regenerate.
+
+ * config/rs6000/eabi.h: Don't include sysv4.h.
+ (MULTILIB_DEFAULTS): Don't define.
+ * config/rs6000/eabiaix.h: Don't include eabi.h.
+ * config/rs6000/eabile.h: Delete.
+ * config/rs6000/eabilesim.h: Delete.
+ * config/rs6000/eabisim.h: Don't include eabi.h.
+ * config/rs6000/linux.h: Don't include sysv4.h.
+ (JUMP_TABLES_IN_TEXT_SECTION): Don't redefine.
+ (MULTILIB_DEFAULTS): Don't redefine.
+ * config/rs6000/rtems.h: Don't include eabi.h.
+ * config/rs6000/sol2.h: Don't include sysv4le.h.
+ * config/rs6000/sysv4le.h: Don't include sysv4.h.
+ * config/rs6000/t-ppc: Delete.
+ * config/rs6000/t-ppcgas: Correct comment.
+ * config/rs6000/t-ppcos: Correct comment. Don't build
+ multilibs for -fPIC, rather use -fPIC -mstrict-align
+ as default.
+ * config/rs6000/t-ppc: Delete.
+ * config/rs6000/vxppc.h: Don't include sysv4.h.
+ * config/rs6000/vxppcle.h: Delete.
+ * configure.in: Use multiple header files for p2pc ELF targets
+ powerpc-eabiaix, powerpc-eabisim, powerpc-rtems, powerpcle-eabi,
+ powerpcle-eabisim, powerpc-elf, powerpcle-elf, powerpc-linux-gnu,
+ powerpc-linux-gnulibc1, powerpc-sysv, powerpcle-sysv,
+ powerpc-vxworks, powerpcle-vxworks. Assume GAS functionality is
+ always available for these platforms.
+
+2000-04-04 Richard Henderson <rth@cygnus.com>
+
+ * calls.c (try_to_integrate): Initialize reg_parm_stack_space.
+
+2000-04-04 Stan Cox <scox@cygnus.com>
+
+ * Makefile.in: Add rules for regrename.o
+ * regrename.c: New file.
+ * rtl.h (regrename_optimize): Add prototype.
+ * toplev.c (rename_registers_dump, flag_rename_registers): New variables
+ (compile_file, decode_d_option): Add support for -frename-registers.
+ (rest_of_compilation): Call regrename_optimize.
+ * config/ia64/ia64.h (HARD_REGNO_RENAME_OK, RENAME_EXTENDED_BLOCKS):
+ New macros.
+
+2000-04-04 Martin v. Löwis <loewis@informatik.hu-berlin.de>
+
+ * Makefile (gccbug): New target.
+ (doc): Depend on it.
+ * gcc.texi (Bugs): Link subnodes.
+ (gccbug): New node.
+ * gccbug.in (CATEGORIES): Remove gc, host, profiling, libgcc.
+ Document severities, priorities, and classes in bug form.
+
+2000-04-04 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplex.c (trigraph_map, speccase): Combine into single
+ table, chartab.
+ (NORMAL, NONTRI): New macros.
+ (_cpp_read_and_prescan): Change to use unified table. Use
+ is_hspace to test for whitespace.
+
+ * dbxout.c (CONTIN): If it doesn't have to do anything, give it a
+ definition that doesn't provoke the "empty body in an
+ if-statement" warning.
+
+2000-04-04 Clinton Popetz <cpopetz@cygnus.com>
+
+ * builtins.c (expand_builtin_strlen): Force the source to
+ be a memory address.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cpplib.c (D): Adjust to call CONCAT2 macro without whitespace.
+
+Tue Apr 4 19:17:20 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * calls.c (ECF_MALLOC, ECF_MAY_BE_ALLOCA, ECF_RETURNS_TWICE,
+ ECF_LONGJMP, ECF_FORK_OR_EXEC): New constants.
+ (ECF_IS_CONST): Rename to ECF_CONST.
+ (special_function_p): Make static, change interface.
+ (flags_from_decl_or_type, try_to_integrate): Break out from ...
+ (expand_call) ... here; convert number of variables to flags.
+ (emit_library_call_vlue_1): Likewise.
+ (setjmp_call_p): New function.
+ (initialize_argument_information): Accepts flags as argument;
+ return flags.
+ (precompute_arguments): Likewise.
+ * tree.h (special_function_p): Remove.
+ (setjmp_call_p): Add prototype.
+
+2000-04-04 Jakub Jelinek <jakub@redhat.com>
+
+ * config/sparc/sparc.h (RTX_OK_FOR_OFFSET_P): Leave minor margin
+ so that addresses are offsetable by up to 16 bytes.
+ (GO_IF_LEGITIMATE_ADDRESS): Don't allow REG+REG addresses for
+ non-optimizing TARGET_ARCH32 in DF or DI modes because it is not
+ offsetable.
+
+ * config/sparc/sparc.md (movdi_insn_sp64_novis): New pattern.
+ (movdi_insn_sp64_vis): Renamed from movdi_insn_sp64.
+ (movsf): Don't force any constant to memory if target is integer
+ hard register.
+ Move fp_zero_operand check below the const0_rtx check.
+ (movtf): Likewise. Also allow fp_zero_operand for stores into
+ memory.
+ (movdf): Likewise. Also allow fp_zero_operand for stores into
+ memory and into integer hard registers.
+ (clear_df, clear_dfp, movdf_const_intreg_sp32,
+ movdf_const_intreg_sp64): Remove.
+ (movdf_insn_sp32, movdf_no_e_insn_sp32): Redo constraints and
+ conditions.
+ (movdf_no_e_insn_v9_sp32): New pattern.
+ (movdf_insn_v9only): Remove.
+ (movdf_insn_v9only_novis, movdf_insn_v9only_vis): New patterns.
+ (movdf_insn_sp64): Remove.
+ (movdf_insn_sp64_novis, movdf_insn_sp64_vis): New patterns.
+ (movdf_no_e_insn_sp64): Allow storing 0.0 into memory.
+ (following splits): Rewrite conditions. Add two new splits
+ for storing 0.0 into memory and registers.
+ (clear_tf, clear_tf+1, clear_tfp, clear_tfp+1): Remove.
+ (movtf_insn_sp32): Redo constraints and conditions.
+ (movtf_insn_vis_sp32): New pattern.
+ (movtf_no_e_insn_sp32): Redo constraints and conditions.
+ (movtf_insn_hq_sp64): Likewise.
+ (movtf_insn_hq_vis_sp64): New pattern.
+ (movtf_insn_sp64): Redo constraints and conditions.
+ (movtf_insn_vis_sp64): New pattern.
+ (movtf_no_e_insn_sp64): Redo constraints and conditions.
+ (movtf_no_e_insn_sp64+1): New split for storing 0.0L into registers
+ or memory.
+ * config/sparc/sparc.c (sparc_override_options): Assume v9 if either
+ -mvis or -m64 to take down the number of various reload patterns.
+
+Tue Apr 4 00:41:53 2000 Jeffrey A Law (law@cygnus.com)
+
+ * pa/pa-64.h: New file.
+ * pa/pa64-regs.h: New file.
+ * pa/pa64-start.h: New file.
+ * pa/t-pa64: New file.
+ * pa/xm-pa64hpux.h: New file.
+
+2000-04-03 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * sparc.c (output_restore_regs): Prototype.
+ (sparc_emit_float_lib_cmp): Constification.
+
+ * emit-rtl.c (const_int_htab_hash, const_int_htab_eq): Likewise.
+
+ * reload1.c (reload_cse_delete_noop_set, reload_cse_simplify):
+ Prototype.
+
+ * simplify-rtx.c (entry_and_rtx_equal_p): Constification.
+ (get_value_hash, hash_rtx): Likewise.
+
+ * ssa.c (compute_conservative_reg_partition): Prototype.
+
+ * tree.c (mark_hash_entry): Prototype.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * bb-reorder.c (verify_insn_chain): #ifdef out unless ENABLE_CHECKING.
+ * i386.h (FUNCTION_ARG_REGNO_P): Remove unnecessary test for N >= 0.
+ * i386.md (call_value, call_value_pop): Remove unused variable 'addr'.
+
+ * gcc.c (C specs): Pass -fno-show-column to the preprocessor.
+ * objc/lang-specs.h: Likewise.
+
+2000-04-03 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: wrap long lines. New macros CPP_ICE, SYNTAX_ERROR
+ and SYNTAX_ERROR2. Replace `' in messages with ''.
+ (op_to_str): Make re-entrant.
+ (_cpp_parse_expr): Implement new error macros. Use | rather
+ than || to logically or 2 boolean integers. Simply expression
+ checking we have a left operand iff needed.
+
+2000-04-03 Nick Clifton <nickc@cygnus.com>
+
+ * Makefile.in (diagnostic.o): Depend upon diagnostic.c
+
+2000-04-03 Philip Blundell <philb@gnu.org>
+
+ * config/arm/linux-elf.h (SUBTARGET_EXTRA_LINK_SPEC): Fix typos.
+
+2000-04-03 Felix Lee <flee@cygnus.com>
+
+ * fixinc/server.c (find_shell): New function. Avoid $SHELL.
+ (run_shell): Use it.
+
+2000-04-03 Jonathan Larmour <jlarmour@redhat.co.uk>
+
+ * Makefile.in (stmp-int-hdrs): Make include subdir here...
+ (stmp-fixproto): ...rather than here.
+
+Mon Apr 3 00:50:06 2000 Jason Eckhardt <jle@cygnus.com>
+
+ * pa.c (print_operand): Compute 'base' only inside the code paths
+ that use it.
+
+2000-04-03 Geoffrey Keating <geoffk@cygnus.com>
+
+ * stor-layout.c (byte_from_pos): Use TRUNC_DIV_EXPR rather than
+ CEIL_DIV_EXPR.
+
+2000-04-03 Philipp Thomas <pthomas@suse.de>
+
+ * i386.h (TARGET_SWITCHES): Remove bogus empty strings, fix typo.
+
+Mon Apr 3 00:02:59 2000 Brad Lucier <lucier@math.purdue.edu>
+
+ * Makefile.in (alias.o): Depend on $(TREE_H).
+
+2000-04-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cppinit.c (cpp_start_read): Turn off -Wtraditional if
+ processing C++.
+ * cpplib.c (_cpp_handle_directive): Improve warnings for
+ traditional C and indented directives.
+
+ * enquire.c, gsyslimits.h, limity.h, config/convex/fixinc.convex,
+ fixinc/fixinc.irix, fixinc/fixinc.sco, fixinc/fixinc.wrap,
+ fixinc/inclhack.def: Indent the # of #include_next one space.
+ * cp/rtti.c: Un-indent #if and #endif.
+
+ * cppexp.c (_cpp_parse_expr): If lex returns '#', it's a
+ syntax error, but an error has already been printed.
+ * cpplex.c (_cpp_parse_assertion): Give a more specific error
+ message when called with nothing remaining on the line.
+ (_cpp_lex_token): If _cpp_parse_assertion fails, return an
+ OTHER token, not an ASSERTION.
+ * cpplib.c (do_assert): When we create a 'base' node, clear
+ its aschain pointer.
+
+2000-04-02 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: New typedef op_t. struct operation and struct
+ token updated to use it.
+ (op_to_str): New function.
+ (_cpp_parse_expr): Error messages modified to use op_to_str.
+
+2000-04-02 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
+
+ * config/c4x/c4x.c (c4x_function_arg): Check for void_type_node
+ before checking MUST_PASS_IN_STACK.
+
+2000-04-02 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: New FINISHED dummy token. Combine operator initial
+ flags and initial priority into a single constant. New
+ EQUALITY macro. New operator flag SHORT_CIRCUIT.
+ (_parse_cpp_expr): Implement new constants. Take left operand
+ checks out of reduction loop. Handle SHORT_CIRCUIT. End of
+ parse indicated by reducing FINISHED token. Remove new lines
+ from cpp_error messages.
+
+2000-04-01 Mark Mitchell <mark@codesourcery.com>
+
+ * emit-rtl.c (gen_rtx_CONST_INT): Create cached CONST_INTs on the
+ permanent obstack.
+
+2000-04-01 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.c: Include symcat.h. Add 'origin' field to struct
+ directive. Add origin values to DIRECTIVE_TABLE. Generate
+ the strings and function names on the fly. Take the #sccs
+ entry out of the table if SCCS_DIRECTIVE is not defined.
+ (_cpp_handle_directive): Decide if the # was at the beginning
+ of the line here. Issue -pedantic warnings for extended
+ directives here. Warn about K+R directives with the #
+ indented, and C89/extended directives with the # not indented,
+ here.
+ (do_import, do_include_next, do_warning, do_ident, do_sccs,
+ do_assert, do_unassert): Don't issue pedantic warning here.
+
+ * cpphash.h: Add CPP_WTRADITIONAL macro.
+ * cpplib.h (struct cpp_options): Rename warn_stringify to
+ warn_traditional; update comments.
+ * cppinit.c (handle_option): Set warn_traditional not
+ warn_stringify.
+ * cpphash.c: Replace CPP_OPTION (pfile, warn_stringify) with
+ CPP_WTRADITIONAL (pfile).
+ * cpplex.c (_cpp_lex_token): Don't decide if directives should
+ be ignored in -traditional mode here.
+
+ * cpplex.c: Copy ISTABLE macros from cppinit.c, and adapt them
+ to initialize speccase[] and trigraph_map[]. Delete all
+ references to pfile->input_speccase. Always treat '?' as a
+ special character. Remove table-initialization code from
+ _cpp_init_input_buffer.
+
+ * cpplib.h (struct cpp_reader): Remove input_speccase field.
+ * cppinit.c (cpp_cleanup): Don't free input_speccase.
+
+2000-04-01 Richard Henderson <rth@cygnus.com>
+
+ * Makefile.in (STAGESTUFF): Wildcard all debugging dumps at once.
+ (mostlyclean): Likewise.
+
+ * toplev.c (rtl_dump, jump_opt_dump, etc): Remove.
+ (struct dump_file_info, enum dump_file_index, dump_file): New.
+ (open_dump_file): Take a dump_file_index not a suffix, and a decl
+ not a string. Clean out file if we havn't yet done so. Do nothing
+ if the dump isn't enabled.
+ (close_dump_file): Do nothing if the dump isn't open. Dump
+ graph data if requested.
+ (dump_rtl, clean_dump_file): Remove.
+ (compile_file): Don't clean the dump files. Only finalize .bp dump
+ if flag_test_coverage or flag_branch_probabilities. Only finalize
+ .combine dump if optimizing. Iterate over dump_file to finalize the
+ graph dumps.
+ (rest_of_compilation): Update for open_dump_file/close_dump_file.
+ Convert all uses of dump_rtl.
+ (decode_d_option): Iterate over dump_file to implement 'a' and to
+ locate pass-specific dumps.
+
+2000-04-01 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: Redefine priority constants.
+ (_cpp_parse_expr): Replace left and right priority scheme with
+ single priority logic. Move LOGICAL to same place as COMPARE.
+ Remove bogus check for multiple unary +/- operators.
+
+2000-04-01 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: (_cpp_parse_expr): Numerical constants are pushed
+ within the switch statement. Binary operations break out of
+ the switch naturally. '(' tokens handled by forcing
+ immediate shift. ')' handled by forcing immediate reduce to
+ the previous '('. New error messages.
+
+2000-03-31 Geoff Keating <geoffk@cygnus.com>
+
+ * config/rs6000/rs6000.c (print_operand): Don't use %l for 'low
+ part', it's already in use. Use %K instead. Add a return at the
+ end of what is now %K.
+ * config/rs6000/rs6000.md (elf_low): Use %K instead of %l.
+
+Sat Apr 1 02:05:29 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * builtins.c (expand_builtin_apply): Pass proper parameters to
+ allocate_dynamic_stack_space.
+ * calls.c (emit_call_1): Do not adjust stack pointer for SIB,
+ update stack_pointer_delta; do not update arg_size_so_far.
+ (compute_argument_block_size): Use stack_delta instead of
+ stack_pointer_pending and arg_size_so_far.
+ (expand_call): Add sanity checking for stack_pointer_delta;
+ save and restore stack_pointer_delta for SIB, use
+ stack_pointer_delta for alignment; do not update arg_space_so_far.
+ (emit_library_call_value): Use stack_pointer_delta for alignment.
+ (store_one_arg): Do not update arg_space_so_far.
+ * explow.c (adjust_stack, anti_adjust_stack): Update
+ stack_pointer_delta.
+ (allocate_dynamic_stack_space): Add sanity checking for
+ stack_pointer_delta.
+ * expr.c (init_expr, clear_pending_stack_adjust): Clear
+ stack_pointer_delta.
+ (emit_push_insn): Update stack_pointer_delta.
+ * function.h (struct expr_status): Add x_stack_pointer_delta;
+ remove x_arg_space_so_far.
+ (arg_space_so_far): Remove.
+ (stack_pointer_delta): New macro.
+
+2000-03-31 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cpplib.h: Merge struct cpp_options into struct cpp_reader.
+ Reorder struct cpp_options and struct cpp_reader for better
+ packing. Replace CPP_OPTIONS macro with CPP_OPTION which
+ takes two args. Change all 'char' flags to 'unsigned char'.
+ Move show_column flag into struct cpp_options. Don't
+ prototype cpp_options_init.
+ * cpphash.h, cpperror.c, cppexp.c, cppfiles.c, cpphash.c,
+ cppinit.c, cpplex.c, cpplib.c:
+ Replace CPP_OPTIONS (pfile)->whatever with
+ CPP_OPTION (pfile, whatever), and likewise for
+ opts = CPP_OPTIONS (pfile); ... opts->whatever;
+
+ * cppinit.c (merge_include_chains): Take a cpp_reader *.
+ Extract CPP_OPTION (pfile, pending) and work with that
+ directly.
+ (cpp_options_init): Delete.
+ (cpp_reader_init): Turn on on-by-default options here.
+ Allocate the pending structure here.
+ (cl_options, enum opt_code): Define these from the same table,
+ kept in a large macro. Add -fshow-column and -fno-show-column
+ options.
+
+ * cpperror.c (v_message): If show_column is off, don't print
+ the column number.
+
+ * cppmain.c: Update for new interface.
+ * fix-header.c: Likewise.
+
+2000-03-30 Geoff Keating <geoffk@cygnus.com>
+
+ * config/rs6000/t-aix43 (AR_FLAGS_FOR_TARGET): Adjust for new
+ definition.
+ * Makefile.in (AR_FLAGS_FOR_TARGET): Is now the flags that
+ are passed to any invocation of AR_FOR_TARGET.
+ (AR_CREATE_FOR_TARGET): New macro.
+ (AR_EXTRACT_FOR_TARGET): New macro.
+ (ORDINARY_FLAGS_TO_PASS): Add AR_CREATE_FOR_TARGET,
+ AR_EXTRACT_FOR_TARGET.
+ (many places): Use AR_CREATE_FOR_TARGET, AR_EXTRACT_FOR_TARGET
+ in place of `$(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET)' and
+ `$(AR_FOR_TARGET) x'. Pass AR_CREATE_FOR_TARGET and
+ AR_EXTRACT_FOR_TARGET to sub-makes.
+
+2000-03-31 Neil Booth <NeilB@earthling.net>
+
+ * cppexp.c: Delete SKIP_OPERAND. Correct priority
+ PAREN_INNER_PRIO.
+ (_cpp_parse_expr): Check for multiple unary +/- operators.
+ Correct priorities of ':' and '?'. Treat ')' as having a
+ value. Ensure conditional expression is not void.
+
+2000-03-31 Mark Mitchell <mark@codesourcery.com>
+
+ * alias.c (canon_rtx): Make it global.
+ (rtx_equal_for_memref_p): CONST_INT equality is now pointer
+ equality.
+ * cse.c (struct table_elt): Add canon_exp.
+ (insert): Clear it.
+ (invalidate): Canonicalize expressions only once.
+ * rtl.h (canon_rtx): Declare.
+
+2000-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (emit-rtl.o): Depend on HASHTAB_H.
+ * alias.c (reg_known_value): Add comments.
+ (init_alias_analysis): Likewise.
+ * cse.c (exp_equiv_p): CONST_INTs are equal iff they have the same
+ address.
+ (cse_basic_block): Fix typo in comment.
+ * emit-rtl.c: Include hashtab.h.
+ (const_int_htab): New variable.
+ (const_int_htab_hash): New function.
+ (const_int_htab_eq): Likewise.
+ (rtx_htab_mark_1): Likewise.
+ (rtx_htab_mark): Likewise.
+ (gen_rtx_CONST_INT): Cache all CONST_INTs.
+ (unshare_all_rtx): Fix formatting.
+ (init_emit_once): Initialize const_int_htab.
+ * rtl.c (rtx_equal_p): CONST_INTs are equal iff they have the same
+ address.
+ * rtl.texi: Document the fact that all CONST_INTs with the same
+ value are shared.
+
+2000-03-30 Richard Henderson <rth@cygnus.com>
+
+ * alpha.h (FUNCTION_BOUNDARY): Reduce to 128 bits.
+
+2000-03-30 Zack Weinberg <zack@wolery.cumb.org>
+
+ * configure.in: Comment out --enable-c-cpplib stanza.
+ * configure: Regenerate.
+
+Thu Mar 30 06:32:51 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (store_constructor): Properly compute displacement and
+ alignment when offset is variable.
+
+ * expmed.c (store_bit_field, store_fixed_bit_field): Fix more
+ cases of alignment in bytes.
+
+Thu Mar 30 13:30:40 2000 Jeffrey A Law (law@cygnus.com)
+
+ * c-parse.in (cast_expr): Move change from March 21 into c-parse.in
+ since it is used to generate c-parse.y.
+ * objc-parse.c, objc-parse.y: Regenerated.
+
+ * function.c (expand_function_end): Pass alignment argument to
+ emit_block_move in bits, not bytes.
+
+Thu Mar 30 06:32:51 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (move_by_pieces_ninsns): Fix one more missing align
+ correction.
+
+ * expmed.c (store_fixed_bit_field): STRUCT_ALIGN is in bits.
+
+ * calls.c (expand_call): Pass bit alignment to mark_reg_pointer.
+ * explow.c (memory_address, allocate_dynamic_stack_space): Likewise.
+ * function.c (assign_parms): Likewise.
+ * integrate.c (expand_inline_function): Likewise.
+ * stmt.c (expand_decl): Likewise.
+ (copy_rtx_and_substitute): Likewise.
+ * expr.c (expand_expr, expand_expr_unaligned): Likewise.
+ (clear_by_pieces): Fix error in last change.
+ * emit-rtl.c (init_emit): Set known registers alignment in bits.
+ * function.h (regno_pointer_align): Now unsigned.
+ * config/arm/arm.c (alignable_memory_operand): REGNO_POINTER_ALIGN
+ is in bits.
+ * config/i386/i386.c (aligned_operand): Likewise.
+ * config/sparc/sparc.c (mem_min_alignment): Likewise.
+ * config/alpha/alpha.c (aligned_memory_operand): Likewise.
+ (unaligned_memory_operand): Likewise.
+ (alpha_expand_block_move, alpha_expand_block_clear): Likewise.
+ Also make alignments and sizes unsigned and some whitespace cleanup.
+ (alpha_va_start): Do nothing if VALIST's type is error_mark_node.
+
+ * builtins.c (get_pointer_alignment): Use host_integerp & tree_low_cst.
+ (expand_builtin_apply): Pass alignment to emit_block_move in bits.
+ (expand_builtin_memcpy, expand_builtin_va_copy): Likewise.
+ (expand_builtin_memset): Likewise, but to clear_storage.
+ * calls.c (save_fixed_argument_area): Likewise, to move_by_pieces.
+ (restore_fixed_argument_area): Likewise.
+ (store_unaligned_arguments_into_pseudos): Likewise, to store_bit_field.
+ (load_register_parameters): Likewise, to emit_group_load.
+ (expand_call): Likewise, to emit_group_store and emit_block_move.
+ (emit_library_call_value_1): Likewise, to emit_block_move.
+ (store_one_arg): Likewise, and to emit_push_insn.
+ * expmed.c (extract_bit_field): Alignment is in bits, not bytes.
+ (extract_fixed_bit_field, extract_split_bit_field): Likewise.
+ * expr.c (move_by_pieces, move_by_pieces_ninsns): Likewise.
+ (emit_block_move, emit_group_load, emit_group_store): Likewise.
+ (clear_by_pieces, clear_storage, emit_push_insn): Likewise.
+ (expand_assigment, store_expr, store_constructor_field): Likewise.
+ (expand_expr_unaligned, do_jump, do_compare_and_jump): Likewise.
+ (store_constructor, store_field, get_inner_reference): Likewise.
+ Use host_integerp and tree_low_cst; sizes and positions HOST_WIDE_INT.
+ (expand_expr, case COMPONENT_REF): Likewise.
+ (copy_blkmode_from_regs): Use UNSIGNED_HOST_WIDE_INT for sizes
+ and positions; reindent code.
+ * expr.h (emit_cmp_insn, emit_cmp_and_jump_insns): Alignment unsigned.
+ * function.c (purge_addressof_1): Pass bit align to store_bit_field.
+ (assign_parms): Likewise to emit_group_store.
+ * optabs.c (prepare_cmp_insn): Alignment is in bits.
+ (emit_cmp_and_jump_insns, emit_cmp_insn): Likewise, and also unsigned.
+ * stmt.c (expand_value_return): Pass align in bits to emit_group_load.
+ (expand_return): Likewise to {extract,store}_bit_field.
+ * stor-layout.c (get_mode_alignment): Minor cleanup.
+ * config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Align is in bits.
+ * config/sh/sh.h (MOVE_BY_PIECES_P): Likewise.
+
+2000-03-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.h: Undo effects of previous delta:
+ (ASM_SPEC): Do not define.
+ (SUBTARGET_EXTRA_ASM_SPEC): Do not define.
+
+ * config/arm/linux-elf.h: (SUBTARGET_EXTRA_ASM_SPEC) Fix
+ typo.
+
+2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cppinit.c (cpp_start_read): Call initialize_dependency_output
+ only after reading in the primary source file.
+
+2000-03-29 Geoff Keating <geoffk@cygnus.com>
+
+ * c-common.c (c_common_nodes_and_builtins): The first parameter to
+ __builtin_va_start and __builtin_va_copy is now either a 'va_list'
+ or a reference to a va_list.
+ * builtins.c (stabilize_va_list): Simplify now we don't have to
+ work around C array address decay.
+ * c-typeck.c (convert_for_assignment): Handle assignment to
+ a reference parameter by taking the address of the RHS.
+ * ginclude/stdarg.h (va_start): Don't take address of first parameter.
+ (va_copy): Likewise.
+ (__va_copy): Likewise.
+ * ginclude/varargs.h (va_start): Likewise.
+ (__va_copy): Likewise.
+
+Wed Mar 29 15:44:53 2000 Jeffrey A Law (law@cygnus.com)
+
+ * i386/djgpp.h: Remove extraneous "+".
+
+ * stmt.c (stmt_loop_nest_empty): Fix thinko in last change.
+
+ * calls.c (expand_call): Fix typo in last change.
+
+2000-03-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * tree.c (unsave_expr_1): Don't mess with a TARGET_EXPR that hasn't
+ been expanded.
+
+Wed Mar 29 15:39:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (bit_from_pos, byte_from_pos): New functions.
+ (pos_from_byte, pos_from_bit, normalize_offset): Likewise.
+ (normalize_rli, rli_size_so_far, rli_size_unit_so_far): Use them.
+ * tree.c (bit_position, byte_position): Likewise.
+ * tree.h: Declare new functions.
+
+2000-03-29 Nick Clifton <nickc@cygnus.com>
+
+ * config/arm/arm.c: Minor formatting changes/
+ * config/arm/arm.h (SUBTARGET_EXTRA_ASM_SPEC): Define if not
+ already defined.
+ (ASM_SPEC): Define if not already defined.
+
+2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cppfiles.c (cpp_read_file): Don't pass zero-length string to
+ _cpp_calc_hash.
+
+2000-03-29 Jakub Jelinek <jakub@redhat.com>
+
+ * dwarf2out.c (gen_enumeration_type_die): If enum has a negative
+ value, don't output it as unsigned.
+
+Wed Mar 29 10:53:49 2000 Jeffrey A Law (law@cygnus.com)
+
+ * stmt.c (stmt_loop_nest_empty): Allow cfun->stmt to be NULL.
+
+2000-03-29 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * c-common.c (c_common_nodes_and_builtins): Don't special case
+ cplus_mode when declaring builtin bzero/bcmp, always avoid
+ prototype arguments.
+
+2000-03-29 Bruce Korb <bkorb@gnu.org>
+
+ * fixinc/mkfixinc.sh: Initially set the variable "fixincludes"
+ to a non-file
+
+Wed Mar 29 15:08:01 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ Convert ACCUMULATE_OUTGOING_ARGS to an expression.
+ * calls.c (PUSH_ARGS_REVERSED) Change to expression.
+ (ACCUMULATE_OUTGOING_ARGS, PUSH_ARGS): Provide default value.
+ (struct arg_data): Remove #ifdef ACCUMULATE_OUTGOING_ARGS.
+ (save_fixed_argument_area, restore_fixed_argument_area):
+ conditionize by #ifdef REG_PARM_STACK_SPACE only.
+ (emit_call): Change #ifdefs on ACCUMULATE_OUTGOING_ARGS
+ to conditions, handle RETURN_POPS_ARGS on ACCUMULATE_OUTGOING_ARGS.
+ (precompute_register_parameters): Avoid #ifdefs on
+ ACCUMULATE_OUTGOING_ARGS and PUSH_ARGS_REVERSED.
+ (stire_one_args): Likewise.
+ (expand_call): Likewise; conditionize PUSH_ROUNDING code by PUSH_ARGS.
+ (emit_library_call_value_1): Likewise.
+ (compute_argument_block_size): Align to STACK_BOUNDARY only for
+ ACCUMULATE_OUTGOING_ARGS.
+ * combine.c (ACCUMULATE_OUTGOING_ARGS, PUSH_ARGS): Provide default
+ value.
+ (nonzero_bits): Conditionize PUSH_ROUNDING code by USE_PUSH.
+ (use_crosses_set_p): Likewise.
+ * all targets (ACCUMULATE_OUTGOING_ARGS define): Change to
+ #define ACCUMULATE_OUTGOING_ARGS 1.
+ * i386.c (ix86_compute_frame_size): Handle ACCUMULATE_OUTGOING_ARGS
+ frames.
+ * i386.h (MASK_NO_PUSH_ARGS, MASK_ACCUMULATE_OUTGOING_ARGS): New
+ constants.
+ (TARGET_PUSH_ARGS, TARGET_ACCUMULATE_OUTGOING_ARGS): New macros.
+ (TARGET_SWITCHES): Add push-args, no-push-args,
+ accumulate-outgoing-args and no-accumulate-outgoing-args.
+ (ACCUMULATE_OUTGOING_ARGS, PUSH_ARGS): New macro.
+ * expr.c (ACCUMULATE_OUTGONG_ARGS, PUSH_ARGS): Provide default.
+ (push_block): Avoid ifdefs on ACCUMULATE_OUTGONG_ARGS
+ and PUSH_ROUNDING.
+ (emit_push_insn): Likewise.
+ * final.c (ACCUMULATE_OUTGOING_ARGS): Provide default.
+ (final_scan_insn): Avoid ifdefs on ACCUMULATE_OUTGOING_ARGS.
+ * function.c (ACCUMULATE_OUTGOING_ARGS): Provide default.
+ (STACK_DYNAMIC_OFFSET): Define correctly for both
+ ACCUMULATE_OUTGOING_ARGS and normal mode.
+ * invoke.texi (-mpush_args, -maccumulate-outgoing-args): Document.
+ * tm.texi (PUSH_ARGS): Document.
+ (ACCUMULATE_OUTGOING_ARGS, PUSH_ROUNDING): Update documentation.
+
+Wed Mar 29 11:51:13 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * flags.h (flag_optimize_sibling_calls): Declare.
+ * calls.c (expand_call): Fail sibcall when
+ !flag_optimize_sibling_calls
+ * invoke.texi (flag_optimize_sibling_calls): Document.
+ * toplev.c (flag_optimize_sibling_calls): New global variable.
+ (f_options): Add flag_optimize_sibling_calls.
+ (rest_of_compilation): Conditionize
+ optimize_sibling_and_tail_recursive_calls by
+ flag_optimize_sibling_calls.
+ (main): Set flag_optimize_sibling_calls for -O2.
+ * stmt.c (expand_return): Conditionize tail recursion by
+ flag_optimize_sibling_calls.
+
+2000-03-29 Richard Henderson <rth@cygnus.com>
+
+ * config/i386/att.h (LOCAL_LABEL_PREFIX): Define.
+ (ASM_GENERATE_INTERNAL_LABEL, ASM_OUTPUT_INTERNAL_LABEL): Use it.
+
+2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * except.c (add_eh_table_entry): Mark type_info's as referenced.
+
+2000-03-29 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * config/rs6000/aix41.h (CPP_SPEC): Define _ANSI_C_SOURCE if -ansi
+ is given.
+ * config/rs6000/aix43.h (CPP_SPEC): Likewise.
+ * config/rs6000/rs6000.h (CPP_SPEC): Moved to...
+ * config/rs6000/aix.h: then modified likewise.
+
+2000-03-28 Richard Henderson <rth@cygnus.com>
+
+ * rtl.h: Redistribute enum reg_note documentation.
+ Kill trailing whitespace.
+ * rtl.c (reg_note_name): Adjust to match enum reg_note tweeks.
+ Kill trailing whitespace.
+
+2000-03-28 Zack Weinberg <zack@wolery.cumb.org>
+
+ * cppfiles.c (hash_IHASH): Just return i->hash.
+ (cpp_included): Set dummy.hash using _cpp_calc_hash. Use
+ htab_find_with_hash.
+ (cpp_read_file): Likewise.
+ (find_include_file): Likewise. Properly initialize
+ ih->nshort. Share ih->name and ih->nshort if possible.
+ * cpphash.c (_cpp_calc_hash): New function.
+ (hash_HASHNODE): Just return h->hash.
+ (_cpp_lookup): Set dummy.hash using _cpp_calc_hash. Use
+ htab_find_with_hash.
+ * cpphash.h: Prototype _cpp_calc_hash.
+ * cppinit.c (initialize_builtins): Provide a valid hash
+ to _cpp_make_hashnode, using _cpp_calc_hash.
+
+ * cpphash.c (collect_expansion): # is not a special character
+ in object-like macros. In -traditional mode, /**/ is not
+ token paste at the beginning or end of the line.
+ * cpplib.c (do_include, do_import, do_include_next): If
+ parse_include fails, return immediately.
+
+2000-03-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * config/arm/arm.md (return peepholes): Update to reflect the new
+ call insn patterns.
+ * config/arm/arm.c (arm_volatile_func): Also check
+ current_function_nothrow.
+ (output_return_instruction, output_func_prologue): Use it.
+ (arm_output_epilogue, arm_expand_prologue): Likewise.
+
+2000-03-27 Tom Tromey <tromey@cygnus.com>
+
+ * gcc.c (handle_braces): In {x*...} case, break out of loop if
+ switch is found.
+
+Tue Mar 28 11:55:48 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (store_constructor): SIZE now signed.
+ For EXPR_SIZE, don't evaluate size; just needed if constant.
+ * fold-const.c (fold): Fix a number of cases when folded tree is
+ wrong type.
+ * function.c (flush_addressof): Reenable.
+ * tree.h (flush_addressof): Likewise.
+ * toplev.c (independent_decode_option): Look at strings_processed.
+ * config/alpha/alpha.h (MINIMUM_ATOMIC_ALIGNMENT): Cast to unsigned.
+
+Tue Mar 28 08:29:46 2000 Jan Hubicka <jh@suse.cz>
+
+ * sibcall.c (indentify_call_return_value): Find last call in the chain;
+ Allow stack adjustment after function call.
+
+ * regmove.c (struct csa_memlist): Make mem field rtx *.
+ (record_one_stack_ref): Accept rtx * instead of rtx as parameter.
+ (try_apply_stack_adjustment): Replace whole MEM rtx.
+ (combine_stack_adjustments_for_block): Update calls
+ to record_one_stack_ref.
+
+2000-03-28 Neil Booth <NeilB@earthling.net>
+
+ * cpplex.c (_cpp_read_and_prescan): Mark end of input buffer with
+ '\\' rather than a null character, so nulls are not special. Fix
+ "\\\n" handling in end-of-buffer conditions. Use trigraph map to
+ speed trigraph conversion.
+ (_cpp_init_input_buffer): Initialize trigraph map.
+
+2000-03-27 Alan Modra <alan@linuxcare.com.au>
+
+ * config/i386/i386.c (output_387_binary_op): Correct intel
+ mode assembly output, and add spaces after commas in AT&T
+ output. Correct Unixware assembler comment. Document input
+ constraints. Comment fp operations. Reduce profligate buffer
+ size. Remove extraneous abort. Localize temp var.
+ (SYSV386_COMPAT): Define. Add !SYSV386_COMPAT code.
+ (output_fix_trunc): Add spaces after commas in assembly output.
+
+2000-03-27 Richard Henderson <rth@cygnus.com>
+
+ * i386-protos.h (ix86_match_ccmode): Declare.
+ * i386.c (ix86_match_ccmode): New.
+ (ix86_expand_fp_compare): Update for pattern renames.
+ (ix86_expand_strlensi_unroll_1): Likewise.
+ * i386.h (EXTRA_CC_MODES): Add CCZ.
+ (SELECT_CC_MODE): Use it for EQ/NE zero.
+ * i386.md (cmpsi_ccz_1): New.
+ (cmpqi_ccz_1): New.
+ (*testsi_ccz_1): New.
+ (testqi_ccz_1): New.
+ (cmpsi_ccno_1): Rename from cmpsi_0.
+ (testsi_ccno_1): Rename from testsi_1.
+ (testqi_ccno_1): Rename from testqi_1.
+ (*testqi_ext_ccz_0): Rename from testqi_ext_0.
+ (testqi_ext_ccno_0): Rename from *testqi_ext_1.
+ (*cmphi_0): Use ix86_match_ccmode.
+ (*cmpqi_ext_2, *addsi_2, *addhi_2, *addqi_2): Likewise.
+ (*subsi_2, *subhi_2, *subqi_2, *testhi_1): Likewise.
+ (*testqi_ext_1, *testqi_ext_2, *testqi_ext_3): Likewise.
+ (*andsi_2, *andhi_2, *andqi_2, *andqi_ext_0_cc): Likewise.
+ (*iorsi_2, *iorhi_2, *iorqi_2): Likewise.
+ (*xorsi_2, *xorhi_2, *xorqi_cc_1): Likewise.
+ (*one_cmplsi2_2, *one_cmplhi2_2, *one_cmplqi2_2): Likewise.
+ (*ashlsi3_cmpno, *ashlhi3_cmpno, *ashlqi3_cmpno): Likewise.
+ (*ashrsi3_cmpno, *ashrhi3_cmpno, *ashrqi3_cmpno): Likewise.
+ (*lshrsi3_cmpno, *lshrhi3_cmpno, *lshrqi3_cmpno): Likewise.
+ (appropriate peepholes): Likewise.
+ (*cmphi_1, *cmpqi_ccno_1, *cmpqi_1): Star out name.
+ (*subsi_3, *subhi_3, *subqi_3): Remove.
+ (*negdi2_1+1 splitter): Use CCZ for neg patterns.
+ (*negsi2_cmp, *neghi2_cmp, *negqi2_cmp): Remove.
+ (*negsi2_cmpz): Rename from *negsi2_cmpno, use CCZ.
+ (*neghi2_cmpz, *negqi2_cmpz): Similarly.
+ (x86_shift_adj_1): Use CCZ.
+ (*dbra_ge+1, *dbra_ge+2, ffssi2, ffssi_1): Likewise.
+
+2000-03-27 Stan Cox <scox@cygnus.com>
+
+ * resource.h (mark_resource_type): New.
+ * resource.c (find_dead_or_set_registers, mark_target_live_regs,
+ find_free_register): Use mark_resource_type.
+ (mark_set_resources): Change include_delayed_effects
+ to mark_resource_type.
+ * reorg.c (steal_delay_list_from_target, try_merge_delay_insns,
+ redundant_insn, fill_simple_delay_slots, fill_slots_from_thread):
+ Use mark_resource_type.
+
+2000-03-27 Richard Henderson <rth@cygnus.com>
+
+ * i386.md (call_pop_0, call_value_pop_0): New.
+ (call_pop_1): Remove constraint from unused arg. Support sibcalls.
+ (call_value_pop_1): Likewise.
+ (call_0, call_value_0): New.
+ (call_1, call_value_1): Remove constraint from unused arg.
+
+2000-03-27 Nick Clifton <nickc@cygnus.com>
+
+ * invoke.texi (Spec Files): Document new spec % command created by
+ Tom Tromey's recent patch.
+
+2000-03-27 Jakub Jelinek <jakub@redhat.com>
+
+ * libgcc2.h (MIN_UNITS_PER_WORD): Define to UNITS_PER_WORD
+ if not defined.
+
+Mon Mar 27 06:04:22 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (expand_assignment): Fix typo in last change.
+
+ * libgcc2.h: Use MIN_UNITS_PER_WORD, not UNITS_PER_WORD.
+
+Sun Mar 26 20:15:26 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * c-convert.c (convert): Return if output or input type is ERROR_MARK.
+ * c-decl.c (duplicate_decls): Only look at DECL_BUILT_IN_NONANSI
+ and DECL_INLINE if FUNCTION_DECL.
+ (pushdecl, redeclaration_error_message): Likewise, for DECL_INLINE.
+ (store_parm_decls): Check for type of PARM_DECL being ERROR_MARK.
+ Use DECL_WEAK, not DECL_RESULT, to flag for already seen.
+ (combine_parm_decls): Likewise.
+ * ggc-common.c (gcc_mark_tree_children, case 'd'): Use DECL_RESULT_FLD.
+ * print-tree.c (print_node): Likewise.
+ Only test DECL_PACKED, DECL_INLINE, DECL_BIT_FIELD, and
+ DECL_TRANSPARENT_UNION on proper decl types.
+ Properly handly DECL_INCOMING_RTL and DECL_SAVED_INSNS.
+ * stor-layout.c (layout_decl): Only check DECL_PACKED and
+ DECL_BIT_FIELD of FIELD_DECL.
+ * tree.h (DECL_RESULT_FLD): New macro.
+
+ * expr.c (expand_assignment): Add code to handle variable-sized
+ BLKmode case.
+
+2000-03-26 Richard Henderson <rth@cygnus.com>
+
+ * calls.c (expand_call): Pass parms not original exp to
+ optimize_tail_recursion. Mind return value instead of looking
+ for a barrier.
+ * stmt.c (optimize_tail_recursion): Take parameter list, not entire
+ call_expr. Move checks for call_expr and current_function_decl ...
+ (expand_return): ... here.
+
+2000-03-26 Tom Tromey <tromey@cygnus.com>
+
+ * gcc.c (handle_braces): Recognize `%{<S}' construct.
+ (SWITCH_OK, SWITCH_FALSE, SWITCH_IGNORE, SWITCH_LIVE): New
+ defines.
+ (process_command): Use them.
+ (check_live_switch): Likewise.
+ (give_switch): Skip ignored switches.
+
+2000-03-26 Jan Hubicka <jh@suse.cz>
+
+ * jump.c (jump_optimize_1): Fix typo in elide optimizations
+ for minimal jump pass test.
+
+2000-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * integrate.c (function_cannot_inline_p): Do inline functions that
+ return `void'.
+
+Sun Mar 26 11:37:55 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * stor-layout.c (layout_type, set_sizetype): early_type_list is
+ now a list of TREE_LIST entries, not types.
+ * tree.c (build_common_tree_nodes_2): Eliminate dupliate type sets.
+
+ * expmed.c (extract_bit_field): Ensure BITS_PER_WORD is signed in MAX.
+ * config/arm/pe.c (arm_pe_return_in_memory): Use host_integerp and
+ int_bit_position.
+ * config/mips/mips.c (function_arg): Likewise; also remove cast
+ and make variables unsigned or HOST_WIDE_INT and use tree_low_cst.
+ (mips_function_value): Use int_byte_position and make HOST_WIDE_INT.
+ * config/mips/abi64.h (SETUP_INCOMING_VARARGS): Offsets are unsigned.
+ * config/mips/mips.h (BITS_PER_WORD, UNITS_PER_WORD): Cast to unsigned.
+ (UNITS_PER_FPREG, INT_TYPE_SIZE, LONG_TYPE_SIZE): Likewise.
+ (POINTER_SIZE, POINTER_BOUNDARY,PARM_BOUNDARY): Likewise.
+ (GP_REG_P, FP_REG_P, MD_REG_P, ST_REG_P): Ensure subtraction signed.
+ (struct mips_arg): arg_number, arg_words, fp_arg_words, and
+ num_adjusts now unsigned.
+ (FUNCTION_ARG_BOUNDARY): Remove unneeded cast.
+ * config/sparc/sparc.c (struct function_arg_record_value_parms):
+ NREGS now unsigned.
+ (function_arg_record_value_1): STARTBITPOS arg now HOST_WIDE_INT
+ as is BITPOS variable; use host_integerp and int_bit_position.
+ (function_arg_record_value_2): Likewise.
+ (function_arg_record_value_3): Arg BITPOS now HOST_WIDE_INT.
+ Variable REGNO now unsigned.
+ (function_arg_record_value): NREGS now unsigned.
+
+2000-03-26 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * jump.c (mark_all_labels): Handle CALL_PLACEHOLDERs.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * Rework fields used to describe positions of bitfields and
+ modify sizes to be unsigned and use HOST_WIDE_INT.
+ * alias.c (reg_known_value_size): Now unsigned.
+ * c-typeck.c (build_unary_op, case ADDR_EXPR): Use byte_position.
+ (really_start_incremental_init): Use bitsize_zero_node.
+ (push_init_level, pop_init_level, output_init_element): Likewise.
+ Use bitsize_unit_node and bitsize_one_node.
+ (output_pending_init_elements, process_init_element): Likewise.
+ * combine.c (combine_max_regno, reg_sign_bit_copies): Now unsigned.
+ (make_extraction): Position and length HOST_WIDE_INT and unsigned
+ HOST_WIDE_INT, respectively.
+ (get_pos_from_mask): Passed in value is unsigned HOST_WIDE_INT.
+ (num_sign_bit_copies): Returns unsigned.
+ BITWIDTH now unsigned; rework arithmetic.
+ Remove recursive call from arg to MAX.
+ (combine_instructions, init_reg_last_arrays): NREGS now unsigned.
+ (setup_incoming_promotions, can_combine_p, try_combine, simplify_set):
+ REGNO now unsigned.
+ (set_nonzero_bit_and_sign_copies): NUM now unsigned.
+ (find_split_point, expand_compound_operation, make_extraction): LEN
+ now unsigned HOST_WIDE_INT, POS now HOST_WIDE_INT.
+ (make_field_assignment): Likewise.
+ (combine_simplify_rtx): Add cast.
+ (expand_compound_operation): MODEWIDTH now unsigned; rework arithmetic.
+ (force_to_mode): WIDTH now unsigned; add cast.
+ (if_then_else_cond): SIZE now unsigned.
+ (nonzero_bits): MODE_WIDTH, RESULT_WIDTH, and WIDTH now unsigned.
+ (extended_count): Now returns unsigned.
+ (simplify_shift_const): COUNT unsigned; arg is now INPUT_COUNT.
+ Add SIGNED_COUNT variable; MODE_WORDS and FIRST_COUNT now unsigned.
+ (simplify_comparison): MODE_WIDTH now unsigned.
+ (update_table_tick): REGNO and ENDREGNO now unsigned; new var R.
+ (mark_used_regs_combine): Likewise; rework arithmetic.
+ (record_value_for_reg): REGNO, ENDREGNO, and I now unsigned.
+ (record_dead_and_set_regs, reg_dead_at_p, distribute_notes): Likewise.
+ (record_promoted_value): REGNO now unsigned.
+ (get_last_value_validate): REGNO, ENDREGNO, and J now unsigned.
+ (get_last_value): REGNO now unsigned.
+ (use_crosses_set_p): REGNO and ENDREGNO now unsigned.
+ (reg_dead_regno, reg_dead_endregno): Now unsigned.
+ (remove_death): Arg REGNO now unsigned.
+ (move_deaths): REGNO, DEADREGNO, DEADEND, OUREND, and I now unsigned.
+ (reg_bitfield_target_p): REGNO, REGNO, ENDREGNO, and ENDTREGNO
+ now unsigned.
+ * convert.c (convert_to_integer): INPREC and OUTPREC now unsigned.
+ * cse.c (struct qty_table_elem): FIRST_REG and LAST_REG now unsigned.
+ (struct cse_reg_info): REGNO now unsigned.
+ (cached_regno): Now unsigned.
+ (REGNO_QTY_VALID_P): Add cast.
+ (make_new_qty, make_regs_eqv, delete_reg_eqiv): Regno args unsigned.
+ (remove_invalid_regs): Likewise.
+ (remove_invalid_subreg_refs): Likewise; arg WORD also unsigned
+ as are variables END and I.
+ (get_cse_reg_info, insert): Likewise.
+ (mention_regs, invalidate_for_call): REGNO, ENDREGNO, and I unsigned.
+ (canon_hash): Likewise.
+ (insert_regs, lookup_for_remove): REGNO now unsigned.
+ (invalidate): REGNO, ENDREGNO, TREGNO, and TENDREGNO now unsigned.
+ New variable RN.
+ * dbxout.c (dbxout_parms, dbxout_reg_parms): Don't check for REGNO < 0.
+ * dwarf2out.c (dwarf2ou_frame_debug_expr): Remove cast.
+ * emit-rtl.c (subreg_realpart_p): Add cast.
+ (operand_subword): Arg I is now unsigned as is var PARTWORDS.
+ (operand_subword_force): Arg I is now unsigned.
+ * except.c (eh_regs): Variable I is now unsigned.
+ * explow.c (hard_function_value): BYTES is unsigned HOST_WIDE_INT.
+ * expmed.c (store_fixed_bit_field): Position is HOST_WIDE_INT;
+ length is unsigned HOST_WIDE_INT; likewise for internal variables.
+ (store_split_bit_field, extract_fixed_bit_field): Likewise.
+ (extract_split_bit_field, store_bit_field, extract_bit_field):
+ Likewise.
+ * expr.c (store_constructor_fields, store_constructor, store_field):
+ Positions are HOST_WIDE_INT and lengths are unsigned HOST_WIDE_INT.
+ (expand_assignment, expand_expr, expand_expr_unaligned): Likewise.
+ (do_jump): Likewise.
+ (move_by_pieces, move_by_pieces_ninsns, clear_by_pieces):
+ MAX_SIZE is now unsigned.
+ (emit_group_load): BYTEPOS is HOST_WIDE_INT; BYTELEN is unsigned.
+ (emit_group_store): Likewise.
+ (emit_move_insn): I now unsigned.
+ (store_constructor): Use host_integerp, tree_low_cst, and
+ bitsize_unit_node.
+ (get_inner_reference): Return bitpos and bitsize as HOST_WIDE_INT.
+ Rework all calculations to use trees and new fields.
+ * expr.h (promoted_input_arg): Regno now unsigned.
+ (store_bit_field, extract_bit_field): Adjust types of pos and size.
+ (mark_seen_cases): Arg is HOST_WIDE_INT.
+ * flow.c (verify_wide_reg_1): REGNO now unsigned.
+ * fold-const.c (decode_field_reference): Size and pos HOST_WIDE_INT;
+ precisions and alignments are unsigned.
+ (optimize_bit_field_compare, fold_truthop): Likewise.
+ (int_const_binop): Adjust threshold for size_int_type_wide call.
+ (fold_convert): Likewise.
+ (size_int_type_wide): Make table larger and fix thinko that only
+ had half of table used.
+ (all_ones_mask_p, fold): Precisions are unsigned.
+ * function.c (put_reg_info_stack): REGNO is unsigned.
+ (instantiate_decl): Size is HOST_WIDE_INT.
+ (instantiate_virtual_regs): I is unsigned.
+ (assign_parms): REGNO, REGNOI, and REGNOR are unsigned.
+ (promoted_input_arg): REGNO is unsigned.
+ * function.h (struct function): x_max_parm_reg is now unsigned.
+ * gcse.c (max_gcse_regno): Now unsigned.
+ (struct null_pointer_info): min_reg and max_reg now unsigned.
+ (lookup_set, next_set): REGNO arg now unsigned.
+ (compute_hash_table): REGNO and I now unsigned.
+ (handle_avail_expr): regnum_for_replacing now unsigned.
+ (cprop_insn): REGNO now unsigned.
+ (delete_null_pointer_checks_1): BLOCK_REG now pointer to unsigned.
+ * ggc-common.c (ggc_mark_tree_children, case FIELD_DECL): New case.
+ * global.c (set_preference): SRC_REGNO, DEST_REGNO, and I now unsigned.
+ * hard-reg-set.h (reg_class_size): Now unsigned.
+ * integrate.c (mark_stores): LAST_REG and I now unsigned; new UREGNO.
+ * jump.c (mark_modified_reg): I now unsigned; add cast.
+ (rtx_equal_for_thread_p): Add cast.
+ * loop.c (max_reg_before_loop): Now unsigned.
+ (struct_movable): REGNO now unsigned.
+ (try_copy_prop): REGNO arg unsigned.
+ (regs_match_p): XN and YN now unsigned.
+ (consec_sets_invariant_p, maybe_eliminate_biv): REGNO now unsigned.
+ (strength_reduce): Likewise; NREGS also unsigned.
+ (first_increment_giv, last_increment_giv unsigned): Now unsigned.
+ * loop.h (struct iv_class): REGNO now unsigned.
+ (max_reg_before_loop, first_increment_giv, last_increment_giv):
+ Now unsigned.
+ * machmode.h (mode_size, mode_unit_size): Now unsigned.
+ (mode_for_size, smallest_mode_for_size): Pass size as unsigned.
+ * optabs.c (expand_binop): I and NWORDS now unsigned.
+ (expand_unop): I now unsigned.
+ * print-tree.c (print_node): Don't print DECL_FIELD_BITPOS, but do
+ print DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.
+ * real.c (significand_size): Now returns unsigned.
+ * real.h (significand_size): Likewise.
+ * regclass.c (reg_class_size): Now unsigned.
+ (choose_hard_reg_mode): Both operands now unsigned.
+ (record_reg_classes): REGNO and NR now unsigned.
+ (reg_scan): NREGS now unsigned.
+ (reg_scan_update): old_max_regno now unsigned.
+ (reg_scan_mark_refs): Arg MIN_REGNO and var REGNO now unsigned.
+ * reload.c (find_valid_class): BEST_SIZE now unsigned.
+ (find_dummy_reload): REGNO, NWORDS, and I now unsigned.
+ (hard_reg_set_here_p): Args BEG_REGNO and END_REGNO now unsigned.
+ Likewise for variable R.
+ (refers_to_regno_for_reload_p): Args REGNO and END_REGNO now unsigned,
+ as are variables INNER_REGNO and INNER_ENDREGNO; add new variable R.
+ (find_equiv_reg): Add casts.
+ (regno_clobbered_p): Arg REGNO now unsigned.
+ * reload.h (struct reload): NREGS now unsigned.
+ (refers_to_regno_for_reload_p): Regno args are unsigned.
+ (regno_clobbered_p): Likewise.
+ * reload1.c (reg_max_ref_width, spill_stack_slot_width): Now unsigned.
+ (compute_use_by_pseudos): REGNO now unsigned.
+ (find_reg): I and J now unsigned, new variable K, and change loop
+ variables accordingly; THIS_NREGS now unsigned.
+ (alter_reg): INHERENT_SIZE and TOTAL_SIZE now unsigned.
+ (spill_hard_reg): REGNO arg now unsigned; add casts.
+ (forget_old_reloads_1): REGNO, NR, and I now unsigned.
+ (mark_reload_reg_in_use): Arg REGNO and vars NREGS and I now unsigned.
+ (clear_reload_reg_in_use): Arg REGNO and vars NREGS, START_REGNO,
+ END_REGNO, CONFLICT_START, and CONFLICT_END now unsigned.
+ (reload_reg_free_p, reload_reg_reaches_end_p): Arg REGNO now unsigned.
+ (choose_reload_regs): MAX_GROUP_SIZE now unsigned.
+ (emit_reload_insns): REGNO now unsigned.
+ (reload_cse_move2add): Add cast.
+ (move2add_note_store): REGNO and I now unsigned; new variable ENDREGNO
+ and rework loop.
+ * resource.c (mark_referenced_resources, mark_set_resources): New
+ variable R; REGNO and LAST_REGNO now unsigned.
+ (mark_target_live_regs): J and REGNO now unsigned.
+ * rtl.c (mode_size, mode_unit_size): Now unsigned.
+ * rtl.h (union rtunion_def): New field rtuint.
+ (XCUINT): New macro.
+ (ADDRESSOF_REGNO, REGNO, SUBREG_WORD): New XCUINT.
+ (operand_subword, operand_subword_force): Word number is unsigned.
+ (choose_hard_reg_mode): Operands are unsigned.
+ (refers_to-regno_p, dead_or_set_regno_p): Regno arg is unsigned.
+ (find_regno_note, find_regno_fusage, replace_regs): Likewise.
+ (regno_use_in, combine_instructions, remove_death): Likewise.
+ (reg_scan, reg_scan_update): Likewise.
+ (extended_count): Return is unsigned.
+ * rtlanal.c (refers_to_regno_p): Args REGNO and ENDREGNO and vars I,
+ INNER_REGNO, and INNER_ENDREGNO now unsigned; new variable X_REGNO.
+ (reg_overlap_mentioned_p): REGNO and ENDREGNO now unsigned.
+ (reg_set_last_first_regno, reg_set_last_last_regno): Now unsigned.
+ (reg_reg_last_1): FIRS and LAST now unsigned.
+ (dead_or_set_p): REGNO, LAST_REGNO, and I now unsigned.
+ (dead_or_set_regno_p): Arg TEST_REGNO and vars REGNO and ENDREGNO
+ now unsigned.
+ (find_regno_note, regno_use_in): Arg REGNO now unsigned.
+ (find_regno_fusage): Likewise; also var REGNOTE now unsigned.
+ (find_reg_fusage): Variables REGNO, END_REGNO, and I now unsigned.
+ (replace_regs): Arg NREGS now unsigned.
+ * sdbout.c (sdbout_parms, sdbout_reg_parms): Don't check REGNO < 0.
+ * simplify-rtx.c (simplify_unary_operation): WIDTH now unsigned.
+ (simplify_binary_operation): Likewise.
+ (cselib_invalidate_regno): Arg REGNO and variables ENDREGNO, I, and
+ THIS_LAST now unsigned.
+ (cselib_record_set): Add cast.
+ * ssa.c (ssa_max_reg_num): Now unsigned.
+ (rename_block): REGNO now unsigned.
+ * stmt.c (expand_return): Bit positions unsigned HOST_WIDE_INT;
+ sizes now unsigned.
+ (all_cases_count): Just return -1 not -2.
+ COUNT, MINVAL, and LASTVAL now HOST_WIDE_INT.
+ Rework tests to use trees whenever possible.
+ Use host_integerp and tree_low_cst.
+ (mark_seen_cases): COUNT arg now HOST_WIDE_INT;
+ Likewise variable NEXT_NODE_OFFSET; XLO now unsigned.
+ (check_for_full_enumeration_handing): BYTES_NEEDED, I to HOST_WIDE_INT.
+ * stor-layout.c (mode_for_size): SIZE arg now unsigned.
+ (smallest_mode_for_size): Likewise.
+ (layout_decl): Simplify handing of a specified DECL_SIZE_UNIT.
+ KNOWN_ALIGN is now an alignment, so simplify code.
+ Don't turn off DECL_BIT_FIELD if field is BLKmode, but not type.
+ (start_record_layout): Renamed from new_record_layout_info.
+ Update to new fields.
+ (debug_rli, normalize_rli, rli_size_unit_so_far, rli_size_so_far):
+ New functions.
+ (place_union_field): Renamed from layout_union_field.
+ Update to use new fields in rli.
+ (place_field): Renamed from layout_field.
+ Major rewrite to use new fields in rli; pass alignment to layout_decl.
+ (finalize_record_size): Rework to use new fields in rli and handle
+ union.
+ (compute_record_mode): Rework to simplify and to use new DECL fields.
+ (finalize_type_size): Make rounding more consistent.
+ (finish_union_layout): Deleted.
+ (layout_type, case VOID_TYPE): Don't set TYPE_SIZE_UNIT either.
+ (layout_type, case RECORD_TYPE): Call new function names.
+ (initialize_sizetypes): Set TYPE_IS_SIZETYPE.
+ (set_sizetype): Set TYPE_IS_SIZETYPE earlier.
+ (get_best_mode): UNIT is now unsigned; remove casts.
+ * tree.c (bit_position): Compute from new fields.
+ (byte_position, int_byte_position): New functions.
+ (print_type_hash_statistics): Cast to remove warning.
+ (build_range_type): Use host_integerp and tree_low_cst to try to hash.
+ (build_index_type): Likewise; make subtype of sizetype.
+ (build_index_2_type): Pass sizetype to build_range_type.
+ (build_common_tree_nodes): Use size_int and bitsize_int to
+ initialize nodes; add bitsize_{zero,one,unit}_node.
+ * tree.h (DECL_FIELD_CONTEXT): Use FIELD_DECL_CHECK.
+ (DECL_BIT_FIELD_TYPE, DECL_QUALIFIER, DECL_FCONTEXT): Likewise.
+ (DECL_PACKED, DECL_BIT_FIELD): Likewise.
+ (DECL_FIELD_BITPOS): Deleted.
+ (DECL_FIELD_OFFSET, DECL_FIELD_BIT_OFFSET): New fields.
+ (DECL_RESULT, DECL_SAVED_INSNS): Use FUNCTION_DECL_CHECK.
+ (DECL_FRAME_SIZE, DECL_FUNCTION_CODE, DECL_NO_STATIC_CHAIN): Likewise.
+ (DECL_INLINE, DECL_BUILT_IN_NONANSI, DECL_IS_MALLOC): Likewise.
+ (DECL_BUILT_IN_CLASS, DECL_STATIC_CONSTRUCTOR): Likewise.
+ (DECL_STATIC_DESTRUCTOR, DECL_NO_CHECK_MEMORY_USAGE): Likewise.
+ (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT, DECL_NO_LIMIT_STACK) Likewise.
+ (DECL_ORIGINAL_TYPE, TYPE_DECL_SUPPRESS_DEBUG): Use TYPE_DECL_CHECK.
+ (DECL_ARG_TYPE_AS_WRITEN, DECL_ARG_TYPE): Use PARM_DECL_CHECK.
+ (DECL_INCOMING_RTL, DECL_TRANSPARENT_UNION): Likewise.
+ (DECL_ALIGN): Adjust to new field in union.
+ (DECL_OFFSET_ALIGN): New field.
+ (DECL_ERROR_ISSUED, DECL_TOO_LATE): Use LABEL_DECL_CHECK.
+ (DECL_IN_TEXT_SECTION): Use VAR_DECL_CHECK.
+ (union tree_decl): Add struct for both aligns.
+ (enum tree_index): Add TI_BITSIZE_{ZERO,ONE,UNIT}.
+ (bitsize_zero_node, bitsize_one_node, bitsize_unit_node): Added.
+ (struct record_layout_info): Rework fields to have offset
+ alignment and byte and bit position.
+ (start_record_layout, place_field): Renamed from old names.
+ (rli_size_so_far, rli_size_unit_so_far, normalize_rli): New decls.
+ (byte_position, int_byte_position): Likewise.
+ (get_inner_reference): Change types of position and length.
+ * unroll.c (unroll_loop): New variable R; use for some loops.
+ MAX_LOCAL_REGNUM and MAXREGNUM now unsigned.
+ (calculate_giv_inc): Arg REGNO now unsigned.
+ (copy_loop_body): REGNO and SRC_REGNO now unsigned.
+ * varasm.c (assemble_variable): Clean up handling of size using
+ host_integerp and tree_low_cst.
+ (decode_addr_const): Use byte, not bit, position.
+ (output_constructor): bitpos and offsets are HOST_WIDE_INT;
+ use tree_low_cst and int_bit_position.
+ * objc/objc-act.c (build_ivar_list_initializer): Use byte_position.
+
Fri Mar 24 20:13:49 2000 Jason Eckhardt <jle@cygnus.com>
* bb-reorder.c (REORDER_MOVED_BLOCK_END): Removed.
@@ -542,8 +2200,8 @@ Thu Mar 23 11:34:39 2000 Jim Wilson <wilson@cygnus.com>
Thu Mar 23 16:04:40 2000 Andrew Haley <aph@cygnus.com>
- * config/mips/mips.md (movdf_internal1a): Delete (set 'f', 'F')
- alternative when using -fp64 -gp32.
+ * config/mips/mips.md (movdf_internal1a): Delete (set 'f', 'F')
+ alternative when using -fp64 -gp32.
2000-03-22 Jason Merrill <jason@casey.cygnus.com>
@@ -561,7 +2219,7 @@ Thu Mar 23 16:04:40 2000 Andrew Haley <aph@cygnus.com>
2000-03-22 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
- * builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
+ * builtin.c (get_pointer_alignment): Use DECL_P and TYPE_P macros.
* c-common.c (decl_attributes,check_format_info,truthvalue_conversion,
c_get_alias_set): Likewise.
* c-decl.c (duplicate_decls): Likewise.
@@ -646,7 +2304,7 @@ Wed Mar 22 11:44:50 MET 2000 Jan Hubicka <jh@suse.cz>
2000-03-21 Richard Henderson <rth@cygnus.com>
- * flow.c (delete_block): Fix typo last change.
+ * flow.c (delete_block): Fix typo last change.
2000-03-21 Mark Mitchell <mark@codesourcery.com>
@@ -1515,7 +3173,7 @@ Tue Mar 14 08:42:21 2000 Jeffrey A Law (law@cygnus.com)
2000-03-12 Zack Weinberg <zack@wolery.cumb.org>
- * cpphash.c: Don't include version.h.
+ * cpphash.c: Don't include version.h.
(special_symbol) [case T_VERSION]: Look for the string in
hp->value.cpval; don't use version_string.
* cppinit.c (initialize_builtins): Set hp->value.cpval for
@@ -1620,7 +3278,7 @@ Sat Mar 11 16:18:12 2000 Jim Wilson <wilson@cygnus.com>
remap_filename, _cpp_read_include_file, actual_directory,
hack_vms_include_specification): Replace bcopy(), index() etc
calls. Add casts to some allocations. Make some variables
- pointers to const [unsigned] char.
+ pointers to const [unsigned] char.
* cpphash.c (_cpp_install, macro_cleanup, collect_expansion,
collect_formal_parameters): Similarly.
* cppinit.c (struct pending_option, append_include_chain,
@@ -2854,7 +4512,7 @@ Mon Feb 28 22:11:12 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
Mon Feb 28 14:21:15 2000 Catherine Moore <clm@cygnus.com>
* config/pa/som.h (MAKE_DECL_ONE_ONLY): Define.
- (ASM_WEAKEN_LABEL): Define.
+ (ASM_WEAKEN_LABEL): Define.
Mon Feb 28 13:07:19 MET 2000 Jan Hubicka <jh@suse.cz>
@@ -3412,7 +5070,7 @@ Fri Feb 18 20:08:57 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* config/alpha/alpha.c (alpha_emit_xfloating_libcall): Cast FUNC
to (char *).
(alpha_expand_unaligned_load, alpha_expand_unaligned_store):
- Cast switch operand of size to int.
+ Cast switch operand of size to int.
(alpha_expand_epilogue): Always initialize fp_offset and sa_reg.
* config/alpha/alpha.h (INITIAL_ELIMINATION_OFFSET): Add abort
in unhandled case.
@@ -3625,7 +5283,7 @@ Tue Feb 15 23:22:26 2000 Andrew Haley <aph@cygnus.com>
* config/sh/sh.h: Correct comment about macros.
Tue Feb 15 22:30:36 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
- Andrew MacLeod <amacleod@cygnus.com>
+ Andrew MacLeod <amacleod@cygnus.com>
* Makefile.in (lcm.o): Depend on insn-attr.h.
* basic-block.h (optimize_mode_switching): Declare.
@@ -3720,7 +5378,7 @@ Tue Feb 15 22:30:36 2000 J"orn Rennecke <amylaar@cygnus.co.uk>
to import the frames themselves.
Mon Feb 14 13:31:01 2000 Stan Cox <scox@cygnus.com>
- Jason Eckhardt <jle@cygnus.com>
+ Jason Eckhardt <jle@cygnus.com>
* basic_block.h: Added prototype for reorder_basic_blocks.
* toplev.c: Changes to add -freorder-blocks and graph dump after
@@ -3773,7 +5431,7 @@ Sun Feb 13 12:57:52 2000 Neil Booth <NeilB@earthling.net>
2000-02-13 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
* flow.c (flow_loop_tree_node_add): Use better algorithm by passing
- previously inserted node instead of root node. Caller changed.
+ previously inserted node instead of root node. Caller changed.
2000-02-13 Michael Hayes <m.hayes@elec.canterbury.ac.nz>
@@ -3949,10 +5607,10 @@ Fri Feb 11 02:48:30 2000 Brad Lucier (lucier@math.purdue.edu)
(ASM_OUTPUT_EXTERNAL_LIBCALL): Likewise.
(ASM_FILE_END): Use c4x_file_end.
* config/c4x/c4x.c (c4x_global_label): New function.
- (c4x_external_ref, c4x_file_end): Likewise.
+ (c4x_external_ref, c4x_file_end): Likewise.
* config/c4x/c4x-protos.h (c4x_global_label): Add prototype.
- (c4x_external_ref, c4x_end_file): Likewise.
+ (c4x_external_ref, c4x_end_file): Likewise.
2000-02-10 Zack Weinberg <zack@wolery.cumb.org>
@@ -4474,14 +6132,14 @@ Mon Feb 7 18:36:41 MET 2000 Jan Hubicka <jh@suse.cz>
2000-02-04 Zack Weinberg <zack@wolery.cumb.org>
- * recog.h: Remove NO_MD_PROTOTYPES ifdefs.
- * genflags.c: Use the max_operand_1 logic from genemit.c to
- calculate how many arguments gen_insn prototypes have. Remove
- NO_MD_PROTOTYPES ifdefs from the generated file.
- * genoutput.c: Don't define NO_MD_PROTOTYPES in the generated
- file. Cast gen_insn initializers to insn_gen_fn.
- * config/alpha/vms.h: Don't define NO_MD_PROTOTYPES.
- * gcc.texi: Remove documentation of NO_MD_PROTOTYPES.
+ * recog.h: Remove NO_MD_PROTOTYPES ifdefs.
+ * genflags.c: Use the max_operand_1 logic from genemit.c to
+ calculate how many arguments gen_insn prototypes have. Remove
+ NO_MD_PROTOTYPES ifdefs from the generated file.
+ * genoutput.c: Don't define NO_MD_PROTOTYPES in the generated
+ file. Cast gen_insn initializers to insn_gen_fn.
+ * config/alpha/vms.h: Don't define NO_MD_PROTOTYPES.
+ * gcc.texi: Remove documentation of NO_MD_PROTOTYPES.
2000-02-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2c0096ab876..dbc558fa469 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -197,7 +197,9 @@ AR_FOR_TARGET = ` \
t='$(program_transform_cross_name)'; echo ar | sed -e $$t ; \
fi; \
fi`
-AR_FLAGS_FOR_TARGET = rc
+AR_FLAGS_FOR_TARGET =
+AR_CREATE_FOR_TARGET = $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) rc
+AR_EXTRACT_FOR_TARGET = $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) x
RANLIB_FOR_TARGET = ` \
if [ -f $(objdir)/../binutils/ranlib ] ; then \
echo $(objdir)/../binutils/ranlib ; \
@@ -216,6 +218,10 @@ RANLIB_TEST_FOR_TARGET = \
# Dir to search for system headers. Overridden by cross-make.
SYSTEM_HEADER_DIR = /usr/include
+# Where to find some libiberty headers.
+HASHTAB_H = $(srcdir)/../include/hashtab.h
+OBSTACK_H = $(srcdir)/../include/obstack.h
+
# Default cross SYSTEM_HEADER_DIR, to be overridden by targets.
CROSS_SYSTEM_HEADER_DIR = $(tooldir)/sys-include
@@ -613,6 +619,8 @@ LANG_EXTRA_HEADERS = @all_headers@
# ??? The choices here will need some experimenting with.
ORDINARY_FLAGS_TO_PASS = \
"AR_FLAGS_FOR_TARGET=$(AR_FLAGS_FOR_TARGET)" \
+ "AR_CREATE_FOR_TARGET=$(AR_CREATE_FOR_TARGET)" \
+ "AR_EXTRACT_FOR_TARGET=$(AR_EXTRACT_FOR_TARGET)" \
"AR_FOR_TARGET=$(AR_FOR_TARGET)" \
"BISON=$(BISON)" \
"BISONFLAGS=$(BISONFLAGS)" \
@@ -671,12 +679,12 @@ OBJS = diagnostic.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 combine.o varray.o \
regclass.o regmove.o local-alloc.o global.o reload.o reload1.o caller-save.o \
- insn-peep.o reorg.o haifa-sched.o final.o recog.o reg-stack.o \
+ insn-peep.o reorg.o haifa-sched.o final.o recog.o reg-stack.o regrename.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) $(EXTRA_OBJS) convert.o \
mbchar.o dyn-string.o splay-tree.o graph.o sbitmap.o resource.o hash.o \
predict.o lists.o ggc-common.o $(GGC) simplify-rtx.o ssa.o bb-reorder.o \
- sibcall.o
+ sibcall.o conflict.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
@@ -692,7 +700,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
insn-attr.h insn-attrtab.c insn-opinit.c tree-check.h \
s-flags s-config s-codes s-mlib s-unders s-genrtl \
s-output s-recog s-emit s-extract s-peep s-check \
- s-attr s-attrtab s-opinit s-crt s-$(T)crtS s-crt0 \
+ s-attr s-attrtab s-opinit s-crt0 \
genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext) \
genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
@@ -703,11 +711,7 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
$(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 *.flow2 *.peephole2 \
- *.ssa *.ussa \
- *.[si] libcpp.a \
+ gcov$(exeext) *.[0-9][0-9].* *.[si] libcpp.a \
$(LANG_STAGESTUFF)
# Members of libgcc1.a.
@@ -762,6 +766,7 @@ REGS_H = regs.h varray.h $(MACHMODE_H)
INTEGRATE_H = integrate.h varray.h
LOOP_H = loop.h varray.h basic-block.h
GCC_H = gcc.h version.h
+GGC_H = ggc.h varray.h
#
# Language makefile fragments.
@@ -803,6 +808,9 @@ Makefile: $(srcdir)/Makefile.in config.status $(srcdir)/version.c \
$(srcdir)/configure: $(srcdir)/configure.in
cd $(srcdir); autoconf
+gccbug: $(srcdir)/gccbug.in
+ CONFIG_FILES=gccbug CONFIG_HEADERS= ./config.status
+
# cstamp-h.in controls rebuilding of config.in.
# It is named cstamp-h.in and not stamp-h.in so the mostlyclean rule doesn't
# delete it. A stamp file is needed as autoheader won't update the file if
@@ -936,7 +944,7 @@ libgcc1.conv: libgcc1.a
libgcc1.null: $(GCC_PASSES)
echo "void __foo () {}" > dummy.c
$(GCC_FOR_TARGET) $(GCC_CFLAGS) -c dummy.c
- $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) libgcc1.null dummy$(objext)
+ $(AR_CREATE_FOR_TARGET) libgcc1.null dummy$(objext)
rm -f dummy$(objext) dummy.c
# This is $(LIBGCC1) for a cross-compiler.
@@ -1021,7 +1029,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_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc1.a $${name}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc1.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
-rm -f libgcc1.S
@@ -1073,7 +1081,7 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(INCLUDES) -c -DL$${name} \
$(MAYBE_USE_COLLECT2) $(srcdir)/libgcc2.c -o $${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
for name in $(LIB2FUNCS_EH); \
@@ -1082,7 +1090,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_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done
if [ x$(FPBIT) != x ]; then \
@@ -1092,7 +1100,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_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a $${name}$(objext); \
rm -f $${name}$(objext); \
done; \
else true; fi;
@@ -1103,7 +1111,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 _dp$${name}$(objext); \
if [ $$? -eq 0 ] ; then true; else exit 1; fi; \
- $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a _dp$${name}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a _dp$${name}$(objext); \
rm -f _dp$${name}$(objext); \
done; \
else true; fi;
@@ -1120,13 +1128,15 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
for f in .. `cat $${file}`; do if [ x$${f} != x.. ]; then \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
+ AR_EXTRACT_FOR_TARGET="$(AR_EXTRACT_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_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${f}; \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a $${f}; \
rm -f $${f}; \
else true; \
fi; done; \
@@ -1137,7 +1147,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_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) tmplibgcc2.a $${oname}$(objext); \
+ $(AR_CREATE_FOR_TARGET) tmplibgcc2.a $${oname}$(objext); \
rm -f $${name}.s $${oname}$(objext); \
fi; \
done
@@ -1156,17 +1166,17 @@ libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \
libgcc.a: $(LIBGCC1) $(LIBGCC2)
-rm -rf tmplibgcc.a libgcc.a tmpcopy
mkdir tmpcopy
- (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2))
+ (cd tmpcopy; $(AR_EXTRACT_FOR_TARGET) ../$(LIBGCC2))
# 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)
-if [ x$(LIBGCC1) != x ]; \
- then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \
+ then (cd tmpcopy; $(AR_EXTRACT_FOR_TARGET) ../$(LIBGCC1)); \
else true; \
fi
- (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext))
+ (cd tmpcopy; $(AR_CREATE_FOR_TARGET) ../tmplibgcc.a *$(objext))
rm -rf tmpcopy
-if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) tmplibgcc.a; \
@@ -1199,6 +1209,8 @@ stmp-multilib: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \
flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
+ AR_EXTRACT_FOR_TARGET="$(AR_EXTRACT_FOR_TARGET)" \
AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
RANLIB_FOR_TARGET="$(RANLIB_FOR_TARGET)" \
@@ -1223,6 +1235,8 @@ stmp-multilib-sub:
fi
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
+ AR_EXTRACT_FOR_TARGET="$(AR_EXTRACT_FOR_TARGET)" \
AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
@@ -1237,6 +1251,8 @@ stmp-multilib-sub:
else \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
+ AR_EXTRACT_FOR_TARGET="$(AR_EXTRACT_FOR_TARGET)" \
AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
@@ -1245,17 +1261,17 @@ stmp-multilib-sub:
fi
rm -rf tmplibgcc.a tmpcopy
mkdir tmpcopy
- (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC2))
+ (cd tmpcopy; $(AR_EXTRACT_FOR_TARGET) ../$(LIBGCC2))
# 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)
if [ x$(LIBGCC1) != x ]; \
- then (cd tmpcopy; $(AR_FOR_TARGET) x ../$(LIBGCC1)); \
+ then (cd tmpcopy; $(AR_EXTRACT_FOR_TARGET) ../$(LIBGCC1)); \
else true; \
fi
- (cd tmpcopy; $(AR_FOR_TARGET) $(AR_FLAGS_FOR_TARGET) ../tmplibgcc.a *$(objext))
+ (cd tmpcopy; $(AR_CREATE_FOR_TARGET) ../tmplibgcc.a *$(objext))
rm -rf libgcc2.a tmpcopy
if $(RANLIB_TEST_FOR_TARGET) ; then \
$(RANLIB_FOR_TARGET) tmplibgcc.a; \
@@ -1265,6 +1281,8 @@ stmp-multilib-sub:
for f in .. $(EXTRA_MULTILIB_PARTS); do if [ x$${f} != x.. ]; then \
$(MAKE) GCC_FOR_TARGET="$(GCC_FOR_TARGET)" \
AR_FOR_TARGET="$(AR_FOR_TARGET)" \
+ AR_CREATE_FOR_TARGET="$(AR_CREATE_FOR_TARGET)" \
+ AR_EXTRACT_FOR_TARGET="$(AR_EXTRACT_FOR_TARGET)" \
AR_FLAGS_FOR_TARGET="$(AR_FLAGS_FOR_TARGET)" \
CC="$(CC)" CFLAGS="$(CFLAGS)" \
HOST_PREFIX="$(HOST_PREFIX)" HOST_PREFIX_1="$(HOST_PREFIX_1)" \
@@ -1291,21 +1309,22 @@ $(T)crtend.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \
-fno-exceptions $(CRTSTUFF_T_CFLAGS) @inhibit_libc@ \
-c $(srcdir)/crtstuff.c -DCRT_END -o $(T)crtend$(objext)
-# On some systems we also want to install versions of these files
-# compiled using PIC for use in shared libraries.
-$(T)crtbeginS.o $(T)crtendS.o: s-$(T)crtS ; @true
+# These are versions of crtbegin and crtend for shared libraries.
+$(T)crtbeginS.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \
+ defaults.h frame.h gbl-ctors.h stmp-int-hdrs tsystem.h
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
+ -finhibit-size-directive -fno-inline-functions \
+ -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) @inhibit_libc@ \
+ -c $(srcdir)/crtstuff.c -DCRT_BEGIN -DCRTSTUFFS_O \
+ -o $(T)crtbeginS$(objext)
-s-$(T)crtS: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \
+$(T)crtendS.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \
defaults.h frame.h gbl-ctors.h stmp-int-hdrs tsystem.h
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS_S) \
- -DCRT_BEGIN -DCRTSTUFFS_O -finhibit-size-directive \
- -fno-inline-functions -fno-exceptions @inhibit_libc@ -g0 \
- -c $(srcdir)/crtstuff.c -o $(T)crtbeginS$(objext)
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS_S) \
- -DCRT_END -DCRTSTUFFS_O -finhibit-size-directive \
- -fno-inline-functions -fno-exceptions @inhibit_libc@ -g0 \
- -c $(srcdir)/crtstuff.c -o $(T)crtendS$(objext)
- touch s-$(T)crtS
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
+ -finhibit-size-directive -fno-inline-functions \
+ -fno-exceptions $(CRTSTUFF_T_CFLAGS_S) @inhibit_libc@ \
+ -c $(srcdir)/crtstuff.c -DCRT_END -DCRTSTUFFS_O \
+ -o $(T)crtendS$(objext)
# Compile the start modules crt0.o and mcrt0.o that are linked with every program
crt0.o: s-crt0 ; @true
@@ -1325,7 +1344,7 @@ s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
# C language specific files.
-c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) c-lex.h ggc.h \
+c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(TREE_H) c-lex.h $(GGC_H) \
$(srcdir)/c-parse.h c-tree.h c-common.h input.h flags.h system.h toplev.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c $(srcdir)/c-parse.c
$(srcdir)/c-parse.h: $(srcdir)/c-parse.c
@@ -1345,20 +1364,20 @@ $(srcdir)/c-gperf.h: c-parse.gperf
exit 1 )
$(SHELL) $(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-common.h ggc.h \
+c-decl.o : c-decl.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h $(GGC_H) \
c-lex.h flags.h function.h output.h toplev.h defaults.h
c-typeck.o : c-typeck.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h \
flags.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-common.h ggc.h \
+c-lang.o : c-lang.c $(CONFIG_H) system.h $(TREE_H) c-tree.h c-common.h $(GGC_H) \
c-lex.h toplev.h output.h function.h
c-lex.o : c-lex.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-lex.h c-tree.h \
c-common.h $(srcdir)/c-parse.h $(srcdir)/c-gperf.h c-pragma.h input.h \
- intl.h flags.h toplev.h output.h mbchar.h ggc.h
+ intl.h flags.h toplev.h output.h mbchar.h $(GGC_H)
c-aux-info.o : c-aux-info.c $(CONFIG_H) system.h $(TREE_H) c-tree.h \
c-common.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) function.h \
- defaults.h c-pragma.h toplev.h ggc.h
+ defaults.h c-pragma.h toplev.h $(GGC_H)
c-iterate.o: c-iterate.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \
c-common.h flags.h toplev.h $(EXPR_H)
mbchar.o: mbchar.c $(CONFIG_H) system.h mbchar.h
@@ -1373,7 +1392,7 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(COLLECT2_OBJS) $(LIBS)
collect2.o : collect2.c $(CONFIG_H) system.h gstab.h intl.h \
- $(srcdir)/../include/obstack.h $(DEMANGLE_H) collect2.h version.h
+ $(OBSTACK_H) $(DEMANGLE_H) collect2.h version.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DTARGET_MACHINE=\"$(target_alias)\" $(MAYBE_USE_COLLECT2) \
-c `echo $(srcdir)/collect2.c | sed 's,^\./,,'`
@@ -1410,7 +1429,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 \
- c-common.h flags.h toplev.h output.h c-pragma.h $(RTL_H) ggc.h \
+ c-common.h flags.h toplev.h output.h c-pragma.h $(RTL_H) $(GGC_H) \
$(EXPR_H)
# Language-independent files.
@@ -1451,17 +1470,17 @@ dumpvers: dumpvers.c
version.o: version.c version.h
ggc-common.o: ggc-common.c $(CONFIG_H) $(RTL_H) $(TREE_H) \
- flags.h ggc.h varray.h hash.h
+ flags.h $(GGC_H) varray.h hash.h
ggc-simple.o: ggc-simple.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
- ggc.h varray.h
+ $(GGC_H) varray.h
ggc-page.o: ggc-page.c $(CONFIG_H) $(RTL_H) $(TREE_H) flags.h \
- ggc.h varray.h
+ $(GGC_H) varray.h
-ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) ggc.h
+ggc-none.o: ggc-none.c $(CONFIG_H) $(RTL_H) $(GGC_H)
-ggc-callbacks.o: ggc-callbacks.c $(CONFIG_H) $(RTL_H) $(TREE_H) ggc.h
+ggc-callbacks.o: ggc-callbacks.c $(CONFIG_H) $(RTL_H) $(TREE_H) $(GGC_H)
obstack.o: $(srcdir)/../libiberty/obstack.c $(CONFIG_H)
rm -f obstack.c
@@ -1476,13 +1495,13 @@ prefix.o: prefix.c $(CONFIG_H) system.h Makefile prefix.h
convert.o: convert.c $(CONFIG_H) system.h $(TREE_H) flags.h convert.h toplev.h
tree.o : tree.c $(CONFIG_H) system.h $(TREE_H) flags.h function.h toplev.h \
- ggc.h $(HASHTAB_H)
-print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) ggc.h
+ $(GGC_H) $(HASHTAB_H)
+print-tree.o : print-tree.c $(CONFIG_H) system.h $(TREE_H) $(GGC_H)
stor-layout.o : stor-layout.c $(CONFIG_H) system.h $(TREE_H) flags.h \
- function.h $(EXPR_H) $(RTL_H) toplev.h ggc.h
+ function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H)
fold-const.o : fold-const.c $(CONFIG_H) system.h $(TREE_H) flags.h toplev.h \
- $(RTL_H) ggc.h
-diagnostic.o : $(CONFIG_H) system.h $(TREE_H) $(RTL_H) tm_p.h flags.h \
+ $(RTL_H) $(GGC_H)
+diagnostic.o : diagnostic.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) tm_p.h flags.h \
input.h insn-attr.h insn-codes.h insn-config.h toplev.h intl.h
toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
flags.h input.h insn-attr.h xcoffout.h defaults.h output.h \
@@ -1493,7 +1512,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) function.h \
-DTARGET_NAME=\"$(target_alias)\" \
-c `echo $(srcdir)/toplev.c | sed 's,^\./,,'`
-rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h ggc.h toplev.h
+rtl.o : rtl.c $(CONFIG_H) system.h $(RTL_H) bitmap.h $(GGC_H) toplev.h
print-rtl.o : print-rtl.c $(CONFIG_H) system.h $(RTL_H) $(BASIC_BLOCK_H)
rtlanal.o : rtlanal.c $(CONFIG_H) system.h $(RTL_H)
@@ -1501,20 +1520,20 @@ errors.o : errors.c $(CONFIG_H) system.h errors.h
varasm.o : varasm.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) flags.h \
function.h defaults.h $(EXPR_H) hard-reg-set.h $(REGS_H) \
- xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h ggc.h
+ xcoffout.h output.h c-pragma.h toplev.h dbxout.h sdbout.h $(GGC_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 hash.h ggc.h
+ insn-config.h $(RECOG_H) output.h toplev.h except.h hash.h $(GGC_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 varray.h ggc.h
+ $(LOOP_H) $(RECOG_H) toplev.h output.h varray.h $(GGC_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 intl.h ggc.h
+ insn-config.h $(RECOG_H) output.h except.h toplev.h intl.h $(GGC_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 \
- ggc.h intl.h
+ $(GGC_H) intl.h
builtins.o : builtins.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 \
@@ -1528,25 +1547,26 @@ explow.o : explow.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-codes.h toplev.h function.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 \
- toplev.h ggc.h real.h
+ toplev.h $(GGC_H) real.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 $(srcdir)/../include/obstack.h xcoffout.h c-pragma.h \
+ insn-config.h $(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 \
flags.h insn-config.h reload.h output.h defaults.h \
hard-reg-set.h $(REGS_H) $(EXPR_H) toplev.h dwarf2out.h varray.h \
- ggc.h except.h
+ $(GGC_H) except.h
xcoffout.o : xcoffout.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) xcoffout.h \
- flags.h toplev.h output.h dbxout.h ggc.h
+ flags.h toplev.h output.h dbxout.h $(GGC_H)
emit-rtl.o : emit-rtl.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
- function.h $(REGS_H) insn-config.h $(RECOG_H) real.h ggc.h \
- $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h
+ function.h $(REGS_H) insn-config.h $(RECOG_H) real.h $(GGC_H) \
+ $(EXPR_H) $(srcdir)/../include/obstack.h hard-reg-set.h bitmap.h toplev.h \
+ $(HASHTAB_H)
real.o : real.c $(CONFIG_H) system.h $(TREE_H) toplev.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) \
@@ -1557,9 +1577,9 @@ jump.o : jump.c $(CONFIG_H) system.h $(RTL_H) flags.h hard-reg-set.h $(REGS_H) \
simplify-rtx.o : simplify-rtx.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \
- output.h function.h cselib.h ggc.h $(srcdir)/../include/obstack.h
+ output.h function.h cselib.h ggc.h $(OBSTACK_H)
cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
- real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h ggc.h
+ real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h $(GGC_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) \
function.h output.h toplev.h
@@ -1572,9 +1592,11 @@ lcm.o : lcm.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
real.h insn-config.h insn-attr.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H)
ssa.o : ssa.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) $(BASIC_BLOCK_H) \
output.h insn-config.h
+conflict.o : conflict.c $(CONFIG_H) system.h $(OBSTACK_H) $(HASHTAB_H) \
+ $(RTL_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 function.h insn-config.h \
- ggc.h
+ $(GGC_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 \
$(BASIC_BLOCK_H) function.h toplev.h varray.h except.h cselib.h
@@ -1589,7 +1611,7 @@ combine.o : combine.c $(CONFIG_H) system.h $(RTL_H) flags.h function.h \
$(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h toplev.h
regclass.o : regclass.c $(CONFIG_H) system.h $(RTL_H) hard-reg-set.h flags.h \
$(BASIC_BLOCK_H) $(REGS_H) insn-config.h $(RECOG_H) reload.h real.h \
- toplev.h function.h output.h ggc.h
+ toplev.h function.h output.h $(GGC_H)
local-alloc.o : local-alloc.c $(CONFIG_H) system.h $(RTL_H) flags.h \
$(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \
output.h function.h insn-attr.h toplev.h
@@ -1611,8 +1633,8 @@ 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) function.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 output.h $(EXPR_H) insn-flags.h ggc.h function.h \
- cselib.h
+ $(REGS_H) toplev.h output.h $(EXPR_H) insn-flags.h $(GGC_H) function.h \
+ cselib.h $(TREE_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 function.h \
$(EXPR_H) insn-flags.h $(BASIC_BLOCK_H) toplev.h
@@ -1634,12 +1656,16 @@ dyn-string.o: dyn-string.c dyn-string.h $(CONFIG_H) system.h
predict.o: predict.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) insn-flags.h function.h except.h $(EXPR_H)
-lists.o: lists.c $(CONFIG_H) system.h toplev.h $(RTL_H) ggc.h
+lists.o: lists.c $(CONFIG_H) system.h toplev.h $(RTL_H) $(GGC_H)
bb-reorder.o : bb-reorder.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h \
$(RECOG_H) insn-flags.h function.h except.h $(EXPR_H)
-$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) ggc.h \
+regrename.o : regrename.c $(CONFIG_H) system.h $(RTL_H) $(TREE_H) flags.h \
+ insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h \
+ $(RECOG_H) function.h resource.h
+
+$(out_object_file): $(out_file) $(CONFIG_H) $(TREE_H) $(GGC_H) \
$(RTL_H) $(REGS_H) hard-reg-set.h real.h insn-config.h conditions.h \
insn-flags.h output.h insn-attr.h insn-codes.h system.h toplev.h function.h
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(out_file)
@@ -1779,7 +1805,7 @@ s-attrtab : $(md_file) genattrtab $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-attrtab.c insn-attrtab.c
touch s-attrtab
-insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) ggc.h $(REGS_H) real.h \
+insn-output.o : insn-output.c $(CONFIG_H) $(RTL_H) $(GGC_H) $(REGS_H) real.h \
conditions.h hard-reg-set.h insn-config.h insn-flags.h insn-attr.h \
output.h $(RECOG_H) function.h insn-codes.h system.h toplev.h flags.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-output.c
@@ -1790,7 +1816,7 @@ s-output : $(md_file) genoutput $(srcdir)/move-if-change
$(SHELL) $(srcdir)/move-if-change tmp-output.c insn-output.c
touch s-output
-genrtl.o : genrtl.c $(CONFIG_H) $(RTL_H) system.h ggc.h
+genrtl.o : genrtl.c $(CONFIG_H) $(RTL_H) system.h $(GGC_H)
genrtl.c genrtl.h : s-genrtl
@true # force gnu make to recheck modification times.
@@ -1884,7 +1910,7 @@ genattrtab : genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEP
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
genattrtab.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
-genattrtab.o : genattrtab.c $(RTL_H) $(build_xm_file) system.h errors.h ggc.h
+genattrtab.o : genattrtab.c $(RTL_H) $(build_xm_file) system.h errors.h $(GGC_H)
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattrtab.c
genoutput : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
@@ -1906,7 +1932,7 @@ gengenrtl.o : gengenrtl.c $(RTL_BASE_H) system.h real.h
# and HOST_PREFIX_1 is `foobar', just to ensure these rules don't conflict
# with the rules for rtl.o, alloca.o, etc.
$(HOST_PREFIX_1)rtl.o: $(srcdir)/rtl.c $(CONFIG_H) system.h $(RTL_H) \
- bitmap.h ggc.h toplev.h
+ bitmap.h $(GGC_H) toplev.h
rm -f $(HOST_PREFIX)rtl.c
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
@@ -2037,7 +2063,6 @@ LIBCPP_OBJS = cpplib.o cpphash.o cpperror.o cppexp.o cppfiles.o \
prefix.o version.o mbchar.o @extra_cpp_objs@
LIBCPP_DEPS = cpplib.h cpphash.h intl.h system.h
-HASHTAB_H = $(srcdir)/../include/hashtab.h
# All the other archives built/used by this makefile are for targets. This
# one is strictly for the host.
@@ -2153,6 +2178,7 @@ stmp-int-hdrs: $(STMP_FIXINC) $(USER_H) xlimits.h
# this is necessary because VPATH could add a dirname.
# Using basename would be simpler, but some systems don't have it.
# The touch command is here to workaround an AIX/Linux NFS bug.
+ -if [ -d include ] ; then true; else mkdir include; chmod a+rx include; fi
for file in .. $(USER_H); do \
if [ X$$file != X.. ]; then \
realfile=`echo $$file | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
@@ -2267,7 +2293,7 @@ fix-header: fix-header.o scan-decls.o scan.o xsys-protos.h $(HOST_LIBDEPS) \
$(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ fix-header.o \
scan-decls.o scan.o libcpp.a $(HOST_LIBS) ../libiberty/libiberty.a
-fix-header.o: fix-header.c $(srcdir)/../include/obstack.h scan.h \
+fix-header.o: fix-header.c $(OBSTACK_H) scan.h \
xsys-protos.h $(build_xm_file) system.h cpplib.h
$(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/fix-header.c
@@ -2290,7 +2316,6 @@ fixhdr.ready: fix-header
# if it has already been run on the files in `include'.
stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
@echo "Various warnings and error messages from fixproto are normal"
- -if [ -d include ] ; then true; else mkdir include; chmod a+rx include; fi
-if [ -f include/fixed ] ; then true; \
else \
: This line works around a 'make' bug in BSDI 1.1.; \
@@ -2306,7 +2331,7 @@ stmp-fixproto: fixhdr.ready fixproto stmp-int-hdrs
#
# Remake the info files.
-doc: info
+doc: info gccbug
info: cpp.info gcc.info lang.info
cpp.info: $(srcdir)/cpp.texi
@@ -2366,13 +2391,7 @@ mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
-rm -f s-* tmp-* stamp-* stmp-*
-rm -f */stamp-* */tmp-*
# 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 *.flow2 *.peephole2 *.ssa *.ussa
- -rm -f */*.greg */*.lreg */*.combine */*.flow */*.cse */*.jump */*.rtl
- -rm -f */*.tree */*.loop */*.dbr */*.jump2 */*.sched */*.cse2
- -rm -f */*.sched2 */*.stack */*.regmove */*.gcse */*.flow2
- -rm -f */*.peephole2 */*.ssa */*.ussa
+ -rm -f *.[0-9][0-9].* */*.[0-9][0-9].*
# Delete some files made during installation.
-rm -f specs float.h-* enquire SYSCALLS.c.X SYSCALLS.c
-rm -f collect collect2 mips-tfile mips-tdump alloca.s
@@ -2386,7 +2405,6 @@ mostlyclean: $(INTL_MOSTLYCLEAN) lang.mostlyclean
-rm -f gcc.vrs gcc.kys gcc.tps gcc.pgs gcc.fns
# Delete core dumps.
-rm -f core */core
- -rm -f *.bp */*.bp
# Delete all files made by compilation
# that don't exist in the distribution.
diff --git a/gcc/acconfig.h b/gcc/acconfig.h
index b0a44d00aca..cfa12f4ed37 100644
--- a/gcc/acconfig.h
+++ b/gcc/acconfig.h
@@ -4,6 +4,12 @@
/* Define if printf supports "%p". */
#undef HAVE_PRINTF_PTR
+/* Define if you want to enable namespaces (-fhonor-std) by default. */
+#undef ENABLE_STD_NAMESPACE
+#if !defined(ENABLE_STD_NAMESPACE)
+# define ENABLE_STD_NAMESPACE 0
+#endif
+
/* Define if you want to always select the new-abi for g++. */
#undef ENABLE_NEW_GXX_ABI
@@ -72,6 +78,9 @@
/* Define if your assembler supports .weak. */
#undef HAVE_GAS_WEAK
+/* Define if your assembler supports .hidden. */
+#undef HAVE_GAS_HIDDEN
+
/* Define if your assembler uses the old HImode fild and fist notation. */
#undef HAVE_GAS_FILDS_FISTS
diff --git a/gcc/alias.c b/gcc/alias.c
index ac09d798a27..db89ecc173e 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -79,7 +79,6 @@ typedef struct alias_set_entry
splay_tree children;
} *alias_set_entry;
-static rtx canon_rtx PARAMS ((rtx));
static int rtx_equal_for_memref_p PARAMS ((rtx, rtx));
static rtx find_symbolic_term PARAMS ((rtx));
static rtx get_addr PARAMS ((rtx));
@@ -153,12 +152,14 @@ static unsigned int reg_base_value_size; /* size of reg_base_value array */
after reload. */
static rtx *alias_invariant;
-/* Vector indexed by N giving the initial (unchanging) value known
- for pseudo-register N. */
+/* Vector indexed by N giving the initial (unchanging) value known for
+ pseudo-register N. This array is initialized in
+ init_alias_analysis, and does not change until end_alias_analysis
+ is called. */
rtx *reg_known_value;
/* Indicates number of valid entries in reg_known_value. */
-static int reg_known_value_size;
+static unsigned int reg_known_value_size;
/* Vector recording for each reg_known_value whether it is due to a
REG_EQUIV note. Future passes (viz., reload) may replace the
@@ -542,7 +543,12 @@ record_base_value (regno, val, invariant)
reg_base_value[regno] = find_base_value (val);
}
-static rtx
+/* Returns a canonical version of X, from the point of view alias
+ analysis. (For example, if X is a MEM whose address is a register,
+ and the register has a known value (say a SYMBOL_REF), then a MEM
+ whose address is the SYMBOL_REF is returned.) */
+
+rtx
canon_rtx (x)
rtx x;
{
@@ -625,23 +631,32 @@ rtx_equal_for_memref_p (x, y)
if (GET_MODE (x) != GET_MODE (y))
return 0;
- /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
-
- if (code == REG)
- return REGNO (x) == REGNO (y);
- if (code == LABEL_REF)
- return XEXP (x, 0) == XEXP (y, 0);
- if (code == SYMBOL_REF)
- return XSTR (x, 0) == XSTR (y, 0);
- if (code == CONST_INT)
- return INTVAL (x) == INTVAL (y);
- /* There's no need to compare the contents of CONST_DOUBLEs because
- they're unique. */
- if (code == CONST_DOUBLE)
- return 0;
- if (code == ADDRESSOF)
- return (REGNO (XEXP (x, 0)) == REGNO (XEXP (y, 0))
- && XINT (x, 1) == XINT (y, 1));
+ /* Some RTL can be compared without a recursive examination. */
+ switch (code)
+ {
+ case REG:
+ return REGNO (x) == REGNO (y);
+
+ case LABEL_REF:
+ return XEXP (x, 0) == XEXP (y, 0);
+
+ case SYMBOL_REF:
+ return XSTR (x, 0) == XSTR (y, 0);
+
+ case CONST_INT:
+ case CONST_DOUBLE:
+ /* There's no need to compare the contents of CONST_DOUBLEs or
+ CONST_INTs because pointer equality is a good enough
+ comparison for these nodes. */
+ return 0;
+
+ case ADDRESSOF:
+ return (REGNO (XEXP (x, 0)) == REGNO (XEXP (y, 0))
+ && XINT (x, 1) == XINT (y, 1));
+
+ default:
+ break;
+ }
/* For commutative operations, the RTX match if the operand match in any
order. Also handle the simple binary and unary cases without a loop. */
@@ -1570,6 +1585,9 @@ init_alias_once ()
alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
}
+/* Initialize the aliasing machinery. Initialize the REG_KNOWN_VALUE
+ array. */
+
void
init_alias_analysis ()
{
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 7705daa2b12..1f98fa4dabd 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -24,6 +24,7 @@ Boston, MA 02111-1307, USA. */
#include "bitmap.h"
#include "sbitmap.h"
#include "varray.h"
+#include "partition.h"
/* Head of register set linked list. */
typedef bitmap_head regset_head;
@@ -146,7 +147,9 @@ typedef struct basic_block_def {
/* The edges into and out of the block. */
edge pred, succ;
- /* Liveness info. */
+ /* Liveness info. Note that in SSA form, global_live_at_start does
+ not reflect the use of regs in phi functions, since the liveness
+ of these regs may depend on which edge was taken into the block. */
regset local_set;
regset global_live_at_start;
regset global_live_at_end;
@@ -228,7 +231,9 @@ extern void make_edge PARAMS ((sbitmap *, basic_block,
basic_block, int));
extern void remove_edge PARAMS ((edge));
extern void create_basic_block PARAMS ((int, rtx, rtx, rtx));
-
+extern void merge_blocks_nomove PARAMS ((basic_block, basic_block));
+extern void tidy_fallthru_edge PARAMS ((edge, basic_block,
+ basic_block));
/* Structure to hold information for each natural loop. */
struct loop
@@ -453,5 +458,37 @@ extern void debug_bb_n PARAMS ((int));
extern void dump_regset PARAMS ((regset, FILE *));
extern void debug_regset PARAMS ((regset));
+/* This function is always defined so it can be called from the
+ debugger, and it is declared extern so we don't get warnings about
+ it being unused. */
+extern void verify_flow_info PARAMS ((void));
+extern int flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
+
+typedef struct conflict_graph_def *conflict_graph;
+
+/* Callback function when enumerating conflicts. The arguments are
+ the smaller and larger regno in the conflict. Returns zero if
+ enumeration is to continue, non-zero to halt enumeration. */
+typedef int (*conflict_graph_enum_fn) PARAMS ((int, int, void *));
+
+
+/* Prototypes of operations on conflict graphs. */
+
+extern conflict_graph conflict_graph_new
+ PARAMS ((int));
+extern void conflict_graph_delete PARAMS ((conflict_graph));
+extern int conflict_graph_add PARAMS ((conflict_graph,
+ int, int));
+extern int conflict_graph_conflict_p PARAMS ((conflict_graph,
+ int, int));
+extern void conflict_graph_enum PARAMS ((conflict_graph, int,
+ conflict_graph_enum_fn,
+ void *));
+extern void conflict_graph_merge_regs PARAMS ((conflict_graph, int,
+ int));
+extern void conflict_graph_print PARAMS ((conflict_graph, FILE*));
+extern conflict_graph conflict_graph_compute
+ PARAMS ((regset,
+ partition));
#endif /* _BASIC_BLOCK_H */
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 00005301989..e2f40f1657e 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -123,8 +123,9 @@ static basic_block get_common_dest PARAMS ((basic_block, basic_block));
static basic_block chain_reorder_blocks PARAMS ((edge, basic_block));
static void make_reorder_chain PARAMS ((basic_block));
static void fixup_reorder_chain PARAMS ((void));
+#ifdef ENABLE_CHECKING
static void verify_insn_chain PARAMS ((void));
-
+#endif
/* Skip over insns BEFORE or AFTER BB which are typically associated with
basic block BB. */
@@ -718,7 +719,7 @@ fixup_reorder_chain ()
reverse direction.
2. Count insns in chain, going both directions, and check if equal.
3. Check that get_last_insn () returns the actual end of chain. */
-
+#ifdef ENABLE_CHECKING
static void
verify_insn_chain ()
{
@@ -775,7 +776,7 @@ verify_insn_chain ()
abort ();
}
}
-
+#endif
/* Reorder basic blocks. */
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 0271d1254ec..1590d38c873 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -135,6 +135,7 @@ get_pointer_alignment (exp, max_align)
exp = TREE_OPERAND (exp, 0);
if (TREE_CODE (TREE_TYPE (exp)) != POINTER_TYPE)
return align;
+
inner = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp)));
align = MIN (inner, max_align);
break;
@@ -143,10 +144,10 @@ get_pointer_alignment (exp, max_align)
/* If sum of pointer + int, restrict our maximum alignment to that
imposed by the integer. If not, we can't do any better than
ALIGN. */
- if (TREE_CODE (TREE_OPERAND (exp, 1)) != INTEGER_CST)
+ if (! host_integerp (TREE_OPERAND (exp, 1), 1))
return align;
- while (((TREE_INT_CST_LOW (TREE_OPERAND (exp, 1)) * BITS_PER_UNIT)
+ while (((tree_low_cst (TREE_OPERAND (exp, 1), 1) * BITS_PER_UNIT)
& (max_align - 1))
!= 0)
max_align >>= 1;
@@ -870,8 +871,6 @@ expand_builtin_apply (function, arguments, argsize)
/* Create a block where the return registers can be saved. */
result = assign_stack_local (BLKmode, apply_result_size (), -1);
- /* ??? The argsize value should be adjusted here. */
-
/* Fetch the arg pointer from the ARGUMENTS block. */
incoming_args = gen_reg_rtx (Pmode);
emit_move_insn (incoming_args,
@@ -900,11 +899,10 @@ expand_builtin_apply (function, arguments, argsize)
haven't figured out how the calling convention macros effect this,
but it's likely that the source and/or destination addresses in
the block copy will need updating in machine specific ways. */
- dest = allocate_dynamic_stack_space (argsize, 0, 0);
+ dest = allocate_dynamic_stack_space (argsize, 0, BITS_PER_UNIT);
emit_block_move (gen_rtx_MEM (BLKmode, dest),
gen_rtx_MEM (BLKmode, incoming_args),
- argsize,
- PARM_BOUNDARY / BITS_PER_UNIT);
+ argsize, PARM_BOUNDARY);
/* Refer to the argument block. */
apply_args_size ();
@@ -1390,7 +1388,8 @@ expand_builtin_strlen (exp, target, mode)
/* Now that we are assured of success, expand the source. */
start_sequence ();
- pat = expand_expr (src, src_reg, ptr_mode, EXPAND_SUM);
+ pat = memory_address (BLKmode,
+ expand_expr (src, src_reg, ptr_mode, EXPAND_SUM));
if (pat != src_reg)
emit_move_insn (src_reg, pat);
pat = gen_sequence ();
@@ -1435,10 +1434,8 @@ expand_builtin_memcpy (arglist)
tree src = TREE_VALUE (TREE_CHAIN (arglist));
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
- int src_align
- = get_pointer_alignment (src, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
- int dest_align
- = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
+ int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
rtx dest_mem, src_mem, dest_addr, len_rtx;
/* If either SRC or DEST is not a pointer type, don't do
@@ -1531,8 +1528,7 @@ expand_builtin_memset (exp)
tree val = TREE_VALUE (TREE_CHAIN (arglist));
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
- int dest_align
- = get_pointer_alignment (dest, BIGGEST_ALIGNMENT) / BITS_PER_UNIT;
+ int dest_align = get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
rtx dest_mem, dest_addr, len_rtx;
/* If DEST is not a pointer type, don't do this
@@ -1901,66 +1897,44 @@ expand_builtin_next_arg (arglist)
from multiple evaluations. */
static tree
-stabilize_va_list (valist, was_ptr)
+stabilize_va_list (valist, needs_lvalue)
tree valist;
- int was_ptr;
+ int needs_lvalue;
{
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
{
- /* If stdarg.h took the address of an array-type valist that was passed
- as a parameter, we'll have taken the address of the parameter itself
- rather than the array as we'd intended. Undo this mistake. */
+ if (TREE_SIDE_EFFECTS (valist))
+ valist = save_expr (valist);
- if (was_ptr)
+ /* For this case, the backends will be expecting a pointer to
+ TREE_TYPE (va_list_type_node), but it's possible we've
+ actually been given an array (an actual va_list_type_node).
+ So fix it. */
+ if (TREE_CODE (TREE_TYPE (valist)) == ARRAY_TYPE)
{
- STRIP_NOPS (valist);
-
- /* Two cases: either &array, which decomposed to
- <ptr <array <record> valist>>
- or &ptr, which turned into
- <ptr <ptr <record>>>
- In the first case we'll need to put the ADDR_EXPR back
- after frobbing the types as if &array[0]. */
-
- if (TREE_CODE (valist) != ADDR_EXPR)
- abort ();
- valist = TREE_OPERAND (valist, 0);
- }
+ tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
+ tree p2 = build_pointer_type (va_list_type_node);
- if (TYPE_MAIN_VARIANT (TREE_TYPE (valist))
- == TYPE_MAIN_VARIANT (va_list_type_node))
- {
- tree pt = build_pointer_type (TREE_TYPE (va_list_type_node));
- valist = build1 (ADDR_EXPR, pt, valist);
- TREE_SIDE_EFFECTS (valist)
- = TREE_SIDE_EFFECTS (TREE_OPERAND (valist, 0));
- }
- else
- {
- if (! POINTER_TYPE_P (TREE_TYPE (valist))
- || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (valist)))
- != TYPE_MAIN_VARIANT (TREE_TYPE (va_list_type_node))))
- abort ();
+ valist = build1 (ADDR_EXPR, p2, valist);
+ valist = fold (build1 (NOP_EXPR, p1, valist));
}
-
- if (TREE_SIDE_EFFECTS (valist))
- valist = save_expr (valist);
}
else
{
- if (! was_ptr)
- {
- tree pt;
+ tree pt;
+ if (! needs_lvalue)
+ {
if (! TREE_SIDE_EFFECTS (valist))
return valist;
-
+
pt = build_pointer_type (va_list_type_node);
- valist = fold (build1 (ADDR_EXPR, pt, valist));
+ valist = fold (build1 (ADDR_EXPR, pt, valist));
TREE_SIDE_EFFECTS (valist) = 1;
}
+
if (TREE_SIDE_EFFECTS (valist))
- valist = save_expr (valist);
+ valist = save_expr (valist);
valist = fold (build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (valist)),
valist));
}
@@ -2213,8 +2187,7 @@ expand_builtin_va_copy (arglist)
MEM_ALIAS_SET (srcb) = get_alias_set (TREE_TYPE (TREE_TYPE (src)));
/* Copy. */
- emit_block_move (dstb, srcb, size,
- TYPE_ALIGN (va_list_type_node) / BITS_PER_UNIT);
+ emit_block_move (dstb, srcb, size, TYPE_ALIGN (va_list_type_node));
}
return const0_rtx;
diff --git a/gcc/c-common.c b/gcc/c-common.c
index b80501d0898..97aba258b12 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -3478,7 +3478,7 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
tree traditional_cptr_type_node;
tree traditional_len_type_node;
tree traditional_len_endlink;
- tree va_list_ptr_type_node;
+ tree va_list_ref_type_node;
tree va_list_arg_type_node;
pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_va_list"),
@@ -3490,13 +3490,17 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
pushdecl (build_decl (TYPE_DECL, get_identifier ("__builtin_size_t"),
sizetype));
- va_list_ptr_type_node = build_pointer_type (va_list_type_node);
-
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
- va_list_arg_type_node = build_pointer_type (TREE_TYPE (va_list_type_node));
+ {
+ va_list_arg_type_node = va_list_ref_type_node =
+ build_pointer_type (TREE_TYPE (va_list_type_node));
+ }
else
- va_list_arg_type_node = va_list_type_node;
-
+ {
+ va_list_arg_type_node = va_list_type_node;
+ va_list_ref_type_node = build_reference_type (va_list_type_node);
+ }
+
endlink = void_list_node;
int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
double_endlink = tree_cons (NULL_TREE, double_type_node, endlink);
@@ -3645,13 +3649,13 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
/* Suppress error if redefined as a non-function. */
DECL_BUILT_IN_NONANSI (temp) = 1;
- /* In C mode, don't conflict with system prototype variations. */
- temp = builtin_function ("bzero",
- cplus_mode ? bzero_ftype : void_ftype_any,
+ /* The system prototypes for these functions have many
+ variations, so don't specify parameters to avoid conflicts.
+ The expand_* functions check the argument types anyway. */
+ temp = builtin_function ("bzero", void_ftype_any,
BUILT_IN_BZERO, BUILT_IN_NORMAL, NULL_PTR);
DECL_BUILT_IN_NONANSI (temp) = 1;
- temp = builtin_function ("bcmp",
- cplus_mode ? bcmp_ftype : int_ftype_any,
+ temp = builtin_function ("bcmp", int_ftype_any,
BUILT_IN_BCMP, BUILT_IN_NORMAL, NULL_PTR);
DECL_BUILT_IN_NONANSI (temp) = 1;
}
@@ -3725,28 +3729,28 @@ c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins)
builtin_function ("__builtin_varargs_start",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
- va_list_ptr_type_node,
+ va_list_ref_type_node,
endlink)),
BUILT_IN_VARARGS_START, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_stdarg_start",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
- va_list_ptr_type_node,
+ va_list_ref_type_node,
NULL_TREE)),
BUILT_IN_STDARG_START, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_va_end",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
- va_list_arg_type_node,
+ va_list_ref_type_node,
endlink)),
BUILT_IN_VA_END, BUILT_IN_NORMAL, NULL_PTR);
builtin_function ("__builtin_va_copy",
build_function_type (void_type_node,
tree_cons (NULL_TREE,
- va_list_ptr_type_node,
+ va_list_ref_type_node,
tree_cons (NULL_TREE,
va_list_arg_type_node,
endlink))),
diff --git a/gcc/c-convert.c b/gcc/c-convert.c
index 7bde098e0e1..b3b144d6a8b 100644
--- a/gcc/c-convert.c
+++ b/gcc/c-convert.c
@@ -65,8 +65,10 @@ convert (type, expr)
register enum tree_code code = TREE_CODE (type);
if (type == TREE_TYPE (expr)
- || TREE_CODE (expr) == ERROR_MARK)
+ || TREE_CODE (expr) == ERROR_MARK
+ || code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
return expr;
+
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
return fold (build1 (NOP_EXPR, type, expr));
if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index a5cc45826a1..df1d707fa6c 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1805,11 +1805,14 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
DECL_RTL (newdecl) = DECL_RTL (olddecl);
/* Merge the type qualifiers. */
- if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
- && !TREE_THIS_VOLATILE (newdecl))
+ if (TREE_CODE (olddecl) == FUNCTION_DECL
+ && DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl)
+ && ! TREE_THIS_VOLATILE (newdecl))
TREE_THIS_VOLATILE (write_olddecl) = 0;
+
if (TREE_READONLY (newdecl))
TREE_READONLY (write_olddecl) = 1;
+
if (TREE_THIS_VOLATILE (newdecl))
{
TREE_THIS_VOLATILE (write_olddecl) = 1;
@@ -1904,14 +1907,15 @@ duplicate_decls (newdecl, olddecl, different_binding_level)
TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl);
}
- /* If either decl says `inline', this fn is inline,
- unless its definition was passed already. */
- if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
- DECL_INLINE (olddecl) = 1;
- DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
-
if (TREE_CODE (newdecl) == FUNCTION_DECL)
{
+ /* If either decl says `inline', this fn is inline,
+ unless its definition was passed already. */
+ if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0)
+ DECL_INLINE (olddecl) = 1;
+
+ DECL_INLINE (newdecl) = DECL_INLINE (olddecl);
+
if (DECL_BUILT_IN (olddecl))
{
/* Get rid of any built-in function if new arg types don't match it
@@ -2145,7 +2149,8 @@ pushdecl (x)
We get warnings about inline functions where they are defined.
Avoid duplicate warnings where they are used. */
- if (TREE_PUBLIC (x) && ! DECL_INLINE (x))
+ if (TREE_PUBLIC (x)
+ && ! (TREE_CODE (x) == FUNCTION_DECL && DECL_INLINE (x)))
{
tree decl;
@@ -2282,15 +2287,16 @@ pushdecl (x)
/* Here to install a non-global value. */
tree oldlocal = IDENTIFIER_LOCAL_VALUE (name);
tree oldglobal = IDENTIFIER_GLOBAL_VALUE (name);
+
IDENTIFIER_LOCAL_VALUE (name) = x;
/* If this is an extern function declaration, see if we
have a global definition or declaration for the function. */
if (oldlocal == 0
- && DECL_EXTERNAL (x) && !DECL_INLINE (x)
&& oldglobal != 0
&& TREE_CODE (x) == FUNCTION_DECL
- && TREE_CODE (oldglobal) == FUNCTION_DECL)
+ && TREE_CODE (oldglobal) == FUNCTION_DECL
+ && DECL_EXTERNAL (x) && ! DECL_INLINE (x))
{
/* We have one. Their types must agree. */
if (! comptypes (TREE_TYPE (x),
@@ -2537,8 +2543,8 @@ redeclaration_error_message (newdecl, olddecl)
if (DECL_INITIAL (olddecl) != 0 && DECL_INITIAL (newdecl) != 0
/* However, defining once as extern inline and a second
time in another way is ok. */
- && !(DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
- && !(DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
+ && ! (DECL_INLINE (olddecl) && DECL_EXTERNAL (olddecl)
+ && ! (DECL_INLINE (newdecl) && DECL_EXTERNAL (newdecl))))
return 1;
return 0;
}
@@ -5932,7 +5938,9 @@ store_parm_decls ()
{
if (DECL_NAME (parm) == 0)
error_with_decl (parm, "parameter name omitted");
- else if (TYPE_MAIN_VARIANT (TREE_TYPE (parm)) == void_type_node)
+ else if (TREE_CODE (TREE_TYPE (parm)) != ERROR_MARK
+ && (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
+ == void_type_node))
{
error_with_decl (parm, "parameter `%s' declared void");
/* Change the type to error_mark_node so this parameter
@@ -5999,8 +6007,10 @@ store_parm_decls ()
Associate decls with the names and store the decls
into the TREE_PURPOSE slots. */
+ /* We use DECL_WEAK as a flag to show which parameters have been
+ seen already since it is not used on PARM_DECL or CONST_DECL. */
for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
- DECL_RESULT (parm) = 0;
+ DECL_WEAK (parm) = 0;
for (parm = specparms; parm; parm = TREE_CHAIN (parm))
{
@@ -6008,7 +6018,8 @@ store_parm_decls ()
if (TREE_VALUE (parm) == 0)
{
- error_with_decl (fndecl, "parameter name missing from parameter list");
+ error_with_decl (fndecl,
+ "parameter name missing from parameter list");
TREE_PURPOSE (parm) = 0;
continue;
}
@@ -6025,7 +6036,7 @@ store_parm_decls ()
/* If declaration already marked, we have a duplicate name.
Complain, and don't use this decl twice. */
- if (found && DECL_RESULT (found) != 0)
+ if (found && DECL_WEAK (found))
{
error_with_decl (found, "multiple parameters named `%s'");
found = 0;
@@ -6064,10 +6075,8 @@ store_parm_decls ()
TREE_PURPOSE (parm) = found;
- /* Mark this decl as "already found" -- see test, above.
- It is safe to use DECL_RESULT for this
- since it is not used in PARM_DECLs or CONST_DECLs. */
- DECL_RESULT (found) = error_mark_node;
+ /* Mark this decl as "already found" */
+ DECL_WEAK (found) = 1;
}
/* Put anything which is on the parmdecls chain and which is
@@ -6093,7 +6102,7 @@ store_parm_decls ()
TREE_TYPE (parm) = error_mark_node;
}
- if (DECL_RESULT (parm) == 0)
+ if (! DECL_WEAK (parm))
{
error_with_decl (parm,
"declaration for parameter `%s' but no such parameter");
@@ -6309,7 +6318,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
tree types = 0;
for (parm = parmdecls; parm; parm = TREE_CHAIN (parm))
- DECL_RESULT (parm) = 0;
+ DECL_WEAK (parm) = 0;
for (parm = specparms; parm; parm = TREE_CHAIN (parm))
{
@@ -6325,7 +6334,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
/* If declaration already marked, we have a duplicate name.
Complain, and don't use this decl twice. */
- if (found && DECL_RESULT (found) != 0)
+ if (found && DECL_WEAK (found))
{
error_with_decl (found, "multiple parameters named `%s'");
found = 0;
@@ -6363,10 +6372,8 @@ combine_parm_decls (specparms, parmlist, void_at_end)
TREE_PURPOSE (parm) = found;
- /* Mark this decl as "already found" -- see test, above.
- It is safe to use DECL_RESULT for this
- since it is not used in PARM_DECLs or CONST_DECLs. */
- DECL_RESULT (found) = error_mark_node;
+ /* Mark this decl as "already found". */
+ DECL_WEAK (found) = 1;
}
/* Complain about any actual PARM_DECLs not matched with any names. */
@@ -6383,7 +6390,7 @@ combine_parm_decls (specparms, parmlist, void_at_end)
TREE_TYPE (parm) = error_mark_node;
}
- if (DECL_RESULT (parm) == 0)
+ if (! DECL_WEAK (parm))
{
error_with_decl (parm,
"declaration for parameter `%s' but no such parameter");
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c
index abdd2a72812..0d395a2b3d4 100644
--- a/gcc/c-typeck.c
+++ b/gcc/c-typeck.c
@@ -2416,11 +2416,12 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
else
sop = xop1, uop = xop0;
- /* Do not warn if the signed quantity is an unsuffixed
- integer literal (or some static constant expression
- involving such literals) and it is non-negative. */
- if (TREE_CODE (sop) == INTEGER_CST
- && tree_int_cst_sgn (sop) >= 0)
+ /* Do not warn if the signed quantity is an
+ unsuffixed integer literal (or some static
+ constant expression involving such literals or a
+ conditional expression involving such literals)
+ and it is non-negative. */
+ if (tree_expr_nonnegative_p (sop))
/* OK */;
/* Do not warn if the comparison is an equality operation,
the unsigned quantity is an integral constant, and it
@@ -2982,17 +2983,16 @@ build_unary_op (code, xarg, noconvert)
/* 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
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 (DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
- {
- if (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg))
- argtype = c_build_type_variant (argtype,
- TREE_READONLY (arg),
- TREE_THIS_VOLATILE (arg));
- }
+ if ((DECL_P (arg) || TREE_CODE_CLASS (TREE_CODE (arg)) == 'r')
+ && (TREE_READONLY (arg) || TREE_THIS_VOLATILE (arg)))
+ argtype = c_build_type_variant (argtype,
+ TREE_READONLY (arg),
+ TREE_THIS_VOLATILE (arg));
argtype = build_pointer_type (argtype);
@@ -3015,19 +3015,9 @@ build_unary_op (code, xarg, noconvert)
return error_mark_node;
}
- addr = convert (argtype, addr);
-
- if (! integer_zerop (bit_position (field)))
- {
- tree offset
- = size_binop (EASY_DIV_EXPR, bit_position (field),
- bitsize_int (BITS_PER_UNIT));
- int flag = TREE_CONSTANT (addr);
-
- addr = fold (build (PLUS_EXPR, argtype,
- addr, convert (argtype, offset)));
- TREE_CONSTANT (addr) = flag;
- }
+ addr = fold (build (PLUS_EXPR, argtype,
+ convert (argtype, addr),
+ convert (argtype, byte_position (field))));
}
else
addr = build1 (code, argtype, arg);
@@ -3394,10 +3384,8 @@ build_conditional_expr (ifexp, op1, op2)
/* Do not warn if the signed quantity is an unsuffixed
integer literal (or some static constant expression
involving such literals) and it is non-negative. */
- else if ((unsigned_op2 && TREE_CODE (op1) == INTEGER_CST
- && tree_int_cst_sgn (op1) >= 0)
- || (unsigned_op1 && TREE_CODE (op2) == INTEGER_CST
- && tree_int_cst_sgn (op2) >= 0))
+ else if ((unsigned_op2 && tree_expr_nonnegative_p (op1))
+ || (unsigned_op1 && tree_expr_nonnegative_p (op2)))
/* OK */;
else
warning ("signed and unsigned type in conditional expression");
@@ -3971,11 +3959,32 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
error ("void value not ignored as it ought to be");
return error_mark_node;
}
+ /* A type converts to a reference to it.
+ This code doesn't fully support references, it's just for the
+ special case of va_start and va_copy. */
+ if (codel == REFERENCE_TYPE
+ && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
+ {
+ if (mark_addressable (rhs) == 0)
+ return error_mark_node;
+ rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
+
+ /* We already know that these two types are compatible, but they
+ may not be exactly identical. In fact, `TREE_TYPE (type)' is
+ likely to be __builtin_va_list and `TREE_TYPE (rhs)' is
+ likely to be va_list, a typedef to __builtin_va_list, which
+ is different enough that it will cause problems later. */
+ if (TREE_TYPE (TREE_TYPE (rhs)) != TREE_TYPE (type))
+ rhs = build1 (NOP_EXPR, build_pointer_type (TREE_TYPE (type)), rhs);
+
+ rhs = build1 (NOP_EXPR, type, rhs);
+ return rhs;
+ }
/* Arithmetic types all interconvert, and enum is treated like int. */
- if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == ENUMERAL_TYPE
- || codel == COMPLEX_TYPE)
- && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == ENUMERAL_TYPE
- || coder == COMPLEX_TYPE))
+ else if ((codel == INTEGER_TYPE || codel == REAL_TYPE
+ || codel == ENUMERAL_TYPE || codel == COMPLEX_TYPE)
+ && (coder == INTEGER_TYPE || coder == REAL_TYPE
+ || coder == ENUMERAL_TYPE || coder == COMPLEX_TYPE))
return convert_and_check (type, rhs);
/* Conversion to a transparent union from its member types.
@@ -5026,7 +5035,7 @@ really_start_incremental_init (type)
constructor_fields = TREE_CHAIN (constructor_fields);
constructor_unfilled_fields = constructor_fields;
- constructor_bit_index = bitsize_int (0);
+ constructor_bit_index = bitsize_zero_node;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -5040,7 +5049,7 @@ really_start_incremental_init (type)
TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type)));
}
else
- constructor_index = bitsize_int (0);
+ constructor_index = bitsize_zero_node;
constructor_unfilled_index = constructor_index;
}
@@ -5104,7 +5113,7 @@ push_init_level (implicit)
size_binop (MINUS_EXPR,
bit_position (constructor_fields),
constructor_bit_index),
- bitsize_int (BITS_PER_UNIT)),
+ bitsize_unit_node),
1));
/* Indicate that we have now filled the structure up to the current
@@ -5196,7 +5205,7 @@ push_init_level (implicit)
constructor_fields = TREE_CHAIN (constructor_fields);
constructor_unfilled_fields = constructor_fields;
- constructor_bit_index = bitsize_int (0);
+ constructor_bit_index = bitsize_zero_node;
}
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -5211,7 +5220,7 @@ push_init_level (implicit)
(TYPE_DOMAIN (constructor_type)));
}
else
- constructor_index = bitsize_int (0);
+ constructor_index = bitsize_zero_node;
constructor_unfilled_index = constructor_index;
}
@@ -5393,9 +5402,8 @@ pop_init_level (implicit)
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
/* Find the offset of the end of that field. */
- filled = size_binop (CEIL_DIV_EXPR,
- constructor_bit_index,
- bitsize_int (BITS_PER_UNIT));
+ filled = size_binop (CEIL_DIV_EXPR, constructor_bit_index,
+ bitsize_unit_node);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE)
{
@@ -5406,7 +5414,7 @@ pop_init_level (implicit)
{
tree maxindex
= copy_node (size_diffop (constructor_unfilled_index,
- bitsize_int (1)));
+ bitsize_one_node));
TYPE_DOMAIN (constructor_type) = build_index_type (maxindex);
TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type);
@@ -5914,7 +5922,7 @@ output_init_element (value, type, field, pending)
(size_binop (TRUNC_DIV_EXPR,
size_binop (MINUS_EXPR, bit_position (field),
constructor_bit_index),
- bitsize_int (BITS_PER_UNIT)),
+ bitsize_unit_node),
0));
output_constant (digest_init (type, value,
@@ -5936,7 +5944,7 @@ output_init_element (value, type, field, pending)
if (TREE_CODE (constructor_type) == ARRAY_TYPE)
constructor_unfilled_index
= size_binop (PLUS_EXPR, constructor_unfilled_index,
- bitsize_int (1));
+ bitsize_one_node);
else if (TREE_CODE (constructor_type) == RECORD_TYPE)
{
constructor_unfilled_fields
@@ -6089,7 +6097,7 @@ output_pending_init_elements (all)
if (constructor_incremental)
{
tree filled;
- tree nextpos_tree = bitsize_int (0);
+ tree nextpos_tree = bitsize_zero_node;
if (TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
@@ -6105,17 +6113,13 @@ output_pending_init_elements (all)
if (tail)
/* Find the offset of the end of that field. */
filled = size_binop (CEIL_DIV_EXPR,
- size_binop (PLUS_EXPR,
- bit_position (tail),
+ size_binop (PLUS_EXPR, bit_position (tail),
DECL_SIZE (tail)),
- bitsize_int (BITS_PER_UNIT));
+ bitsize_unit_node);
else
- filled = bitsize_int (0);
-
- nextpos_tree = size_binop (CEIL_DIV_EXPR,
- bit_position (next),
- bitsize_int (BITS_PER_UNIT));
+ filled = bitsize_zero_node;
+ nextpos_tree = convert (bitsizetype, byte_position (next));
constructor_bit_index = bit_position (next);
constructor_unfilled_fields = next;
}
@@ -6395,7 +6399,7 @@ process_init_element (value)
}
constructor_index
- = size_binop (PLUS_EXPR, constructor_index, bitsize_int (1));
+ = size_binop (PLUS_EXPR, constructor_index, bitsize_one_node);
if (! value)
/* If we are doing the bookkeeping for an element that was
diff --git a/gcc/calls.c b/gcc/calls.c
index ed4b31be4c3..90afe1e5d57 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -32,6 +32,19 @@ Boston, MA 02111-1307, USA. */
#include "output.h"
#include "tm_p.h"
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
+/* Supply a default definition for PUSH_ARGS. */
+#ifndef PUSH_ARGS
+#ifdef PUSH_ROUNDING
+#define PUSH_ARGS !ACCUMULATE_OUTGOING_ARGS
+#else
+#define PUSH_ARGS 0
+#endif
+#endif
+
#if !defined FUNCTION_OK_FOR_SIBCALL
#define FUNCTION_OK_FOR_SIBCALL(DECL) 1
#endif
@@ -49,9 +62,13 @@ Boston, MA 02111-1307, USA. */
#ifdef PUSH_ROUNDING
#if defined (STACK_GROWS_DOWNWARD) != defined (ARGS_GROW_DOWNWARD)
-#define PUSH_ARGS_REVERSED /* If it's last to first */
+#define PUSH_ARGS_REVERSED PUSH_ARGS
+#endif
+
#endif
+#ifndef PUSH_ARGS_REVERSED
+#define PUSH_ARGS_REVERSED 0
#endif
/* Like PREFERRED_STACK_BOUNDARY but in units of bytes, not bits. */
@@ -101,10 +118,8 @@ struct arg_data
differ from STACK if this arg pads downward. This location is known
to be aligned to FUNCTION_ARG_BOUNDARY. */
rtx stack_slot;
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* Place that this stack area has been saved, if needed. */
rtx save_area;
-#endif
/* If an argument's alignment does not permit direct copying into registers,
copy in smaller-sized pieces into pseudos. These are stored in a
block pointed to by this field. The next field says how many
@@ -116,7 +131,6 @@ struct arg_data
struct args_size alignment_pad;
};
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* A vector of one char per byte of stack space. A byte if non-zero if
the corresponding stack location has been used.
This vector is used to prevent a function call within an argument from
@@ -132,14 +146,29 @@ static int highest_outgoing_arg_in_use;
to make sure the object being constructed does not overlap the
argument list for the constructor call. */
int stack_arg_under_construction;
-#endif
static int calls_function PARAMS ((tree, int));
static int calls_function_1 PARAMS ((tree, int));
-#define ECF_IS_CONST 1
-#define ECF_NOTHROW 2
-#define ECF_SIBCALL 4
+/* Nonzero if this is a call to a `const' function. */
+#define ECF_CONST 1
+/* Nonzero if this is a call to a `volatile' function. */
+#define ECF_NORETURN 2
+/* Nonzero if this is a call to malloc or a related function. */
+#define ECF_MALLOC 4
+/* Nonzero if it is plausible that this is a call to alloca. */
+#define ECF_MAY_BE_ALLOCA 8
+/* Nonzero if this is a call to a function that won't throw an exception. */
+#define ECF_NOTHROW 16
+/* Nonzero if this is a call to setjmp or a related function. */
+#define ECF_RETURNS_TWICE 32
+/* Nonzero if this is a call to `longjmp'. */
+#define ECF_LONGJMP 64
+/* Nonzero if this is a syscall that makes a new process in the image of
+ the current one. */
+#define ECF_FORK_OR_EXEC 128
+#define ECF_SIBCALL 256
+
static void emit_call_1 PARAMS ((rtx, tree, tree, HOST_WIDE_INT,
HOST_WIDE_INT, HOST_WIDE_INT, rtx,
rtx, int, rtx, int));
@@ -165,7 +194,7 @@ static void initialize_argument_information PARAMS ((int,
int, tree, tree,
CUMULATIVE_ARGS *,
int, rtx *, int *,
- int *, int *, int));
+ int *, int *));
static void compute_argument_addresses PARAMS ((struct arg_data *,
rtx, int));
static rtx rtx_for_function_call PARAMS ((tree, tree));
@@ -175,8 +204,12 @@ static int libfunc_nothrow PARAMS ((rtx));
static rtx emit_library_call_value_1 PARAMS ((int, rtx, rtx, int,
enum machine_mode,
int, va_list));
+static int special_function_p PARAMS ((tree, int));
+static int flags_from_decl_or_type PARAMS ((tree));
+static rtx try_to_integrate PARAMS ((tree, tree, rtx,
+ int, tree, rtx));
-#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+#ifdef REG_PARM_STACK_SPACE
static rtx save_fixed_argument_area PARAMS ((int, rtx, int *, int *));
static void restore_fixed_argument_area PARAMS ((rtx, rtx, int, int));
#endif
@@ -388,9 +421,7 @@ prepare_call_address (funexp, fndecl, call_fusage, reg_parm_seen)
We restore `inhibit_defer_pop' to that value.
CALL_FUSAGE is either empty or an EXPR_LIST of USE expressions that
- denote registers used by the called function.
-
- IS_CONST is true if this is a `const' call. */
+ denote registers used by the called function. */
static void
emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
@@ -413,10 +444,8 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
rtx struct_value_size_rtx = GEN_INT (struct_value_size);
#endif
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,
and we don't want to load it into a register as an optimization,
@@ -424,7 +453,6 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
if (GET_CODE (funexp) != SYMBOL_REF)
funexp = memory_address (FUNCTION_MODE, funexp);
-#ifndef ACCUMULATE_OUTGOING_ARGS
#if defined (HAVE_sibcall_pop) && defined (HAVE_sibcall_value_pop)
if ((ecf_flags & ECF_SIBCALL)
&& HAVE_sibcall_pop && HAVE_sibcall_value_pop
@@ -459,7 +487,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
even if the call has no arguments to pop. */
#if defined (HAVE_call) && defined (HAVE_call_value)
if (HAVE_call && HAVE_call_value && HAVE_call_pop && HAVE_call_value_pop
- && n_popped > 0)
+ && n_popped > 0)
#else
if (HAVE_call_pop && HAVE_call_value_pop)
#endif
@@ -483,7 +511,6 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
}
else
#endif
-#endif
#if defined (HAVE_sibcall) && defined (HAVE_sibcall_value)
if ((ecf_flags & ECF_SIBCALL)
@@ -544,7 +571,7 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
/* If this is a const call, then set the insn's unchanging bit. */
- if (ecf_flags & ECF_IS_CONST)
+ if (ecf_flags & ECF_CONST)
CONST_CALL_P (call_insn) = 1;
/* If this call can't throw, attach a REG_EH_REGION reg note to that
@@ -559,18 +586,6 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
if the context of the call as a whole permits. */
inhibit_defer_pop = old_inhibit_defer_pop;
-#ifndef ACCUMULATE_OUTGOING_ARGS
- /* If returning from the subroutine does not automatically pop the args,
- we need an instruction to pop them sooner or later.
- Perhaps do it now; perhaps just record how much space to pop later.
-
- If returning from the subroutine does pop the args, indicate that the
- stack pointer will be changed. */
-
- /* The space for the args is no longer waiting for the call; either it
- was popped by the call, or it'll be popped below. */
- arg_space_so_far -= rounded_stack_size;
-
if (n_popped > 0)
{
if (!already_popped)
@@ -580,17 +595,40 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
CALL_INSN_FUNCTION_USAGE (call_insn));
rounded_stack_size -= n_popped;
rounded_stack_size_rtx = GEN_INT (rounded_stack_size);
+ stack_pointer_delta -= n_popped;
}
- if (rounded_stack_size != 0)
+ if (!ACCUMULATE_OUTGOING_ARGS)
{
- if (flag_defer_pop && inhibit_defer_pop == 0
- && !(ecf_flags & ECF_IS_CONST))
- pending_stack_adjust += rounded_stack_size;
- else
- adjust_stack (rounded_stack_size_rtx);
+ /* If returning from the subroutine does not automatically pop the args,
+ we need an instruction to pop them sooner or later.
+ Perhaps do it now; perhaps just record how much space to pop later.
+
+ If returning from the subroutine does pop the args, indicate that the
+ stack pointer will be changed. */
+
+ if (rounded_stack_size != 0)
+ {
+ if (flag_defer_pop && inhibit_defer_pop == 0
+ && !(ecf_flags & ECF_CONST))
+ pending_stack_adjust += rounded_stack_size;
+ else
+ adjust_stack (rounded_stack_size_rtx);
+ }
}
-#endif
+ /* When we accumulate outgoing args, we must avoid any stack manipulations.
+ Restore the stack pointer to its original value now. Usually
+ ACCUMULATE_OUTGOING_ARGS targets don't get here, but there are exceptions.
+ On i386 ACCUMULATE_OUTGOING_ARGS can be enabled on demand, and
+ popping variants of functions exist as well.
+
+ ??? We may optimize similar to defer_pop above, but it is
+ probably not worthwhile.
+
+ ??? It will be worthwhile to enable combine_stack_adjustments even for
+ such machines. */
+ else if (n_popped)
+ anti_adjust_stack (GEN_INT (n_popped));
}
/* Determine if the function identified by NAME and FNDECL is one with
@@ -599,33 +637,20 @@ emit_call_1 (funexp, fndecl, funtype, stack_size, rounded_stack_size,
For example, if the function might return more than one time (setjmp), then
set RETURNS_TWICE to a nonzero value.
- Similarly set IS_LONGJMP for if the function is in the longjmp family.
+ Similarly set LONGJMP for if the function is in the longjmp family.
- Set IS_MALLOC for any of the standard memory allocation functions which
+ Set MALLOC for any of the standard memory allocation functions which
allocate from the heap.
Set MAY_BE_ALLOCA for any memory allocation function that might allocate
space from the stack such as alloca. */
-void
-special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
- is_malloc, may_be_alloca)
+static int
+special_function_p (fndecl, flags)
tree fndecl;
- int *returns_twice;
- int *is_longjmp;
- int *fork_or_exec;
- int *is_malloc;
- int *may_be_alloca;
+ int flags;
{
- *returns_twice = 0;
- *is_longjmp = 0;
- *fork_or_exec = 0;
- *may_be_alloca = 0;
-
- /* The function decl may have the `malloc' attribute. */
- *is_malloc = fndecl && DECL_IS_MALLOC (fndecl);
-
- if (! *is_malloc
+ if (! (flags & ECF_MALLOC)
&& fndecl && DECL_NAME (fndecl)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
/* Exclude functions not at the file scope, or not `extern',
@@ -639,13 +664,13 @@ special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
/* 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"))));
+ if (((IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 6
+ && name[0] == 'a'
+ && ! strcmp (name, "alloca"))
+ || (IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 16
+ && name[0] == '_'
+ && ! strcmp (name, "__builtin_alloca"))))
+ flags |= ECF_MAY_BE_ALLOCA;
/* Disregard prefix _, __ or __x. */
if (name[0] == '_')
@@ -660,27 +685,28 @@ special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
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] == 'e'
+ && (! strcmp (tname, "setjmp")
+ || ! strcmp (tname, "setjmp_syscall")))
+ || (tname[1] == 'i'
+ && ! strcmp (tname, "sigsetjmp"))
+ || (tname[1] == 'a'
+ && ! strcmp (tname, "savectx")))
+ flags |= ECF_RETURNS_TWICE;
+
if (tname[1] == 'i'
&& ! strcmp (tname, "siglongjmp"))
- *is_longjmp = 1;
+ flags |= ECF_LONGJMP;
}
else if ((tname[0] == 'q' && tname[1] == 's'
&& ! strcmp (tname, "qsetjmp"))
|| (tname[0] == 'v' && tname[1] == 'f'
&& ! strcmp (tname, "vfork")))
- *returns_twice = 1;
+ flags |= ECF_RETURNS_TWICE;
else if (tname[0] == 'l' && tname[1] == 'o'
&& ! strcmp (tname, "longjmp"))
- *is_longjmp = 1;
+ flags |= ECF_LONGJMP;
else if ((tname[0] == 'f' && tname[1] == 'o'
&& ! strcmp (tname, "fork"))
@@ -694,7 +720,7 @@ special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
&& (tname[5] == '\0'
|| ((tname[5] == 'p' || tname[5] == 'e')
&& tname[6] == '\0'))))
- *fork_or_exec = 1;
+ flags |= ECF_FORK_OR_EXEC;
/* Do not add any more malloc-like functions to this list,
instead mark them as malloc functions using the malloc attribute.
@@ -707,10 +733,46 @@ special_function_p (fndecl, returns_twice, is_longjmp, fork_or_exec,
&& (! strcmp (tname, "malloc")
|| ! strcmp (tname, "calloc")
|| ! strcmp (tname, "strdup")))
- *is_malloc = 1;
+ flags |= ECF_MALLOC;
}
+ return flags;
}
+/* Return nonzero when tree represent call to longjmp. */
+int
+setjmp_call_p (fndecl)
+ tree fndecl;
+{
+ return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
+}
+
+/* Detect flags (function attributes) from the function type node. */
+static int
+flags_from_decl_or_type (exp)
+ tree exp;
+{
+ int flags = 0;
+ /* ??? We can't set IS_MALLOC for function types? */
+ if (DECL_P (exp))
+ {
+ /* The function exp may have the `malloc' attribute. */
+ if (DECL_P (exp) && DECL_IS_MALLOC (exp))
+ flags |= ECF_MALLOC;
+
+ if (TREE_NOTHROW (exp))
+ flags |= ECF_NOTHROW;
+ }
+
+ if (TREE_READONLY (exp) && !TREE_THIS_VOLATILE (exp))
+ flags |= ECF_CONST;
+
+ if (TREE_THIS_VOLATILE (exp))
+ flags |= ECF_NORETURN;
+
+ return flags;
+}
+
+
/* Precompute all register parameters as described by ARGS, storing values
into fields within the ARGS array.
@@ -774,7 +836,7 @@ precompute_register_parameters (num_actuals, args, reg_parm_seen)
}
}
-#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+#ifdef 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
@@ -833,11 +895,11 @@ save_fixed_argument_area (reg_parm_stack_space, argblock,
if (save_mode == BLKmode)
{
save_area = assign_stack_temp (BLKmode, num_to_save, 0);
- /* Cannot use emit_block_move here because it can be done by a library
- call which in turn gets into this place again and deadly infinite
- recursion happens. */
+ /* Cannot use emit_block_move here because it can be done by a
+ library call which in turn gets into this place again and deadly
+ infinite recursion happens. */
move_by_pieces (validize_mem (save_area), stack_area, num_to_save,
- PARM_BOUNDARY / BITS_PER_UNIT);
+ PARM_BOUNDARY);
}
else
{
@@ -877,8 +939,7 @@ restore_fixed_argument_area (save_area, argblock, high_to_save, low_to_save)
call which in turn gets into this place again and deadly infinite
recursion happens. */
move_by_pieces (stack_area, validize_mem (save_area),
- high_to_save - low_to_save + 1,
- PARM_BOUNDARY / BITS_PER_UNIT);
+ high_to_save - low_to_save + 1, PARM_BOUNDARY);
}
#endif
@@ -945,12 +1006,10 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
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,
+ extract_bit_field (word, bitsize, 0, 1, NULL_RTX,
+ word_mode, word_mode, bitalign,
BITS_PER_WORD),
- bitalign / BITS_PER_UNIT, BITS_PER_WORD);
+ bitalign, BITS_PER_WORD);
}
}
}
@@ -973,14 +1032,14 @@ store_unaligned_arguments_into_pseudos (args, num_actuals)
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
+ OLD_PENDING_ADJ, MUST_PREALLOCATE and FLAGS 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,
+ old_pending_adj, must_preallocate,
ecf_flags)
int num_actuals ATTRIBUTE_UNUSED;
struct arg_data *args;
@@ -993,8 +1052,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
rtx *old_stack_level;
int *old_pending_adj;
int *must_preallocate;
- int *is_const;
- int ecf_flags;
+ int *ecf_flags;
{
/* 1 if scanning parms front to back, -1 if scanning back to front. */
int inc;
@@ -1013,13 +1071,16 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
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
+ if (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;
+ }
/* 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++)
@@ -1134,7 +1195,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
MEM_SET_IN_STRUCT_P (copy, AGGREGATE_TYPE_P (type));
store_expr (args[i].tree_value, copy, 0);
- *is_const = 0;
+ *ecf_flags &= ~ECF_CONST;
args[i].tree_value = build1 (ADDR_EXPR,
build_pointer_type (type),
@@ -1157,7 +1218,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* If this is a sibling call and the machine has register windows, the
register window has to be unwinded before calling the routine, so
arguments have to go into the incoming registers. */
- if (ecf_flags & ECF_SIBCALL)
+ if (*ecf_flags & ECF_SIBCALL)
args[i].reg = FUNCTION_INCOMING_ARG (*args_so_far, mode, type,
argpos < n_named_args);
else
@@ -1193,7 +1254,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
/* 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;
+ *ecf_flags &= ~ECF_CONST;
/* Compute the stack-size of this argument. */
if (args[i].reg == 0 || args[i].partial != 0
@@ -1262,6 +1323,14 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
{
int unadjusted_args_size = args_size->constant;
+ /* For accumulate outgoing args mode we don't need to align, since the frame
+ will be already aligned. Align to STACK_BOUNDARY in order to prevent
+ backends from generating missaligned frame sizes. */
+#ifdef STACK_BOUNDARY
+ if (ACCUMULATE_OUTGOING_ARGS && preferred_stack_boundary > STACK_BOUNDARY)
+ preferred_stack_boundary = STACK_BOUNDARY;
+#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. */
@@ -1274,7 +1343,14 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
#ifdef PREFERRED_STACK_BOUNDARY
preferred_stack_boundary /= BITS_PER_UNIT;
if (preferred_stack_boundary > 1)
- args_size->var = round_up (args_size->var, preferred_stack_boundary);
+ {
+ /* We don't handle this case yet. To handle it correctly we have
+ to add the delta, round and substract the delta.
+ Currently no machine description requires this support. */
+ if (stack_pointer_delta & (preferred_stack_boundary - 1))
+ abort();
+ args_size->var = round_up (args_size->var, preferred_stack_boundary);
+ }
#endif
if (reg_parm_stack_space > 0)
@@ -1299,13 +1375,11 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
if (preferred_stack_boundary < 1)
preferred_stack_boundary = 1;
args_size->constant = (((args_size->constant
- + arg_space_so_far
- + pending_stack_adjust
+ + stack_pointer_delta
+ preferred_stack_boundary - 1)
/ preferred_stack_boundary
* preferred_stack_boundary)
- - arg_space_so_far
- - pending_stack_adjust);
+ - stack_pointer_delta);
#endif
args_size->constant = MAX (args_size->constant,
@@ -1325,7 +1399,7 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
/* Precompute parameters as needed for a function call.
- IS_CONST indicates the target function is a pure function.
+ FLAGS is mask of ECF_* constants.
MUST_PREALLOCATE indicates that we must preallocate stack space for
any stack arguments.
@@ -1338,8 +1412,8 @@ compute_argument_block_size (reg_parm_stack_space, args_size,
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;
+precompute_arguments (flags, must_preallocate, num_actuals, args, args_size)
+ int flags;
int must_preallocate;
int num_actuals;
struct arg_data *args;
@@ -1361,7 +1435,7 @@ precompute_arguments (is_const, must_preallocate, num_actuals, args, args_size)
which have already been stored into the stack. */
for (i = 0; i < num_actuals; i++)
- if (is_const
+ if ((flags & ECF_CONST)
|| ((args_size->var != 0 || args_size->constant != 0)
&& calls_function (args[i].tree_value, 1))
|| (must_preallocate
@@ -1622,12 +1696,9 @@ load_register_parameters (args, num_actuals, call_fusage)
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));
- }
+ 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)));
/* If simple case, just do move. If normal partial, store_one_arg
has already loaded the register for us. In all other cases,
@@ -1661,6 +1732,122 @@ load_register_parameters (args, num_actuals, call_fusage)
}
}
+/* Try to integreate function. See expand_inline_function for documentation
+ about the parameters. */
+
+static rtx
+try_to_integrate (fndecl, actparms, target, ignore, type, structure_value_addr)
+ tree fndecl;
+ tree actparms;
+ rtx target;
+ int ignore;
+ tree type;
+ rtx structure_value_addr;
+{
+ rtx temp;
+ rtx before_call;
+ int i;
+ rtx old_stack_level = 0;
+ int reg_parm_stack_space = 0;
+
+#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
+
+ before_call = get_last_insn ();
+
+ temp = expand_inline_function (fndecl, actparms, target,
+ ignore, type,
+ structure_value_addr);
+
+ /* If inlining succeeded, return. */
+ if (temp != (rtx) (HOST_WIDE_INT) - 1)
+ {
+ if (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 = NULL_RTX, seq;
+
+ /* Look for a call in the inline function code.
+ If DECL_SAVED_INSNS (fndecl)->outgoing_args_size is
+ nonzero then there is a call and it is not necessary
+ to scan the insns. */
+
+ if (DECL_SAVED_INSNS (fndecl)->outgoing_args_size == 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 = (DECL_SAVED_INSNS (fndecl)->outgoing_args_size
+ + 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);
+ }
+ }
+ }
+
+ /* 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);
+ return (rtx) (HOST_WIDE_INT) - 1;
+}
+
/* 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.
@@ -1692,9 +1879,6 @@ expand_call (exp, target, ignore)
or 0 if the function is computed (not known by name). */
tree fndecl = 0;
char *name = 0;
-#ifdef ACCUMULATE_OUTGOING_ARGS
- rtx before_call;
-#endif
rtx insn;
int try_tail_call;
int pass;
@@ -1744,11 +1928,7 @@ expand_call (exp, target, ignore)
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
+ int must_preallocate = !PUSH_ARGS;
/* Size of the stack reserved for parameter registers. */
int reg_parm_stack_space = 0;
@@ -1757,42 +1937,25 @@ expand_call (exp, target, ignore)
(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 syscall that makes a new process in the image of
- the current one. */
- int fork_or_exec;
+ /* Mask of ECF_ flags. */
+ int flags = 0;
/* 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;
- /* Nonzero if this is a call to a function that won't throw an exception. */
- int nothrow = TREE_NOTHROW (exp);
-#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
save, if any. */
int low_to_save = -1, high_to_save;
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 = 0;
-#endif
rtx old_stack_level = 0;
int old_pending_adj = 0;
int old_inhibit_defer_pop = inhibit_defer_pop;
+ int old_stack_allocated;
rtx call_fusage;
register tree p;
register int i;
@@ -1805,6 +1968,10 @@ expand_call (exp, target, ignore)
if (current_function_check_memory_usage)
target = 0;
+ /* See if this is "nothrow" function call. */
+ if (TREE_NOTHROW (exp))
+ flags |= ECF_NOTHROW;
+
/* 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. */
@@ -1838,24 +2005,15 @@ expand_call (exp, target, ignore)
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 (TREE_NOTHROW (fndecl))
- nothrow = 1;
+ flags |= flags_from_decl_or_type (fndecl);
}
}
/* If we don't have specific function to call, see if we have a
- constant or `noreturn' function from the type. */
+ attributes set in the type. */
if (fndecl == 0)
{
- is_const = TREE_READONLY (TREE_TYPE (TREE_TYPE (p)));
- is_volatile = TREE_THIS_VOLATILE (TREE_TYPE (TREE_TYPE (p)));
+ flags |= flags_from_decl_or_type (TREE_TYPE (TREE_TYPE (p)));
}
#ifdef REG_PARM_STACK_SPACE
@@ -1866,8 +2024,8 @@ expand_call (exp, target, ignore)
#endif
#endif
-#if defined(PUSH_ROUNDING) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
- if (reg_parm_stack_space > 0)
+#ifndef OUTGOING_REG_PARM_STACK_SPACE
+ if (reg_parm_stack_space > 0 && PUSH_ARGS)
must_preallocate = 1;
#endif
@@ -1882,7 +2040,7 @@ expand_call (exp, target, ignore)
if (aggregate_value_p (exp))
{
/* This call returns a big structure. */
- is_const = 0;
+ flags &= ~ECF_CONST;
#ifdef PCC_STATIC_STRUCT_RETURN
{
@@ -1933,96 +2091,11 @@ expand_call (exp, target, ignore)
if (is_integrable)
{
- rtx temp;
-
-#ifdef ACCUMULATE_OUTGOING_ARGS
- 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 = NULL_RTX, seq;
-
- /* Look for a call in the inline function code.
- If DECL_SAVED_INSNS (fndecl)->outgoing_args_size is
- nonzero then there is a call and it is not necessary
- to scan the insns. */
-
- if (DECL_SAVED_INSNS (fndecl)->outgoing_args_size == 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 = (DECL_SAVED_INSNS (fndecl)->outgoing_args_size
- + 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);
+ rtx temp = try_to_integrate (fndecl, actparms, target,
+ ignore, TREE_TYPE (exp),
+ structure_value_addr);
+ if (temp != (rtx) (HOST_WIDE_INT) - 1)
+ return temp;
}
currently_expanding_call++;
@@ -2034,7 +2107,7 @@ expand_call (exp, target, ignore)
the call. */
try_tail_call = 0;
- if (optimize >= 2
+ if (flag_optimize_sibling_calls
&& currently_expanding_call == 1
&& stmt_loop_nest_empty ()
&& ! any_pending_cleanups (1))
@@ -2099,31 +2172,25 @@ expand_call (exp, target, ignore)
recursion call can be ignored if we indeed use the tail recursion
call expansion. */
int save_pending_stack_adjust = pending_stack_adjust;
- rtx last;
+ int save_stack_pointer_delta = stack_pointer_delta;
/* Use a new sequence to hold any RTL we generate. We do not even
know if we will use this RTL yet. The final decision can not be
made until after RTL generation for the entire function is
complete. */
- push_to_sequence (0);
+ start_sequence ();
/* Emit the pending stack adjustments before we expand any arguments. */
do_pending_stack_adjust ();
- optimize_tail_recursion (exp, get_last_insn ());
-
- last = get_last_insn ();
- tail_recursion_insns = get_insns ();
+ if (optimize_tail_recursion (actparms, get_last_insn ()))
+ tail_recursion_insns = get_insns ();
end_sequence ();
- /* If the last insn on the tail recursion sequence is not a
- BARRIER, then tail recursion optimization failed. */
- if (last == NULL_RTX || GET_CODE (last) != BARRIER)
- tail_recursion_insns = NULL_RTX;
-
/* Restore the original pending stack adjustment for the sibling and
normal call cases below. */
pending_stack_adjust = save_pending_stack_adjust;
+ stack_pointer_delta = save_stack_pointer_delta;
}
function_call_count++;
@@ -2146,10 +2213,9 @@ expand_call (exp, target, ignore)
/* 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 (fndecl, &returns_twice, &is_longjmp, &fork_or_exec,
- &is_malloc, &may_be_alloca);
+ flags |= special_function_p (fndecl, flags);
- if (may_be_alloca)
+ if (flags & ECF_MAY_BE_ALLOCA)
current_function_calls_alloca = 1;
/* Operand 0 is a pointer-to-function; get the type of the function. */
@@ -2169,6 +2235,7 @@ expand_call (exp, target, ignore)
recursion call can be ignored if we indeed use the tail recursion
call expansion. */
int save_pending_stack_adjust;
+ int save_stack_pointer_delta;
rtx insns;
rtx before_call, next_arg_reg;
@@ -2197,6 +2264,10 @@ expand_call (exp, target, ignore)
|| ! FUNCTION_OK_FOR_SIBCALL (fndecl))
continue;
+ /* Emit any queued insns now; otherwise they would end up in
+ only one of the alternates. */
+ emit_queue ();
+
/* We know at this point that there are not currently any
pending cleanups. If, however, in the process of evaluating
the arguments we were to create some, we'll need to be
@@ -2206,10 +2277,15 @@ expand_call (exp, target, ignore)
/* State variables we need to save and restore between
iterations. */
save_pending_stack_adjust = pending_stack_adjust;
+ save_stack_pointer_delta = stack_pointer_delta;
}
+ if (pass)
+ flags &= ~ECF_SIBCALL;
+ else
+ flags |= ECF_SIBCALL;
/* Other state variables that we must reinitialize each time
- through the loop (that are not initialized by the loop itself. */
+ through the loop (that are not initialized by the loop itself). */
argblock = 0;
call_fusage = 0;
@@ -2221,7 +2297,7 @@ expand_call (exp, target, ignore)
/* 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)
+ if (flags & ECF_CONST)
NO_DEFER_POP;
/* Don't let pending stack adjusts add up to too much.
@@ -2229,11 +2305,11 @@ expand_call (exp, target, ignore)
this might be a call to alloca or if we are expanding a sibling
call sequence. */
if (pending_stack_adjust >= 32
- || (pending_stack_adjust > 0 && may_be_alloca)
+ || (pending_stack_adjust > 0 && (flags & ECF_MAY_BE_ALLOCA))
|| pass == 0)
do_pending_stack_adjust ();
- if (profile_arc_flag && fork_or_exec)
+ if (profile_arc_flag && (flags & ECF_FORK_OR_EXEC))
{
/* A fork duplicates the profile information, and an exec discards
it. We can't rely on fork/exec to be paired. So write out the
@@ -2268,10 +2344,9 @@ expand_call (exp, target, ignore)
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
+ || (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);
@@ -2327,8 +2402,7 @@ expand_call (exp, target, ignore)
n_named_args, actparms, fndecl,
&args_so_far, reg_parm_stack_space,
&old_stack_level, &old_pending_adj,
- &must_preallocate, &is_const,
- (pass == 0) ? ECF_SIBCALL : 0);
+ &must_preallocate, &flags);
#ifdef FINAL_REG_PARM_STACK_SPACE
reg_parm_stack_space = FINAL_REG_PARM_STACK_SPACE (args_size.constant,
@@ -2344,7 +2418,7 @@ expand_call (exp, target, ignore)
Also do not make a sibling call. */
- is_const = 0;
+ flags &= ~ECF_CONST;
must_preallocate = 1;
sibcall_failure = 1;
}
@@ -2388,21 +2462,21 @@ expand_call (exp, target, ignore)
|| reg_mentioned_p (virtual_outgoing_args_rtx,
structure_value_addr))
&& (args_size.var
-#ifndef ACCUMULATE_OUTGOING_ARGS
- || args_size.constant
-#endif
+ || (!ACCUMULATE_OUTGOING_ARGS && args_size.constant)
))
structure_value_addr = copy_to_reg (structure_value_addr);
/* Precompute any arguments as needed. */
- precompute_arguments (is_const, must_preallocate, num_actuals,
+ precompute_arguments (flags, must_preallocate, num_actuals,
args, &args_size);
/* Now we are about to start emitting insns that can be deleted
if a libcall is deleted. */
- if (is_const || is_malloc)
+ if (flags & (ECF_CONST | ECF_MALLOC))
start_sequence ();
+ old_stack_allocated = stack_pointer_delta - pending_stack_adjust;
+
/* If we have no actual push instructions, or shouldn't use them,
make space for all args right now. */
@@ -2413,13 +2487,11 @@ expand_call (exp, target, ignore)
emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
old_pending_adj = pending_stack_adjust;
pending_stack_adjust = 0;
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* stack_arg_under_construction says whether a stack arg is
being constructed at the old stack level. Pushing the stack
gets a clean outgoing argument block. */
old_stack_arg_under_construction = stack_arg_under_construction;
stack_arg_under_construction = 0;
-#endif
}
argblock = push_block (ARGS_SIZE_RTX (args_size), 0, 0);
}
@@ -2441,85 +2513,87 @@ expand_call (exp, target, ignore)
if (must_preallocate)
{
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* Since the stack pointer will never be pushed, it is possible
- for the evaluation of a parm to clobber something we have
- already written to the stack. Since most function calls on
- RISC machines do not use the stack, this is uncommon, but
- must work correctly.
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* Since the stack pointer will never be pushed, it is possible
+ for the evaluation of a parm to clobber something we have
+ already written to the stack. Since most function calls on
+ RISC machines do not use the stack, this is uncommon, but
+ must work correctly.
- Therefore, we save any area of the stack that was already
- written and that we are using. Here we set up to do this by
- making a new stack usage map from the old one. The actual
- save will be done by store_one_arg.
+ Therefore, we save any area of the stack that was already
+ written and that we are using. Here we set up to do this by
+ making a new stack usage map from the old one. The actual
+ save will be done by store_one_arg.
- Another approach might be to try to reorder the argument
- evaluations to avoid this conflicting stack usage. */
+ Another approach might be to try to reorder the argument
+ evaluations to avoid this conflicting stack usage. */
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- /* Since we will be writing into the entire argument area, the
- map must be allocated for its entire size, not just the part
- that is the responsibility of the caller. */
- needed += reg_parm_stack_space;
+ /* Since we will be writing into the entire argument area, the
+ map must be allocated for its entire size, not just the part
+ that is the responsibility of the caller. */
+ needed += reg_parm_stack_space;
#endif
#ifdef ARGS_GROW_DOWNWARD
- highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
- needed + 1);
+ highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
+ needed + 1);
#else
- highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
- needed);
+ highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
+ needed);
#endif
- stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
+ stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
- if (initial_highest_arg_in_use)
- bcopy (initial_stack_usage_map, stack_usage_map,
- initial_highest_arg_in_use);
+ if (initial_highest_arg_in_use)
+ bcopy (initial_stack_usage_map, stack_usage_map,
+ initial_highest_arg_in_use);
- if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
- bzero (&stack_usage_map[initial_highest_arg_in_use],
- (highest_outgoing_arg_in_use
- - initial_highest_arg_in_use));
- needed = 0;
+ if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
+ bzero (&stack_usage_map[initial_highest_arg_in_use],
+ (highest_outgoing_arg_in_use
+ - initial_highest_arg_in_use));
+ needed = 0;
- /* The address of the outgoing argument list must not be copied
- to a register here, because argblock would be left pointing
- to the wrong place after the call to
- allocate_dynamic_stack_space below. */
+ /* The address of the outgoing argument list must not be copied
+ to a register here, because argblock would be left pointing
+ to the wrong place after the call to
+ allocate_dynamic_stack_space below. */
- argblock = virtual_outgoing_args_rtx;
-
-#else /* not ACCUMULATE_OUTGOING_ARGS */
- if (inhibit_defer_pop == 0)
+ argblock = virtual_outgoing_args_rtx;
+ }
+ else
{
- /* Try to reuse some or all of the pending_stack_adjust
- to get this space. Maybe we can avoid any pushing. */
- if (needed > pending_stack_adjust)
+ if (inhibit_defer_pop == 0)
{
- needed -= pending_stack_adjust;
- pending_stack_adjust = 0;
+ /* Try to reuse some or all of the pending_stack_adjust
+ to get this space. Maybe we can avoid any pushing. */
+ if (needed > pending_stack_adjust)
+ {
+ needed -= pending_stack_adjust;
+ pending_stack_adjust = 0;
+ }
+ else
+ {
+ pending_stack_adjust -= needed;
+ needed = 0;
+ }
}
+ /* Special case this because overhead of `push_block' in this
+ case is non-trivial. */
+ if (needed == 0)
+ argblock = virtual_outgoing_args_rtx;
else
- {
- pending_stack_adjust -= needed;
- needed = 0;
- }
+ argblock = push_block (GEN_INT (needed), 0, 0);
+
+ /* We only really need to call `copy_to_reg' in the case where
+ push insns are going to be used to pass ARGBLOCK to a function
+ call in ARGS. In that case, the stack pointer changes value
+ from the allocation point to the call point, and hence
+ the value of VIRTUAL_OUTGOING_ARGS_RTX changes as well.
+ But might as well always do it. */
+ argblock = copy_to_reg (argblock);
}
- /* Special case this because overhead of `push_block' in this
- case is non-trivial. */
- if (needed == 0)
- argblock = virtual_outgoing_args_rtx;
- else
- argblock = push_block (GEN_INT (needed), 0, 0);
-
- /* We only really need to call `copy_to_reg' in the case where
- push insns are going to be used to pass ARGBLOCK to a function
- call in ARGS. In that case, the stack pointer changes value
- from the allocation point to the call point, and hence
- the value of VIRTUAL_OUTGOING_ARGS_RTX changes as well.
- But might as well always do it. */
- argblock = copy_to_reg (argblock);
-#endif /* not ACCUMULATE_OUTGOING_ARGS */
}
}
@@ -2532,79 +2606,78 @@ expand_call (exp, target, ignore)
argblock = force_reg (Pmode, force_operand (temp, NULL_RTX));
}
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* The save/restore code in store_one_arg handles all cases except one:
- a constructor call (including a C function returning a BLKmode struct)
- to initialize an argument. */
- if (stack_arg_under_construction)
+ if (ACCUMULATE_OUTGOING_ARGS)
{
+ /* The save/restore code in store_one_arg handles all cases except one:
+ a constructor call (including a C function returning a BLKmode struct)
+ to initialize an argument. */
+ if (stack_arg_under_construction)
+ {
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- rtx push_size = GEN_INT (reg_parm_stack_space + args_size.constant);
+ rtx push_size = GEN_INT (reg_parm_stack_space + args_size.constant);
#else
- rtx push_size = GEN_INT (args_size.constant);
+ rtx push_size = GEN_INT (args_size.constant);
#endif
- if (old_stack_level == 0)
- {
- emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
- old_pending_adj = pending_stack_adjust;
- pending_stack_adjust = 0;
- /* stack_arg_under_construction says whether a stack arg is
- being constructed at the old stack level. Pushing the stack
- gets a clean outgoing argument block. */
- old_stack_arg_under_construction = stack_arg_under_construction;
- stack_arg_under_construction = 0;
- /* Make a new map for the new argument list. */
- stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use);
- bzero (stack_usage_map, highest_outgoing_arg_in_use);
- highest_outgoing_arg_in_use = 0;
+ if (old_stack_level == 0)
+ {
+ emit_stack_save (SAVE_BLOCK, &old_stack_level, NULL_RTX);
+ old_pending_adj = pending_stack_adjust;
+ pending_stack_adjust = 0;
+ /* stack_arg_under_construction says whether a stack arg is
+ being constructed at the old stack level. Pushing the stack
+ gets a clean outgoing argument block. */
+ old_stack_arg_under_construction = stack_arg_under_construction;
+ stack_arg_under_construction = 0;
+ /* Make a new map for the new argument list. */
+ stack_usage_map = (char *)alloca (highest_outgoing_arg_in_use);
+ bzero (stack_usage_map, highest_outgoing_arg_in_use);
+ highest_outgoing_arg_in_use = 0;
+ }
+ allocate_dynamic_stack_space (push_size, NULL_RTX, BITS_PER_UNIT);
}
- allocate_dynamic_stack_space (push_size, NULL_RTX, BITS_PER_UNIT);
+ /* If argument evaluation might modify the stack pointer, copy the
+ address of the argument list to a register. */
+ for (i = 0; i < num_actuals; i++)
+ if (args[i].pass_on_stack)
+ {
+ argblock = copy_addr_to_reg (argblock);
+ break;
+ }
}
- /* If argument evaluation might modify the stack pointer, copy the
- address of the argument list to a register. */
- for (i = 0; i < num_actuals; i++)
- if (args[i].pass_on_stack)
- {
- argblock = copy_addr_to_reg (argblock);
- break;
- }
-#endif
compute_argument_addresses (args, argblock, num_actuals);
-#ifdef PUSH_ARGS_REVERSED
#ifdef PREFERRED_STACK_BOUNDARY
/* If we push args individually in reverse order, perform stack alignment
before the first push (the last arg). */
- if (args_size.constant != unadjusted_args_size)
+ if (PUSH_ARGS_REVERSED && argblock == 0
+ && args_size.constant != unadjusted_args_size)
{
/* When the stack adjustment is pending, we get better code
by combining the adjustments. */
- if (pending_stack_adjust && ! is_const
+ if (pending_stack_adjust && ! (flags & ECF_CONST)
&& ! inhibit_defer_pop)
{
+ int adjust;
args_size.constant = (unadjusted_args_size
+ ((pending_stack_adjust
+ args_size.constant
- + arg_space_so_far
- unadjusted_args_size)
% (preferred_stack_boundary
/ BITS_PER_UNIT)));
- pending_stack_adjust -= (args_size.constant
- - unadjusted_args_size);
- do_pending_stack_adjust ();
+ adjust = (pending_stack_adjust - args_size.constant
+ + unadjusted_args_size);
+ adjust_stack (GEN_INT (adjust));
+ pending_stack_adjust = 0;
}
else if (argblock == 0)
anti_adjust_stack (GEN_INT (args_size.constant
- unadjusted_args_size));
- arg_space_so_far += args_size.constant - unadjusted_args_size;
-
/* Now that the stack is properly aligned, pops can't safely
be deferred during the evaluation of the arguments. */
NO_DEFER_POP;
}
#endif
-#endif
/* Don't try to defer pops if preallocating, not even from the first arg,
since ARGBLOCK probably refers to the SP. */
@@ -2629,11 +2702,12 @@ expand_call (exp, target, ignore)
once we have started filling any specific hard regs. */
precompute_register_parameters (num_actuals, args, &reg_parm_seen);
-#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+#ifdef REG_PARM_STACK_SPACE
/* 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);
+ if (ACCUMULATE_OUTGOING_ARGS)
+ 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.
@@ -2644,7 +2718,7 @@ 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,
+ store_one_arg (&args[i], argblock, flags & ECF_MAY_BE_ALLOCA,
args_size.var != 0, reg_parm_stack_space);
/* If we have a parm that is passed in registers but not in memory
@@ -2659,25 +2733,23 @@ expand_call (exp, target, ignore)
if (reg_parm_seen)
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,
+ store_one_arg (&args[i], argblock, flags & ECF_MAY_BE_ALLOCA,
args_size.var != 0, reg_parm_stack_space);
-#ifndef PUSH_ARGS_REVERSED
#ifdef PREFERRED_STACK_BOUNDARY
/* If we pushed args in forward order, perform stack alignment
after pushing the last arg. */
- /* ??? Fix for arg_space_so_far. */
- if (argblock == 0)
+ if (!PUSH_ARGS_REVERSED && argblock == 0)
anti_adjust_stack (GEN_INT (args_size.constant
- unadjusted_args_size));
#endif
-#endif
/* If register arguments require space on the stack and stack space
was not preallocated, allocate stack space here for arguments
passed in registers. */
-#if ! defined(ACCUMULATE_OUTGOING_ARGS) && defined(OUTGOING_REG_PARM_STACK_SPACE)
- if (must_preallocate == 0 && reg_parm_stack_space > 0)
+#ifdef OUTGOING_REG_PARM_STACK_SPACE
+ if (!ACCUMULATE_OUTGOING_ARGS
+ && must_preallocate == 0 && reg_parm_stack_space > 0)
anti_adjust_stack (GEN_INT (reg_parm_stack_space));
#endif
@@ -2734,15 +2806,18 @@ expand_call (exp, target, ignore)
emit_call_1 (funexp, fndecl, funtype, unadjusted_args_size,
args_size.constant, struct_value_size,
next_arg_reg, valreg, old_inhibit_defer_pop, call_fusage,
- ((is_const ? ECF_IS_CONST : 0)
- | (nothrow ? ECF_NOTHROW : 0)
- | (pass == 0 ? ECF_SIBCALL : 0)));
+ flags);
+
+ /* Verify that we've deallocated all the stack we used. */
+ if (pass
+ && old_stack_allocated != stack_pointer_delta - pending_stack_adjust)
+ abort();
/* If call is cse'able, make appropriate pair of reg-notes around it.
Test valreg so we don't crash; may safely ignore `const'
if return type is void. Disable for PARALLEL return values, because
we have no way to move such values into a pseudo register. */
- if (is_const && valreg != 0 && GET_CODE (valreg) != PARALLEL)
+ if ((flags & ECF_CONST) && valreg != 0 && GET_CODE (valreg) != PARALLEL)
{
rtx note = 0;
rtx temp = gen_reg_rtx (GET_MODE (valreg));
@@ -2750,20 +2825,16 @@ expand_call (exp, target, ignore)
/* Mark the return value as a pointer if needed. */
if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
- {
- tree pointed_to = TREE_TYPE (TREE_TYPE (exp));
- mark_reg_pointer (temp, TYPE_ALIGN (pointed_to) / BITS_PER_UNIT);
- }
+ mark_reg_pointer (temp, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (exp))));
/* Construct an "equal form" for the value which mentions all the
arguments in order as well as the function name. */
-#ifdef PUSH_ARGS_REVERSED
- for (i = 0; i < num_actuals; i++)
- note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
-#else
- for (i = num_actuals - 1; i >= 0; i--)
- note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
-#endif
+ if (PUSH_ARGS_REVERSED)
+ for (i = 0; i < num_actuals; i++)
+ note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
+ else
+ for (i = num_actuals - 1; i >= 0; i--)
+ note = gen_rtx_EXPR_LIST (VOIDmode, args[i].initial_value, note);
note = gen_rtx_EXPR_LIST (VOIDmode, funexp, note);
insns = get_insns ();
@@ -2773,7 +2844,7 @@ expand_call (exp, target, ignore)
valreg = temp;
}
- else if (is_const)
+ else if (flags & ECF_CONST)
{
/* Otherwise, just write out the sequence without a note. */
rtx insns = get_insns ();
@@ -2781,14 +2852,14 @@ expand_call (exp, target, ignore)
end_sequence ();
emit_insns (insns);
}
- else if (is_malloc)
+ else if (flags & ECF_MALLOC)
{
rtx temp = gen_reg_rtx (GET_MODE (valreg));
rtx last, insns;
/* The return value from a malloc-like function is a pointer. */
if (TREE_CODE (TREE_TYPE (exp)) == POINTER_TYPE)
- mark_reg_pointer (temp, BIGGEST_ALIGNMENT / BITS_PER_UNIT);
+ mark_reg_pointer (temp, BIGGEST_ALIGNMENT);
emit_move_insn (temp, valreg);
@@ -2809,7 +2880,7 @@ expand_call (exp, target, ignore)
if nonvolatile values are live. For functions that cannot return,
inform flow that control does not fall through. */
- if (returns_twice || is_volatile || is_longjmp || pass == 0)
+ if ((flags & (ECF_RETURNS_TWICE | ECF_NORETURN | ECF_LONGJMP)) || pass == 0)
{
/* The barrier or NOTE_INSN_SETJMP note must be emitted
immediately after the CALL_INSN. Some ports emit more
@@ -2824,7 +2895,7 @@ expand_call (exp, target, ignore)
abort ();
}
- if (returns_twice)
+ if (flags & ECF_RETURNS_TWICE)
{
emit_note_after (NOTE_INSN_SETJMP, last);
current_function_calls_setjmp = 1;
@@ -2834,7 +2905,7 @@ expand_call (exp, target, ignore)
emit_barrier_after (last);
}
- if (is_longjmp)
+ if (flags & ECF_LONGJMP)
current_function_calls_longjmp = 1, sibcall_failure = 1;
/* If this function is returning into a memory location marked as
@@ -2898,7 +2969,8 @@ expand_call (exp, target, ignore)
if (! rtx_equal_p (target, valreg))
emit_group_store (target, valreg, bytes,
- TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (exp)));
+
/* We can not support sibling calls for this case. */
sibcall_failure = 1;
}
@@ -2947,15 +3019,12 @@ expand_call (exp, target, ignore)
{
emit_stack_restore (SAVE_BLOCK, old_stack_level, NULL_RTX);
pending_stack_adjust = old_pending_adj;
-#ifdef ACCUMULATE_OUTGOING_ARGS
stack_arg_under_construction = old_stack_arg_under_construction;
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
stack_usage_map = initial_stack_usage_map;
-#endif
sibcall_failure = 1;
}
-#ifdef ACCUMULATE_OUTGOING_ARGS
- else
+ else if (ACCUMULATE_OUTGOING_ARGS)
{
#ifdef REG_PARM_STACK_SPACE
if (save_area)
@@ -2982,20 +3051,19 @@ expand_call (exp, target, ignore)
emit_block_move (stack_area,
validize_mem (args[i].save_area),
GEN_INT (args[i].size.constant),
- PARM_BOUNDARY / BITS_PER_UNIT);
+ PARM_BOUNDARY);
sibcall_failure = 1;
}
highest_outgoing_arg_in_use = initial_highest_arg_in_use;
stack_usage_map = initial_stack_usage_map;
}
-#endif
/* If this was alloca, record the new stack level for nonlocal gotos.
Check for the handler slots since we might not have a save area
for non-local gotos. */
- if (may_be_alloca && nonlocal_goto_handler_slots != 0)
+ if ((flags & ECF_MAY_BE_ALLOCA) && nonlocal_goto_handler_slots != 0)
emit_stack_save (SAVE_NONLOCAL, &nonlocal_goto_stack_level, NULL_RTX);
pop_temp_slots ();
@@ -3024,10 +3092,11 @@ expand_call (exp, target, ignore)
zero out the sequence. */
if (sibcall_failure)
tail_call_insns = NULL_RTX;
-
/* Restore the pending stack adjustment now that we have
finished generating the sibling call sequence. */
+
pending_stack_adjust = save_pending_stack_adjust;
+ stack_pointer_delta = save_stack_pointer_delta;
}
else
normal_call_insns = insns;
@@ -3130,25 +3199,20 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
rtx mem_value = 0;
int pcc_struct_value = 0;
int struct_value_size = 0;
- int is_const;
+ int flags = 0;
int reg_parm_stack_space = 0;
- int nothrow;
-#ifdef ACCUMULATE_OUTGOING_ARGS
int needed;
-#endif
-#if defined(ACCUMULATE_OUTGOING_ARGS) && defined(REG_PARM_STACK_SPACE)
+#ifdef REG_PARM_STACK_SPACE
/* Define the boundary of the register parm stack space that needs to be
save, if any. */
int low_to_save = -1, high_to_save = 0;
rtx save_area = 0; /* Place that it is saved */
#endif
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* Size of the stack reserved for parameter registers. */
int initial_highest_arg_in_use = highest_outgoing_arg_in_use;
char *initial_stack_usage_map = stack_usage_map;
-#endif
#ifdef REG_PARM_STACK_SPACE
#ifdef MAYBE_REG_PARM_STACK_SPACE
@@ -3158,10 +3222,12 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
#endif
#endif
- is_const = no_queue;
+ if (no_queue)
+ flags |= ECF_CONST;
fun = orgfun;
- nothrow = libfunc_nothrow (fun);
+ if (libfunc_nothrow (fun))
+ flags |= ECF_NOTHROW;
#ifdef PREFERRED_STACK_BOUNDARY
/* Ensure current function's preferred stack boundary is at least
@@ -3191,7 +3257,7 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
#endif
/* This call returns a big structure. */
- is_const = 0;
+ flags &= ~ECF_CONST;
}
/* ??? Unfinished: must pass the memory address as an argument. */
@@ -3330,8 +3396,12 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
original_args_size = args_size;
#ifdef PREFERRED_STACK_BOUNDARY
- args_size.constant = (((args_size.constant + (STACK_BYTES - 1))
- / STACK_BYTES) * STACK_BYTES);
+ args_size.constant = (((args_size.constant
+ + stack_pointer_delta
+ + STACK_BYTES - 1)
+ / STACK_BYTES
+ * STACK_BYTES)
+ - stack_pointer_delta);
#endif
args_size.constant = MAX (args_size.constant,
@@ -3344,133 +3414,138 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
if (args_size.constant > current_function_outgoing_args_size)
current_function_outgoing_args_size = args_size.constant;
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* Since the stack pointer will never be pushed, it is possible for
- the evaluation of a parm to clobber something we have already
- written to the stack. Since most function calls on RISC machines
- do not use the stack, this is uncommon, but must work correctly.
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* Since the stack pointer will never be pushed, it is possible for
+ the evaluation of a parm to clobber something we have already
+ written to the stack. Since most function calls on RISC machines
+ do not use the stack, this is uncommon, but must work correctly.
- Therefore, we save any area of the stack that was already written
- and that we are using. Here we set up to do this by making a new
- stack usage map from the old one.
+ Therefore, we save any area of the stack that was already written
+ and that we are using. Here we set up to do this by making a new
+ stack usage map from the old one.
- Another approach might be to try to reorder the argument
- evaluations to avoid this conflicting stack usage. */
+ Another approach might be to try to reorder the argument
+ evaluations to avoid this conflicting stack usage. */
- needed = args_size.constant;
+ needed = args_size.constant;
#ifndef OUTGOING_REG_PARM_STACK_SPACE
- /* Since we will be writing into the entire argument area, the
- map must be allocated for its entire size, not just the part that
- is the responsibility of the caller. */
- needed += reg_parm_stack_space;
+ /* Since we will be writing into the entire argument area, the
+ map must be allocated for its entire size, not just the part that
+ is the responsibility of the caller. */
+ needed += reg_parm_stack_space;
#endif
#ifdef ARGS_GROW_DOWNWARD
- highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
- needed + 1);
+ highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
+ needed + 1);
#else
- highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
- needed);
-#endif
- stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
-
- if (initial_highest_arg_in_use)
- bcopy (initial_stack_usage_map, stack_usage_map,
- initial_highest_arg_in_use);
-
- if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
- bzero (&stack_usage_map[initial_highest_arg_in_use],
- highest_outgoing_arg_in_use - initial_highest_arg_in_use);
- needed = 0;
-
- /* The address of the outgoing argument list must not be copied to a
- register here, because argblock would be left pointing to the
- wrong place after the call to allocate_dynamic_stack_space below.
- */
-
- argblock = virtual_outgoing_args_rtx;
-#else /* not ACCUMULATE_OUTGOING_ARGS */
-#ifndef PUSH_ROUNDING
- argblock = push_block (GEN_INT (args_size.constant), 0, 0);
-#endif
+ highest_outgoing_arg_in_use = MAX (initial_highest_arg_in_use,
+ needed);
#endif
+ stack_usage_map = (char *) alloca (highest_outgoing_arg_in_use);
+
+ if (initial_highest_arg_in_use)
+ bcopy (initial_stack_usage_map, stack_usage_map,
+ initial_highest_arg_in_use);
+
+ if (initial_highest_arg_in_use != highest_outgoing_arg_in_use)
+ bzero (&stack_usage_map[initial_highest_arg_in_use],
+ highest_outgoing_arg_in_use - initial_highest_arg_in_use);
+ needed = 0;
+
+ /* The address of the outgoing argument list must not be copied to a
+ register here, because argblock would be left pointing to the
+ wrong place after the call to allocate_dynamic_stack_space below.
+ */
+
+ argblock = virtual_outgoing_args_rtx;
+ }
+ else
+ {
+ if (!PUSH_ARGS)
+ argblock = push_block (GEN_INT (args_size.constant), 0, 0);
+ }
-#ifdef PUSH_ARGS_REVERSED
#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)
+ if (argblock == 0 && PUSH_ARGS_REVERSED)
anti_adjust_stack (GEN_INT (args_size.constant
- original_args_size.constant));
#endif
-#endif
-#ifdef PUSH_ARGS_REVERSED
- inc = -1;
- argnum = nargs - 1;
-#else
- inc = 1;
- argnum = 0;
-#endif
+ if (PUSH_ARGS_REVERSED)
+ {
+ inc = -1;
+ argnum = nargs - 1;
+ }
+ else
+ {
+ inc = 1;
+ argnum = 0;
+ }
-#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.
+#ifdef REG_PARM_STACK_SPACE
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* 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. */
+ Here we compute the boundary of the that needs to be saved, if any. */
#ifdef ARGS_GROW_DOWNWARD
- for (count = 0; count < reg_parm_stack_space + 1; count++)
+ for (count = 0; count < reg_parm_stack_space + 1; count++)
#else
- for (count = 0; count < reg_parm_stack_space; count++)
+ for (count = 0; count < reg_parm_stack_space; count++)
#endif
- {
- if (count >= highest_outgoing_arg_in_use
- || stack_usage_map[count] == 0)
- continue;
+ {
+ if (count >= highest_outgoing_arg_in_use
+ || stack_usage_map[count] == 0)
+ continue;
- if (low_to_save == -1)
- low_to_save = count;
+ if (low_to_save == -1)
+ low_to_save = count;
- high_to_save = count;
- }
+ high_to_save = count;
+ }
- if (low_to_save >= 0)
- {
- int num_to_save = high_to_save - low_to_save + 1;
- enum machine_mode save_mode
- = mode_for_size (num_to_save * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area;
+ if (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;
+ /* 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)));
+ 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)));
+ 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);
- 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);
+ if (save_mode == BLKmode)
+ {
+ save_area = assign_stack_temp (BLKmode, num_to_save, 0);
+ emit_block_move (validize_mem (save_area), stack_area,
+ GEN_INT (num_to_save), PARM_BOUNDARY);
+ }
+ else
+ {
+ save_area = gen_reg_rtx (save_mode);
+ emit_move_insn (save_area, stack_area);
+ }
}
}
#endif
@@ -3485,80 +3560,76 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
register rtx val = argvec[argnum].value;
rtx reg = argvec[argnum].reg;
int partial = argvec[argnum].partial;
-#ifdef ACCUMULATE_OUTGOING_ARGS
- int lower_bound, upper_bound, i;
-#endif
+ int lower_bound = 0, upper_bound = 0, i;
if (! (reg != 0 && partial == 0))
{
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* If this is being stored into a pre-allocated, fixed-size, stack
- area, save any previous data at that location. */
+ if (ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* If this is being stored into a pre-allocated, fixed-size, stack
+ area, save any previous data at that location. */
#ifdef ARGS_GROW_DOWNWARD
- /* stack_slot is negative, but we want to index stack_usage_map
- with positive values. */
- upper_bound = -argvec[argnum].offset.constant + 1;
- lower_bound = upper_bound - argvec[argnum].size.constant;
+ /* stack_slot is negative, but we want to index stack_usage_map
+ with positive values. */
+ upper_bound = -argvec[argnum].offset.constant + 1;
+ lower_bound = upper_bound - argvec[argnum].size.constant;
#else
- lower_bound = argvec[argnum].offset.constant;
- upper_bound = lower_bound + argvec[argnum].size.constant;
+ lower_bound = argvec[argnum].offset.constant;
+ upper_bound = lower_bound + argvec[argnum].size.constant;
#endif
- for (i = lower_bound; i < upper_bound; i++)
- if (stack_usage_map[i]
- /* Don't store things in the fixed argument area at this point;
- it has already been saved. */
- && i > reg_parm_stack_space)
- break;
+ for (i = lower_bound; i < upper_bound; i++)
+ if (stack_usage_map[i]
+ /* Don't store things in the fixed argument area at this point;
+ it has already been saved. */
+ && i > reg_parm_stack_space)
+ break;
- if (i != upper_bound)
- {
- /* We need to make a save area. See what mode we can make it. */
- enum machine_mode save_mode
- = mode_for_size (argvec[argnum].size.constant * BITS_PER_UNIT,
- MODE_INT, 1);
- rtx stack_area
- = gen_rtx_MEM
- (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[argnum].offset.constant)));
- argvec[argnum].save_area = gen_reg_rtx (save_mode);
-
- emit_move_insn (argvec[argnum].save_area, stack_area);
+ if (i != upper_bound)
+ {
+ /* We need to make a save area. See what mode we can make it. */
+ enum machine_mode save_mode
+ = mode_for_size (argvec[argnum].size.constant * BITS_PER_UNIT,
+ MODE_INT, 1);
+ rtx stack_area
+ = gen_rtx_MEM
+ (save_mode,
+ memory_address
+ (save_mode,
+ plus_constant (argblock,
+ argvec[argnum].offset.constant)));
+ argvec[argnum].save_area = gen_reg_rtx (save_mode);
+
+ emit_move_insn (argvec[argnum].save_area, stack_area);
+ }
}
-#endif
+
emit_push_insn (val, mode, NULL_TREE, NULL_RTX, 0, partial, reg, 0,
argblock, GEN_INT (argvec[argnum].offset.constant),
reg_parm_stack_space, ARGS_SIZE_RTX (alignment_pad));
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* Now mark the segment we just used. */
- for (i = lower_bound; i < upper_bound; i++)
- stack_usage_map[i] = 1;
-#endif
+ if (ACCUMULATE_OUTGOING_ARGS)
+ for (i = lower_bound; i < upper_bound; i++)
+ stack_usage_map[i] = 1;
NO_DEFER_POP;
}
}
-#ifndef PUSH_ARGS_REVERSED
#ifdef PREFERRED_STACK_BOUNDARY
/* If we pushed args in forward order, perform stack alignment
after pushing the last arg. */
- if (argblock == 0)
+ if (argblock == 0 && !PUSH_ARGS_REVERSED)
anti_adjust_stack (GEN_INT (args_size.constant
- original_args_size.constant));
#endif
-#endif
-#ifdef PUSH_ARGS_REVERSED
- argnum = nargs - 1;
-#else
- argnum = 0;
-#endif
+ if (PUSH_ARGS_REVERSED)
+ argnum = nargs - 1;
+ else
+ argnum = 0;
fun = prepare_call_address (fun, NULL_TREE, &call_fusage, 0);
@@ -3630,9 +3701,7 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
struct_value_size,
FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1),
mem_value == 0 && outmode != VOIDmode ? hard_libcall_value (outmode) : NULL_RTX,
- old_inhibit_defer_pop + 1, call_fusage,
- ((is_const ? ECF_IS_CONST : 0)
- | (nothrow ? ECF_NOTHROW : 0)));
+ old_inhibit_defer_pop + 1, call_fusage, flags);
/* Now restore inhibit_defer_pop to its actual original value. */
OK_DEFER_POP;
@@ -3655,50 +3724,51 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
value = hard_libcall_value (outmode);
}
-#ifdef ACCUMULATE_OUTGOING_ARGS
-#ifdef REG_PARM_STACK_SPACE
- if (save_area)
+ if (ACCUMULATE_OUTGOING_ARGS)
{
- enum machine_mode save_mode = GET_MODE (save_area);
+#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)));
+ 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)));
+ rtx stack_area
+ = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ plus_constant (argblock, 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);
- }
+ 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);
+ }
#endif
-
- /* If we saved any argument areas, restore them. */
- for (count = 0; count < nargs; count++)
- if (argvec[count].save_area)
- {
- enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address
- (save_mode,
- plus_constant (argblock,
- argvec[count].offset.constant)));
-
- emit_move_insn (stack_area, argvec[count].save_area);
- }
+
+ /* If we saved any argument areas, restore them. */
+ for (count = 0; count < nargs; count++)
+ if (argvec[count].save_area)
+ {
+ enum machine_mode save_mode = GET_MODE (argvec[count].save_area);
+ rtx stack_area
+ = gen_rtx_MEM (save_mode,
+ memory_address
+ (save_mode,
+ plus_constant (argblock,
+ argvec[count].offset.constant)));
+
+ emit_move_insn (stack_area, argvec[count].save_area);
+ }
- highest_outgoing_arg_in_use = initial_highest_arg_in_use;
- stack_usage_map = initial_stack_usage_map;
-#endif
+ highest_outgoing_arg_in_use = initial_highest_arg_in_use;
+ stack_usage_map = initial_stack_usage_map;
+ }
return value;
@@ -3713,7 +3783,7 @@ emit_library_call_value_1 (retval, orgfun, value, no_queue, outmode, nargs, p)
NO_QUEUE will be true if and only if the library call is a `const' call
which will be enclosed in REG_LIBCALL/REG_RETVAL notes; it is equivalent
- to the variable is_const in expand_call.
+ to the flag ECF_CONST in expand_call.
NO_QUEUE must be true for const calls, because if it isn't, then
any pending increment will be emitted between REG_LIBCALL/REG_RETVAL notes,
@@ -3855,9 +3925,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
rtx reg = 0;
int partial = 0;
int used = 0;
-#ifdef ACCUMULATE_OUTGOING_ARGS
int i, lower_bound = 0, upper_bound = 0;
-#endif
if (TREE_CODE (pval) == ERROR_MARK)
return;
@@ -3866,75 +3934,75 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
this argument. */
push_temp_slots ();
-#ifdef ACCUMULATE_OUTGOING_ARGS
- /* If this is being stored into a pre-allocated, fixed-size, stack area,
- save any previous data at that location. */
- if (argblock && ! variable_size && arg->stack)
+ if (ACCUMULATE_OUTGOING_ARGS)
{
+ /* If this is being stored into a pre-allocated, fixed-size, stack area,
+ save any previous data at that location. */
+ if (argblock && ! variable_size && arg->stack)
+ {
#ifdef ARGS_GROW_DOWNWARD
- /* stack_slot is negative, but we want to index stack_usage_map
- with positive values. */
- if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
- upper_bound = -INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)) + 1;
- else
- upper_bound = 0;
+ /* stack_slot is negative, but we want to index stack_usage_map
+ with positive values. */
+ if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
+ upper_bound = -INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1)) + 1;
+ else
+ upper_bound = 0;
- lower_bound = upper_bound - arg->size.constant;
+ lower_bound = upper_bound - arg->size.constant;
#else
- if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
- lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
- else
- lower_bound = 0;
+ if (GET_CODE (XEXP (arg->stack_slot, 0)) == PLUS)
+ lower_bound = INTVAL (XEXP (XEXP (arg->stack_slot, 0), 1));
+ else
+ lower_bound = 0;
- upper_bound = lower_bound + arg->size.constant;
+ upper_bound = lower_bound + arg->size.constant;
#endif
- for (i = lower_bound; i < upper_bound; i++)
- if (stack_usage_map[i]
- /* Don't store things in the fixed argument area at this point;
- it has already been saved. */
- && i > reg_parm_stack_space)
- break;
-
- if (i != upper_bound)
- {
- /* We need to make a save area. See what mode we can make it. */
- enum machine_mode save_mode
- = mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1);
- rtx stack_area
- = gen_rtx_MEM (save_mode,
- memory_address (save_mode,
- XEXP (arg->stack_slot, 0)));
+ for (i = lower_bound; i < upper_bound; i++)
+ if (stack_usage_map[i]
+ /* Don't store things in the fixed argument area at this point;
+ it has already been saved. */
+ && i > reg_parm_stack_space)
+ break;
- if (save_mode == BLKmode)
- {
- arg->save_area = assign_stack_temp (BLKmode,
- arg->size.constant, 0);
- 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),
- PARM_BOUNDARY / BITS_PER_UNIT);
- }
- else
+ if (i != upper_bound)
{
- arg->save_area = gen_reg_rtx (save_mode);
- emit_move_insn (arg->save_area, stack_area);
+ /* We need to make a save area. See what mode we can make it. */
+ enum machine_mode save_mode
+ = mode_for_size (arg->size.constant * BITS_PER_UNIT, MODE_INT, 1);
+ rtx stack_area
+ = gen_rtx_MEM (save_mode,
+ memory_address (save_mode,
+ XEXP (arg->stack_slot, 0)));
+
+ if (save_mode == BLKmode)
+ {
+ arg->save_area = assign_stack_temp (BLKmode,
+ arg->size.constant, 0);
+ 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),
+ PARM_BOUNDARY);
+ }
+ else
+ {
+ arg->save_area = gen_reg_rtx (save_mode);
+ emit_move_insn (arg->save_area, stack_area);
+ }
}
}
+ /* 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;
}
- /* 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,
set up the register and number of words. */
if (! arg->pass_on_stack)
@@ -3954,7 +4022,6 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
it directly into its stack slot. Otherwise, we can. */
if (arg->value == 0)
{
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* stack_arg_under_construction is nonzero if a function argument is
being evaluated directly into the outgoing argument list and
expand_call must take special action to preserve the argument list
@@ -3975,7 +4042,7 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
if (arg->pass_on_stack)
stack_arg_under_construction++;
-#endif
+
arg->value = expand_expr (pval,
(partial
|| TYPE_MODE (TREE_TYPE (pval)) != arg->mode)
@@ -3989,10 +4056,8 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
arg->value = convert_modes (arg->mode, TYPE_MODE (TREE_TYPE (pval)),
arg->value, arg->unsignedp);
-#ifdef ACCUMULATE_OUTGOING_ARGS
if (arg->pass_on_stack)
stack_arg_under_construction--;
-#endif
}
/* Don't allow anything left on stack from computation
@@ -4049,8 +4114,6 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
partial, reg, used - size, argblock,
ARGS_SIZE_RTX (arg->offset), reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
-
- arg_space_so_far += used;
}
else
{
@@ -4078,12 +4141,11 @@ store_one_arg (arg, argblock, may_be_alloca, variable_size,
excess = (arg->size.constant - int_size_in_bytes (TREE_TYPE (pval))
+ partial * UNITS_PER_WORD);
size_rtx = expr_size (pval);
- arg_space_so_far += excess + INTVAL (size_rtx);
}
emit_push_insn (arg->value, arg->mode, TREE_TYPE (pval), size_rtx,
- TYPE_ALIGN (TREE_TYPE (pval)) / BITS_PER_UNIT, partial,
- reg, excess, argblock, ARGS_SIZE_RTX (arg->offset),
+ TYPE_ALIGN (TREE_TYPE (pval)), partial, reg, excess,
+ argblock, ARGS_SIZE_RTX (arg->offset),
reg_parm_stack_space,
ARGS_SIZE_RTX (arg->alignment_pad));
}
diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog
index 9336309aa66..4b7e2253abb 100644
--- a/gcc/ch/ChangeLog
+++ b/gcc/ch/ChangeLog
@@ -1,3 +1,17 @@
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+Thu Mar 30 06:32:51 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * expr.c (chill_expand_expr): Pass bit alignment to emit_block_move.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * actions.c (check_missing_cases): BYTES_NEEDED is HOST_WIDE_INT.
+ * typeck.c (expand_constant_to_buffer): Use int_byte_position.
+ (extract_constant_from_buffer): Likewise.
+
Fri Mar 17 08:09:14 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* typeck.c (min_precision): New function.
diff --git a/gcc/ch/actions.c b/gcc/ch/actions.c
index d7b10e60270..32bb18152ad 100644
--- a/gcc/ch/actions.c
+++ b/gcc/ch/actions.c
@@ -1453,7 +1453,8 @@ check_missing_cases (type)
unsigned char *cases_seen;
/* The number of possible selector values. */
HOST_WIDE_INT size = all_cases_count (type, &is_sparse);
- long bytes_needed = (size+HOST_BITS_PER_CHAR)/HOST_BITS_PER_CHAR;
+ HOST_WIDE_INT bytes_needed
+ = (size + HOST_BITS_PER_CHAR) / HOST_BITS_PER_CHAR;
if (size == -1)
warning ("CASE selector with variable range");
diff --git a/gcc/ch/expr.c b/gcc/ch/expr.c
index b4bdf35aec7..40f74a42af0 100644
--- a/gcc/ch/expr.c
+++ b/gcc/ch/expr.c
@@ -362,7 +362,7 @@ chill_expand_expr (exp, target, tmode, modifier)
if (temp == target || target == NULL_RTX)
return temp;
emit_block_move (target, temp, expr_size (exp0),
- TYPE_ALIGN (TREE_TYPE(exp0)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE(exp0)));
return target;
}
else
diff --git a/gcc/ch/lang-specs.h b/gcc/ch/lang-specs.h
index 1b377f57aeb..f5bbd61ab68 100644
--- a/gcc/ch/lang-specs.h
+++ b/gcc/ch/lang-specs.h
@@ -29,6 +29,7 @@ Boston, MA 02111-1307, USA. */
%{!no-gcc:-D__GNUCHILL__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:-D__OPTIMIZE__} %{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional} %{!undef:%{!ansi:%p} %P} %{trigraphs}\
+ %{fshow-column} %{fno-show-column}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!E:%g.i}%{E:%W{o*}} \n",
"%{!E:cc1chill %g.i %1 \
diff --git a/gcc/ch/typeck.c b/gcc/ch/typeck.c
index 9126ede3e3a..17539602e30 100644
--- a/gcc/ch/typeck.c
+++ b/gcc/ch/typeck.c
@@ -830,7 +830,7 @@ expand_constant_to_buffer (value, buffer, buf_size)
if (DECL_BIT_FIELD (field))
return 0;
- offset = int_bit_position (field) / BITS_PER_UNIT;
+ offset = int_byte_position (field);
if (!expand_constant_to_buffer (TREE_VALUE (list),
buffer + offset,
buf_size - offset))
@@ -946,7 +946,7 @@ extract_constant_from_buffer (type, buffer, buf_size)
tree field = TYPE_FIELDS (type);
for (; field != NULL_TREE; field = TREE_CHAIN (field))
{
- HOST_WIDE_INT offset = int_bit_position (field) / BITS_PER_UNIT;
+ HOST_WIDE_INT offset = int_byte_position (field);
if (DECL_BIT_FIELD (field))
return 0;
diff --git a/gcc/combine.c b/gcc/combine.c
index 149b5495359..911ebbf8c9e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -93,6 +93,20 @@ Boston, MA 02111-1307, USA. */
#include "recog.h"
#include "real.h"
#include "toplev.h"
+#include "defaults.h"
+
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
+/* Supply a default definition for PUSH_ARGS. */
+#ifndef PUSH_ARGS
+#ifdef PUSH_ROUNDING
+#define PUSH_ARGS !ACCUMULATE_OUTGOING_ARGS
+#else
+#define PUSH_ARGS 0
+#endif
+#endif
/* It is not safe to use ordinary gen_lowpart in combine.
Use gen_lowpart_for_combine instead. See comments there. */
@@ -142,7 +156,7 @@ static int max_uid_cuid;
/* Maximum register number, which is the size of the tables below. */
-static int combine_max_regno;
+static unsigned int combine_max_regno;
/* Record last point of death of (hard or pseudo) register n. */
@@ -291,7 +305,7 @@ static enum machine_mode nonzero_bits_mode;
/* Nonzero if we know that a register has some leading bits that are always
equal to the sign bit. */
-static char *reg_sign_bit_copies;
+static unsigned char *reg_sign_bit_copies;
/* Nonzero when reg_nonzero_bits and reg_sign_bit_copies can be safely used.
It is zero while computing them and after combine has completed. This
@@ -371,11 +385,13 @@ static rtx simplify_set PARAMS ((rtx));
static rtx simplify_logical PARAMS ((rtx, int));
static rtx expand_compound_operation PARAMS ((rtx));
static rtx expand_field_assignment PARAMS ((rtx));
-static rtx make_extraction PARAMS ((enum machine_mode, rtx, int, rtx, int,
- int, int, int));
+static rtx make_extraction PARAMS ((enum machine_mode, rtx, HOST_WIDE_INT,
+ rtx, unsigned HOST_WIDE_INT, int,
+ int, int));
static rtx extract_left_shift PARAMS ((rtx, int));
static rtx make_compound_operation PARAMS ((rtx, enum rtx_code));
-static int get_pos_from_mask PARAMS ((unsigned HOST_WIDE_INT, int *));
+static int get_pos_from_mask PARAMS ((unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT *));
static rtx force_to_mode PARAMS ((rtx, enum machine_mode,
unsigned HOST_WIDE_INT, rtx, int));
static rtx if_then_else_cond PARAMS ((rtx, rtx *, rtx *));
@@ -386,7 +402,7 @@ static rtx apply_distributive_law PARAMS ((rtx));
static rtx simplify_and_const_int PARAMS ((rtx, enum machine_mode, rtx,
unsigned HOST_WIDE_INT));
static unsigned HOST_WIDE_INT nonzero_bits PARAMS ((rtx, enum machine_mode));
-static int num_sign_bit_copies PARAMS ((rtx, enum machine_mode));
+static unsigned int num_sign_bit_copies PARAMS ((rtx, enum machine_mode));
static int merge_outer_ops PARAMS ((enum rtx_code *, HOST_WIDE_INT *,
enum rtx_code, HOST_WIDE_INT,
enum machine_mode, int *));
@@ -488,7 +504,7 @@ do_SUBST_INT(into, newval)
int
combine_instructions (f, nregs)
rtx f;
- int nregs;
+ unsigned int nregs;
{
register rtx insn, next;
#ifdef HAVE_cc0
@@ -508,7 +524,8 @@ combine_instructions (f, nregs)
reg_nonzero_bits = ((unsigned HOST_WIDE_INT *)
xcalloc (nregs, sizeof (unsigned HOST_WIDE_INT)));
- reg_sign_bit_copies = (char *) xcalloc (nregs, sizeof (char));
+ reg_sign_bit_copies
+ = (unsigned char *) xcalloc (nregs, sizeof (unsigned char));
reg_last_death = (rtx *) xmalloc (nregs * sizeof (rtx));
reg_last_set = (rtx *) xmalloc (nregs * sizeof (rtx));
@@ -764,7 +781,7 @@ combine_instructions (f, nregs)
static void
init_reg_last_arrays ()
{
- int nregs = combine_max_regno;
+ unsigned int nregs = combine_max_regno;
bzero ((char *) reg_last_death, nregs * sizeof (rtx));
bzero ((char *) reg_last_set, nregs * sizeof (rtx));
@@ -783,7 +800,7 @@ static void
setup_incoming_promotions ()
{
#ifdef PROMOTE_FUNCTION_ARGS
- int regno;
+ unsigned int regno;
rtx reg;
enum machine_mode mode;
int unsignedp;
@@ -825,7 +842,7 @@ set_nonzero_bits_and_sign_copies (x, set, data)
rtx set;
void *data ATTRIBUTE_UNUSED;
{
- int num;
+ unsigned int num;
if (GET_CODE (x) == REG
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
@@ -967,10 +984,12 @@ can_combine_p (insn, i3, pred, succ, pdest, psrc)
{
rtx i3pat = PATTERN (i3);
int i = XVECLEN (i3pat, 0) - 1;
- int regno = REGNO (XEXP (elt, 0));
+ unsigned int regno = REGNO (XEXP (elt, 0));
+
do
{
rtx i3elt = XVECEXP (i3pat, 0, i);
+
if (GET_CODE (i3elt) == USE
&& GET_CODE (XEXP (i3elt, 0)) == REG
&& (REGNO (XEXP (i3elt, 0)) == regno
@@ -1866,7 +1885,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
i2src, const0_rtx))
!= GET_MODE (SET_DEST (newpat))))
{
- int regno = REGNO (SET_DEST (newpat));
+ unsigned int regno = REGNO (SET_DEST (newpat));
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno < FIRST_PSEUDO_REGISTER
@@ -2431,7 +2450,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
rtx i3notes, i2notes, i1notes = 0;
rtx i3links, i2links, i1links = 0;
rtx midnotes = 0;
- register int regno;
+ unsigned int regno;
/* Compute which registers we expect to eliminate. newi2pat may be setting
either i3dest or i2dest, so we must check it. Also, i1dest may be the
same as i3dest, in which case newi2pat may be setting i1dest. */
@@ -2691,9 +2710,7 @@ try_combine (i3, i2, i1, new_direct_jump_p)
regno = REGNO (i1dest);
if (! added_sets_1 && ! i1dest_in_i1src)
- {
- REG_N_SETS (regno)--;
- }
+ REG_N_SETS (regno)--;
}
/* Update reg_nonzero_bits et al for any changes that may have been made
@@ -2795,7 +2812,9 @@ find_split_point (loc, insn)
rtx x = *loc;
enum rtx_code code = GET_CODE (x);
rtx *split;
- int len = 0, pos = 0, unsignedp = 0;
+ unsigned HOST_WIDE_INT len = 0;
+ HOST_WIDE_INT pos = 0;
+ int unsignedp = 0;
rtx inner = NULL_RTX;
/* First special-case some codes. */
@@ -2930,9 +2949,9 @@ find_split_point (loc, insn)
<= GET_MODE_BITSIZE (GET_MODE (XEXP (SET_DEST (x), 0))))
&& ! side_effects_p (XEXP (SET_DEST (x), 0)))
{
- int pos = INTVAL (XEXP (SET_DEST (x), 2));
- int len = INTVAL (XEXP (SET_DEST (x), 1));
- int src = INTVAL (SET_SRC (x));
+ HOST_WIDE_INT pos = INTVAL (XEXP (SET_DEST (x), 2));
+ unsigned HOST_WIDE_INT len = INTVAL (XEXP (SET_DEST (x), 1));
+ unsigned HOST_WIDE_INT src = INTVAL (SET_SRC (x));
rtx dest = XEXP (SET_DEST (x), 0);
enum machine_mode mode = GET_MODE (dest);
unsigned HOST_WIDE_INT mask = ((HOST_WIDE_INT) 1 << len) - 1;
@@ -2940,7 +2959,7 @@ find_split_point (loc, insn)
if (BITS_BIG_ENDIAN)
pos = GET_MODE_BITSIZE (mode) - len - pos;
- if ((unsigned HOST_WIDE_INT) src == mask)
+ if (src == mask)
SUBST (SET_SRC (x),
gen_binary (IOR, mode, dest, GEN_INT (src << pos)));
else
@@ -4143,7 +4162,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
== ((HOST_WIDE_INT) 1 << (i + 1)) - 1))
|| (GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND
&& (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (XEXP (x, 0), 0), 0)))
- == i + 1))))
+ == (unsigned int) i + 1))))
return simplify_shift_const
(NULL_RTX, ASHIFTRT, mode,
simplify_shift_const (NULL_RTX, ASHIFT, mode,
@@ -4866,7 +4885,7 @@ simplify_set (x)
which case we can safely change its mode. */
if (compare_mode != GET_MODE (dest))
{
- int regno = REGNO (dest);
+ unsigned int regno = REGNO (dest);
rtx new_dest = gen_rtx_REG (compare_mode, regno);
if (regno < FIRST_PSEUDO_REGISTER
@@ -5458,9 +5477,9 @@ static rtx
expand_compound_operation (x)
rtx x;
{
- int pos = 0, len;
+ unsigned HOST_WIDE_INT pos = 0, len;
int unsignedp = 0;
- int modewidth;
+ unsigned int modewidth;
rtx tem;
switch (GET_CODE (x))
@@ -5608,7 +5627,7 @@ expand_compound_operation (x)
a such a position. */
modewidth = GET_MODE_BITSIZE (GET_MODE (x));
- if (modewidth >= pos - len)
+ if (modewidth + len >= pos)
tem = simplify_shift_const (NULL_RTX, unsignedp ? LSHIFTRT : ASHIFTRT,
GET_MODE (x),
simplify_shift_const (NULL_RTX, ASHIFT,
@@ -5800,9 +5819,9 @@ make_extraction (mode, inner, pos, pos_rtx, len,
unsignedp, in_dest, in_compare)
enum machine_mode mode;
rtx inner;
- int pos;
+ HOST_WIDE_INT pos;
rtx pos_rtx;
- int len;
+ unsigned HOST_WIDE_INT len;
int unsignedp;
int in_dest, in_compare;
{
@@ -5819,7 +5838,7 @@ make_extraction (mode, inner, pos, pos_rtx, len,
int spans_byte = 0;
rtx new = 0;
rtx orig_pos_rtx = pos_rtx;
- int orig_pos;
+ HOST_WIDE_INT orig_pos;
/* Get some information about INNER and get the innermost object. */
if (GET_CODE (inner) == USE)
@@ -6528,7 +6547,7 @@ make_compound_operation (x, in_code)
static int
get_pos_from_mask (m, plen)
unsigned HOST_WIDE_INT m;
- int *plen;
+ unsigned HOST_WIDE_INT *plen;
{
/* Get the bit number of the first 1 bit from the right, -1 if none. */
int pos = exact_log2 (m & - m);
@@ -6748,7 +6767,7 @@ force_to_mode (x, mode, mask, reg, just_select)
This may eliminate that PLUS and, later, the AND. */
{
- int width = GET_MODE_BITSIZE (mode);
+ unsigned int width = GET_MODE_BITSIZE (mode);
unsigned HOST_WIDE_INT smask = mask;
/* If MODE is narrower than HOST_WIDE_INT and mask is a negative
@@ -6920,7 +6939,7 @@ force_to_mode (x, mode, mask, reg, just_select)
+ num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0))))
>= GET_MODE_BITSIZE (GET_MODE (x)))
&& exact_log2 (mask + 1) >= 0
- && (num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
+ && ((int) num_sign_bit_copies (XEXP (x, 0), GET_MODE (XEXP (x, 0)))
>= exact_log2 (mask + 1)))
x = gen_binary (LSHIFTRT, GET_MODE (x), XEXP (x, 0),
GEN_INT (GET_MODE_BITSIZE (GET_MODE (x))
@@ -7119,7 +7138,7 @@ if_then_else_cond (x, ptrue, pfalse)
{
enum machine_mode mode = GET_MODE (x);
enum rtx_code code = GET_CODE (x);
- int size = GET_MODE_BITSIZE (mode);
+ unsigned int size = GET_MODE_BITSIZE (mode);
rtx cond0, cond1, true0, true1, false0, false1;
unsigned HOST_WIDE_INT nz;
@@ -7455,7 +7474,8 @@ make_field_assignment (x)
rtx assign;
rtx rhs, lhs;
HOST_WIDE_INT c1;
- int pos, len;
+ HOST_WIDE_INT pos;
+ unsigned HOST_WIDE_INT len;
rtx other;
enum machine_mode mode;
@@ -7802,7 +7822,7 @@ nonzero_bits (x, mode)
unsigned HOST_WIDE_INT nonzero = GET_MODE_MASK (mode);
unsigned HOST_WIDE_INT inner_nz;
enum rtx_code code;
- int mode_width = GET_MODE_BITSIZE (mode);
+ unsigned int mode_width = GET_MODE_BITSIZE (mode);
rtx tem;
/* For floating-point values, assume all bits are needed. */
@@ -7877,7 +7897,7 @@ nonzero_bits (x, mode)
int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
#ifdef PUSH_ROUNDING
- if (REGNO (x) == STACK_POINTER_REGNUM)
+ if (REGNO (x) == STACK_POINTER_REGNUM && PUSH_ARGS)
sp_alignment = MIN (PUSH_ROUNDING (1), sp_alignment);
#endif
@@ -8050,7 +8070,7 @@ nonzero_bits (x, mode)
= (nz0 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
HOST_WIDE_INT op1_maybe_minusp
= (nz1 & ((HOST_WIDE_INT) 1 << (mode_width - 1)));
- int result_width = mode_width;
+ unsigned int result_width = mode_width;
int result_low = 0;
switch (code)
@@ -8171,7 +8191,7 @@ nonzero_bits (x, mode)
&& INTVAL (XEXP (x, 1)) < HOST_BITS_PER_WIDE_INT)
{
enum machine_mode inner_mode = GET_MODE (x);
- int width = GET_MODE_BITSIZE (inner_mode);
+ unsigned int width = GET_MODE_BITSIZE (inner_mode);
int count = INTVAL (XEXP (x, 1));
unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (inner_mode);
unsigned HOST_WIDE_INT op_nonzero = nonzero_bits (XEXP (x, 0), mode);
@@ -8228,13 +8248,13 @@ nonzero_bits (x, mode)
VOIDmode, X will be used in its own mode. The returned value will always
be between 1 and the number of bits in MODE. */
-static int
+static unsigned int
num_sign_bit_copies (x, mode)
rtx x;
enum machine_mode mode;
{
enum rtx_code code = GET_CODE (x);
- int bitwidth;
+ unsigned int bitwidth;
int num0, num1, result;
unsigned HOST_WIDE_INT nonzero;
rtx tem;
@@ -8253,8 +8273,11 @@ num_sign_bit_copies (x, mode)
/* For a smaller object, just ignore the high bits. */
if (bitwidth < GET_MODE_BITSIZE (GET_MODE (x)))
- return MAX (1, (num_sign_bit_copies (x, GET_MODE (x))
- - (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth)));
+ {
+ num0 = num_sign_bit_copies (x, GET_MODE (x));
+ return MAX (1,
+ num0 - (int) (GET_MODE_BITSIZE (GET_MODE (x)) - bitwidth));
+ }
if (GET_MODE (x) != VOIDmode && bitwidth > GET_MODE_BITSIZE (GET_MODE (x)))
{
@@ -8310,7 +8333,8 @@ num_sign_bit_copies (x, mode)
#ifdef LOAD_EXTEND_OP
/* Some RISC machines sign-extend all loads of smaller than a word. */
if (LOAD_EXTEND_OP (GET_MODE (x)) == SIGN_EXTEND)
- return MAX (1, bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1);
+ return MAX (1, ((int) bitwidth
+ - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1));
#endif
break;
@@ -8330,16 +8354,20 @@ num_sign_bit_copies (x, mode)
high-order bits are known to be sign bit copies. */
if (SUBREG_PROMOTED_VAR_P (x) && ! SUBREG_PROMOTED_UNSIGNED_P (x))
- return MAX (bitwidth - GET_MODE_BITSIZE (GET_MODE (x)) + 1,
- num_sign_bit_copies (SUBREG_REG (x), mode));
-
+ {
+ num0 = num_sign_bit_copies (SUBREG_REG (x), mode);
+ return MAX ((int) bitwidth
+ - (int) GET_MODE_BITSIZE (GET_MODE (x)) + 1,
+ num0);
+ }
+
/* For a smaller object, just ignore the high bits. */
if (bitwidth <= GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x))))
{
num0 = num_sign_bit_copies (SUBREG_REG (x), VOIDmode);
return MAX (1, (num0
- - (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
- - bitwidth)));
+ - (int) (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
+ - bitwidth)));
}
#ifdef WORD_REGISTER_OPERATIONS
@@ -8364,7 +8392,7 @@ num_sign_bit_copies (x, mode)
case SIGN_EXTRACT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
- return MAX (1, bitwidth - INTVAL (XEXP (x, 1)));
+ return MAX (1, (int) bitwidth - INTVAL (XEXP (x, 1)));
break;
case SIGN_EXTEND:
@@ -8374,8 +8402,8 @@ num_sign_bit_copies (x, mode)
case TRUNCATE:
/* For a smaller object, just ignore the high bits. */
num0 = num_sign_bit_copies (XEXP (x, 0), VOIDmode);
- return MAX (1, (num0 - (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
- - bitwidth)));
+ return MAX (1, (num0 - (int) (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))
+ - bitwidth)));
case NOT:
return num_sign_bit_copies (XEXP (x, 0), mode);
@@ -8389,7 +8417,7 @@ num_sign_bit_copies (x, mode)
{
num0 = num_sign_bit_copies (XEXP (x, 0), mode);
return MAX (1, num0 - (code == ROTATE ? INTVAL (XEXP (x, 1))
- : bitwidth - INTVAL (XEXP (x, 1))));
+ : (int) bitwidth - INTVAL (XEXP (x, 1))));
}
break;
@@ -8557,7 +8585,7 @@ num_sign_bit_copies (x, mode)
This function will always return 0 unless called during combine, which
implies that it must be called from a define_split. */
-int
+unsigned int
extended_count (x, mode, unsignedp)
rtx x;
enum machine_mode mode;
@@ -8568,8 +8596,9 @@ extended_count (x, mode, unsignedp)
return (unsignedp
? (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
- && (GET_MODE_BITSIZE (mode) - 1
- - floor_log2 (nonzero_bits (x, mode))))
+ ? (GET_MODE_BITSIZE (mode) - 1
+ - floor_log2 (nonzero_bits (x, mode)))
+ : 0)
: num_sign_bit_copies (x, mode) - 1);
}
@@ -8719,18 +8748,20 @@ merge_outer_ops (pop0, pconst0, op1, const1, mode, pcomp_p)
are ASHIFTRT and ROTATE, which are always done in their original mode, */
static rtx
-simplify_shift_const (x, code, result_mode, varop, count)
+simplify_shift_const (x, code, result_mode, varop, input_count)
rtx x;
enum rtx_code code;
enum machine_mode result_mode;
rtx varop;
- int count;
+ int input_count;
{
enum rtx_code orig_code = code;
- int orig_count = count;
+ int orig_count = input_count;
+ unsigned int count;
+ int signed_count;
enum machine_mode mode = result_mode;
enum machine_mode shift_mode, tmode;
- int mode_words
+ unsigned int mode_words
= (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
/* We form (outer_op (code varop count) (outer_const)). */
enum rtx_code outer_op = NIL;
@@ -8742,14 +8773,16 @@ simplify_shift_const (x, code, result_mode, varop, count)
/* If we were given an invalid count, don't do anything except exactly
what was requested. */
- if (count < 0 || count > GET_MODE_BITSIZE (mode))
+ if (input_count < 0 || input_count > (int) GET_MODE_BITSIZE (mode))
{
if (x)
return x;
- return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (count));
+ return gen_rtx_fmt_ee (code, mode, varop, GEN_INT (input_count));
}
+ count = input_count;
+
/* Unless one of the branches of the `if' in this loop does a `continue',
we will `break' the loop after the `if'. */
@@ -8803,12 +8836,6 @@ simplify_shift_const (x, code, result_mode, varop, count)
}
}
- /* Negative counts are invalid and should not have been made (a
- programmer-specified negative count should have been handled
- above). */
- else if (count < 0)
- abort ();
-
/* An arithmetic right shift of a quantity known to be -1 or 0
is a no-op. */
if (code == ASHIFTRT
@@ -8931,8 +8958,9 @@ simplify_shift_const (x, code, result_mode, varop, count)
if (GET_CODE (XEXP (varop, 1)) == CONST_INT
&& exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
{
- varop = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
- GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
+ varop
+ = gen_binary (ASHIFT, GET_MODE (varop), XEXP (varop, 0),
+ GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
continue;
}
break;
@@ -8942,8 +8970,9 @@ simplify_shift_const (x, code, result_mode, varop, count)
if (GET_CODE (XEXP (varop, 1)) == CONST_INT
&& exact_log2 (INTVAL (XEXP (varop, 1))) >= 0)
{
- varop = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
- GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
+ varop
+ = gen_binary (LSHIFTRT, GET_MODE (varop), XEXP (varop, 0),
+ GEN_INT (exact_log2 (INTVAL (XEXP (varop, 1)))));
continue;
}
break;
@@ -8971,7 +9000,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
&& GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
{
enum rtx_code first_code = GET_CODE (varop);
- int first_count = INTVAL (XEXP (varop, 1));
+ unsigned int first_count = INTVAL (XEXP (varop, 1));
unsigned HOST_WIDE_INT mask;
rtx mask_rtx;
@@ -9012,10 +9041,14 @@ simplify_shift_const (x, code, result_mode, varop, count)
&& (num_sign_bit_copies (XEXP (varop, 0), shift_mode)
> first_count))
{
- count -= first_count;
- if (count < 0)
- count = - count, code = ASHIFT;
varop = XEXP (varop, 0);
+
+ signed_count = count - first_count;
+ if (signed_count < 0)
+ count = - signed_count, code = ASHIFT;
+ else
+ count = signed_count;
+
continue;
}
@@ -9075,22 +9108,25 @@ simplify_shift_const (x, code, result_mode, varop, count)
/* If the shifts are in the same direction, we add the
counts. Otherwise, we subtract them. */
+ signed_count = count;
if ((code == ASHIFTRT || code == LSHIFTRT)
== (first_code == ASHIFTRT || first_code == LSHIFTRT))
- count += first_count;
+ signed_count += first_count;
else
- count -= first_count;
+ signed_count -= first_count;
/* If COUNT is positive, the new shift is usually CODE,
except for the two exceptions below, in which case it is
FIRST_CODE. If the count is negative, FIRST_CODE should
always be used */
- if (count > 0
+ if (signed_count > 0
&& ((first_code == ROTATE && code == ASHIFT)
|| (first_code == ASHIFTRT && code == LSHIFTRT)))
- code = first_code;
- else if (count < 0)
- code = first_code, count = - count;
+ code = first_code, count = signed_count;
+ else if (signed_count < 0)
+ code = first_code, count = - signed_count;
+ else
+ count = signed_count;
varop = XEXP (varop, 0);
continue;
@@ -9191,7 +9227,8 @@ simplify_shift_const (x, code, result_mode, varop, count)
&& count == GET_MODE_BITSIZE (result_mode) - 1
&& GET_MODE_BITSIZE (result_mode) <= HOST_BITS_PER_WIDE_INT
&& ((STORE_FLAG_VALUE
- & ((HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (result_mode) - 1))))
+ & ((HOST_WIDE_INT) 1
+ < (GET_MODE_BITSIZE (result_mode) - 1))))
&& nonzero_bits (XEXP (varop, 0), result_mode) == 1
&& merge_outer_ops (&outer_op, &outer_const, XOR,
(HOST_WIDE_INT) 1, result_mode,
@@ -9276,7 +9313,7 @@ simplify_shift_const (x, code, result_mode, varop, count)
&& (new = simplify_binary_operation (ASHIFT, result_mode,
XEXP (varop, 1),
GEN_INT (count))) != 0
- && GET_CODE(new) == CONST_INT
+ && GET_CODE (new) == CONST_INT
&& merge_outer_ops (&outer_op, &outer_const, PLUS,
INTVAL (new), result_mode, &complement_p))
{
@@ -9324,10 +9361,11 @@ simplify_shift_const (x, code, result_mode, varop, count)
{
rtx varop_inner = XEXP (varop, 0);
- varop_inner = gen_rtx_combine (LSHIFTRT,
- GET_MODE (varop_inner),
- XEXP (varop_inner, 0),
- GEN_INT (count + INTVAL (XEXP (varop_inner, 1))));
+ varop_inner
+ = gen_rtx_combine (LSHIFTRT, GET_MODE (varop_inner),
+ XEXP (varop_inner, 0),
+ GEN_INT (count
+ + INTVAL (XEXP (varop_inner, 1))));
varop = gen_rtx_combine (TRUNCATE, GET_MODE (varop),
varop_inner);
count = 0;
@@ -9968,7 +10006,7 @@ simplify_comparison (code, pop0, pop1)
while (GET_CODE (op1) == CONST_INT)
{
enum machine_mode mode = GET_MODE (op0);
- int mode_width = GET_MODE_BITSIZE (mode);
+ unsigned int mode_width = GET_MODE_BITSIZE (mode);
unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
int equality_comparison_p;
int sign_bit_comparison_p;
@@ -10414,13 +10452,10 @@ simplify_comparison (code, pop0, pop1)
break;
case MINUS:
- /* (op (minus A B) 0) -> (op A B) */
- if (op1 == const0_rtx)
- {
- op1 = XEXP (op0, 1);
- op0 = XEXP (op0, 0);
- continue;
- }
+ /* We used to optimize signed comparisons against zero, but that
+ was incorrect. Unsigned comparisons against zero (GTU, LEU)
+ arrive here as equality comparisons, or (GEU, LTU) are
+ optimized away. No need to special-case them. */
/* (eq (minus A B) C) -> (eq A (plus B C)) or
(eq B (minus A C)), whichever simplifies. We can only do
@@ -10943,12 +10978,14 @@ update_table_tick (x)
if (code == REG)
{
- int regno = REGNO (x);
- int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ unsigned int regno = REGNO (x);
+ unsigned int endregno
+ = regno + (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ unsigned int r;
- for (i = regno; i < endregno; i++)
- reg_last_set_table_tick[i] = label_tick;
+ for (r = regno; r < endregno; r++)
+ reg_last_set_table_tick[r] = label_tick;
return;
}
@@ -10971,10 +11008,11 @@ record_value_for_reg (reg, insn, value)
rtx insn;
rtx value;
{
- int regno = REGNO (reg);
- int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
- int i;
+ unsigned int regno = REGNO (reg);
+ unsigned int endregno
+ = regno + (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (reg)) : 1);
+ unsigned int i;
/* If VALUE contains REG and we have a previous value for REG, substitute
the previous value. */
@@ -11007,10 +11045,11 @@ record_value_for_reg (reg, insn, value)
we don't know about its bitwise content, that its value has been
updated, and that we don't know the location of the death of the
register. */
- for (i = regno; i < endregno; i ++)
+ for (i = regno; i < endregno; i++)
{
if (insn)
reg_last_set[i] = insn;
+
reg_last_set_value[i] = 0;
reg_last_set_mode[i] = 0;
reg_last_set_nonzero_bits[i] = 0;
@@ -11118,15 +11157,15 @@ record_dead_and_set_regs (insn)
rtx insn;
{
register rtx link;
- int i;
+ unsigned int i;
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
{
if (REG_NOTE_KIND (link) == REG_DEAD
&& GET_CODE (XEXP (link, 0)) == REG)
{
- int regno = REGNO (XEXP (link, 0));
- int endregno
+ unsigned int regno = REGNO (XEXP (link, 0));
+ unsigned int endregno
= regno + (regno < FIRST_PSEUDO_REGISTER
? HARD_REGNO_NREGS (regno, GET_MODE (XEXP (link, 0)))
: 1);
@@ -11171,7 +11210,7 @@ record_promoted_value (insn, subreg)
rtx subreg;
{
rtx links, set;
- int regno = REGNO (SUBREG_REG (subreg));
+ unsigned int regno = REGNO (SUBREG_REG (subreg));
enum machine_mode mode = GET_MODE (subreg);
if (GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT)
@@ -11262,10 +11301,11 @@ get_last_value_validate (loc, insn, tick, replace)
if (GET_CODE (x) == REG)
{
- int regno = REGNO (x);
- int endregno = regno + (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
- int j;
+ unsigned int regno = REGNO (x);
+ unsigned int endregno
+ = regno + (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ unsigned int j;
for (j = regno; j < endregno; j++)
if (reg_last_set_invalid[j]
@@ -11273,7 +11313,8 @@ get_last_value_validate (loc, insn, tick, replace)
live at the beginning of the function, it is always valid. */
|| (! (regno >= FIRST_PSEUDO_REGISTER
&& REG_N_SETS (regno) == 1
- && ! REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))
+ && (! REGNO_REG_SET_P
+ (BASIC_BLOCK (0)->global_live_at_start, regno)))
&& reg_last_set_label[j] > tick))
{
if (replace)
@@ -11313,7 +11354,7 @@ static rtx
get_last_value (x)
rtx x;
{
- int regno;
+ unsigned int regno;
rtx value;
/* If this is a non-paradoxical SUBREG, get the value of its operand and
@@ -11346,7 +11387,8 @@ get_last_value (x)
|| (reg_last_set_label[regno] != label_tick
&& (regno < FIRST_PSEUDO_REGISTER
|| REG_N_SETS (regno) != 1
- || REGNO_REG_SET_P (BASIC_BLOCK (0)->global_live_at_start, regno))))
+ || (REGNO_REG_SET_P
+ (BASIC_BLOCK (0)->global_live_at_start, regno)))))
return 0;
/* If the value was set in a later insn than the ones we are processing,
@@ -11384,17 +11426,17 @@ use_crosses_set_p (x, from_cuid)
if (code == REG)
{
- register int regno = REGNO (x);
- int endreg = regno + (regno < FIRST_PSEUDO_REGISTER
+ unsigned int regno = REGNO (x);
+ unsigned endreg = regno + (regno < FIRST_PSEUDO_REGISTER
? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
#ifdef PUSH_ROUNDING
/* Don't allow uses of the stack pointer to be moved,
because we don't know whether the move crosses a push insn. */
- if (regno == STACK_POINTER_REGNUM)
+ if (regno == STACK_POINTER_REGNUM && PUSH_ARGS)
return 1;
#endif
- for (;regno < endreg; regno++)
+ for (; regno < endreg; regno++)
if (reg_last_set[regno]
&& INSN_CUID (reg_last_set[regno]) > from_cuid)
return 1;
@@ -11425,7 +11467,7 @@ use_crosses_set_p (x, from_cuid)
/* Define three variables used for communication between the following
routines. */
-static int reg_dead_regno, reg_dead_endregno;
+static unsigned int reg_dead_regno, reg_dead_endregno;
static int reg_dead_flag;
/* Function called via note_stores from reg_dead_at_p.
@@ -11439,7 +11481,7 @@ reg_dead_at_p_1 (dest, x, data)
rtx x;
void *data ATTRIBUTE_UNUSED;
{
- int regno, endregno;
+ unsigned int regno, endregno;
if (GET_CODE (dest) != REG)
return;
@@ -11465,7 +11507,8 @@ reg_dead_at_p (reg, insn)
rtx reg;
rtx insn;
{
- int block, i;
+ int block;
+ unsigned int i;
/* Set variables for reg_dead_at_p_1. */
reg_dead_regno = REGNO (reg);
@@ -11524,8 +11567,8 @@ static void
mark_used_regs_combine (x)
rtx x;
{
- register RTX_CODE code = GET_CODE (x);
- register int regno;
+ RTX_CODE code = GET_CODE (x);
+ unsigned int regno;
int i;
switch (code)
@@ -11559,6 +11602,8 @@ mark_used_regs_combine (x)
If so, mark all of them just like the first. */
if (regno < FIRST_PSEUDO_REGISTER)
{
+ unsigned int endregno, r;
+
/* None of this applies to the stack, frame or arg pointers */
if (regno == STACK_POINTER_REGNUM
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
@@ -11570,9 +11615,9 @@ mark_used_regs_combine (x)
|| regno == FRAME_POINTER_REGNUM)
return;
- i = HARD_REGNO_NREGS (regno, GET_MODE (x));
- while (i-- > 0)
- SET_HARD_REG_BIT (newpat_used_regs, regno + i);
+ endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ for (r = regno; r < endregno; r++)
+ SET_HARD_REG_BIT (newpat_used_regs, r);
}
return;
@@ -11626,7 +11671,7 @@ mark_used_regs_combine (x)
rtx
remove_death (regno, insn)
- int regno;
+ unsigned int regno;
rtx insn;
{
register rtx note = find_regno_note (insn, REG_DEAD, regno);
@@ -11664,13 +11709,13 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
if (code == REG)
{
- register int regno = REGNO (x);
+ unsigned int regno = REGNO (x);
register rtx where_dead = reg_last_death[regno];
register rtx before_dead, after_dead;
/* Don't move the register if it gets killed in between from and to */
if (maybe_kill_insn && reg_set_p (x, maybe_kill_insn)
- && !reg_referenced_p (x, maybe_kill_insn))
+ && ! reg_referenced_p (x, maybe_kill_insn))
return;
/* WHERE_DEAD could be a USE insn made by combine, so first we
@@ -11678,6 +11723,7 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
before_dead = where_dead;
while (before_dead && INSN_UID (before_dead) > max_uid_cuid)
before_dead = PREV_INSN (before_dead);
+
after_dead = where_dead;
while (after_dead && INSN_UID (after_dead) > max_uid_cuid)
after_dead = NEXT_INSN (after_dead);
@@ -11703,12 +11749,13 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
&& (GET_MODE_SIZE (GET_MODE (XEXP (note, 0)))
> GET_MODE_SIZE (GET_MODE (x))))
{
- int deadregno = REGNO (XEXP (note, 0));
- int deadend
+ unsigned int deadregno = REGNO (XEXP (note, 0));
+ unsigned int deadend
= (deadregno + HARD_REGNO_NREGS (deadregno,
GET_MODE (XEXP (note, 0))));
- int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- int i;
+ unsigned int ourend
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ unsigned int i;
for (i = deadregno; i < deadend; i++)
if (i < regno || i >= ourend)
@@ -11717,6 +11764,7 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
gen_rtx_REG (reg_raw_mode[i], i),
REG_NOTES (where_dead));
}
+
/* If we didn't find any note, or if we found a REG_DEAD note that
covers only part of the given reg, and we have a multi-reg hard
register, then to be safe we must check for REG_DEAD notes
@@ -11729,8 +11777,9 @@ move_deaths (x, maybe_kill_insn, from_cuid, to_insn, pnotes)
&& regno < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
{
- int ourend = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- int i, offset;
+ unsigned int ourend
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ unsigned int i, offset;
rtx oldnotes = 0;
if (note)
@@ -11829,7 +11878,7 @@ reg_bitfield_target_p (x, body)
{
rtx dest = SET_DEST (body);
rtx target;
- int regno, tregno, endregno, endtregno;
+ unsigned int regno, tregno, endregno, endtregno;
if (GET_CODE (dest) == ZERO_EXTRACT)
target = XEXP (dest, 0);
@@ -11949,7 +11998,8 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
is one already. */
else if (reg_referenced_p (XEXP (note, 0), PATTERN (i3))
&& ! (GET_CODE (XEXP (note, 0)) == REG
- ? find_regno_note (i3, REG_DEAD, REGNO (XEXP (note, 0)))
+ ? find_regno_note (i3, REG_DEAD,
+ REGNO (XEXP (note, 0)))
: find_reg_note (i3, REG_DEAD, XEXP (note, 0))))
{
PUT_REG_NOTE_KIND (note, REG_DEAD);
@@ -12219,14 +12269,12 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
of the block. If the existing life info says the reg
was dead, there's nothing left to do. Otherwise, we'll
need to do a global life update after combine. */
- if (REG_NOTE_KIND (note) == REG_DEAD && place == 0)
+ if (REG_NOTE_KIND (note) == REG_DEAD && place == 0
+ && REGNO_REG_SET_P (bb->global_live_at_start,
+ REGNO (XEXP (note, 0))))
{
- int regno = REGNO (XEXP (note, 0));
- if (REGNO_REG_SET_P (bb->global_live_at_start, regno))
- {
- SET_BIT (refresh_blocks, this_basic_block);
- need_refresh = 1;
- }
+ SET_BIT (refresh_blocks, this_basic_block);
+ need_refresh = 1;
}
}
@@ -12238,7 +12286,7 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
if (place && REG_NOTE_KIND (note) == REG_DEAD)
{
- int regno = REGNO (XEXP (note, 0));
+ unsigned int regno = REGNO (XEXP (note, 0));
if (dead_or_set_p (place, XEXP (note, 0))
|| reg_bitfield_target_p (XEXP (note, 0), PATTERN (place)))
@@ -12267,11 +12315,11 @@ distribute_notes (notes, from_insn, i3, i2, elim_i2, elim_i1)
if (place && regno < FIRST_PSEUDO_REGISTER
&& HARD_REGNO_NREGS (regno, GET_MODE (XEXP (note, 0))) > 1)
{
- int endregno
+ unsigned int endregno
= regno + HARD_REGNO_NREGS (regno,
GET_MODE (XEXP (note, 0)));
int all_used = 1;
- int i;
+ unsigned int i;
for (i = regno; i < endregno; i++)
if (! refers_to_regno_p (i, i + 1, PATTERN (place), 0)
diff --git a/gcc/config.in b/gcc/config.in
index 879360b882f..f623b490d1f 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -5,6 +5,12 @@
/* Define if printf supports "%p". */
#undef HAVE_PRINTF_PTR
+/* Define if you want to enable namespaces (-fhonor-std) by default. */
+#undef ENABLE_STD_NAMESPACE
+#if !defined(ENABLE_STD_NAMESPACE)
+# define ENABLE_STD_NAMESPACE 0
+#endif
+
/* Define if you want to always select the new-abi for g++. */
#undef ENABLE_NEW_GXX_ABI
@@ -73,6 +79,9 @@
/* Define if your assembler supports .weak. */
#undef HAVE_GAS_WEAK
+/* Define if your assembler supports .hidden. */
+#undef HAVE_GAS_HIDDEN
+
/* Define if your assembler uses the old HImode fild and fist notation. */
#undef HAVE_GAS_FILDS_FISTS
diff --git a/gcc/config/a29k/a29k.h b/gcc/config/a29k/a29k.h
index deca666acd1..d7a2bd426f4 100644
--- a/gcc/config/a29k/a29k.h
+++ b/gcc/config/a29k/a29k.h
@@ -716,7 +716,7 @@ enum reg_class { NO_REGS, LR0_REGS, GENERAL_REGS, BP_REGS, FC_REGS, CR_REGS,
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
found in the variable current_function_outgoing_args_size. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset of first parameter from the argument pointer register value. */
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 7c53f52932b..7d82f3062b0 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -828,8 +828,7 @@ aligned_memory_operand (op, mode)
base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
}
- return (GET_CODE (base) == REG
- && REGNO_POINTER_ALIGN (REGNO (base)) >= 4);
+ return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) >= 32);
}
/* Similar, but return 1 if OP is a MEM which is not alignable. */
@@ -873,8 +872,7 @@ unaligned_memory_operand (op, mode)
base = (GET_CODE (op) == PLUS ? XEXP (op, 0) : op);
}
- return (GET_CODE (base) == REG
- && REGNO_POINTER_ALIGN (REGNO (base)) < 4);
+ return (GET_CODE (base) == REG && REGNO_POINTER_ALIGN (REGNO (base)) < 32);
}
/* Return 1 if OP is either a register or an unaligned memory location. */
@@ -1771,11 +1769,14 @@ alpha_emit_conditional_move (cmp, mode)
&& (op0 == CONST0_RTX (cmp_mode) || op1 == CONST0_RTX (cmp_mode)))
return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
- /* We can't put the comparison insides a conditional move;
+ /* We can't put the comparison inside the conditional move;
emit a compare instruction and put that inside the
conditional move. Make sure we emit only comparisons we have;
swap or reverse as necessary. */
+ if (no_new_pseudos)
+ return NULL_RTX;
+
switch (code)
{
case EQ: case LE: case LT: case LEU: case LTU:
@@ -2501,77 +2502,69 @@ alpha_expand_block_move (operands)
rtx bytes_rtx = operands[2];
rtx align_rtx = operands[3];
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];
- rtx orig_dst = operands[0];
- rtx data_regs[2*MAX_MOVE_WORDS+16];
+ unsigned HOST_WIDE_INT bytes = orig_bytes;
+ unsigned HOST_WIDE_INT src_align = INTVAL (align_rtx) * BITS_PER_UNIT;
+ unsigned HOST_WIDE_INT dst_align = src_align;
+ rtx orig_src = operands[1];
+ rtx orig_dst = operands[0];
+ rtx data_regs[2 * MAX_MOVE_WORDS + 16];
rtx tmp;
- int i, words, ofs, nregs = 0;
+ unsigned int i, words, ofs, nregs = 0;
- if (bytes <= 0)
+ if (orig_bytes <= 0)
return 1;
- if (bytes > MAX_MOVE_WORDS*8)
+ else if (bytes > MAX_MOVE_WORDS * BITS_PER_UNIT)
return 0;
/* Look for additional alignment information from recorded register info. */
tmp = XEXP (orig_src, 0);
if (GET_CODE (tmp) == REG)
- {
- if (REGNO_POINTER_ALIGN (REGNO (tmp)) > src_align)
- src_align = REGNO_POINTER_ALIGN (REGNO (tmp));
- }
+ src_align = MAX (src_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
else if (GET_CODE (tmp) == PLUS
&& GET_CODE (XEXP (tmp, 0)) == REG
&& GET_CODE (XEXP (tmp, 1)) == CONST_INT)
{
- HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
- int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
+ unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
+ unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
if (a > src_align)
{
- if (a >= 8 && c % 8 == 0)
- src_align = 8;
- else if (a >= 4 && c % 4 == 0)
- src_align = 4;
- else if (a >= 2 && c % 2 == 0)
- src_align = 2;
+ if (a >= 64 && c % 8 == 0)
+ src_align = 64;
+ else if (a >= 32 && c % 4 == 0)
+ src_align = 32;
+ else if (a >= 16 && c % 2 == 0)
+ src_align = 16;
}
}
tmp = XEXP (orig_dst, 0);
if (GET_CODE (tmp) == REG)
- {
- if (REGNO_POINTER_ALIGN (REGNO (tmp)) > dst_align)
- dst_align = REGNO_POINTER_ALIGN (REGNO (tmp));
- }
+ dst_align = MAX (dst_align, REGNO_POINTER_ALIGN (REGNO (tmp)));
else if (GET_CODE (tmp) == PLUS
&& GET_CODE (XEXP (tmp, 0)) == REG
&& GET_CODE (XEXP (tmp, 1)) == CONST_INT)
{
- HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
- int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
+ unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
+ unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
if (a > dst_align)
{
- if (a >= 8 && c % 8 == 0)
- dst_align = 8;
- else if (a >= 4 && c % 4 == 0)
- dst_align = 4;
- else if (a >= 2 && c % 2 == 0)
- dst_align = 2;
+ if (a >= 64 && c % 8 == 0)
+ dst_align = 64;
+ else if (a >= 32 && c % 4 == 0)
+ dst_align = 32;
+ else if (a >= 16 && c % 2 == 0)
+ dst_align = 16;
}
}
- /*
- * Load the entire block into registers.
- */
-
+ /* Load the entire block into registers. */
if (GET_CODE (XEXP (orig_src, 0)) == ADDRESSOF)
{
enum machine_mode mode;
+
tmp = XEXP (XEXP (orig_src, 0), 0);
/* Don't use the existing register if we're reading more than
@@ -2589,6 +2582,7 @@ alpha_expand_block_move (operands)
}
else
data_regs[nregs++] = gen_lowpart (mode, tmp);
+
goto src_done;
}
@@ -2598,50 +2592,48 @@ alpha_expand_block_move (operands)
}
ofs = 0;
- if (src_align >= 8 && bytes >= 8)
+ if (src_align >= 64 && bytes >= 8)
{
words = bytes / 8;
for (i = 0; i < words; ++i)
- data_regs[nregs+i] = gen_reg_rtx(DImode);
+ data_regs[nregs + i] = gen_reg_rtx(DImode);
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)));
- }
+ emit_move_insn (data_regs[nregs + i],
+ change_address (orig_src, DImode,
+ plus_constant (XEXP (orig_src, 0),
+ ofs + i * 8)));
nregs += words;
bytes -= words * 8;
ofs += words * 8;
}
- if (src_align >= 4 && bytes >= 4)
+
+ if (src_align >= 32 && bytes >= 4)
{
words = bytes / 4;
for (i = 0; i < words; ++i)
- data_regs[nregs+i] = gen_reg_rtx(SImode);
+ data_regs[nregs + i] = gen_reg_rtx(SImode);
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)));
- }
+ emit_move_insn (data_regs[nregs + i],
+ change_address (orig_src, SImode,
+ plus_constant (XEXP (orig_src, 0),
+ ofs + i * 4)));
nregs += words;
bytes -= words * 4;
ofs += words * 4;
}
+
if (bytes >= 16)
{
words = bytes / 8;
for (i = 0; i < words+1; ++i)
- data_regs[nregs+i] = gen_reg_rtx(DImode);
+ data_regs[nregs + i] = gen_reg_rtx(DImode);
alpha_expand_unaligned_load_words (data_regs + nregs, orig_src,
words, ofs);
@@ -2650,23 +2642,26 @@ alpha_expand_block_move (operands)
bytes -= words * 8;
ofs += words * 8;
}
- if (!TARGET_BWX && bytes >= 8)
+
+ if (! TARGET_BWX && bytes >= 8)
{
data_regs[nregs++] = tmp = gen_reg_rtx (DImode);
alpha_expand_unaligned_load (tmp, orig_src, 8, ofs, 0);
bytes -= 8;
ofs += 8;
}
- if (!TARGET_BWX && bytes >= 4)
+
+ if (! TARGET_BWX && bytes >= 4)
{
data_regs[nregs++] = tmp = gen_reg_rtx (SImode);
alpha_expand_unaligned_load (tmp, orig_src, 4, ofs, 0);
bytes -= 4;
ofs += 4;
}
+
if (bytes >= 2)
{
- if (src_align >= 2)
+ if (src_align >= 16)
{
do {
data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
@@ -2678,7 +2673,8 @@ alpha_expand_block_move (operands)
ofs += 2;
} while (bytes >= 2);
}
- else if (!TARGET_BWX)
+
+ else if (! TARGET_BWX)
{
data_regs[nregs++] = tmp = gen_reg_rtx (HImode);
alpha_expand_unaligned_load (tmp, orig_src, 2, ofs, 0);
@@ -2686,6 +2682,7 @@ alpha_expand_block_move (operands)
ofs += 2;
}
}
+
while (bytes > 0)
{
data_regs[nregs++] = tmp = gen_reg_rtx (QImode);
@@ -2696,14 +2693,13 @@ alpha_expand_block_move (operands)
bytes -= 1;
ofs += 1;
}
+
src_done:
- if (nregs > (int)(sizeof(data_regs)/sizeof(*data_regs)))
- abort();
+ if (nregs > sizeof data_regs / sizeof *data_regs)
+ abort ();
- /*
- * Now save it back out again.
- */
+ /* Now save it back out again. */
i = 0, ofs = 0;
@@ -2721,15 +2717,14 @@ alpha_expand_block_move (operands)
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]));
- }
+ emit_move_insn (tmp, SUBREG_REG (data_regs[0]));
else
{
rtx seq;
@@ -2760,7 +2755,7 @@ alpha_expand_block_move (operands)
}
/* Write out the data in whatever chunks reading the source allowed. */
- if (dst_align >= 8)
+ if (dst_align >= 64)
{
while (i < nregs && GET_MODE (data_regs[i]) == DImode)
{
@@ -2772,7 +2767,8 @@ alpha_expand_block_move (operands)
i++;
}
}
- if (dst_align >= 4)
+
+ if (dst_align >= 32)
{
/* If the source has remaining DImode regs, write them out in
two pieces. */
@@ -2787,7 +2783,7 @@ alpha_expand_block_move (operands)
gen_lowpart (SImode, data_regs[i]));
emit_move_insn (change_address (orig_dst, SImode,
plus_constant (XEXP (orig_dst, 0),
- ofs+4)),
+ ofs + 4)),
gen_lowpart (SImode, tmp));
ofs += 8;
i++;
@@ -2803,18 +2799,20 @@ alpha_expand_block_move (operands)
i++;
}
}
+
if (i < nregs && GET_MODE (data_regs[i]) == DImode)
{
/* Write out a remaining block of words using unaligned methods. */
- for (words = 1; i+words < nregs ; ++words)
- if (GET_MODE (data_regs[i+words]) != DImode)
+ for (words = 1; i + words < nregs; words++)
+ if (GET_MODE (data_regs[i + words]) != DImode)
break;
if (words == 1)
alpha_expand_unaligned_store (orig_dst, data_regs[i], 8, ofs);
else
- alpha_expand_unaligned_store_words (data_regs+i, orig_dst, words, ofs);
+ alpha_expand_unaligned_store_words (data_regs + i, orig_dst,
+ words, ofs);
i += words;
ofs += words * 8;
@@ -2830,7 +2828,7 @@ alpha_expand_block_move (operands)
i++;
}
- if (dst_align >= 2)
+ if (dst_align >= 16)
while (i < nregs && GET_MODE (data_regs[i]) == HImode)
{
emit_move_insn (change_address (orig_dst, HImode,
@@ -2847,6 +2845,7 @@ alpha_expand_block_move (operands)
i++;
ofs += 2;
}
+
while (i < nregs && GET_MODE (data_regs[i]) == QImode)
{
emit_move_insn (change_address (orig_dst, QImode,
@@ -2856,10 +2855,11 @@ alpha_expand_block_move (operands)
i++;
ofs += 1;
}
+
dst_done:
if (i != nregs)
- abort();
+ abort ();
return 1;
}
@@ -2870,42 +2870,40 @@ alpha_expand_block_clear (operands)
{
rtx bytes_rtx = operands[1];
rtx align_rtx = operands[2];
- HOST_WIDE_INT bytes = INTVAL (bytes_rtx);
- HOST_WIDE_INT align = INTVAL (align_rtx);
- rtx orig_dst = operands[0];
+ HOST_WIDE_INT orig_bytes = INTVAL (bytes_rtx);
+ unsigned HOST_WIDE_INT bytes = orig_bytes;
+ unsigned HOST_WIDE_INT align = INTVAL (align_rtx);
+ rtx orig_dst = operands[0];
rtx tmp;
- HOST_WIDE_INT i, words, ofs = 0;
+ unsigned HOST_WIDE_INT i, words, ofs = 0;
- if (bytes <= 0)
+ if (orig_bytes <= 0)
return 1;
if (bytes > MAX_MOVE_WORDS*8)
return 0;
/* Look for stricter alignment. */
-
tmp = XEXP (orig_dst, 0);
if (GET_CODE (tmp) == REG)
- {
- if (REGNO_POINTER_ALIGN (REGNO (tmp)) > align)
- align = REGNO_POINTER_ALIGN (REGNO (tmp));
- }
+ align = MAX (align, REGNO_POINTER_ALIGN (REGNO (tmp)));
else if (GET_CODE (tmp) == PLUS
&& GET_CODE (XEXP (tmp, 0)) == REG
&& GET_CODE (XEXP (tmp, 1)) == CONST_INT)
{
- HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
- int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
+ unsigned HOST_WIDE_INT c = INTVAL (XEXP (tmp, 1));
+ unsigned int a = REGNO_POINTER_ALIGN (REGNO (XEXP (tmp, 0)));
if (a > align)
{
- if (a >= 8 && c % 8 == 0)
- align = 8;
- else if (a >= 4 && c % 4 == 0)
- align = 4;
- else if (a >= 2 && c % 2 == 0)
- align = 2;
+ if (a >= 64 && c % 8 == 0)
+ align = 64;
+ else if (a >= 32 && c % 4 == 0)
+ align = 32;
+ else if (a >= 16 && c % 2 == 0)
+ align = 16;
}
}
+
else if (GET_CODE (tmp) == ADDRESSOF)
{
enum machine_mode mode;
@@ -2925,36 +2923,34 @@ alpha_expand_block_clear (operands)
/* Handle a block of contiguous words first. */
- if (align >= 8 && bytes >= 8)
+ if (align >= 64 && bytes >= 8)
{
words = bytes / 8;
for (i = 0; i < words; ++i)
- {
- emit_move_insn (change_address(orig_dst, DImode,
- plus_constant (XEXP (orig_dst, 0),
- ofs + i*8)),
+ emit_move_insn (change_address(orig_dst, DImode,
+ plus_constant (XEXP (orig_dst, 0),
+ ofs + i * 8)),
const0_rtx);
- }
bytes -= words * 8;
ofs += words * 8;
}
- if (align >= 4 && bytes >= 4)
+
+ if (align >= 16 && bytes >= 4)
{
words = bytes / 4;
for (i = 0; i < words; ++i)
- {
- emit_move_insn (change_address (orig_dst, SImode,
- plus_constant (XEXP (orig_dst, 0),
- ofs + i*4)),
- const0_rtx);
- }
+ emit_move_insn (change_address (orig_dst, SImode,
+ plus_constant (XEXP (orig_dst, 0),
+ ofs + i * 4)),
+ const0_rtx);
bytes -= words * 4;
ofs += words * 4;
}
+
if (bytes >= 16)
{
words = bytes / 8;
@@ -2968,21 +2964,23 @@ alpha_expand_block_clear (operands)
/* Next clean up any trailing pieces. We know from the contiguous
block move that there are no aligned SImode or DImode hunks left. */
- if (!TARGET_BWX && bytes >= 8)
+ if (! TARGET_BWX && bytes >= 8)
{
alpha_expand_unaligned_store (orig_dst, const0_rtx, 8, ofs);
bytes -= 8;
ofs += 8;
}
+
if (!TARGET_BWX && bytes >= 4)
{
alpha_expand_unaligned_store (orig_dst, const0_rtx, 4, ofs);
bytes -= 4;
ofs += 4;
}
+
if (bytes >= 2)
{
- if (align >= 2)
+ if (align >= 16)
{
do {
emit_move_insn (change_address (orig_dst, HImode,
@@ -2993,13 +2991,14 @@ alpha_expand_block_clear (operands)
ofs += 2;
} while (bytes >= 2);
}
- else if (!TARGET_BWX)
+ else if (! TARGET_BWX)
{
alpha_expand_unaligned_store (orig_dst, const0_rtx, 2, ofs);
bytes -= 2;
ofs += 2;
}
}
+
while (bytes > 0)
{
emit_move_insn (change_address (orig_dst, QImode,
@@ -3012,7 +3011,6 @@ alpha_expand_block_clear (operands)
return 1;
}
-
/* Adjust the cost of a scheduling dependency. Return the new cost of
a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
@@ -3756,6 +3754,9 @@ alpha_va_start (stdarg_p, valist, nextarg)
HOST_WIDE_INT offset;
tree t, offset_field, base_field;
+ if (TREE_CODE (TREE_TYPE (valist)) == ERROR_MARK)
+ return;
+
if (TARGET_OPEN_VMS)
std_expand_builtin_va_start (stdarg_p, valist, nextarg);
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 4fadf8e55e5..31ad3bb968e 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -487,7 +487,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
#define STACK_BOUNDARY 64
/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 256
+#define FUNCTION_BOUNDARY 128
/* Alignment of field after `int : 0' in a structure. */
#define EMPTY_FIELD_BOUNDARY 64
@@ -519,7 +519,7 @@ extern const char *alpha_mlat_string; /* For -mmemory-latency= */
/* For atomic access to objects, must have at least 32-bit alignment
unless the machine has byte operations. */
-#define MINIMUM_ATOMIC_ALIGNMENT (TARGET_BWX ? 8 : 32)
+#define MINIMUM_ATOMIC_ALIGNMENT ((unsigned int) (TARGET_BWX ? 8 : 32))
/* Align all constants and variables to at least a word boundary so
we can pick up pieces of them faster. */
@@ -919,7 +919,7 @@ extern int alpha_memory_latency;
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
found in the variable current_function_outgoing_args_size. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset of first parameter from the argument pointer register value. */
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 03c70036416..5b9dd8e9459 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -2240,7 +2240,7 @@
which prevents rounding error in the final conversion to SFmode. */
emit_insn (gen_rtx_SET (VOIDmode, sticky,
- gen_rtx_LTU (DImode, const0_rtx, lo)));
+ gen_rtx_NE (DImode, lo, const0_rtx)));
emit_insn (gen_iordi3 (hi, hi, sticky));
emit_insn (gen_trunctfdf2 (tmpf, arg));
emit_insn (gen_truncdfsf2 (operands[0], tmpf));
@@ -2497,6 +2497,14 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
+ (ne:DI (match_operand:DI 1 "reg_or_8bit_operand" "rI")
+ (const_int 0)))]
+ ""
+ "cmpult $31,%1,%0"
+ [(set_attr "type" "icmp")])
+
+(define_insn ""
+ [(set (match_operand:DI 0 "register_operand" "=r")
(match_operator:DI 1 "alpha_comparison_operator"
[(match_operand:DI 2 "reg_or_0_operand" "rJ")
(match_operand:DI 3 "reg_or_8bit_operand" "rI")]))]
@@ -3314,7 +3322,9 @@
if (alpha_compare.op1 == const0_rtx)
{
- emit_insn (gen_sgtu (operands[0]));
+ operands[1] = gen_rtx_NE (DImode, alpha_compare.op0, alpha_compare.op1);
+ alpha_compare.op0 = alpha_compare.op1 = NULL_RTX;
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
DONE;
}
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 0689d2e274a..b71d76294f7 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -643,7 +643,7 @@ extern enum reg_class arc_regno_reg_class[];
`current_function_outgoing_args_size'. No space will be pushed
onto the stack for each call; instead, the function prologue should
increase the stack frame size by this amount. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index ba828e4a91f..3a4acd79846 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -106,23 +106,23 @@ static int max_insns_skipped = 5;
extern FILE * asm_out_file;
-/* True if we are currently building a constant table. */
+/* True if we are currently building a constant table. */
int making_const_table;
/* Define the information needed to generate branch insns. This is
- stored from the compare operation. */
+ stored from the compare operation. */
rtx arm_compare_op0, arm_compare_op1;
-/* What type of floating point are we tuning for? */
+/* What type of floating point are we tuning for? */
enum floating_point_type arm_fpu;
-/* What type of floating point instructions are available? */
+/* What type of floating point instructions are available? */
enum floating_point_type arm_fpu_arch;
-/* What program mode is the cpu running in? 26-bit mode or 32-bit mode */
+/* What program mode is the cpu running in? 26-bit mode or 32-bit mode. */
enum prog_mode_type arm_prgmode;
-/* Set by the -mfp=... option */
+/* Set by the -mfp=... option. */
const char * target_fp_name = NULL;
/* Used to parse -mstructure_size_boundary command line option. */
@@ -156,10 +156,10 @@ static int tune_flags = 0;
/* Nonzero if this is an "M" variant of the processor. */
int arm_fast_multiply = 0;
-/* Nonzero if this chip supports the ARM Architecture 4 extensions */
+/* Nonzero if this chip supports the ARM Architecture 4 extensions. */
int arm_arch4 = 0;
-/* Nonzero if this chip supports the ARM Architecture 5 extensions */
+/* Nonzero if this chip supports the ARM Architecture 5 extensions. */
int arm_arch5 = 0;
/* Nonzero if this chip can benefit from load scheduling. */
@@ -184,11 +184,11 @@ const char * arm_pic_register_string = NULL;
int arm_pic_register = 9;
/* Set to one if we think that lr is only saved because of subroutine calls,
- but all of these can be `put after' return insns */
+ but all of these can be `put after' return insns. */
int lr_save_eliminated;
/* Set to 1 when a return insn is output, this means that the epilogue
- is not needed. */
+ is not needed. */
int return_used_this_function;
/* Set to 1 after arm_reorg has started. Reset to start at the start of
@@ -213,7 +213,7 @@ char * arm_condition_codes[] =
#define streq(string1, string2) (strcmp (string1, string2) == 0)
-/* Initialization code */
+/* Initialization code. */
struct processors
{
@@ -337,7 +337,7 @@ arm_override_options ()
/* If we have been given an architecture and a processor
make sure that they are compatible. We only generate
a warning though, and we prefer the CPU over the
- architecture. */
+ architecture. */
if (insn_flags != 0 && (insn_flags ^ sel->flags))
warning ("switch -mcpu=%s conflicts with -march= switch",
ptr->string);
@@ -703,7 +703,7 @@ use_return_insn (iscond)
}
/* Can't be done if any of the FPU regs are pushed, since this also
- requires an insn */
+ requires an insn. */
if (TARGET_HARD_FLOAT)
for (regno = FIRST_ARM_FP_REGNUM; regno <= LAST_ARM_FP_REGNUM; regno++)
if (regs_ever_live[regno] && ! call_used_regs[regno])
@@ -748,7 +748,7 @@ const_ok_for_arm (i)
return FALSE;
}
-/* Return true if I is a valid constant for the operation CODE. */
+/* Return true if I is a valid constant for the operation CODE. */
static int
const_ok_for_op (i, code)
HOST_WIDE_INT i;
@@ -976,10 +976,8 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
return 1;
}
-
/* Calculate a few attributes that may be useful for specific
- optimizations. */
-
+ optimizations. */
for (i = 31; i >= 0; i--)
{
if ((remainder & (1 << i)) == 0)
@@ -1061,7 +1059,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
temp1 = remainder & (unsigned HOST_WIDE_INT)0xffff0000;
temp2 = remainder & 0x0000ffff;
- /* Overlaps outside this range are best done using other methods. */
+ /* Overlaps outside this range are best done using other methods. */
for (i = 9; i < 24; i++)
{
if ((((temp2 | (temp2 << i))
@@ -1085,7 +1083,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
}
}
- /* Don't duplicate cases already considered. */
+ /* Don't duplicate cases already considered. */
for (i = 17; i < 24; i++)
{
if (((temp1 | (temp1 >> i)) == remainder)
@@ -1296,7 +1294,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
We start by looking for the largest block of zeros that are aligned on
a 2-bit boundary, we then fill up the temps, wrapping around to the
top of the word when we drop off the bottom.
- In the worst case this code should produce no more than four insns. */
+ In the worst case this code should produce no more than four insns. */
{
int best_start = 0;
int best_consecutive_zeros = 0;
@@ -1323,7 +1321,7 @@ arm_gen_constant (code, mode, val, target, source, subtargets, generate)
/* Now start emitting the insns, starting with the one with the highest
bit set: we do this so that the smallest number will be emitted last;
- this is more likely to be combinable with addressing insns. */
+ this is more likely to be combinable with addressing insns. */
i = best_start;
do
{
@@ -1711,8 +1709,8 @@ arm_encode_call_attribute (decl, flag)
char flag;
{
const char * str = XSTR (XEXP (DECL_RTL (decl), 0), 0);
- int len = strlen (str);
- char * newstr;
+ int len = strlen (str);
+ char * newstr;
if (TREE_CODE (decl) != FUNCTION_DECL)
return;
@@ -2294,7 +2292,7 @@ arm_rtx_costs (x, code, outer)
case MULT:
/* There is no point basing this on the tuning, since it is always the
- fast variant if it exists at all */
+ fast variant if it exists at all. */
if (arm_fast_multiply && mode == DImode
&& (GET_CODE (XEXP (x, 0)) == GET_CODE (XEXP (x, 1)))
&& (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
@@ -2311,7 +2309,8 @@ arm_rtx_costs (x, code, outer)
& (unsigned HOST_WIDE_INT) 0xffffffff);
int add_cost = const_ok_for_arm (i) ? 4 : 8;
int j;
- /* Tune as appropriate */
+
+ /* Tune as appropriate. */
int booth_unit_size = ((tune_flags & FL_FAST_MULT) ? 8 : 2);
for (j = 0; i && j < 32; j += booth_unit_size)
@@ -2441,7 +2440,7 @@ arm_adjust_cost (insn, link, dep, cost)
/* This is a load after a store, there is no conflict if the load reads
from a cached area. Assume that loads from the stack, and from the
constant pool are cached, and that others will miss. This is a
- hack. */
+ hack. */
if (CONSTANT_POOL_ADDRESS_P (XEXP (SET_SRC (i_pat), 0))
|| reg_mentioned_p (stack_pointer_rtx, XEXP (SET_SRC (i_pat), 0))
@@ -2454,7 +2453,7 @@ arm_adjust_cost (insn, link, dep, cost)
return cost;
}
-/* This code has been fixed for cross compilation. */
+/* This code has been fixed for cross compilation. */
static int fpa_consts_inited = 0;
@@ -2481,7 +2480,7 @@ init_fpa_table ()
fpa_consts_inited = 1;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
+/* Return TRUE if rtx X is a valid immediate FPU constant. */
int
const_double_rtx_ok_for_fpu (x)
@@ -2504,7 +2503,7 @@ const_double_rtx_ok_for_fpu (x)
return 0;
}
-/* Return TRUE if rtx X is a valid immediate FPU constant. */
+/* Return TRUE if rtx X is a valid immediate FPU constant. */
int
neg_const_double_rtx_ok_for_fpu (x)
@@ -2615,20 +2614,20 @@ bad_signed_byte_operand (op, mode)
op = XEXP (op, 0);
- /* A sum of anything more complex than reg + reg or reg + const is bad */
+ /* A sum of anything more complex than reg + reg or reg + const is bad. */
if ((GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
&& (! s_register_operand (XEXP (op, 0), VOIDmode)
|| (! s_register_operand (XEXP (op, 1), VOIDmode)
&& GET_CODE (XEXP (op, 1)) != CONST_INT)))
return 1;
- /* Big constants are also bad */
+ /* Big constants are also bad. */
if (GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT
&& (INTVAL (XEXP (op, 1)) > 0xff
|| -INTVAL (XEXP (op, 1)) > 0xff))
return 1;
- /* Everything else is good, or can will automatically be made so. */
+ /* Everything else is good, or can will automatically be made so. */
return 0;
}
@@ -2725,7 +2724,7 @@ alignable_memory_operand (op, mode)
&& (GET_CODE (reg = XEXP (op, 0)) == REG
|| (GET_CODE (XEXP (op, 0)) == SUBREG
&& GET_CODE (reg = SUBREG_REG (XEXP (op, 0))) == REG))))
- && REGNO_POINTER_ALIGN (REGNO (reg)) >= 4);
+ && REGNO_POINTER_ALIGN (REGNO (reg)) >= 32);
}
/* Similar to s_register_operand, but does not allow hard integer
@@ -2909,7 +2908,7 @@ nonimmediate_soft_df_operand (op, mode)
return FALSE;
}
-/* Return TRUE for valid index operands. */
+/* Return TRUE for valid index operands. */
int
index_operand (op, mode)
rtx op;
@@ -2923,7 +2922,7 @@ index_operand (op, mode)
/* Return TRUE for valid shifts by a constant. This also accepts any
power of two on the (somewhat overly relaxed) assumption that the
- shift operator in this case was a mult. */
+ shift operator in this case was a mult. */
int
const_shift_operand (op, mode)
@@ -2972,7 +2971,7 @@ logical_binary_operator (x, mode)
}
}
-/* Return TRUE for shift operators. */
+/* Return TRUE for shift operators. */
int
shift_operator (x, mode)
@@ -2993,15 +2992,16 @@ shift_operator (x, mode)
}
}
-int equality_operator (x, mode)
+/* Return TRUE if x is EQ or NE. */
+int
+equality_operator (x, mode)
rtx x;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
return GET_CODE (x) == EQ || GET_CODE (x) == NE;
}
-/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
-
+/* Return TRUE for SMIN SMAX UMIN UMAX operators. */
int
minmax_operator (x, mode)
rtx x;
@@ -3015,11 +3015,8 @@ minmax_operator (x, mode)
return code == SMIN || code == SMAX || code == UMIN || code == UMAX;
}
-/* return TRUE if x is EQ or NE */
-
/* Return TRUE if this is the condition code register, if we aren't given
- a mode, accept any class CCmode register */
-
+ a mode, accept any class CCmode register. */
int
cc_register (x, mode)
rtx x;
@@ -3044,7 +3041,6 @@ cc_register (x, mode)
/* Return TRUE if this is the condition code register, if we aren't given
a mode, accept any class CCmode register which indicates a dominance
expression. */
-
int
dominant_cc_register (x, mode)
rtx x;
@@ -3145,8 +3141,7 @@ minmax_code (x)
abort ();
}
-/* Return 1 if memory locations are adjacent */
-
+/* Return 1 if memory locations are adjacent. */
int
adjacent_mem_locations (a, b)
rtx a, b;
@@ -3235,7 +3230,7 @@ load_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_DEST (elt)) != REG
|| GET_MODE (SET_DEST (elt)) != SImode
- || REGNO (SET_DEST (elt)) != dest_regno + i - base
+ || REGNO (SET_DEST (elt)) != (unsigned int)(dest_regno + i - base)
|| GET_CODE (SET_SRC (elt)) != MEM
|| GET_MODE (SET_SRC (elt)) != SImode
|| GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
@@ -3303,7 +3298,7 @@ store_multiple_operation (op, mode)
if (GET_CODE (elt) != SET
|| GET_CODE (SET_SRC (elt)) != REG
|| GET_MODE (SET_SRC (elt)) != SImode
- || REGNO (SET_SRC (elt)) != src_regno + i - base
+ || REGNO (SET_SRC (elt)) != (unsigned int)(src_regno + i - base)
|| GET_CODE (SET_DEST (elt)) != MEM
|| GET_MODE (SET_DEST (elt)) != SImode
|| GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
@@ -3379,7 +3374,7 @@ load_multiple_sequence (operands, nops, regs, base, load_offset)
}
else
{
- if (base_reg != REGNO (reg))
+ if (base_reg != (int) REGNO (reg))
/* Not addressed from the same base register. */
return 0;
@@ -3614,7 +3609,7 @@ store_multiple_sequence (operands, nops, regs, base, load_offset)
}
else
{
- if (base_reg != REGNO (reg))
+ if (base_reg != (int) REGNO (reg))
/* Not addressed from the same base register. */
return 0;
@@ -3798,8 +3793,7 @@ arm_naked_function_p (func)
return a != NULL_TREE;
}
-/* Routines for use in generating RTL */
-
+/* Routines for use in generating RTL. */
rtx
arm_gen_load_multiple (base_regno, count, from, up, write_back, unchanging_p,
in_struct_p, scalar_p)
@@ -4331,7 +4325,7 @@ arm_reload_in_hi (operands)
base = find_replacement (&XEXP (ref, 0));
}
else
- /* The slot is out of range, or was dressed up in a SUBREG */
+ /* The slot is out of range, or was dressed up in a SUBREG. */
base = reg_equiv_address[REGNO (ref)];
}
else
@@ -4348,13 +4342,13 @@ arm_reload_in_hi (operands)
}
else if (GET_CODE (base) == PLUS)
{
- /* The addend must be CONST_INT, or we would have dealt with it above */
+ /* The addend must be CONST_INT, or we would have dealt with it above. */
HOST_WIDE_INT hi, lo;
offset += INTVAL (XEXP (base, 1));
base = XEXP (base, 0);
- /* Rework the address into a legal sequence of insns */
+ /* Rework the address into a legal sequence of insns. */
/* Valid range for lo is -4095 -> 4095 */
lo = (offset >= 0
? (offset & 0xfff)
@@ -4378,7 +4372,7 @@ arm_reload_in_hi (operands)
rtx base_plus = gen_rtx_REG (SImode, REGNO (operands[2]) + 1);
/* Get the base address; addsi3 knows how to handle constants
- that require more than one insn */
+ that require more than one insn. */
emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
base = base_plus;
offset = lo;
@@ -4449,7 +4443,7 @@ arm_reload_out_hi (operands)
base = find_replacement (&XEXP (ref, 0));
}
else
- /* The slot is out of range, or was dressed up in a SUBREG */
+ /* The slot is out of range, or was dressed up in a SUBREG. */
base = reg_equiv_address[REGNO (ref)];
}
else
@@ -4494,13 +4488,13 @@ arm_reload_out_hi (operands)
}
else if (GET_CODE (base) == PLUS)
{
- /* The addend must be CONST_INT, or we would have dealt with it above */
+ /* The addend must be CONST_INT, or we would have dealt with it above. */
HOST_WIDE_INT hi, lo;
offset += INTVAL (XEXP (base, 1));
base = XEXP (base, 0);
- /* Rework the address into a legal sequence of insns */
+ /* Rework the address into a legal sequence of insns. */
/* Valid range for lo is -4095 -> 4095 */
lo = (offset >= 0
? (offset & 0xfff)
@@ -4550,7 +4544,7 @@ arm_reload_out_hi (operands)
}
/* Get the base address; addsi3 knows how to handle constants
- that require more than one insn */
+ that require more than one insn. */
emit_insn (gen_addsi3 (base_plus, base, GEN_INT (hi)));
base = base_plus;
offset = lo;
@@ -4681,7 +4675,7 @@ arm_print_value (f, x)
been inserted, the insns are then modified to reference the
relevant entry in the pool.
- Possible enhancements to the alogorithm (not implemented) are:
+ Possible enhancements to the algorithm (not implemented) are:
1) For some processors and object formats, there may be benefit in
aligning the pools to the start of cache lines; this alignment
@@ -5636,7 +5630,7 @@ arm_reorg (first)
/* If the rtx is the correct value then return the string of the number.
In this way we can ensure that valid double constants are generated even
- when cross compiling. */
+ when cross compiling. */
char *
fp_immediate_constant (x)
rtx x;
@@ -5705,13 +5699,13 @@ print_multi_reg (stream, instr, reg, mask, hat)
fprintf (stream, "}%s\n", hat ? "^" : "");
}
-/* Output a 'call' insn. */
+/* Output a 'call' insn. */
char *
output_call (operands)
rtx * operands;
{
- /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
+ /* Handle calls to lr using ip (which may be clobbered in subr anyway). */
if (REGNO (operands[0]) == LR_REGNUM)
{
@@ -5749,7 +5743,7 @@ eliminate_lr2ip (x)
}
return 0;
default:
- /* Scan through the sub-elements and change any references there */
+ /* Scan through the sub-elements and change any references there. */
fmt = GET_RTX_FORMAT (code);
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -5763,15 +5757,14 @@ eliminate_lr2ip (x)
}
}
-/* Output a 'call' insn that is a reference in memory. */
+/* Output a 'call' insn that is a reference in memory. */
char *
output_call_mem (operands)
rtx * operands;
{
- operands[0] = copy_rtx (operands[0]); /* Be ultra careful */
- /* Handle calls using lr by using ip (which may be clobbered in subr anyway).
- */
+ operands[0] = copy_rtx (operands[0]); /* Be ultra careful. */
+ /* Handle calls using lr by using ip (which may be clobbered in subr anyway). */
if (eliminate_lr2ip (&operands[0]))
output_asm_insn ("mov%?\t%|ip, %|lr", operands);
@@ -5845,7 +5838,7 @@ char *
output_mov_long_double_arm_from_arm (operands)
rtx * operands;
{
- /* We have to be careful here because the two might overlap */
+ /* We have to be careful here because the two might overlap. */
int dest_start = REGNO (operands[0]);
int src_start = REGNO (operands[1]);
rtx ops[2];
@@ -5940,7 +5933,7 @@ output_move_double (operands)
if (reg1 == IP_REGNUM)
abort ();
- /* Ensure the second source is not overwritten */
+ /* Ensure the second source is not overwritten. */
if (reg1 == reg0 + (WORDS_BIG_ENDIAN ? -1 : 1))
output_asm_insn ("mov%?\t%Q0, %Q1\n\tmov%?\t%R0, %R1", operands);
else
@@ -5993,7 +5986,7 @@ output_move_double (operands)
operands[1] = GEN_INT (ARM_SIGN_EXTEND (INTVAL (operands[1])));
}
#else
- /* Sign extend the intval into the high-order word */
+ /* Sign extend the intval into the high-order word. */
if (WORDS_BIG_ENDIAN)
{
otherops[1] = operands[1];
@@ -6015,7 +6008,7 @@ output_move_double (operands)
break;
case PRE_INC:
- abort (); /* Should never happen now */
+ abort (); /* Should never happen now. */
break;
case PRE_DEC:
@@ -6027,7 +6020,7 @@ output_move_double (operands)
break;
case POST_DEC:
- abort (); /* Should never happen now */
+ abort (); /* Should never happen now. */
break;
case LABEL_REF:
@@ -6090,7 +6083,7 @@ output_move_double (operands)
}
}
else
- abort (); /* Constraints should prevent this */
+ abort (); /* Constraints should prevent this. */
}
else if (code0 == MEM && code1 == REG)
{
@@ -6104,7 +6097,7 @@ output_move_double (operands)
break;
case PRE_INC:
- abort (); /* Should never happen now */
+ abort (); /* Should never happen now. */
break;
case PRE_DEC:
@@ -6116,7 +6109,7 @@ output_move_double (operands)
break;
case POST_DEC:
- abort (); /* Should never happen now */
+ abort (); /* Should never happen now. */
break;
case PLUS:
@@ -6179,14 +6172,15 @@ output_mov_immediate (operands)
return "";
}
- /* If all else fails, make it out of ORRs or BICs as appropriate. */
+ /* If all else fails, make it out of ORRs or BICs as appropriate. */
for (i=0; i < 32; i++)
if (n & 1 << i)
n_ones++;
- if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
- output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1, ~n);
+ if (n_ones > 16) /* Shorter to use MVN with BIC in this case. */
+ output_multi_immediate (operands, "mvn%?\t%0, %1", "bic%?\t%0, %0, %1", 1,
+ ~n);
else
output_multi_immediate (operands, "mov%?\t%0, %1", "orr%?\t%0, %0, %1", 1, n);
@@ -6239,14 +6233,14 @@ output_multi_immediate (operands, instr1, instr2, immed_op, n)
if (n == 0)
{
operands[immed_op] = const0_rtx;
- output_asm_insn (instr1, operands); /* Quick and easy output */
+ output_asm_insn (instr1, operands); /* Quick and easy output. */
}
else
{
int i;
char *instr = instr1;
- /* Note that n is never zero here (which would give no output) */
+ /* Note that n is never zero here (which would give no output). */
for (i = 0; i < 32; i += 2)
{
if (n & (3 << i))
@@ -6299,7 +6293,7 @@ arithmetic_instr (op, shift_first_arg)
for the operation code. The returned result should not be overwritten.
OP is the rtx code of the shift.
On exit, *AMOUNTP will be -1 if the shift is by a register, or a constant
- shift. */
+ shift. */
static char *
shift_op (op, amountp)
@@ -6374,8 +6368,7 @@ shift_op (op, amountp)
}
-/* Obtain the shift from the POWER of two. */
-
+/* Obtain the shift from the POWER of two. */
static HOST_WIDE_INT
int_log2 (power)
HOST_WIDE_INT power;
@@ -6481,8 +6474,7 @@ output_ascii_pseudo_op (stream, p, len)
NOTE: This code does not check for side-effect expressions in a SET_SRC:
such a check should not be needed because these only update an existing
value within a register; the register must still be set elsewhere within
- the function. */
-
+ the function. */
static int
pattern_really_clobbers_lr (x)
rtx x;
@@ -6561,7 +6553,7 @@ function_really_clobbers_lr (first)
case CALL_INSN:
/* Don't yet know how to handle those calls that are not to a
- SYMBOL_REF */
+ SYMBOL_REF. */
if (GET_CODE (PATTERN (insn)) != PARALLEL)
abort ();
@@ -6580,7 +6572,7 @@ function_really_clobbers_lr (first)
return 1;
break;
- default: /* Don't recognize it, be safe */
+ default: /* Don't recognize it, be safe. */
return 1;
}
@@ -6594,7 +6586,7 @@ function_really_clobbers_lr (first)
if ((next = next_nonnote_insn (insn)) == NULL)
return 1;
- /* No need to worry about lr if the call never returns */
+ /* No need to worry about lr if the call never returns. */
if (GET_CODE (next) == BARRIER)
break;
@@ -6617,7 +6609,7 @@ function_really_clobbers_lr (first)
}
}
- /* We have reached the end of the chain so lr was _not_ clobbered */
+ /* We have reached the end of the chain so lr was _not_ clobbered. */
return 0;
}
@@ -6629,8 +6621,7 @@ output_return_instruction (operand, really_return, reverse)
{
char instr[100];
int reg, live_regs = 0;
- int volatile_func = (optimize > 0
- && TREE_THIS_VOLATILE (current_function_decl));
+ int volatile_func = arm_volatile_func ();
/* If a function is naked, don't use the "return" insn. */
if (arm_naked_function_p (current_function_decl))
@@ -6782,12 +6773,13 @@ output_return_instruction (operand, really_return, reverse)
Such functions never return, and many memory cycles can be saved
by not storing register values that will never be needed again.
This optimization was added to speed up context switching in a
- kernel application. */
-
+ kernel application. */
int
arm_volatile_func ()
{
- return (optimize > 0 && TREE_THIS_VOLATILE (current_function_decl));
+ return (optimize > 0
+ && current_function_nothrow
+ && TREE_THIS_VOLATILE (current_function_decl));
}
/* Write the function name into the code section, directly preceding
@@ -6842,23 +6834,21 @@ arm_poke_function_name (stream, name)
no stack frame requirement and no live registers execpt for `lr'. If we
can guarantee that by making all function calls into tail calls and that
lr is not clobbered in any other way, then there is no need to push lr
- onto the stack. */
-
+ onto the stack. */
void
output_arm_prologue (f, frame_size)
FILE * f;
int frame_size;
{
int reg, live_regs_mask = 0;
- int volatile_func = (optimize > 0
- && TREE_THIS_VOLATILE (current_function_decl));
+ int volatile_func = arm_volatile_func ();
/* Nonzero if we must stuff some register arguments onto the stack as if
they were passed there. */
int store_arg_regs = 0;
if (arm_ccfsm_state || arm_target_insn)
- abort (); /* Sanity check */
+ abort (); /* Sanity check. */
if (arm_naked_function_p (current_function_decl))
return;
@@ -6906,11 +6896,10 @@ output_arm_prologue (f, frame_size)
if (live_regs_mask)
{
- /* if a di mode load/store multiple is used, and the base register
+ /* If a di mode load/store multiple is used, and the base register
is r3, then r4 can become an ever live register without lr
doing so, in this case we need to push lr as well, or we
- will fail to get a proper return. */
-
+ will fail to get a proper return. */
live_regs_mask |= 1 << LR_REGNUM;
lr_save_eliminated = 0;
@@ -6930,7 +6919,7 @@ arm_output_epilogue ()
{
int reg;
int live_regs_mask = 0;
- /* If we need this, then it will always be at least this much */
+ /* If we need this, then it will always be at least this much. */
int floats_offset = 12;
rtx operands[3];
int frame_size = get_frame_size ();
@@ -7009,7 +6998,7 @@ arm_output_epilogue ()
{
floats_offset += 12;
- /* We can't unstack more than four registers at once */
+ /* We can't unstack more than four registers at once. */
if (start_reg - reg == 3)
{
asm_fprintf (f, "\tlfm\t%r, 4, [%r, #-%d]\n",
@@ -7185,7 +7174,7 @@ arm_output_epilogue ()
if (current_function_pretend_args_size)
{
- /* Unwind the pre-pushed regs */
+ /* Unwind the pre-pushed regs. */
operands[0] = operands[1] = stack_pointer_rtx;
operands[2] = GEN_INT (current_function_pretend_args_size);
output_add_immediate (operands);
@@ -7195,7 +7184,7 @@ arm_output_epilogue ()
asm_fprintf (f, "\tadd\t%r, %r, %r\n", SP_REGNUM, SP_REGNUM,
REGNO (eh_ofs));
- /* And finally, go home */
+ /* And finally, go home. */
if (TARGET_INTERWORK)
asm_fprintf (f, "\tbx\t%r\n", return_regnum);
else if (TARGET_APCS_32 || eh_ofs)
@@ -7237,7 +7226,6 @@ output_func_epilogue (frame_size)
Unfortunately, since this insn does not reflect very well the actual
semantics of the operation, we need to annotate the insn for the benefit
of DWARF2 frame unwind information. */
-
static rtx
emit_multi_reg_push (mask)
int mask;
@@ -7373,8 +7361,7 @@ arm_expand_prologue ()
int store_arg_regs = 0;
/* If this function doesn't return, then there is no need to push
the call-saved regs. */
- int volatile_func = (optimize > 0
- && TREE_THIS_VOLATILE (current_function_decl));
+ int volatile_func = arm_volatile_func ();
rtx insn;
/* Naked functions don't have prologues. */
@@ -7691,7 +7678,7 @@ arm_print_operand (stream, x, code)
else if (GET_CODE (x) == CONST_DOUBLE)
fprintf (stream, "#%s", fp_immediate_constant (x));
else if (GET_CODE (x) == NEG)
- abort (); /* This should never happen now. */
+ abort (); /* This should never happen now. */
else
{
fputc ('#', stream);
@@ -7861,7 +7848,7 @@ arm_final_prescan_insn (insn)
out what the conditions are when the jump isn't taken. */
int jump_clobbers = 0;
- /* If we start with a return insn, we only succeed if we find another one. */
+ /* If we start with a return insn, we only succeed if we find another one. */
int seeking_return = 0;
/* START_INSN will hold the insn from where we start looking. This is the
@@ -8017,7 +8004,7 @@ arm_final_prescan_insn (insn)
/* Succeed if the following insn is the target label.
Otherwise fail.
If return insns are used then the last insn in a function
- will be a barrier. */
+ will be a barrier. */
this_insn = next_nonnote_insn (this_insn);
if (this_insn && this_insn == label)
{
@@ -9746,7 +9733,7 @@ arm_strip_name_encoding (const char * name)
}
#ifdef AOF_ASSEMBLER
-/* Special functions only needed when producing AOF syntax assembler. */
+/* Special functions only needed when producing AOF syntax assembler. */
rtx aof_pic_label = NULL_RTX;
struct pic_chain
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 126daa90359..268f1c58d7d 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -268,7 +268,6 @@ Unrecognized value in TARGET_CPU_DEFAULT.
#ifndef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC ""
#endif
-
/* Run-time Target Specification. */
#ifndef TARGET_VERSION
@@ -2582,7 +2581,7 @@ extern int making_const_table;
fprintf (STREAM, "\t.thumb_func\n") ; \
} \
if (TARGET_POKE_FUNCTION_NAME) \
- arm_poke_function_name (STREAM, NAME); \
+ arm_poke_function_name (STREAM, (char *) NAME); \
} \
while (0)
@@ -2777,7 +2776,7 @@ extern int making_const_table;
do \
{ \
int mi_delta = (DELTA); \
- const char *mi_op = mi_delta < 0 ? "sub" : "add"; \
+ const char * mi_op = mi_delta < 0 ? "sub" : "add"; \
int shift = 0; \
int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (FUNCTION))) \
? 1 : 0); \
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index e3e8b436621..f357d67e4d1 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA. */
" %{mapcs-26:-m armelf_linux26} %{!mapcs-26:-m armelf_linux} -p"
# endif
# define SUBTARGET_EXTRA_ASM_SPEC \
- " %{!mapcs-26:-mapcs-32}"
+ " %{mapcs-26:-mapcs-26} %{!mapcs-26:-mapcs-32}"
# define MULTILIB_DEFAULTS \
{ "marm", "mlittle-endian", "mhard-float", "mapcs-32", "mno-thumb-interwork" }
# define CPP_APCS_PC_DEFAULT_SPEC "-D__APCS_32__"
@@ -50,7 +50,7 @@ Boston, MA 02111-1307, USA. */
" %{mapcs-32:-m armelf_linux} %{!mapcs-32:-m armelf_linux26} -p"
# endif
# define SUBTARGET_EXTRA_ASM_SPEC \
- " %{!mapcs-32:-mapcs-26}"
+ " %{mapcs-32:-mapcs-32} %{!mapcs-32:-mapcs-26}"
# define MULTILIB_DEFAULTS \
{ "marm", "mlittle-endian", "mhard-float", "mapcs-26", "mno-thumb-interwork" }
#endif
diff --git a/gcc/config/c4x/c4x.c b/gcc/config/c4x/c4x.c
index 3ee934c08b5..9972f472f68 100644
--- a/gcc/config/c4x/c4x.c
+++ b/gcc/config/c4x/c4x.c
@@ -603,6 +603,11 @@ c4x_function_arg (cum, mode, type, named)
cum->init = 1;
}
+ /* This marks the last argument. We don't need to pass this through
+ to the call insn. */
+ if (type == void_type_node)
+ return 0;
+
if (! TARGET_MEMPARM
&& named
&& type
@@ -742,7 +747,8 @@ c4x_assembler_function_p ()
tree type;
type = TREE_TYPE (current_function_decl);
- return lookup_attribute ("assembler", TYPE_ATTRIBUTES (type)) != NULL;
+ return (lookup_attribute ("assembler", TYPE_ATTRIBUTES (type)) != NULL)
+ || (lookup_attribute ("naked", TYPE_ATTRIBUTES (type)) != NULL);
}
diff --git a/gcc/config/clipper/clipper.h b/gcc/config/clipper/clipper.h
index 4720f869fc7..93e674dcb8f 100644
--- a/gcc/config/clipper/clipper.h
+++ b/gcc/config/clipper/clipper.h
@@ -368,7 +368,7 @@ enum reg_class { NO_REGS, GENERAL_REGS, FLOAT_REGS, ALL_REGS, LIM_REG_CLASSES};
/* we can't set this for clipper as library calls may have 3 args and we pass
only 2 args in regs. */
-/* #define ACCUMULATE_OUTGOING_ARGS */
+/* #define ACCUMULATE_OUTGOING_ARGS 1*/
/* Offset of first parameter from the argument pointer register value.
diff --git a/gcc/config/convex/fixinc.convex b/gcc/config/convex/fixinc.convex
index 0dc5f302c8c..c14dcd42b03 100644
--- a/gcc/config/convex/fixinc.convex
+++ b/gcc/config/convex/fixinc.convex
@@ -15,7 +15,7 @@ sed 's/^@//' > "include/limits.h" <<'@//E*O*F include/limits.h//'
#ifndef _LIMITS_H
#define _LIMITS_H
-#include_next <limits.h>
+ #include_next <limits.h>
/* Minimum and maximum values a `char' can hold. */
#ifdef __CHAR_UNSIGNED__
@@ -34,7 +34,7 @@ sed 's/^@//' > "include/math.h" <<'@//E*O*F include/math.h//'
#ifndef _MATH_H
#define _MATH_H
-#include_next <math.h>
+ #include_next <math.h>
#undef HUGE_VAL
@@ -386,7 +386,7 @@ typedef __WCHAR_TYPE__ wchar_t;
#endif /* __WCHAR_T */
-#include_next <stddef.h>
+ #include_next <stddef.h>
#endif /* _STDDEF_H */
@//E*O*F include/stddef.h//
@@ -400,12 +400,12 @@ sed 's/^@//' > "include/stdlib.h" <<'@//E*O*F include/stdlib.h//'
#if _CONVEX_SOURCE
#define alloca __non_builtin_alloca
-#include_next <stdlib.h>
+ #include_next <stdlib.h>
#undef alloca
#else
-#include_next <stdlib.h>
+ #include_next <stdlib.h>
#endif /* _CONVEX_SOURCE */
diff --git a/gcc/config/dsp16xx/dsp16xx.h b/gcc/config/dsp16xx/dsp16xx.h
index 51d66c60439..ce2016e2e0f 100644
--- a/gcc/config/dsp16xx/dsp16xx.h
+++ b/gcc/config/dsp16xx/dsp16xx.h
@@ -1071,7 +1071,7 @@ extern struct dsp16xx_frame_info current_frame_info;
It is not proper to define both 'PUSH_ROUNDING' and
'ACCUMULATE_OUTGOING_ARGS'. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset of first parameter from the argument pointer
register value. */
diff --git a/gcc/config/fr30/fr30.h b/gcc/config/fr30/fr30.h
index b7ea8b2239e..4d934bab7c0 100644
--- a/gcc/config/fr30/fr30.h
+++ b/gcc/config/fr30/fr30.h
@@ -837,7 +837,7 @@ enum reg_class
Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
proper. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* A C expression that should indicate the number of bytes of its own arguments
that a function pops on returning, or 0 if the function pops no arguments
diff --git a/gcc/config/i370/i370.h b/gcc/config/i370/i370.h
index 8ff7a6c96e1..08ac64484ce 100644
--- a/gcc/config/i370/i370.h
+++ b/gcc/config/i370/i370.h
@@ -520,7 +520,7 @@ enum reg_class
/* Accumulate the outgoing argument count so we can request the right
DSA size and determine stack offset. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Define offset from stack pointer, to location where a parm can be
pushed. */
diff --git a/gcc/config/i386/att.h b/gcc/config/i386/att.h
index e5c2d9c7e99..b98948e2bf2 100644
--- a/gcc/config/i386/att.h
+++ b/gcc/config/i386/att.h
@@ -71,6 +71,10 @@ do \
/* Define the syntax of labels and symbol definitions/declarations. */
+/* The prefix to add for compiler private assembler symbols. */
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "."
+
/* This is how to store into the string BUF
the symbol_ref name of an internal numbered label where
PREFIX is the class of label and NUM is the number within the class.
@@ -78,14 +82,14 @@ do \
#undef ASM_GENERATE_INTERNAL_LABEL
#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \
- sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER))
+ sprintf ((BUF), "%s%s%d", LOCAL_LABEL_PREFIX, (PREFIX), (NUMBER))
/* This is how to output an internal numbered label where
PREFIX is the class of label and NUM is the number within the class. */
#undef ASM_OUTPUT_INTERNAL_LABEL
#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- fprintf (FILE, ".%s%d:\n", PREFIX, NUM)
+ fprintf (FILE, "%s%s%d:\n", LOCAL_LABEL_PREFIX, PREFIX, NUM)
/* The prefix to add to user-visible assembler symbols. */
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index f98a45bcadb..23591c54784 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -87,7 +87,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "-remap %(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
-imacros %s../include/sys/version.h"
-+
+
/* 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.
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 81afd7b6469..d73fc5ef99d 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -96,6 +96,7 @@ extern void ix86_expand_unary_operator PARAMS ((enum rtx_code, enum machine_mode
rtx[]));
extern int ix86_unary_operator_ok PARAMS ((enum rtx_code, enum machine_mode,
rtx[]));
+extern int ix86_match_ccmode PARAMS ((rtx, enum machine_mode));
extern void ix86_expand_branch PARAMS ((enum rtx_code, int, rtx));
extern int ix86_expand_setcc PARAMS ((enum rtx_code, int, rtx));
extern int ix86_expand_int_movcc PARAMS ((rtx[]));
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9fc4425eba1..9eb13ea3559 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1373,7 +1373,7 @@ memory_displacement_operand (op, mode)
return parts.disp != NULL_RTX;
}
-/* To avoid problems when jump re-emits comparisons like testqi_ext_0,
+/* To avoid problems when jump re-emits comparisons like testqi_ext_ccno_0,
re-recognize the operand to avoid a copy_to_mode_reg that will fail.
??? It seems likely that this will only work because cmpsi is an
@@ -1449,12 +1449,12 @@ aligned_operand (op, mode)
if (parts.index)
{
if (parts.scale < 4
- && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 4)
+ && REGNO_POINTER_ALIGN (REGNO (parts.index)) < 32)
return 0;
}
if (parts.base)
{
- if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 4)
+ if (REGNO_POINTER_ALIGN (REGNO (parts.base)) < 32)
return 0;
}
if (parts.disp)
@@ -1797,6 +1797,9 @@ ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2)
offset += nregs * UNITS_PER_WORD;
+ if (ACCUMULATE_OUTGOING_ARGS)
+ total_size += current_function_outgoing_args_size;
+
total_size += offset;
/* Align start of frame for local function. */
@@ -1808,6 +1811,9 @@ ix86_compute_frame_size (size, nregs_on_stack, rpadding1, rpadding2)
padding2 = ((total_size + preferred_alignment - 1)
& -preferred_alignment) - total_size;
+ if (ACCUMULATE_OUTGOING_ARGS)
+ padding2 += current_function_outgoing_args_size;
+
if (nregs_on_stack)
*nregs_on_stack = nregs;
if (rpadding1)
@@ -3103,12 +3109,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:
- putc ('b', file);
- return;
-
case 2:
- putc ('w', file);
+#ifdef HAVE_GAS_FILDS_FISTS
+ putc ('s', file);
+#endif
return;
case 4:
@@ -3138,6 +3142,9 @@ print_operand (file, x, code)
else
putc ('l', file);
return;
+
+ default:
+ abort ();
}
case 'b':
@@ -3434,15 +3441,39 @@ split_di (operands, num, lo_half, hi_half)
There is no guarantee that the operands are the same mode, as they
might be within FLOAT or FLOAT_EXTEND expressions. */
+#ifndef SYSV386_COMPAT
+/* Set to 1 for compatibility with brain-damaged assemblers. No-one
+ wants to fix the assemblers because that causes incompatibility
+ with gcc. No-one wants to fix gcc because that causes
+ incompatibility with assemblers... You can use the option of
+ -DSYSV386_COMPAT=0 if you recompile both gcc and gas this way. */
+#define SYSV386_COMPAT 1
+#endif
+
const char *
output_387_binary_op (insn, operands)
rtx insn;
rtx *operands;
{
- static char buf[100];
- rtx temp;
+ static char buf[30];
const char *p;
+#ifdef ENABLE_CHECKING
+ /* Even if we do not want to check the inputs, this documents input
+ constraints. Which helps in understanding the following code. */
+ if (STACK_REG_P (operands[0])
+ && ((REG_P (operands[1])
+ && REGNO (operands[0]) == REGNO (operands[1])
+ && (STACK_REG_P (operands[2]) || GET_CODE (operands[2]) == MEM))
+ || (REG_P (operands[2])
+ && REGNO (operands[0]) == REGNO (operands[2])
+ && (STACK_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)))
+ && (STACK_TOP_P (operands[1]) || STACK_TOP_P (operands[2])))
+ ; /* ok */
+ else
+ abort ();
+#endif
+
switch (GET_CODE (operands[3]))
{
case PLUS:
@@ -3489,11 +3520,13 @@ output_387_binary_op (insn, operands)
case PLUS:
if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2]))
{
- temp = operands[2];
+ rtx temp = operands[2];
operands[2] = operands[1];
operands[1] = temp;
}
+ /* know operands[0] == operands[1]. */
+
if (GET_CODE (operands[2]) == MEM)
{
p = "%z2\t%2";
@@ -3503,16 +3536,23 @@ output_387_binary_op (insn, operands)
if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
{
if (STACK_TOP_P (operands[0]))
- p = "p\t{%0,%2|%2, %0}";
+ /* How is it that we are storing to a dead operand[2]?
+ Well, presumably operands[1] is dead too. We can't
+ store the result to st(0) as st(0) gets popped on this
+ instruction. Instead store to operands[2] (which I
+ think has to be st(1)). st(1) will be popped later.
+ gcc <= 2.8.1 didn't have this check and generated
+ assembly code that the Unixware assembler rejected. */
+ p = "p\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
else
- p = "p\t{%2,%0|%0, %2}";
+ p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
break;
}
if (STACK_TOP_P (operands[0]))
- p = "\t{%y2,%0|%0, %y2}";
+ p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
else
- p = "\t{%2,%0|%0, %2}";
+ p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
break;
case MINUS:
@@ -3529,42 +3569,69 @@ output_387_binary_op (insn, operands)
break;
}
- if (! STACK_REG_P (operands[1]) || ! STACK_REG_P (operands[2]))
- abort ();
-
- /* Note that the Unixware assembler, and the AT&T assembler before
- that, are confusingly not reversed from Intel syntax in this
- area. */
if (find_regno_note (insn, REG_DEAD, REGNO (operands[2])))
{
+#if SYSV386_COMPAT
+ /* The SystemV/386 SVR3.2 assembler, and probably all AT&T
+ derived assemblers, confusingly reverse the direction of
+ the operation for fsub{r} and fdiv{r} when the
+ destination register is not st(0). The Intel assembler
+ doesn't have this brain damage. Read !SYSV386_COMPAT to
+ figure out what the hardware really does. */
if (STACK_TOP_P (operands[0]))
- p = "p\t%0,%2";
+ p = "{p\t%0, %2|rp\t%2, %0}";
else
- p = "rp\t%2,%0";
+ p = "{rp\t%2, %0|p\t%0, %2}";
+#else
+ if (STACK_TOP_P (operands[0]))
+ /* As above for fmul/fadd, we can't store to st(0). */
+ p = "rp\t{%0, %2|%2, %0}"; /* st(1) = st(0) op st(1); pop */
+ else
+ p = "p\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0); pop */
+#endif
break;
}
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
{
+#if SYSV386_COMPAT
if (STACK_TOP_P (operands[0]))
- p = "rp\t%0,%1";
+ p = "{rp\t%0, %1|p\t%1, %0}";
else
- p = "p\t%1,%0";
+ p = "{p\t%1, %0|rp\t%0, %1}";
+#else
+ if (STACK_TOP_P (operands[0]))
+ p = "p\t{%0, %1|%1, %0}"; /* st(1) = st(1) op st(0); pop */
+ else
+ p = "rp\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2); pop */
+#endif
break;
}
if (STACK_TOP_P (operands[0]))
{
if (STACK_TOP_P (operands[1]))
- p = "\t%y2,%0";
+ p = "\t{%y2, %0|%0, %y2}"; /* st(0) = st(0) op st(r2) */
else
- p = "r\t%y1,%0";
+ p = "r\t{%y1, %0|%0, %y1}"; /* st(0) = st(r1) op st(0) */
break;
}
else if (STACK_TOP_P (operands[1]))
- p = "\t%1,%0";
+ {
+#if SYSV386_COMPAT
+ p = "{\t%1, %0|r\t%0, %1}";
+#else
+ p = "r\t{%1, %0|%0, %1}"; /* st(r2) = st(0) op st(r2) */
+#endif
+ }
else
- p = "r\t%2,%0";
+ {
+#if SYSV386_COMPAT
+ p = "{r\t%2, %0|\t%0, %2}";
+#else
+ p = "\t{%2, %0|%0, %2}"; /* st(r1) = st(r1) op st(0) */
+#endif
+ }
break;
default:
@@ -3628,7 +3695,7 @@ output_fix_trunc (insn, operands)
output_asm_insn ("mov{l}\t{%3, %1|%1, %3}", xops);
}
else
- output_asm_insn ("mov{l}\t{%3,%0|%0, %3}", operands);
+ output_asm_insn ("mov{l}\t{%3, %0|%0, %3}", operands);
}
return "";
@@ -4252,6 +4319,45 @@ ix86_unary_operator_ok (code, mode, operands)
return TRUE;
}
+/* Return TRUE or FALSE depending on whether the first SET in INSN
+ has source and destination with matching CC modes, and that the
+ CC mode is at least as constrained as REQ_MODE. */
+
+int
+ix86_match_ccmode (insn, req_mode)
+ rtx insn;
+ enum machine_mode req_mode;
+{
+ rtx set;
+ enum machine_mode set_mode;
+
+ set = PATTERN (insn);
+ if (GET_CODE (set) == PARALLEL)
+ set = XVECEXP (set, 0, 0);
+ if (GET_CODE (set) != SET)
+ abort ();
+
+ set_mode = GET_MODE (SET_DEST (set));
+ switch (set_mode)
+ {
+ case CCmode:
+ if (req_mode == CCNOmode)
+ return 0;
+ /* FALLTHRU */
+ case CCNOmode:
+ if (req_mode == CCZmode)
+ return 0;
+ /* FALLTHRU */
+ case CCZmode:
+ break;
+
+ default:
+ abort ();
+ }
+
+ return (GET_MODE (SET_SRC (set)) == set_mode);
+}
+
/* Produce an unsigned comparison for a given signed comparison. */
static enum rtx_code
@@ -4455,7 +4561,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
abort ();
}
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (mask)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (mask)));
intcmp_mode = CCNOmode;
}
}
@@ -4470,7 +4576,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
switch (code)
{
case GT:
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x45)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x45)));
code = EQ;
break;
case LT:
@@ -4480,7 +4586,7 @@ ix86_expand_fp_compare (code, op0, op1, unordered)
code = EQ;
break;
case GE:
- emit_insn (gen_testqi_ext_0 (tmp, GEN_INT (0x05)));
+ emit_insn (gen_testqi_ext_ccno_0 (tmp, GEN_INT (0x05)));
code = EQ;
break;
case LE:
@@ -5490,7 +5596,8 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
rtx align_4_label = gen_label_rtx ();
rtx end_0_label = gen_label_rtx ();
rtx mem;
- rtx flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ rtx no_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ rtx z_flags = gen_rtx_REG (CCNOmode, FLAGS_REG);
rtx tmpreg = gen_reg_rtx (SImode);
align = 0;
@@ -5512,25 +5619,25 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (3),
NULL_RTX, 0, OPTAB_WIDEN);
- emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
+ emit_insn (gen_cmpsi_ccz_1 (align_rtx, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_4_label),
pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- emit_insn (gen_cmpsi_1 (align_rtx, GEN_INT (2)));
+ emit_insn (gen_cmpsi_ccno_1 (align_rtx, GEN_INT (2)));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, no_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_2_label),
pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
- tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_GTU (VOIDmode, no_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_3_label),
@@ -5545,9 +5652,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
align_rtx = expand_binop (SImode, and_optab, scratch, GEN_INT (2),
NULL_RTX, 0, OPTAB_WIDEN);
- emit_insn (gen_cmpsi_0 (align_rtx, const0_rtx));
+ emit_insn (gen_cmpsi_ccz_1 (align_rtx, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
align_4_label),
@@ -5560,9 +5667,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
/* Now compare the bytes. */
/* Compare the first n unaligned byte on a byte per byte basis. */
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, end_0_label),
pc_rtx);
@@ -5576,9 +5683,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
{
emit_label (align_2_label);
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode,
end_0_label),
@@ -5590,9 +5697,9 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
emit_label (align_3_label);
}
- emit_insn (gen_cmpqi_0 (mem, const0_rtx));
+ emit_insn (gen_cmpqi_ccz_1 (mem, const0_rtx));
- tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
+ tmp = gen_rtx_EQ (VOIDmode, z_flags, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, end_0_label),
pc_rtx);
@@ -5626,7 +5733,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
emit_insn (gen_lshrsi3 (reg, reg, GEN_INT (16)));
/* If zero is not in the first two bytes, move two bytes forward. */
- emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
+ emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
emit_insn (gen_rtx_SET (VOIDmode, tmpreg,
@@ -5650,7 +5757,7 @@ ix86_expand_strlensi_unroll_1 (out, align_rtx, scratch)
rtx end_2_label = gen_label_rtx ();
/* Is zero in the first two bytes? */
- emit_insn (gen_testsi_1 (tmpreg, GEN_INT (0x8080)));
+ emit_insn (gen_testsi_ccno_1 (tmpreg, GEN_INT (0x8080)));
tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
tmp = gen_rtx_NE (VOIDmode, tmp, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 2b81e8c0628..d73e7b0c65c 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -100,6 +100,8 @@ extern int target_flags;
#define MASK_STACK_PROBE 0x00000100 /* Enable stack probing */
#define MASK_NO_ALIGN_STROPS 0x00001000 /* Enable aligning of string ops. */
#define MASK_INLINE_ALL_STROPS 0x00002000 /* Inline stringops in all cases */
+#define MASK_NO_PUSH_ARGS 0x00004000 /* Use push instructions */
+#define MASK_ACCUMULATE_OUTGOING_ARGS 0x00008000/* Accumulate outgoing args */
/* Temporary codegen switches */
#define MASK_INTEL_SYNTAX 0x00000200
@@ -119,6 +121,13 @@ extern int target_flags;
faster code on the pentium. */
#define TARGET_ALIGN_DOUBLE (target_flags & MASK_ALIGN_DOUBLE)
+/* Use push instructions to save outgoing args. */
+#define TARGET_PUSH_ARGS (!(target_flags & MASK_NO_PUSH_ARGS))
+
+/* Accumulate stack adjustments to prologue/epilogue. */
+#define TARGET_ACCUMULATE_OUTGOING_ARGS \
+ (target_flags & MASK_ACCUMULATE_OUTGOING_ARGS)
+
/* Put uninitialized locals into bss, not data.
Meaningful only on svr3. */
#define TARGET_SVR3_SHLIB (target_flags & MASK_SVR3_SHLIB)
@@ -254,6 +263,14 @@ extern const int x86_promote_hi_regs;
"Inline all known string operations" }, \
{ "no-inline-all-stringops", -MASK_INLINE_ALL_STROPS, \
"Do not inline all known string operations" }, \
+ { "push-args", -MASK_NO_PUSH_ARGS, \
+ "Use push instructions to save outgoing arguments" }, \
+ { "no-push-args", MASK_NO_PUSH_ARGS, \
+ "Do not use push instructions to save outgoing arguments" }, \
+ { "accumulate-outgoing-args", MASK_ACCUMULATE_OUTGOING_ARGS, \
+ "Use push instructions to save outgoing arguments" }, \
+ { "no-accumulate-outgoing-args",-MASK_ACCUMULATE_OUTGOING_ARGS, \
+ "Do not use push instructions to save outgoing arguments" }, \
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT, 0 }}
@@ -1136,6 +1153,19 @@ enum reg_class
#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & (-2))
+/* If defined, the maximum amount of space required for outgoing arguments will
+ be computed and placed into the variable
+ `current_function_outgoing_args_size'. No space will be pushed onto the
+ stack for each call; instead, the function prologue should increase the stack
+ frame size by this amount. */
+
+#define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
+
+/* If defined, a C expression whose value is nonzero when we want to use PUSH
+ instructions to pass outgoing arguments. */
+
+#define PUSH_ARGS (TARGET_PUSH_ARGS && !ACCUMULATE_OUTGOING_ARGS)
+
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) 0
@@ -1180,7 +1210,7 @@ enum reg_class
#define APPLY_RESULT_SIZE (8+108)
/* 1 if N is a possible register number for function argument passing. */
-#define FUNCTION_ARG_REGNO_P(N) ((N) >= 0 && (N) < REGPARM_MAX)
+#define FUNCTION_ARG_REGNO_P(N) ((N) < REGPARM_MAX)
/* Define a data type for recording info about an argument list
during the scan of that argument list. This data type should
@@ -2160,10 +2190,13 @@ while (0)
Add CCNO to indicate No Overflow, which is often also includes
No Carry. This is typically used on the output of logicals,
- and is only valid in comparisons against zero. */
+ and is only valid in comparisons against zero.
+
+ Add CCZ to indicate that only the Zero flag is valid. */
#define EXTRA_CC_MODES \
CC(CCNOmode, "CCNO") \
+ CC(CCZmode, "CCZ") \
CC(CCFPmode, "CCFP") \
CC(CCFPUmode, "CCFPU")
@@ -2173,7 +2206,7 @@ while (0)
For floating-point equality comparisons, CCFPEQmode should be used.
VOIDmode should be used in all other cases.
- For integer comparisons against zero, reduce to CCNOmode if
+ For integer comparisons against zero, reduce to CCNOmode or CCZmode if
possible, to allow for more combinations. */
#define SELECT_CC_MODE(OP,X,Y) \
@@ -2181,7 +2214,7 @@ while (0)
? (OP) == EQ || (OP) == NE ? CCFPUmode : CCFPmode \
: (OP) == LE || (OP) == GT ? CCmode \
: (Y) != const0_rtx ? CCmode \
- : CCNOmode)
+ : (OP) == EQ || (OP) == NE ? CCZmode : CCNOmode)
/* Control the assembler format that we output, to the extent
this does not vary between assemblers. */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b188d915f31..dc24d5f6d4c 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -911,7 +911,17 @@
DONE;
}")
-(define_insn "cmpsi_0"
+(define_insn "cmpsi_ccz_1"
+ [(set (reg:CCZ 17)
+ (compare:CCZ (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
+ (match_operand:SI 1 "const0_operand" "n,n")))]
+ ""
+ "@
+ test{l}\\t{%0, %0|%0, %0}
+ cmp{l}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "icmp")])
+
+(define_insn "cmpsi_ccno_1"
[(set (reg:CCNO 17)
(compare:CCNO (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
(match_operand:SI 1 "const0_operand" "n,n")))]
@@ -929,17 +939,17 @@
"cmp{l}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")])
-(define_insn "cmphi_0"
- [(set (reg:CCNO 17)
- (compare:CCNO (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
- (match_operand:HI 1 "const0_operand" "n,n")))]
- ""
+(define_insn "*cmphi_0"
+ [(set (reg 17)
+ (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
+ (match_operand:HI 1 "const0_operand" "n,n")))]
+ "ix86_match_ccmode (insn, CCNOmode)"
"@
test{w}\\t{%0, %0|%0, %0}
cmp{w}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")])
-(define_insn "cmphi_1"
+(define_insn "*cmphi_1"
[(set (reg:CC 17)
(compare:CC (match_operand:HI 0 "nonimmediate_operand" "rm,r")
(match_operand:HI 1 "general_operand" "ri,mr")))]
@@ -947,7 +957,17 @@
"cmp{w}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")])
-(define_insn "cmpqi_0"
+(define_insn "cmpqi_ccz_1"
+ [(set (reg:CCZ 17)
+ (compare:CCZ (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
+ (match_operand:QI 1 "const0_operand" "n,n")))]
+ ""
+ "@
+ test{b}\\t{%0, %0|%0, %0}
+ cmp{b}\\t{$0, %0|%0, 0}"
+ [(set_attr "type" "icmp")])
+
+(define_insn "*cmpqi_ccno_1"
[(set (reg:CCNO 17)
(compare:CCNO (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
(match_operand:QI 1 "const0_operand" "n,n")))]
@@ -957,7 +977,7 @@
cmp{b}\\t{$0, %0|%0, 0}"
[(set_attr "type" "icmp")])
-(define_insn "cmpqi_1"
+(define_insn "*cmpqi_1"
[(set (reg:CC 17)
(compare:CC (match_operand:QI 0 "nonimmediate_operand" "qm,q")
(match_operand:QI 1 "general_operand" "qi,mq")))]
@@ -979,15 +999,15 @@
[(set_attr "type" "icmp")])
(define_insn "*cmpqi_ext_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(subreg:QI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "q")
(const_int 8)
(const_int 8)) 0)
(match_operand:QI 1 "const0_operand" "n")))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
"test{b}\\t%h0, %h0"
[(set_attr "type" "icmp")])
@@ -3115,6 +3135,16 @@
;; Even though we only accept memory inputs, the backend _really_
;; wants to be able to do this between registers.
+(define_insn "floathisf2"
+ [(set (match_operand:SF 0 "register_operand" "=f,f")
+ (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "fp_int_src" "true")])
+
(define_insn "floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
@@ -3135,6 +3165,16 @@
[(set_attr "type" "fmov,multi")
(set_attr "fp_int_src" "true")])
+(define_insn "floathidf2"
+ [(set (match_operand:DF 0 "register_operand" "=f,f")
+ (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "fp_int_src" "true")])
+
(define_insn "floatsidf2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
@@ -3155,6 +3195,16 @@
[(set_attr "type" "fmov,multi")
(set_attr "fp_int_src" "true")])
+(define_insn "floathixf2"
+ [(set (match_operand:XF 0 "register_operand" "=f,f")
+ (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "fp_int_src" "true")])
+
(define_insn "floatsixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
@@ -3178,6 +3228,16 @@
;; %%% Kill these when reload knows how to do it.
(define_split
[(set (match_operand 0 "register_operand" "")
+ (float (match_operand:HI 1 "register_operand" "")))]
+ "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
+ [(set (mem:HI (pre_dec:SI (reg:SI 7))) (match_dup 1))
+ (set (match_dup 0) (match_dup 2))
+ (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 2)))]
+ "operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]),
+ gen_rtx_MEM (HImode, stack_pointer_rtx));")
+
+(define_split
+ [(set (match_operand 0 "register_operand" "")
(float (match_operand:SI 1 "register_operand" "")))]
"reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
[(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
@@ -3347,14 +3407,15 @@
"")
(define_insn "*addsi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
(match_operand:SI 2 "general_operand" "rmni,rni"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
(plus:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, SImode, operands)
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (PLUS, SImode, operands)
/* Current assemblers are broken and do not allow @GOTOFF in
ought but a memory context. */
&& ! pic_symbolic_operand (operands[2], VOIDmode)"
@@ -3458,14 +3519,15 @@
(const_string "alu")))])
(define_insn "*addhi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
(match_operand:HI 2 "general_operand" "rmni,rni"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
(plus:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (PLUS, HImode, operands)"
"*
{
switch (get_attr_type (insn))
@@ -3564,14 +3626,15 @@
(const_string "alu")))])
(define_insn "*addqi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qmni,qni"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
(plus:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (PLUS, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (PLUS, QImode, operands)"
"*
{
switch (get_attr_type (insn))
@@ -3784,26 +3847,15 @@
[(set_attr "type" "alu")])
(define_insn "*subsi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
(match_operand:SI 2 "general_operand" "ri,rm"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
(minus:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, SImode, operands)"
- "sub{l}\\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")])
-
-(define_insn "*subsi_3"
- [(set (reg:CC 17)
- (compare:CC
- (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
- (match_operand:SI 2 "general_operand" "ri,rm"))
- (const_int 0)))
- (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
- (minus:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, SImode, operands)"
+ "ix86_match_ccmode (insn, CCmode)
+ && ix86_binary_operator_ok (MINUS, SImode, operands)"
"sub{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -3825,26 +3877,15 @@
[(set_attr "type" "alu")])
(define_insn "*subhi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
- (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
- (match_operand:HI 2 "general_operand" "ri,rm"))
- (const_int 0)))
- (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
- (minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, HImode, operands)"
- "sub{w}\\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")])
-
-(define_insn "*subhi_3"
- [(set (reg:CC 17)
- (compare:CC
+ [(set (reg 17)
+ (compare
(minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
(match_operand:HI 2 "general_operand" "ri,rm"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
(minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, HImode, operands)"
+ "ix86_match_ccmode (insn, CCmode)
+ && ix86_binary_operator_ok (MINUS, HImode, operands)"
"sub{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -3866,26 +3907,15 @@
[(set_attr "type" "alu")])
(define_insn "*subqi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
(match_operand:QI 2 "general_operand" "qi,qm"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
(minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, QImode, operands)"
- "sub{b}\\t{%2, %0|%0, %2}"
- [(set_attr "type" "alu")])
-
-(define_insn "*subqi_3"
- [(set (reg:CC 17)
- (compare:CC
- (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
- (match_operand:QI 2 "general_operand" "qi,qm"))
- (const_int 0)))
- (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
- (minus:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (MINUS, QImode, operands)"
+ "ix86_match_ccmode (insn, CCmode)
+ && ix86_binary_operator_ok (MINUS, QImode, operands)"
"sub{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4301,27 +4331,50 @@
;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
;; Note that this excludes ah.
-(define_insn "testsi_1"
- [(set (reg:CCNO 17)
- (compare:CCNO (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
- (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
- (const_int 0)))]
+(define_insn "*testsi_ccz_1"
+ [(set (reg:CCZ 17)
+ (compare:CCZ
+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
+ (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
+ (const_int 0)))]
""
"test{l}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
(set_attr "pent_pair" "uv,np,uv")])
-(define_insn "*testhi_1"
+(define_insn "testsi_ccno_1"
[(set (reg:CCNO 17)
- (compare:CCNO (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
- (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
- (const_int 0)))]
+ (compare:CCNO
+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
+ (match_operand:SI 1 "nonmemory_operand" "in,in,rin"))
+ (const_int 0)))]
""
+ "test{l}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "icmp")
+ (set_attr "pent_pair" "uv,np,uv")])
+
+(define_insn "*testhi_1"
+ [(set (reg 17)
+ (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
+ (match_operand:HI 1 "nonmemory_operand" "n,n,rn"))
+ (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode)"
"test{w}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
(set_attr "pent_pair" "uv,np,uv")])
-(define_insn "testqi_1"
+(define_insn "testqi_ccz_1"
+ [(set (reg:CCZ 17)
+ (compare:CCZ
+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
+ (match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
+ (const_int 0)))]
+ ""
+ "test{b}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "icmp")
+ (set_attr "pent_pair" "uv,np,uv")])
+
+(define_insn "testqi_ccno_1"
[(set (reg:CCNO 17)
(compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
(match_operand:QI 1 "nonmemory_operand" "n,n,qn"))
@@ -4331,11 +4384,22 @@
[(set_attr "type" "icmp")
(set_attr "pent_pair" "uv,np,uv")])
-;; ??? A bug in recog prevents it from recognizing a const_int as an
-;; operand to zero_extend in andqi_ext_1. It was checking explicitly
-;; for a QImode operand, which of course failed.
+(define_insn "*testqi_ext_ccz_0"
+ [(set (reg:CCZ 17)
+ (compare:CCZ
+ (and:SI
+ (zero_extract:SI
+ (match_operand 0 "ext_register_operand" "q")
+ (const_int 8)
+ (const_int 8))
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))]
+ "(unsigned HOST_WIDE_INT) INTVAL (operands[1]) <= 0xff"
+ "test{b}\\t{%1, %h0|%h0, %1}"
+ [(set_attr "type" "icmp")
+ (set_attr "pent_pair" "np")])
-(define_insn "testqi_ext_0"
+(define_insn "testqi_ext_ccno_0"
[(set (reg:CCNO 17)
(compare:CCNO
(and:SI
@@ -4351,8 +4415,8 @@
(set_attr "pent_pair" "np")])
(define_insn "*testqi_ext_1"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(and:SI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "q")
@@ -4361,13 +4425,13 @@
(zero_extend:SI
(match_operand:QI 1 "nonimmediate_operand" "qm")))
(const_int 0)))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
"test{b}\\t{%1, %h0|%h0, %1}"
[(set_attr "type" "icmp")])
(define_insn "*testqi_ext_2"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(and:SI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "q")
@@ -4378,31 +4442,32 @@
(const_int 8)
(const_int 8)))
(const_int 0)))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
"test{b}\\t{%h1, %h0|%h0, %h1}"
[(set_attr "type" "icmp")])
;; Combine likes to form bit extractions for some tests. Humor it.
(define_insn "*testqi_ext_3"
- [(set (reg:CCNO 17)
- (compare:CCNO (zero_extract:SI
- (match_operand 0 "nonimmediate_operand" "rm")
- (match_operand:SI 1 "const_int_operand" "")
- (match_operand:SI 2 "const_int_operand" ""))
- (const_int 0)))]
- "GET_MODE (operands[0]) == SImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == QImode"
+ [(set (reg 17)
+ (compare (zero_extract:SI
+ (match_operand 0 "nonimmediate_operand" "rm")
+ (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "const_int_operand" ""))
+ (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (GET_MODE (operands[0]) == SImode
+ || GET_MODE (operands[0]) == HImode
+ || GET_MODE (operands[0]) == QImode)"
"#")
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (zero_extract:SI
- (match_operand 0 "nonimmediate_operand" "rm")
- (match_operand:SI 1 "const_int_operand" "")
- (match_operand:SI 2 "const_int_operand" ""))
- (const_int 0)))]
- ""
+ [(set (reg 17)
+ (compare (zero_extract:SI
+ (match_operand 0 "nonimmediate_operand" "rm")
+ (match_operand:SI 1 "const_int_operand" "")
+ (match_operand:SI 2 "const_int_operand" ""))
+ (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode)"
[(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
"
{
@@ -4506,13 +4571,14 @@
[(set_attr "type" "alu,alu,imovx")])
(define_insn "*andsi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
(and:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (AND, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (AND, SImode, operands)"
"and{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4566,13 +4632,14 @@
[(set_attr "type" "alu,alu,imovx")])
(define_insn "*andhi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
(and:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (AND, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (AND, HImode, operands)"
"and{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4598,14 +4665,15 @@
[(set_attr "type" "alu")])
(define_insn "*andqi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (and:QI
- (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "qim,qi,i"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (and:QI
+ (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
+ (match_operand:QI 2 "general_operand" "qim,qi,i"))
+ (const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
(and:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (AND, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (AND, QImode, operands)"
"@
and{b}\\t{%2, %0|%0, %2}
and{b}\\t{%2, %0|%0, %2}
@@ -4635,8 +4703,8 @@
;; often in fp comparisons.
(define_insn "*andqi_ext_0_cc"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(and:SI
(zero_extract:SI
(match_operand 1 "ext_register_operand" "q")
@@ -4653,7 +4721,8 @@
(const_int 8)
(const_int 8))
(match_dup 2)))]
- "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
"and{b}\\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")])
@@ -4714,13 +4783,14 @@
[(set_attr "type" "alu")])
(define_insn "*iorsi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
(ior:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (IOR, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (IOR, SImode, operands)"
"or{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4742,13 +4812,14 @@
[(set_attr "type" "alu")])
(define_insn "*iorhi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
(ior:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (IOR, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (IOR, HImode, operands)"
"or{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4774,13 +4845,14 @@
[(set_attr "type" "alu")])
(define_insn "*iorqi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
- (match_operand:QI 2 "general_operand" "qim,qi"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:QI 2 "general_operand" "qim,qi"))
+ (const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
(ior:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (IOR, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (IOR, QImode, operands)"
"or{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4807,13 +4879,14 @@
[(set_attr "type" "alu")])
(define_insn "*xorsi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
- (match_operand:SI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
(xor:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (XOR, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (XOR, SImode, operands)"
"xor{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4835,13 +4908,14 @@
[(set_attr "type" "alu")])
(define_insn "*xorhi_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
- (match_operand:HI 2 "general_operand" "rim,ri"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:HI 2 "general_operand" "rim,ri"))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
(xor:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (XOR, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (XOR, HImode, operands)"
"xor{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4867,14 +4941,15 @@
[(set_attr "type" "alu")])
(define_insn "*xorqi_cc_1"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
(match_operand:QI 2 "general_operand" "qim,qi"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
(xor:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (XOR, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (XOR, QImode, operands)"
"xor{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
@@ -4922,8 +4997,8 @@
(clobber (reg:CC 17))]
"reload_completed"
[(parallel
- [(set (reg:CCNO 17)
- (compare:CCNO (neg:SI (match_dup 2)) (const_int 0)))
+ [(set (reg:CCZ 17)
+ (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
(set (match_dup 0) (neg:SI (match_dup 2)))])
(parallel
[(set (match_dup 1)
@@ -4953,20 +5028,14 @@
"neg{l}\\t%0"
[(set_attr "type" "negnot")])
-(define_insn "*negsi2_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
- (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
- (neg:SI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, SImode, operands)"
- "neg{l}\\t%0"
- [(set_attr "type" "negnot")])
+;; The problem with neg is that it does not perform (compare x 0),
+;; it really performs (compare 0 x), which leaves us with the zero
+;; flag being the only useful item.
-(define_insn "*negsi2_cmp"
- [(set (reg:CC 17)
- (compare:CC (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+(define_insn "*negsi2_cmpz"
+ [(set (reg:CCZ 17)
+ (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(neg:SI (match_dup 1)))]
"ix86_unary_operator_ok (NEG, SImode, operands)"
@@ -4988,20 +5057,10 @@
"neg{w}\\t%0"
[(set_attr "type" "negnot")])
-(define_insn "*neghi2_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
- (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
- (neg:HI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, HImode, operands)"
- "neg{w}\\t%0"
- [(set_attr "type" "negnot")])
-
-(define_insn "*neghi2_cmp"
- [(set (reg:CC 17)
- (compare:CC (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+(define_insn "*neghi2_cmpz"
+ [(set (reg:CCZ 17)
+ (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(neg:HI (match_dup 1)))]
"ix86_unary_operator_ok (NEG, HImode, operands)"
@@ -5023,20 +5082,10 @@
"neg{b}\\t%0"
[(set_attr "type" "negnot")])
-(define_insn "*negqi2_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
- (neg:QI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, QImode, operands)"
- "neg{b}\\t%0"
- [(set_attr "type" "negnot")])
-
-(define_insn "*negqi2_cmp"
- [(set (reg:CC 17)
- (compare:CC (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+(define_insn "*negqi2_cmpz"
+ [(set (reg:CCZ 17)
+ (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(neg:QI (match_dup 1)))]
"ix86_unary_operator_ok (NEG, QImode, operands)"
@@ -5416,22 +5465,23 @@
[(set_attr "type" "negnot")])
(define_insn "*one_cmplsi2_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(not:SI (match_dup 1)))]
- "ix86_unary_operator_ok (NOT, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_unary_operator_ok (NOT, SImode, operands)"
"#"
[(set_attr "type" "alu1")])
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
+ (const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "")
(not:SI (match_dup 1)))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
[(parallel [(set (reg:CCNO 17)
(compare:CCNO (xor:SI (match_dup 1) (const_int -1))
(const_int 0)))
@@ -5453,22 +5503,23 @@
[(set_attr "type" "negnot")])
(define_insn "*one_cmplhi2_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(not:HI (match_dup 1)))]
- "ix86_unary_operator_ok (NEG, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_unary_operator_ok (NEG, HImode, operands)"
"#"
[(set_attr "type" "alu1")])
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
+ (const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "")
(not:HI (match_dup 1)))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
[(parallel [(set (reg:CCNO 17)
(compare:CCNO (xor:HI (match_dup 1) (const_int -1))
(const_int 0)))
@@ -5493,22 +5544,23 @@
[(set_attr "type" "negnot")])
(define_insn "*one_cmplqi2_2"
- [(set (reg:CCNO 17)
- (compare:CCNO (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
+ (const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(not:QI (match_dup 1)))]
- "ix86_unary_operator_ok (NOT, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_unary_operator_ok (NOT, QImode, operands)"
"#"
[(set_attr "type" "alu1")])
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
+ (const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "")
(not:QI (match_dup 1)))]
- ""
+ "ix86_match_ccmode (insn, CCNOmode)"
[(parallel [(set (reg:CCNO 17)
(compare:CCNO (xor:QI (match_dup 1) (const_int -1))
(const_int 0)))
@@ -5611,16 +5663,16 @@
(set_attr "ppro_uops" "few")])
(define_expand "x86_shift_adj_1"
- [(set (reg:CCNO 17)
- (compare:CCNO (and:QI (match_operand:QI 2 "register_operand" "")
- (const_int 32))
- (const_int 0)))
+ [(set (reg:CCZ 17)
+ (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
+ (const_int 32))
+ (const_int 0)))
(set (match_operand:SI 0 "register_operand" "")
- (if_then_else:SI (ne (reg:CCNO 17) (const_int 0))
+ (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
(match_operand:SI 1 "register_operand" "")
(match_dup 0)))
(set (match_dup 1)
- (if_then_else:SI (ne (reg:CCNO 17) (const_int 0))
+ (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
(match_operand:SI 3 "register_operand" "r")
(match_dup 1)))]
"TARGET_CMOVE"
@@ -5636,9 +5688,9 @@
rtx label = gen_label_rtx ();
rtx tmp;
- emit_insn (gen_testqi_1 (operands[2], GEN_INT (32)));
+ emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
- tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
@@ -5723,14 +5775,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlsi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashift:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
"*
{
switch (get_attr_type (insn))
@@ -5799,14 +5852,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlhi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashift:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
"*
{
switch (get_attr_type (insn))
@@ -5889,14 +5943,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashlqi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(ashift:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
"*
{
switch (get_attr_type (insn))
@@ -6003,9 +6058,9 @@
rtx label = gen_label_rtx ();
rtx tmp;
- emit_insn (gen_testqi_1 (operands[2], GEN_INT (32)));
+ emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
- tmp = gen_rtx_REG (CCNOmode, FLAGS_REG);
+ tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, label),
@@ -6037,7 +6092,7 @@
(define_expand "ashrsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
- (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
""
@@ -6058,21 +6113,22 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashrsi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(ashiftrt:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
"@
sar{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
(define_expand "ashrhi3"
[(set (match_operand:HI 0 "nonimmediate_operand" "")
- (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
+ (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"TARGET_HIMODE_MATH"
@@ -6093,21 +6149,22 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashrhi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(ashiftrt:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
"@
sar{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
(define_expand "ashrqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
- (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
+ (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"TARGET_QIMODE_MATH"
@@ -6128,14 +6185,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*ashrqi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
(ashiftrt:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
"@
sar{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
@@ -6220,14 +6278,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*lshrsi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(lshiftrt:SI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"@
shr{l}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
@@ -6255,14 +6314,15 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*lshrhi3_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(lshiftrt:HI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
"@
shr{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
@@ -6290,16 +6350,16 @@
;; zero don't affect the flags. We assume that shifts by constant
;; zero are optimized away.
(define_insn "*lshrqi2_cmpno"
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "immediate_operand" "I"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
(lshiftrt:QI (match_dup 1) (match_dup 2)))]
- "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
- "@
- shr{b}\\t{%2, %0|%0, %2}"
+ "ix86_match_ccmode (insn, CCNOmode)
+ && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
+ "shr{b}\\t{%2, %0|%0, %2}"
[(set_attr "type" "ishift")])
;; Rotate instructions
@@ -6930,11 +6990,11 @@
"TARGET_USE_LOOP && reload_completed
&& ! (REGNO (operands[1]) == 2 && rtx_equal_p (operands[1], operands[2]))"
[(set (match_dup 2) (match_dup 1))
- (parallel [(set (reg:CCNO 17)
- (compare:CCNO (plus:SI (match_dup 2) (const_int -1))
+ (parallel [(set (reg:CCZ 17)
+ (compare:CCZ (plus:SI (match_dup 2) (const_int -1))
(const_int 0)))
(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1)))])
- (set (pc) (if_then_else (ne (reg:CCNO 17) (const_int 0))
+ (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
(match_dup 0)
(pc)))]
"")
@@ -6952,12 +7012,12 @@
(clobber (reg:CC 17))]
"TARGET_USE_LOOP && reload_completed"
[(set (match_dup 3) (match_dup 1))
- (parallel [(set (reg:CCNO 17)
- (compare:CCNO (plus:SI (match_dup 3) (const_int -1))
- (const_int 0)))
+ (parallel [(set (reg:CCZ 17)
+ (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
+ (const_int 0)))
(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
(set (match_dup 2) (match_dup 3))
- (set (pc) (if_then_else (ne (reg:CCNO 17) (const_int 0))
+ (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
(match_dup 0)
(pc)))]
"")
@@ -7039,19 +7099,41 @@
XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
}")
+(define_insn "*call_pop_0"
+ [(call (match_operand:QI 0 "constant_call_address_operand" "")
+ (match_operand:SI 1 "" ""))
+ (set (reg:SI 7) (plus:SI (reg:SI 7)
+ (match_operand:SI 3 "immediate_operand" "")))]
+ ""
+ "*
+{
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P0\";
+ else
+ return \"call\\t%P0\";
+}"
+ [(set_attr "type" "call")])
+
(define_insn "*call_pop_1"
[(call (match_operand:QI 0 "call_insn_operand" "m")
- (match_operand:SI 1 "general_operand" "g"))
+ (match_operand:SI 1 "" ""))
(set (reg:SI 7) (plus:SI (reg:SI 7)
(match_operand:SI 3 "immediate_operand" "i")))]
""
"*
{
- if (constant_call_address_operand (operands[0], GET_MODE (operands[0])))
- return \"call\\t%P0\";
-
+ if (constant_call_address_operand (operands[0], QImode))
+ {
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P0\";
+ else
+ return \"call\\t%P0\";
+ }
operands[0] = XEXP (operands[0], 0);
- return \"call\\t%*%0\";
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%*%0\";
+ else
+ return \"call\\t%*%0\";
}"
[(set_attr "type" "call")])
@@ -7070,21 +7152,32 @@
XEXP (operands[0], 0) = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
}")
+(define_insn "*call_0"
+ [(call (match_operand:QI 0 "constant_call_address_operand" "")
+ (match_operand:SI 1 "" ""))]
+ ""
+ "*
+{
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P0\";
+ else
+ return \"call\\t%P0\";
+}"
+ [(set_attr "type" "call")])
+
(define_insn "*call_1"
[(call (match_operand:QI 0 "call_insn_operand" "m")
- (match_operand:SI 1 "general_operand" "g"))]
- ;; Operand 1 not used on the i386.
+ (match_operand:SI 1 "" ""))]
""
"*
{
- if (constant_call_address_operand (operands[0], GET_MODE (operands[0])))
+ if (constant_call_address_operand (operands[0], QImode))
{
if (SIBLING_CALL_P (insn))
return \"jmp\\t%P0\";
else
return \"call\\t%P0\";
}
-
operands[0] = XEXP (operands[0], 0);
if (SIBLING_CALL_P (insn))
return \"jmp\\t%*%0\";
@@ -7106,8 +7199,6 @@
""
"
{
- rtx addr;
-
if (operands[4] == const0_rtx)
{
emit_insn (gen_call_value (operands[0], operands[1], operands[2]));
@@ -7130,8 +7221,6 @@
""
"
{
- rtx addr;
-
/* ??? Not true for calls to static functions. */
if (flag_pic)
current_function_uses_pic_offset_table = 1;
@@ -7300,7 +7389,7 @@
emit_insn (gen_ffssi_1 (out, in));
emit_insn (gen_rtx_SET (VOIDmode, out,
gen_rtx_IF_THEN_ELSE (SImode,
- gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG),
+ gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCZmode, FLAGS_REG),
const0_rtx),
tmp,
out)));
@@ -7308,8 +7397,8 @@
emit_move_insn (operands[0], out);
}
- /* Pentium bsf instruction is extremly slow. Following code is recommended by
- the Intel Optimizing Manual as resonable replacement:
+ /* Pentium bsf instruction is extremly slow. The following code is
+ recommended by the Intel Optimizing Manual as a reasonable replacement:
TEST EAX,EAX
JZ SHORT BS2
XOR ECX,ECX
@@ -7349,7 +7438,7 @@
emit_move_insn (gen_rtx_MEM (DFmode, XEXP (mem, 0)), fptmp);
emit_move_insn (out, hi);
emit_insn (gen_lshrsi3 (out, out, GEN_INT (20)));
- emit_insn (gen_subsi3 (out, out, GEN_INT (0x3fe)));
+ emit_insn (gen_subsi3 (out, out, GEN_INT (0x3ff - 1)));
emit_label (label);
LABEL_NUSES (label) = 1;
@@ -7362,7 +7451,7 @@
emit_insn (gen_ffssi_1 (out, in));
emit_insn (gen_rtx_SET (VOIDmode,
gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (QImode, tmp)),
- gen_rtx_EQ (QImode, gen_rtx_REG (CCmode, FLAGS_REG),
+ gen_rtx_EQ (QImode, gen_rtx_REG (CCZmode, FLAGS_REG),
const0_rtx)));
emit_insn (gen_negsi2 (tmp, tmp));
emit_insn (gen_iorsi3 (out, out, tmp));
@@ -7372,12 +7461,10 @@
DONE;
}")
-;; %%% The CCmode here is not strictly correct -- only Z is defined.
-;; But I don't think this can be used except for from above.
(define_insn "ffssi_1"
- [(set (reg:CC 17)
- (compare:CC (match_operand:SI 1 "nonimmediate_operand" "rm")
- (const_int 0)))
+ [(set (reg:CCZ 17)
+ (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
+ (const_int 0)))
(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_dup 1)] 5))]
""
@@ -8917,13 +9004,14 @@
GET_MODE (operands[3]) = SImode;")
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (and (match_operand 1 "aligned_operand" "")
- (match_operand 2 "const_int_operand" ""))
- (const_int 0)))
+ [(set (reg 17)
+ (compare (and (match_operand 1 "aligned_operand" "")
+ (match_operand 2 "const_int_operand" ""))
+ (const_int 0)))
(set (match_operand 0 "register_operand" "")
(and (match_dup 1) (match_dup 2)))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
+ && ix86_match_ccmode (insn, CCNOmode)
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
@@ -8938,11 +9026,12 @@
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_split
- [(set (reg:CCNO 17)
- (compare:CCNO (and (match_operand 0 "aligned_operand" "")
- (match_operand 1 "const_int_operand" ""))
- (const_int 0)))]
+ [(set (reg 17)
+ (compare (and (match_operand 0 "aligned_operand" "")
+ (match_operand 1 "const_int_operand" ""))
+ (const_int 0)))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
+ && ix86_match_ccmode (insn, CCNOmode)
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
@@ -9111,13 +9200,13 @@
;; Don't compare memory with zero, load and use a test instead.
(define_peephole2
- [(set (reg:CCNO 17)
- (compare:CCNO (match_operand:SI 0 "memory_operand" "")
- (const_int 0)))
+ [(set (reg 17)
+ (compare (match_operand:SI 0 "memory_operand" "")
+ (const_int 0)))
(match_scratch:SI 3 "r")]
- "! optimize_size"
- [(set (match_dup 3) (match_dup 0))
- (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
+ [(set (match_dup 3) (match_dup 0))
+ (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
"")
;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
@@ -9181,12 +9270,13 @@
;; versions if we're concerned about partial register stalls.
(define_peephole2
- [(set (reg:CCNO 17)
- (compare:CCNO (and:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "immediate_operand" ""))
- (const_int 0)))]
- "(true_regnum (operands[0]) != 0
- || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
+ [(set (reg 17)
+ (compare (and:SI (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "immediate_operand" ""))
+ (const_int 0)))]
+ "ix86_match_ccmode (insn, CCNOmode)
+ && (true_regnum (operands[0]) != 0
+ || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(parallel
[(set (reg:CCNO 17)
@@ -9201,11 +9291,12 @@
;; on ! TARGET_PARTIAL_REG_STALL
(define_peephole2
- [(set (reg:CCNO 17)
- (compare:CCNO (and:QI (match_operand:QI 0 "register_operand" "")
- (match_operand:QI 1 "immediate_operand" ""))
- (const_int 0)))]
+ [(set (reg 17)
+ (compare (and:QI (match_operand:QI 0 "register_operand" "")
+ (match_operand:QI 1 "immediate_operand" ""))
+ (const_int 0)))]
"! TARGET_PARTIAL_REG_STALL
+ && ix86_match_ccmode (insn, CCNOmode)
&& true_regnum (operands[0]) != 0
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(parallel
@@ -9218,8 +9309,8 @@
"")
(define_peephole2
- [(set (reg:CCNO 17)
- (compare:CCNO
+ [(set (reg 17)
+ (compare
(and:SI
(zero_extract:SI
(match_operand 0 "ext_register_operand" "q")
@@ -9228,6 +9319,7 @@
(match_operand 1 "const_int_operand" "n"))
(const_int 0)))]
"! TARGET_PARTIAL_REG_STALL
+ && ix86_match_ccmode (insn, CCNOmode)
&& true_regnum (operands[0]) != 0
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(parallel [(set (reg:CCNO 17)
@@ -9363,39 +9455,74 @@
;; Call-value patterns last so that the wildcard operand does not
;; disrupt insn-recog's switch tables.
+(define_insn "*call_value_pop_0"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "constant_call_address_operand" "")
+ (match_operand:SI 2 "" "")))
+ (set (reg:SI 7) (plus:SI (reg:SI 7)
+ (match_operand:SI 4 "immediate_operand" "")))]
+ ""
+ "*
+{
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P1\";
+ else
+ return \"call\\t%P1\";
+}"
+ [(set_attr "type" "callv")])
+
(define_insn "*call_value_pop_1"
[(set (match_operand 0 "" "")
(call (match_operand:QI 1 "call_insn_operand" "m")
- (match_operand:SI 2 "general_operand" "g")))
+ (match_operand:SI 2 "" "")))
(set (reg:SI 7) (plus:SI (reg:SI 7)
(match_operand:SI 4 "immediate_operand" "i")))]
""
"*
{
- if (constant_call_address_operand (operands[1], GET_MODE (operands[1])))
- return \"call\\t%P1\";
-
+ if (constant_call_address_operand (operands[1], QImode))
+ {
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P1\";
+ else
+ return \"call\\t%P1\";
+ }
operands[1] = XEXP (operands[1], 0);
- return \"call\\t%*%1\";
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%*%1\";
+ else
+ return \"call\\t%*%1\";
+}"
+ [(set_attr "type" "callv")])
+
+(define_insn "*call_value_0"
+ [(set (match_operand 0 "" "")
+ (call (match_operand:QI 1 "constant_call_address_operand" "")
+ (match_operand:SI 2 "" "")))]
+ ""
+ "*
+{
+ if (SIBLING_CALL_P (insn))
+ return \"jmp\\t%P1\";
+ else
+ return \"call\\t%P1\";
}"
[(set_attr "type" "callv")])
(define_insn "*call_value_1"
[(set (match_operand 0 "" "")
(call (match_operand:QI 1 "call_insn_operand" "m")
- (match_operand:SI 2 "general_operand" "g")))]
- ;; Operand 2 not used on the i386.
+ (match_operand:SI 2 "" "")))]
""
"*
{
- if (constant_call_address_operand (operands[1], GET_MODE (operands[1])))
+ if (constant_call_address_operand (operands[1], QImode))
{
if (SIBLING_CALL_P (insn))
return \"jmp\\t%P1\";
else
return \"call\\t%P1\";
}
-
operands[1] = XEXP (operands[1], 0);
if (SIBLING_CALL_P (insn))
return \"jmp\\t%*%1\";
diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h
index 8ccd758eb20..10cc66560ad 100644
--- a/gcc/config/i960/i960.h
+++ b/gcc/config/i960/i960.h
@@ -833,7 +833,7 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS,
#define OUTGOING_REG_PARM_STACK_SPACE
/* Keep the stack pointer constant throughout the function. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is 1 if returning from a function call automatically
pops the arguments described by the number-of-args field in the call.
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 9c3b1f8db18..362c8583e9c 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -20,8 +20,6 @@ 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 <stdio.h>
-#include <ctype.h>
#include "config.h"
#include "system.h"
#include "rtl.h"
diff --git a/gcc/config/ia64/ia64.h b/gcc/config/ia64/ia64.h
index dd07ae1dab0..dca777477b1 100644
--- a/gcc/config/ia64/ia64.h
+++ b/gcc/config/ia64/ia64.h
@@ -1270,7 +1270,7 @@ extern int ia64_local_regs;
be computed and placed into the variable
`current_function_outgoing_args_size'. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* A C expression that should indicate the number of bytes of its own arguments
that a function pops on returning, or 0 if the function pops no arguments
@@ -2590,6 +2590,25 @@ do { \
#define REAL_ARITHMETIC
+/* Register Renaming Parameters. */
+
+/* A C expression that is nonzero if hard register number REGNO2 can be
+ considered for use as a rename register for REGNO1 */
+
+#define HARD_REGNO_RENAME_OK(REGNO1,REGNO2) \
+ ((! PR_REGNO_P (REGNO1) && ! PR_REGNO_P (REGNO2)) \
+ ? (!call_fixed_regs [REGNO1] && !call_fixed_regs [REGNO2]) \
+ ? 1 : 0 \
+ : ((REGNO2) > 256 && ((REGNO2 & 1) == 0)) \
+ ? 1 : 0)
+
+/* Define this macro if the compiler should use extended basic blocks
+ when renaming registers. Define this macro if the target has predicate
+ registers. */
+
+#define RENAME_EXTENDED_BLOCKS
+
+
/* Miscellaneous Parameters. */
/* Define this if you have defined special-purpose predicates in the file
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index a19548622bd..4f8645c5792 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -983,7 +983,7 @@ M32R_STACK_ALIGN (current_function_outgoing_args_size)
`current_function_outgoing_args_size'. No space will be pushed
onto the stack for each call; instead, the function prologue should
increase the stack frame size by this amount. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Define this macro if functions should assume that stack space has
been allocated for arguments even when their values are passed in
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index a31dc41996d..4c54fe4e76a 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -54,7 +54,9 @@ extern int standard_sun_fpa_constant_p PARAMS ((rtx));
extern void print_operand_address PARAMS ((FILE *, rtx));
extern void print_operand PARAMS ((FILE *, rtx, int));
extern void notice_update_cc PARAMS ((rtx, rtx));
-//extern void finalize_pic PARAMS ((rtx, enum machine_mode));
+#if 0
+extern void finalize_pic PARAMS ((rtx, enum machine_mode));
+#endif
extern int general_src_operand PARAMS ((rtx, enum machine_mode));
extern int nonimmediate_src_operand PARAMS ((rtx, enum machine_mode));
extern int memory_src_operand PARAMS ((rtx, enum machine_mode));
diff --git a/gcc/config/m88k/m88k.h b/gcc/config/m88k/m88k.h
index 04bc245e6db..5cbae71a077 100644
--- a/gcc/config/m88k/m88k.h
+++ b/gcc/config/m88k/m88k.h
@@ -872,7 +872,7 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS,
`current_function_outgoing_args_size'. No space will be pushed
onto the stack for each call; instead, the function prologue should
increase the stack frame size by this amount. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset from the stack pointer register to the first location at which
outgoing arguments are placed. Use the default value zero. */
diff --git a/gcc/config/mcore/mcore.h b/gcc/config/mcore/mcore.h
index a165004e014..94eeb94cb5e 100644
--- a/gcc/config/mcore/mcore.h
+++ b/gcc/config/mcore/mcore.h
@@ -673,7 +673,7 @@ extern enum reg_class reg_class_from_letter[];
`current_function_outgoing_args_size'. No space will be pushed
onto the stack for each call; instead, the function prologue should
increase the stack frame size by this amount. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset of first parameter from the argument pointer register value. */
#define FIRST_PARM_OFFSET(FNDECL) 0
diff --git a/gcc/config/mips/abi64.h b/gcc/config/mips/abi64.h
index e74e2f4b32d..a8833466380 100644
--- a/gcc/config/mips/abi64.h
+++ b/gcc/config/mips/abi64.h
@@ -105,19 +105,21 @@ extern struct rtx_def *mips_function_value PARAMS ((union tree_node *, union tre
For stdarg, we do not need to save the current argument, because it
is a real argument. */
#define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \
-{ int mips_off = (! current_function_varargs) && (! (CUM).last_arg_fp); \
- int mips_fp_off = (! current_function_varargs) && ((CUM).last_arg_fp); \
+{ unsigned int mips_off \
+ = (! current_function_varargs) && (! (CUM).last_arg_fp); \
+ unsigned int mips_fp_off \
+ = (! current_function_varargs) && ((CUM).last_arg_fp); \
if (((mips_abi != ABI_32 && mips_abi != ABI_O64) \
&& (CUM).arg_words < MAX_ARGS_IN_REGISTERS - mips_off) \
|| (mips_abi == ABI_EABI \
&& ! TARGET_SOFT_FLOAT \
&& (CUM).fp_arg_words < MAX_ARGS_IN_REGISTERS - mips_fp_off)) \
{ \
- int mips_save_gp_regs = \
- MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off; \
- int mips_save_fp_regs = \
- (mips_abi != ABI_EABI ? 0 \
- : MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \
+ int mips_save_gp_regs \
+ = MAX_ARGS_IN_REGISTERS - (CUM).arg_words - mips_off; \
+ int mips_save_fp_regs \
+ = (mips_abi != ABI_EABI ? 0 \
+ : MAX_ARGS_IN_REGISTERS - (CUM).fp_arg_words - mips_fp_off); \
\
if (mips_save_gp_regs < 0) \
mips_save_gp_regs = 0; \
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index dedbe05b9c4..95f7f23fbbc 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -3801,7 +3801,7 @@ function_arg (cum, mode, type, named)
/* Drops through. */
case BLKmode:
- if (type != (tree)0 && TYPE_ALIGN (type) > (unsigned) BITS_PER_WORD
+ if (type != NULL_TREE && TYPE_ALIGN (type) > BITS_PER_WORD
&& ! TARGET_64BIT && mips_abi != ABI_EABI)
cum->arg_words += (cum->arg_words & 1);
regbase = GP_ARG_FIRST;
@@ -3833,7 +3833,8 @@ function_arg (cum, mode, type, named)
abort ();
if (! type || TREE_CODE (type) != RECORD_TYPE || mips_abi == ABI_32
- || mips_abi == ABI_EABI || mips_abi == ABI_O64 || ! named)
+ || mips_abi == ABI_EABI || mips_abi == ABI_O64 || ! named
+ || ! host_integerp (TYPE_SIZE_UNIT (type), 1))
ret = gen_rtx_REG (mode, regbase + *arg_words + bias);
else
{
@@ -3847,8 +3848,8 @@ function_arg (cum, mode, type, named)
if (TREE_CODE (field) == FIELD_DECL
&& TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
- && (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
- % BITS_PER_WORD == 0))
+ && host_integerp (bit_position (field), 0)
+ && int_bit_position (field) % BITS_PER_WORD == 0)
break;
/* If the whole struct fits a DFmode register,
@@ -3859,15 +3860,16 @@ function_arg (cum, mode, type, named)
{
/* Now handle the special case by returning a PARALLEL
indicating where each 64 bit chunk goes. */
- int chunks;
- int bitpos;
- int regno;
+ unsigned int chunks;
+ HOST_WIDE_INT bitpos;
+ unsigned int regno;
int i;
/* ??? If this is a packed structure, then the last hunk won't
be 64 bits. */
- chunks = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_WORD;
+ chunks
+ = tree_low_cst (TYPE_SIZE_UNIT (type), 1) / UNITS_PER_WORD;
if (chunks + *arg_words + bias > MAX_ARGS_IN_REGISTERS)
chunks = MAX_ARGS_IN_REGISTERS - *arg_words - bias;
@@ -3884,12 +3886,11 @@ function_arg (cum, mode, type, named)
for (; field; field = TREE_CHAIN (field))
if (TREE_CODE (field) == FIELD_DECL
- && (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
- >= bitpos))
+ && int_bit_position (field) >= bitpos)
break;
if (field
- && TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) == bitpos
+ && int_bit_position (field) == bitpos
&& TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD)
reg = gen_rtx_REG (DFmode,
@@ -7417,10 +7418,8 @@ mips_function_value (valtype, func)
= TYPE_MODE (TREE_TYPE (fields[0]));
enum machine_mode second_mode
= TYPE_MODE (TREE_TYPE (fields[1]));
- int first_offset
- = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fields[0]));
- int second_offset
- = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fields[1]));
+ HOST_WIDE_INT first_offset = int_byte_position (fields[0]);
+ HOST_WIDE_INT second_offset = int_byte_position (fields[1]);
return gen_rtx_PARALLEL
(mode,
@@ -7428,13 +7427,11 @@ mips_function_value (valtype, func)
gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (first_mode,
FP_RETURN),
- GEN_INT (first_offset
- / BITS_PER_UNIT)),
+ GEN_INT (first_offset)),
gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (second_mode,
FP_RETURN + 2),
- GEN_INT (second_offset
- / BITS_PER_UNIT))));
+ GEN_INT (second_offset))));
}
}
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 9369f452569..bc8c83e0732 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -217,9 +217,9 @@ extern void sbss_section PARAMS ((void));
/* Debug switches, not documented */
#define MASK_DEBUG 0 /* Eliminate version # in .s file */
-#define MASK_DEBUG_A 0x40000000 /* don't allow <label>($reg) addrs */
-#define MASK_DEBUG_B 0x20000000 /* GO_IF_LEGITIMATE_ADDRESS debug */
-#define MASK_DEBUG_C 0x10000000 /* don't expand seq, etc. */
+#define MASK_DEBUG_A 0x0 /* don't allow <label>($reg) addrs */
+#define MASK_DEBUG_B 0x0 /* GO_IF_LEGITIMATE_ADDRESS debug */
+#define MASK_DEBUG_C 0x0 /* don't expand seq, etc. */
#define MASK_DEBUG_D 0 /* don't do define_split's */
#define MASK_DEBUG_E 0 /* function_arg debug */
#define MASK_DEBUG_F 0
@@ -1295,20 +1295,20 @@ do { \
Note that this is not necessarily the width of data type `int';
if using 16-bit ints on a 68000, this would still be 32.
But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD (TARGET_64BIT ? 64 : 32)
+#define BITS_PER_WORD ((unsigned int) (TARGET_64BIT ? 64 : 32))
#define MAX_BITS_PER_WORD 64
/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD (TARGET_64BIT ? 8 : 4)
+#define UNITS_PER_WORD ((unsigned int) (TARGET_64BIT ? 8 : 4))
#define MIN_UNITS_PER_WORD 4
/* For MIPS, width of a floating point register. */
-#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
+#define UNITS_PER_FPREG ((unsigned int) (TARGET_FLOAT64 ? 8 : 4))
/* A C expression for the size in bits of the type `int' on the
target machine. If you don't define this, the default is one
word. */
-#define INT_TYPE_SIZE (TARGET_INT64 ? 64 : 32)
+#define INT_TYPE_SIZE ((unsigned int) (TARGET_INT64 ? 64 : 32))
#define MAX_INT_TYPE_SIZE 64
/* Tell the preprocessor the maximum size of wchar_t. */
@@ -1327,7 +1327,7 @@ do { \
/* A C expression for the size in bits of the type `long' on the
target machine. If you don't define this, the default is one
word. */
-#define LONG_TYPE_SIZE (TARGET_LONG64 ? 64 : 32)
+#define LONG_TYPE_SIZE ((unsigned int) (TARGET_LONG64 ? 64 : 32))
#define MAX_LONG_TYPE_SIZE 64
/* A C expression for the size in bits of the type `long long' on the
@@ -1359,14 +1359,14 @@ do { \
/* Width in bits of a pointer.
See also the macro `Pmode' defined below. */
#ifndef POINTER_SIZE
-#define POINTER_SIZE (Pmode == DImode ? 64 : 32)
+#define POINTER_SIZE ((unsigned int) (Pmode == DImode ? 64 : 32))
#endif
/* Allocation boundary (in *bits*) for storing pointers in memory. */
-#define POINTER_BOUNDARY (Pmode == DImode ? 64 : 32)
+#define POINTER_BOUNDARY ((unsigned int) (Pmode == DImode ? 64 : 32))
/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-#define PARM_BOUNDARY (TARGET_64BIT ? 64 : 32)
+#define PARM_BOUNDARY ((unsigned int) (TARGET_64BIT ? 64 : 32))
/* Allocation boundary (in *bits*) for the code of a function. */
#define FUNCTION_BOUNDARY 32
@@ -1421,9 +1421,7 @@ do { \
#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
((TREE_CODE (EXP) == STRING_CST || TREE_CODE (EXP) == CONSTRUCTOR) \
- && (ALIGN) < BITS_PER_WORD \
- ? BITS_PER_WORD \
- : (ALIGN))
+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
/* If defined, a C expression to compute the alignment for a static
variable. TYPE is the data type, and ALIGN is the alignment that
@@ -1582,12 +1580,16 @@ do { \
should be used instead. */
#define FPSW_REGNUM ST_REG_FIRST
-#define GP_REG_P(REGNO) ((unsigned) ((REGNO) - GP_REG_FIRST) < GP_REG_NUM)
+#define GP_REG_P(REGNO) \
+ ((unsigned int) ((int) (REGNO) - GP_REG_FIRST) < GP_REG_NUM)
#define M16_REG_P(REGNO) \
(((REGNO) >= 2 && (REGNO) <= 7) || (REGNO) == 16 || (REGNO) == 17)
-#define FP_REG_P(REGNO) ((unsigned) ((REGNO) - FP_REG_FIRST) < FP_REG_NUM)
-#define MD_REG_P(REGNO) ((unsigned) ((REGNO) - MD_REG_FIRST) < MD_REG_NUM)
-#define ST_REG_P(REGNO) ((unsigned) ((REGNO) - ST_REG_FIRST) < ST_REG_NUM)
+#define FP_REG_P(REGNO) \
+ ((unsigned int) ((int) (REGNO) - FP_REG_FIRST) < FP_REG_NUM)
+#define MD_REG_P(REGNO) \
+ ((unsigned int) ((int) (REGNO) - MD_REG_FIRST) < MD_REG_NUM)
+#define ST_REG_P(REGNO) \
+ ((unsigned int) ((int) (REGNO) - ST_REG_FIRST) < ST_REG_NUM)
/* Return number of consecutive hard regs needed starting at reg REGNO
to hold something of mode MODE.
@@ -2258,7 +2260,7 @@ extern struct mips_frame_info current_frame_info;
It is not proper to define both `PUSH_ROUNDING' and
`ACCUMULATE_OUTGOING_ARGS'. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Offset from the argument pointer register to the first argument's
address. On some machines it may depend on the data type of the
@@ -2453,12 +2455,12 @@ extern struct mips_frame_info current_frame_info;
typedef struct mips_args {
int gp_reg_found; /* whether a gp register was found yet */
- int arg_number; /* argument number */
- int arg_words; /* # total words the arguments take */
- int fp_arg_words; /* # words for FP args (MIPS_EABI only) */
+ unsigned int arg_number; /* argument number */
+ unsigned int arg_words; /* # total words the arguments take */
+ unsigned int fp_arg_words; /* # words for FP args (MIPS_EABI only) */
int last_arg_fp; /* nonzero if last arg was FP (EABI only) */
int fp_code; /* Mode of FP arguments (mips16) */
- int num_adjusts; /* number of adjustments made */
+ unsigned int num_adjusts; /* number of adjustments made */
/* Adjustments made to args pass in regs. */
/* ??? The size is doubled to work around a
bug in the code that sets the adjustments
@@ -2511,7 +2513,7 @@ typedef struct mips_args {
#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
(((TYPE) != 0) \
- ? ((TYPE_ALIGN(TYPE) <= (unsigned)PARM_BOUNDARY) \
+ ? ((TYPE_ALIGN(TYPE) <= PARM_BOUNDARY) \
? PARM_BOUNDARY \
: TYPE_ALIGN(TYPE)) \
: ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \
diff --git a/gcc/config/mn10200/mn10200.h b/gcc/config/mn10200/mn10200.h
index 60928c4dab3..bc11832e65f 100644
--- a/gcc/config/mn10200/mn10200.h
+++ b/gcc/config/mn10200/mn10200.h
@@ -401,7 +401,7 @@ enum reg_class {
We allow frame pointers to be eliminated when not having one will
not interfere with debugging. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
#define FRAME_POINTER_REQUIRED 0
#define CAN_DEBUG_WITHOUT_FP
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 403091e8c5f..c1507c0dba1 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -447,7 +447,7 @@ enum reg_class {
for a register flushback area. */
#define REG_PARM_STACK_SPACE(DECL) 8
#define OUTGOING_REG_PARM_STACK_SPACE
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* So we can allocate space for return pointers once for the function
instead of around every call. */
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 4fc8a0ce43b..f47ce37ba72 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -3912,15 +3912,17 @@ print_operand (file, x, code)
else if (GET_CODE (x) == MEM)
{
int size = GET_MODE_SIZE (GET_MODE (x));
- rtx base = XEXP (XEXP (x, 0), 0);
+ rtx base = NULL_RTX;
switch (GET_CODE (XEXP (x, 0)))
{
case PRE_DEC:
case POST_DEC:
+ base = XEXP (XEXP (x, 0), 0);
fprintf (file, "-%d(%s)", size, reg_names [REGNO (base)]);
break;
case PRE_INC:
case POST_INC:
+ base = XEXP (XEXP (x, 0), 0);
fprintf (file, "%d(%s)", size, reg_names [REGNO (base)]);
break;
default:
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 1a719f860f6..06571c9ec8d 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -556,7 +556,7 @@ extern int target_flags;
This is both an optimization and a necessity: longjmp
doesn't behave itself when the stack pointer moves within
the function! */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* The weird HPPA calling conventions require a minimum of 48 bytes on
the stack: 16 bytes for register saves, and 32 bytes for magic.
diff --git a/gcc/config/romp/romp.h b/gcc/config/romp/romp.h
index cc2914d9ab5..ec6602f80f7 100644
--- a/gcc/config/romp/romp.h
+++ b/gcc/config/romp/romp.h
@@ -499,7 +499,7 @@ enum reg_class { NO_REGS, R0_REGS, R15_REGS, BASE_REGS, GENERAL_REGS,
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
found in the variable current_function_outgoing_args_size. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h
index 9f2b996b74c..fdd74d979ce 100644
--- a/gcc/config/rs6000/aix.h
+++ b/gcc/config/rs6000/aix.h
@@ -66,6 +66,13 @@ Boston, MA 02111-1307, USA. */
#define CPP_PREDEFINES "-D_IBMR2 -D_POWER -D_AIX -D_AIX32 -D_LONG_LONG \
-Asystem(unix) -Asystem(aix) -Acpu(rs6000) -Amachine(rs6000)"
+/* Define appropriate architecture macros for preprocessor depending on
+ target switches. */
+
+#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
+ %{ansi: -D_ANSI_C_SOURCE}\
+ %(cpp_cpu)"
+
/* Tell the assembler to assume that all undefined names are external.
Don't do this until the fixed IBM assembler is more generally available.
diff --git a/gcc/config/rs6000/aix41.h b/gcc/config/rs6000/aix41.h
index 7ab7eedc12d..b28d2439956 100644
--- a/gcc/config/rs6000/aix41.h
+++ b/gcc/config/rs6000/aix41.h
@@ -44,6 +44,7 @@ Boston, MA 02111-1307, USA. */
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
+ %{ansi: -D_ANSI_C_SOURCE}\
%{mpe: -I/usr/lpp/ppe.poe/include}\
%{mthreads: -D_THREAD_SAFE}\
%(cpp_cpu)"
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 3822c0a2aa3..d700a44ff97 100644
--- a/gcc/config/rs6000/aix43.h
+++ b/gcc/config/rs6000/aix43.h
@@ -105,6 +105,7 @@ do { \
#undef CPP_SPEC
#define CPP_SPEC "%{posix: -D_POSIX_SOURCE}\
+ %{ansi: -D_ANSI_C_SOURCE}\
%{maix64: -D__64BIT__ -D_ARCH_PPC}\
%{mpe: -I/usr/lpp/ppe.poe/include}\
%{mthreads: -D_THREAD_SAFE}\
diff --git a/gcc/config/rs6000/eabi.h b/gcc/config/rs6000/eabi.h
index 5293a076cce..3da807f8379 100644
--- a/gcc/config/rs6000/eabi.h
+++ b/gcc/config/rs6000/eabi.h
@@ -20,8 +20,6 @@ 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 "rs6000/sysv4.h"
-
/* Add -meabi to target flags */
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_EABI)
@@ -36,6 +34,3 @@ Boston, MA 02111-1307, USA. */
#undef CPP_PREDEFINES
#define CPP_PREDEFINES \
"-DPPC -D__embedded__ -Asystem(embedded) -Acpu(powerpc) -Amachine(powerpc)"
-
-#undef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mbig", "mcall-sysv" }
diff --git a/gcc/config/rs6000/eabiaix.h b/gcc/config/rs6000/eabiaix.h
index 5cfd890a03e..639a3358356 100644
--- a/gcc/config/rs6000/eabiaix.h
+++ b/gcc/config/rs6000/eabiaix.h
@@ -1,5 +1,5 @@
/* Embedded ELF system support, using old AIX based calling sequence.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GNU CC.
@@ -19,8 +19,6 @@ 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 "rs6000/eabi.h"
-
/* Default ABI to use */
#undef RS6000_ABI_NAME
#define RS6000_ABI_NAME "aix"
diff --git a/gcc/config/rs6000/eabile.h b/gcc/config/rs6000/eabile.h
deleted file mode 100644
index 97e2b7c6e85..00000000000
--- a/gcc/config/rs6000/eabile.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Core target definitions for GNU compiler for PowerPC targeted to
- little endian embedded ELF systems.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
- Contributed by Cygnus Support.
-
-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 "rs6000/eabi.h"
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN | MASK_EABI)
-
-#undef CPP_ENDIAN_DEFAULT_SPEC
-#define CPP_ENDIAN_DEFAULT_SPEC "%(cpp_endian_little)"
-
-#undef CC1_ENDIAN_DEFAULT_SPEC
-#define CC1_ENDIAN_DEFAULT_SPEC "%(cc1_endian_little)"
-
-#undef LINK_TARGET_SPEC
-#define LINK_TARGET_SPEC "\
-%{mbig: -oformat elf32-powerpc } %{mbig-endian: -oformat elf32-powerpc } \
-%{!mlittle: %{!mlittle-endian: %{!mbig: %{!mbig-endian: %{mcall-linux: -oformat elf32-powerpc}}}}}"
-
-/* Define this macro as a C expression for the initializer of an
- array of string to tell the driver program which options are
- defaults for this target and thus do not need to be handled
- specially when using `MULTILIB_OPTIONS'.
-
- Do not define this macro if `MULTILIB_OPTIONS' is not defined in
- the target makefile fragment or if none of the options listed in
- `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
-
-#undef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mlittle", "mcall-sysv" }
diff --git a/gcc/config/rs6000/eabilesim.h b/gcc/config/rs6000/eabilesim.h
deleted file mode 100644
index 7ced05c7cb2..00000000000
--- a/gcc/config/rs6000/eabilesim.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Support for GCC on simulated PowerPC systems targeted to embedded ELF
- systems.
- Copyright (C) 1995 Free Software Foundation, Inc.
- Contributed by Cygnus Support.
-
-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 "rs6000/eabile.h"
-
-#undef TARGET_VERSION
-#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES \
- "-DPPC -D__embedded__ -D__simulator__ -Asystem(embedded) -Asystem(simulator) -Acpu(powerpc) -Amachine(powerpc)"
-
-/* Make the simulator the default */
-#undef LIB_DEFAULT_SPEC
-#define LIB_DEFAULT_SPEC "%(lib_sim)"
-
-#undef STARTFILE_DEFAULT_SPEC
-#define STARTFILE_DEFAULT_SPEC "%(startfile_sim)"
-
-#undef ENDFILE_DEFAULT_SPEC
-#define ENDFILE_DEFAULT_SPEC "%(endfile_sim)"
-
-#undef LINK_START_DEFAULT_SPEC
-#define LINK_START_DEFAULT_SPEC "%(link_start_sim)"
-
-#undef LINK_OS_DEFAULT_SPEC
-#define LINK_OS_DEFAULT_SPEC "%(link_start_sim)"
diff --git a/gcc/config/rs6000/eabisim.h b/gcc/config/rs6000/eabisim.h
index 0fc590bd6f2..7e6effb4cb4 100644
--- a/gcc/config/rs6000/eabisim.h
+++ b/gcc/config/rs6000/eabisim.h
@@ -1,6 +1,6 @@
/* Support for GCC on simulated PowerPC systems targeted to embedded ELF
systems.
- Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc.
Contributed by Cygnus Support.
This file is part of GNU CC.
@@ -20,8 +20,6 @@ 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 "rs6000/eabi.h"
-
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC Simulated)");
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index c2a04fa85b1..ffa78ae4359 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -1,6 +1,6 @@
/* Definitions of target machine for GNU compiler,
for IBM RS/6000 running AIX version 3.1.
- Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
Contributed by Michael Meissner (meissner@cygnus.com).
This file is part of GNU CC.
@@ -20,8 +20,6 @@ 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 "rs6000/sysv4.h"
-
/* Don't assume anything about the header files. */
#define NO_IMPLICIT_EXTERN_C
@@ -55,22 +53,7 @@ Boston, MA 02111-1307, USA. */
#undef TARGET_VERSION
#define TARGET_VERSION fprintf (stderr, " (PowerPC GNU/Linux)");
-/* Define this macro as a C expression for the initializer of an
- array of string to tell the driver program which options are
- defaults for this target and thus do not need to be handled
- specially when using `MULTILIB_OPTIONS'.
-
- Do not define this macro if `MULTILIB_OPTIONS' is not defined in
- the target makefile fragment or if none of the options listed in
- `MULTILIB_OPTIONS' are set by default. *Note Target Fragment::. */
-
-#undef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mbig", "mcall-linux" }
-
#undef DEFAULT_VTABLE_THUNKS
#ifndef USE_GNULIBC_1
#define DEFAULT_VTABLE_THUNKS 1
#endif
-
-#undef JUMP_TABLES_IN_TEXT_SECTION
-#define JUMP_TABLES_IN_TEXT_SECTION 0
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 04539ee0c13..82ad6ed086c 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3325,6 +3325,8 @@ print_operand (file, x, code)
putc ((DEFAULT_ABI == ABI_SOLARIS) ? '.' : '$', file);
return;
+ /* %a is output_address. */
+
case 'A':
/* If X is a constant integer whose low-order 5 bits are zero,
write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
@@ -3350,6 +3352,9 @@ print_operand (file, x, code)
putc (((INT_LOWPART(x) & 1) == 0 ? 'r' : 'l'), file);
return;
+ /* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
+ output_operand. */
+
case 'C':
{
enum rtx_code code = GET_CODE (x);
@@ -3496,7 +3501,7 @@ print_operand (file, x, code)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, ~ INT_LOWPART (x));
return;
- case 'l':
+ case 'K':
/* X must be a symbolic constant on ELF. Write an
expression suitable for an 'addi' that adds in the low 16
bits of the MEM. */
@@ -3516,6 +3521,9 @@ print_operand (file, x, code)
fputs ("@l", file);
print_operand (file, XEXP (XEXP (x, 0), 1), 0);
}
+ return;
+
+ /* %l is output_asm_label. */
case 'L':
/* Write second word of DImode or DFmode reference. Works on register
@@ -3610,6 +3618,8 @@ print_operand (file, x, code)
fprintf (file, "%d", i);
return;
+ /* %n outputs the negative of its operand. */
+
case 'N':
/* Write the number of elements in the vector times 4. */
if (GET_CODE (x) != PARALLEL)
@@ -3918,11 +3928,11 @@ print_operand (file, x, code)
/* We need to handle PRE_INC and PRE_DEC here, since we need to
know the width from the mode. */
if (GET_CODE (XEXP (x, 0)) == PRE_INC)
- fprintf (file, "%d(%d)", GET_MODE_SIZE (GET_MODE (x)),
- REGNO (XEXP (XEXP (x, 0), 0)));
+ fprintf (file, "%d(%s)", GET_MODE_SIZE (GET_MODE (x)),
+ reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
- fprintf (file, "%d(%d)", - GET_MODE_SIZE (GET_MODE (x)),
- REGNO (XEXP (XEXP (x, 0), 0)));
+ fprintf (file, "%d(%s)", - GET_MODE_SIZE (GET_MODE (x)),
+ reg_names[REGNO (XEXP (XEXP (x, 0), 0))]);
else
output_address (XEXP (x, 0));
}
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9b4ed256a86..11f96a381b6 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -43,11 +43,6 @@ Boston, MA 02111-1307, USA. */
#define TARGET_CPU_DEFAULT ((char *)0)
#endif
-/* Define appropriate architecture macros for preprocessor depending on
- target switches. */
-
-#define CPP_SPEC "%{posix: -D_POSIX_SOURCE} %(cpp_cpu)"
-
/* Common CPP definitions used by CPP_SPEC among the various targets
for handling -mcpu=xxx switches. */
#define CPP_CPU_SPEC \
@@ -623,7 +618,7 @@ extern int rs6000_debug_arg; /* debug argument handling */
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
((STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == DImode) \
- && (ALIGN) < 4)) ? 1 : 0)
+ && (ALIGN) < 32)) ? 1 : 0)
/* Standard register usage. */
@@ -1288,7 +1283,7 @@ extern int rs6000_sysv_varargs_p;
/* Define this if the maximum size of all the outgoing args is to be
accumulated and pushed during the prologue. The amount can be
found in the variable current_function_outgoing_args_size. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 8d9d8a70f83..4573330a820 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -7923,7 +7923,7 @@
"TARGET_ELF && ! TARGET_64BIT"
"@
{cal|la} %0,%2@l(%1)
- {ai|addic} %0,%1,%l2")
+ {ai|addic} %0,%1,%K2")
;; Set up a register with a value from the GOT table
diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h
index 1215c7283e3..2be11f1c16c 100644
--- a/gcc/config/rs6000/rtems.h
+++ b/gcc/config/rs6000/rtems.h
@@ -19,8 +19,6 @@ 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 "rs6000/eabi.h"
-
/* Specify predefined symbols in preprocessor. */
#undef CPP_PREDEFINES
diff --git a/gcc/config/rs6000/sol2.h b/gcc/config/rs6000/sol2.h
index 76df9b01529..55f32614054 100644
--- a/gcc/config/rs6000/sol2.h
+++ b/gcc/config/rs6000/sol2.h
@@ -20,8 +20,6 @@ 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 "rs6000/sysv4le.h"
-
/* Default ABI to use */
#undef RS6000_ABI_NAME
#define RS6000_ABI_NAME "solaris"
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 644438cc6c6..f87f7aef32b 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -1293,12 +1293,12 @@ do { \
#define STARTFILE_LINUX_SPEC "\
%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} %{!p:crt1.o%s}}} \
-%{mnewlib: ecrti.o%s} \
-%{!mnewlib: crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
+%{mnewlib: ecrti.o%s} %{!mnewlib: crti.o%s} \
+crtbegin.o%s"
-#define ENDFILE_LINUX_SPEC "\
+#define ENDFILE_LINUX_SPEC "crtend.o%s \
%{mnewlib: ecrtn.o%s} \
-%{!mnewlib: %{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s}"
+%{!mnewlib: crtn.o%s}"
#define LINK_START_LINUX_SPEC "-Ttext 0x400074"
diff --git a/gcc/config/rs6000/sysv4le.h b/gcc/config/rs6000/sysv4le.h
index a19dd787991..09ec2f72bf6 100644
--- a/gcc/config/rs6000/sysv4le.h
+++ b/gcc/config/rs6000/sysv4le.h
@@ -20,8 +20,6 @@ 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 "rs6000/sysv4.h"
-
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_LITTLE_ENDIAN)
diff --git a/gcc/config/rs6000/t-aix43 b/gcc/config/rs6000/t-aix43
index 814ef42e6f3..aa17f106e90 100644
--- a/gcc/config/rs6000/t-aix43
+++ b/gcc/config/rs6000/t-aix43
@@ -51,7 +51,7 @@ INSTALL_LIBGCC = install-multilib
# Both 32-bit and 64-bit objects in archives
-AR_FLAGS_FOR_TARGET=-X32_64 rc
+AR_FLAGS_FOR_TARGET=-X32_64
# We need -lld for collect2 (actually this only matters
# for a native compiler, but this is as good a place as any
diff --git a/gcc/config/rs6000/t-ppc b/gcc/config/rs6000/t-ppc
deleted file mode 100644
index 8143488a5d6..00000000000
--- a/gcc/config/rs6000/t-ppc
+++ /dev/null
@@ -1,12 +0,0 @@
-# PowerPC support without gas
-
-# Build libgcc.a with different options. If no gas support, don't build
-# explicit little endian or big endian libraries, since it depends on the
-# -mbig/-mlittle switches passed to gas. The -mrelocatable support also needs
-# -mrelocatable passed to gas, so don't use it either.
-
-MULTILIB_OPTIONS = msoft-float
-MULTILIB_DIRNAMES = nof
-MULTILIB_EXCEPTIONS =
-MULTILIB_EXTRA_OPTS = mstrict-align
-MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
diff --git a/gcc/config/rs6000/t-ppccomm b/gcc/config/rs6000/t-ppccomm
index 231c9cec446..00fd44b16b8 100644
--- a/gcc/config/rs6000/t-ppccomm
+++ b/gcc/config/rs6000/t-ppccomm
@@ -1,4 +1,4 @@
-# Common support for PowerPC eabi, System V targets.
+# Common support for PowerPC ELF targets (both EABI and SVR4).
# Do not build libgcc1.
LIBGCC1 =
@@ -43,7 +43,8 @@ MULTILIB_MATCHES_SYSV = mcall-sysv=mcall-sysv-eabi mcall-sysv=mcall-sysv-noeabi
LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
-EXTRA_MULTILIB_PARTS = ecrti$(objext) ecrtn$(objext) scrt0$(objext) scrti$(objext) scrtn$(objext)
+EXTRA_MULTILIB_PARTS = crtbegin$(objext) crtend$(objext) \
+ ecrti$(objext) ecrtn$(objext) scrt0$(objext) scrti$(objext) scrtn$(objext)
# We build {e,s}crti.o, {e,s}crtn.o, and scrt0.o which serve to add begin and
# end labels to all of the special sections used when we link using gcc.
@@ -82,4 +83,4 @@ $(T)scrt0$(objext): scrt0.c
# It is important that crtbegin.o, etc., aren't surprised by stuff in .sdata.
CRTSTUFF_T_CFLAGS = -msdata=none
-CRTSTUFF_T_CFLAGS_S = -fpic -msdata=none
+
diff --git a/gcc/config/rs6000/t-ppcgas b/gcc/config/rs6000/t-ppcgas
index 0765a9e4c6e..9b82b9f1796 100644
--- a/gcc/config/rs6000/t-ppcgas
+++ b/gcc/config/rs6000/t-ppcgas
@@ -1,5 +1,4 @@
-# PowerPC embedded support with gas.
-# Build libgcc.a with different options.
+# Multilibs for powerpc embedded ELF targets.
MULTILIB_OPTIONS = msoft-float \
mlittle/mbig \
diff --git a/gcc/config/rs6000/t-ppcos b/gcc/config/rs6000/t-ppcos
index 480665a8937..68a58161654 100644
--- a/gcc/config/rs6000/t-ppcos
+++ b/gcc/config/rs6000/t-ppcos
@@ -1,12 +1,8 @@
-# Target config file for a System V based system (Solaris, GNU/Linux, Netbsd)
-# with gas.
+# Multilibs for a powerpc hosted ELF target (linux, SVR4, solaris)
-# Build libgcc.a with different options. With gas, build pic libraries
-# as well no floating point
-MULTILIB_OPTIONS = msoft-float fPIC
-MULTILIB_DIRNAMES = nof pic
-MULTILIB_EXCEPTIONS =
-MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT} \
- fPIC=mrelocatable-lib \
- fPIC=mrelocatable \
- fPIC=fpic
+MULTILIB_OPTIONS = msoft-float
+MULTILIB_DIRNAMES = nof
+MULTILIB_EXTRA_OPTS = fPIC mstrict-align
+MULTILIB_EXCEPTIONS =
+
+MULTILIB_MATCHES = ${MULTILIB_MATCHES_FLOAT}
diff --git a/gcc/config/rs6000/vxppc.h b/gcc/config/rs6000/vxppc.h
index fa25760264c..01bc5f9908d 100644
--- a/gcc/config/rs6000/vxppc.h
+++ b/gcc/config/rs6000/vxppc.h
@@ -20,8 +20,6 @@ Boston, MA 02111-1307, USA. */
/* This file just exists to give specs for the PowerPC running on VxWorks. */
-#include "rs6000/sysv4.h"
-
/* Reset defaults */
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)"
diff --git a/gcc/config/rs6000/vxppcle.h b/gcc/config/rs6000/vxppcle.h
deleted file mode 100644
index fadec99ed78..00000000000
--- a/gcc/config/rs6000/vxppcle.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Definitions of target machine for GNU compiler. Vxworks PowerPC version.
- Copyright (C) 1996, 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. */
-
-/* This file just exists to give specs for the PowerPC running on VxWorks. */
-
-#include "rs6000/sysv4le.h"
-
-/* Reset defaults */
-#undef CPP_OS_DEFAULT_SPEC
-#define CPP_OS_DEFAULT_SPEC "%(cpp_os_vxworks)"
-
-#undef LIB_DEFAULT_SPEC
-#define LIB_DEFAULT_SPEC "%(lib_vxworks)"
-
-#undef STARTFILE_DEFAULT_SPEC
-#define STARTFILE_DEFAULT_SPEC "%(startfile_vxworks)"
-
-#undef ENDFILE_DEFAULT_SPEC
-#define ENDFILE_DEFAULT_SPEC "%(endfile_vxworks)"
-
-#undef LINK_START_DEFAULT_SPEC
-#define LINK_START_DEFAULT_SPEC "%(link_start_vxworks)"
-
-#undef LINK_OS_DEFAULT_SPEC
-#define LINK_OS_DEFAULT_SPEC "%(link_os_vxworks)"
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "\
--D__vxworks -D__vxworks__ -Asystem(vxworks) -Asystem(embedded) \
--Acpu(powerpc) -Amachine(powerpc)"
-
-/* Don't define _LITTLE_ENDIAN or _BIG_ENDIAN */
-#undef CPP_ENDIAN_BIG_SPEC
-#define CPP_ENDIAN_BIG_SPEC "-D__BIG_ENDIAN__ -Amachine(bigendian)"
-
-#undef CPP_ENDIAN_LITTLE_SPEC
-#define CPP_ENDIAN_LITTLE_SPEC "-D__LITTLE_ENDIAN__ -Amachine(littleendian)"
-
-/* We use stabs-in-elf for debugging */
-#undef PREFERRED_DEBUGGING_TYPE
-#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
diff --git a/gcc/config/sh/lib1funcs.asm b/gcc/config/sh/lib1funcs.asm
index 4db8ddc6c43..7cff30a05cc 100644
--- a/gcc/config/sh/lib1funcs.asm
+++ b/gcc/config/sh/lib1funcs.asm
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1994, 95, 97, 98, 1999, 2000 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
@@ -1044,6 +1044,9 @@ trivial:
lds r4,fpul
.align 2
+#ifdef FMOVD_WORKS
+ .align 3 ! make double below 8 byte aligned.
+#endif
L1:
.double 2147483648
@@ -1083,13 +1086,16 @@ ___udivsi3_i4:
rts
lds.l @r15+,fpscr
+#ifdef FMOVD_WORKS
+ .align 3 ! make double below 8 byte aligned.
+#endif
trivial:
rts
lds r4,fpul
.align 2
L1:
-#if defined (__LITTLE_ENDIAN__) || ! defined (FMOVD_WORKS)
+#ifndef FMOVD_WORKS
.long 0x80000
#else
.long 0x180000
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index a36e4c6fbb8..acc316ea376 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -90,6 +90,7 @@ extern void expand_sf_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *));
extern void expand_df_unop PARAMS ((rtx (*)(rtx, rtx, rtx), rtx *));
extern void expand_df_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *));
extern void expand_fp_branch PARAMS ((rtx (*)(void), rtx (*)(void)));
+extern int sh_insn_length_adjustment PARAMS ((rtx));
#ifdef TREE_CODE
extern void sh_va_start PARAMS ((int, tree, rtx));
extern rtx sh_va_arg PARAMS ((tree, tree));
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index 28d199cebfc..d4d38d35922 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -5127,3 +5127,79 @@ fpscr_set_from_mem (mode, regs_live)
REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_DEAD, addr_reg, REG_NOTES (i));
REG_NOTES (i) = gen_rtx_EXPR_LIST (REG_INC, addr_reg, REG_NOTES (i));
}
+
+/* Is the given character a logical line separator for the assembler? */
+#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
+#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == ';')
+#endif
+
+int
+sh_insn_length_adjustment (insn)
+ rtx insn;
+{
+ /* Instructions with unfilled delay slots take up an extra two bytes for
+ the nop in the delay slot. */
+ if (((GET_CODE (insn) == INSN
+ && GET_CODE (PATTERN (insn)) != USE
+ && GET_CODE (PATTERN (insn)) != CLOBBER)
+ || GET_CODE (insn) == CALL_INSN
+ || (GET_CODE (insn) == JUMP_INSN
+ && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
+ && GET_CODE (PATTERN (insn)) != ADDR_VEC))
+ && GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) != SEQUENCE
+ && get_attr_needs_delay_slot (insn) == NEEDS_DELAY_SLOT_YES)
+ return 2;
+
+ /* sh-dsp parallel processing insn take four bytes instead of two. */
+
+ if (GET_CODE (insn) == INSN)
+ {
+ int sum = 0;
+ rtx body = PATTERN (insn);
+ char *template, c;
+ int maybe_label = 1;
+
+ if (GET_CODE (body) == ASM_INPUT)
+ template = XSTR (body, 0);
+ else if (asm_noperands (body) >= 0)
+ template
+ = decode_asm_operands (body, NULL_PTR, NULL_PTR, NULL_PTR, NULL_PTR);
+ else
+ return 0;
+ do
+ {
+ int ppi_adjust = 0;
+
+ do
+ c = *template++;
+ while (c == ' ' || c == '\t');
+ /* all sh-dsp parallel-processing insns start with p.
+ The only non-ppi sh insn starting with p is pref.
+ The only ppi starting with pr is prnd. */
+ if ((c == 'p' || c == 'P') && strncasecmp ("re", template, 2))
+ ppi_adjust = 2;
+ /* The repeat pseudo-insn expands two three insns, a total of
+ six bytes in size. */
+ else if ((c == 'r' || c == 'R')
+ && ! strncasecmp ("epeat", template, 5))
+ ppi_adjust = 4;
+ while (c && c != '\n' && ! IS_ASM_LOGICAL_LINE_SEPARATOR (c))
+ {
+ /* If this is a label, it is obviously not a ppi insn. */
+ if (c == ':' && maybe_label)
+ {
+ ppi_adjust = 0;
+ break;
+ }
+ else if (c == '\'' || c == '"')
+ maybe_label = 0;
+ c = *template++;
+ }
+ sum += ppi_adjust;
+ maybe_label = c != ':';
+ }
+ while (c);
+ return sum;
+ }
+ return 0;
+}
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 777fd51e3f0..acd1fdc29dc 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -592,7 +592,25 @@ do { \
where the address is passed. If it returns 0, the address is
passed as an "invisible" first argument. */
-/*#define STRUCT_VALUE ((rtx)0)*/
+/* The Hitachi calling convention doesn't quite fit into this scheme since
+ the address is passed like an invisible argument, but one that is always
+ passed in memory. We approximate this by saying where the pointer is;
+ however, this will put any actual arguments that are passed in memory
+ in the wrong place.
+ If we wanted to implement this exactly, we'd need a STRUCT_VALUE of 0,
+ an extra field in CUMULATIVE_ARGS, initialize it in INIT_CUMULATIVE_ARGS,
+ and hack FUNCTION_ARG (actually PASS_IN_REG_P) / FUNCTION_ARG_ADVANCE
+ to look directly at DECL_RESULT of the current function in conjunction
+ with CUM to determine if the argument in question it is a struct value
+ pointer, and if it is, pass it in memory. */
+#define STRUCT_VALUE \
+ (TARGET_HITACHI \
+ ? gen_rtx_MEM (Pmode, arg_pointer_rtx) \
+ : gen_rtx_REG (Pmode, STRUCT_VALUE_REGNUM))
+
+#define RETURN_IN_MEMORY(TYPE) \
+ (TYPE_MODE (TYPE) == BLKmode \
+ || TARGET_HITACHI && TREE_CODE (TYPE) == RECORD_TYPE)
/* Don't default to pcc-struct-return, because we have already specified
exactly how to return structures in the RETURN_IN_MEMORY macro. */
@@ -1066,7 +1084,7 @@ struct sh_args {
+ ((MODE) != BLKmode \
? ROUND_ADVANCE (GET_MODE_SIZE (MODE)) \
: ROUND_ADVANCE (int_size_in_bytes (TYPE))) \
- - NPARM_REGS (MODE) > 0)) \
+ > NPARM_REGS (MODE))) \
? NPARM_REGS (MODE) - ROUND_REG ((CUM), (MODE)) \
: 0)
@@ -1183,7 +1201,7 @@ extern int current_function_anonymous_args;
#define MOVE_BY_PIECES_P(SIZE, ALIGN) (move_by_pieces_ninsns (SIZE, ALIGN) \
< (TARGET_SMALLCODE ? 2 : \
- ((ALIGN >= 4) ? 16 : 2)))
+ ((ALIGN >= 32) ? 16 : 2)))
/* Macros to check register numbers against specific register classes. */
@@ -2122,20 +2140,12 @@ extern int rtx_equal_function_value_matters;
extern struct rtx_def *fpscr_rtx;
-/* Instructions with unfilled delay slots take up an extra two bytes for
- the nop in the delay slot. */
+/* Instructions with unfilled delay slots take up an
+ extra two bytes for the nop in the delay slot.
+ sh-dsp parallel processing insns are four bytes long. */
#define ADJUST_INSN_LENGTH(X, LENGTH) \
- if (((GET_CODE (X) == INSN \
- && GET_CODE (PATTERN (X)) != USE \
- && GET_CODE (PATTERN (X)) != CLOBBER) \
- || GET_CODE (X) == CALL_INSN \
- || (GET_CODE (X) == JUMP_INSN \
- && GET_CODE (PATTERN (X)) != ADDR_DIFF_VEC \
- && GET_CODE (PATTERN (X)) != ADDR_VEC)) \
- && GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (X)))) != SEQUENCE \
- && get_attr_needs_delay_slot (X) == NEEDS_DELAY_SLOT_YES) \
- (LENGTH) += 2;
+ (LENGTH) += sh_insn_length_adjustment (X);
/* Define the codes that are matched by predicates in sh.c. */
#define PREDICATE_CODES \
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 57981bc1aa6..fdab0f4cb94 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -3803,6 +3803,7 @@
(use (match_operand:SI 0 "arith_reg_operand" "r"))
(use (reg:SI 6))
(clobber (reg:SI 17))
+ (clobber (reg:SI 18))
(clobber (reg:SI 4))
(clobber (reg:SI 5))
(clobber (reg:SI 6))
@@ -3831,6 +3832,7 @@
(use (match_operand:SI 0 "arith_reg_operand" "r"))
(use (reg:SI 6))
(clobber (reg:SI 17))
+ (clobber (reg:SI 18))
(clobber (reg:SI 4))
(clobber (reg:SI 5))
(clobber (reg:SI 6))
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 8d8487512eb..557079695ec 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -155,6 +155,7 @@ static void ultra_build_types_avail PARAMS ((rtx *, int));
static void ultra_flush_pipeline PARAMS ((void));
static void ultra_rescan_pipeline_state PARAMS ((rtx *, int));
static int set_extends PARAMS ((rtx, rtx));
+static void output_restore_regs PARAMS ((FILE *, int));
/* Option handling. */
@@ -341,6 +342,16 @@ sparc_override_options ()
target_flags &= ~MASK_FPU_SET;
}
+ /* Don't allow -mvis if FPU is disabled. */
+ if (! TARGET_FPU)
+ target_flags &= ~MASK_VIS;
+
+ /* -mvis assumes UltraSPARC+, so we are sure v9 instructions
+ are available.
+ -m64 also implies v9. */
+ if (TARGET_VIS || TARGET_ARCH64)
+ target_flags |= MASK_V9;
+
/* Use the deprecated v8 insns for sparc64 in 32 bit mode. */
if (TARGET_V9 && TARGET_ARCH32)
target_flags |= MASK_DEPRECATED_V8_INSNS;
@@ -353,10 +364,6 @@ sparc_override_options ()
if (TARGET_ARCH32)
target_flags &= ~MASK_STACK_BIAS;
- /* Don't allow -mvis if FPU is disabled. */
- if (! TARGET_FPU)
- target_flags &= ~MASK_VIS;
-
/* Supply a default value for align_functions. */
if (align_functions == 0 && sparc_cpu == PROCESSOR_ULTRASPARC)
align_functions = 32;
@@ -2938,9 +2945,10 @@ mem_min_alignment (mem, desired)
completed, we already matched with proper alignments.
If not running global_alloc, reload might give us
unaligned pointer to local stack though. */
- if (((cfun != 0 && REGNO_POINTER_ALIGN (regno) >= desired)
+ if (((cfun != 0
+ && REGNO_POINTER_ALIGN (regno) >= desired * BITS_PER_UNIT)
|| (optimize && reload_completed))
- && ((INTVAL (offset) & (desired - 1)) == 0))
+ && (INTVAL (offset) & (desired - 1)) == 0)
return 1;
}
else
@@ -4057,22 +4065,25 @@ struct function_arg_record_value_parms
{
rtx ret;
int slotno, named, regbase;
- int nregs, intoffset;
+ unsigned int nregs;
+ int intoffset;
};
static void function_arg_record_value_3
- PARAMS ((int, struct function_arg_record_value_parms *));
+ PARAMS ((HOST_WIDE_INT, struct function_arg_record_value_parms *));
static void function_arg_record_value_2
- PARAMS ((tree, int, struct function_arg_record_value_parms *));
+ PARAMS ((tree, HOST_WIDE_INT,
+ struct function_arg_record_value_parms *));
static void function_arg_record_value_1
- PARAMS ((tree, int, struct function_arg_record_value_parms *));
+ PARAMS ((tree, HOST_WIDE_INT,
+ struct function_arg_record_value_parms *));
static rtx function_arg_record_value
PARAMS ((tree, enum machine_mode, int, int, int));
static void
function_arg_record_value_1 (type, startbitpos, parms)
tree type;
- int startbitpos;
+ HOST_WIDE_INT startbitpos;
struct function_arg_record_value_parms *parms;
{
tree field;
@@ -4100,15 +4111,16 @@ function_arg_record_value_1 (type, startbitpos, parms)
{
if (TREE_CODE (field) == FIELD_DECL)
{
- int bitpos = startbitpos;
- if (DECL_FIELD_BITPOS (field))
- bitpos += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
+ HOST_WIDE_INT bitpos = startbitpos;
+
+ if (DECL_SIZE (field) != 0
+ && host_integerp (bit_position (field), 1))
+ bitpos += int_bit_position (field);
+
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- {
- function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
- }
+ function_arg_record_value_1 (TREE_TYPE (field), bitpos, parms);
else if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
&& TARGET_FPU
&& ! packed_p
@@ -4146,15 +4158,17 @@ function_arg_record_value_1 (type, startbitpos, parms)
static void
function_arg_record_value_3 (bitpos, parms)
- int bitpos;
+ HOST_WIDE_INT bitpos;
struct function_arg_record_value_parms *parms;
{
enum machine_mode mode;
- int regno, this_slotno, intslots, intoffset;
+ unsigned int regno;
+ int this_slotno, intslots, intoffset;
rtx reg;
if (parms->intoffset == -1)
return;
+
intoffset = parms->intoffset;
parms->intoffset = -1;
@@ -4171,10 +4185,8 @@ function_arg_record_value_3 (bitpos, parms)
at the moment but may wish to revisit. */
if (intoffset % BITS_PER_WORD != 0)
- {
- mode = mode_for_size (BITS_PER_WORD - intoffset%BITS_PER_WORD,
- MODE_INT, 0);
- }
+ mode = mode_for_size (BITS_PER_WORD - intoffset % BITS_PER_WORD,
+ MODE_INT, 0);
else
mode = word_mode;
@@ -4197,7 +4209,7 @@ function_arg_record_value_3 (bitpos, parms)
static void
function_arg_record_value_2 (type, startbitpos, parms)
tree type;
- int startbitpos;
+ HOST_WIDE_INT startbitpos;
struct function_arg_record_value_parms *parms;
{
tree field;
@@ -4216,15 +4228,16 @@ function_arg_record_value_2 (type, startbitpos, parms)
{
if (TREE_CODE (field) == FIELD_DECL)
{
- int bitpos = startbitpos;
- if (DECL_FIELD_BITPOS (field))
- bitpos += TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
+ HOST_WIDE_INT bitpos = startbitpos;
+
+ if (DECL_SIZE (field) != 0
+ && host_integerp (bit_position (field), 1))
+ bitpos += int_bit_position (field);
+
/* ??? FIXME: else assume zero offset. */
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
- {
- function_arg_record_value_2 (TREE_TYPE (field), bitpos, parms);
- }
+ function_arg_record_value_2 (TREE_TYPE (field), bitpos, parms);
else if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
&& TARGET_FPU
&& ! packed_p
@@ -4261,7 +4274,7 @@ function_arg_record_value (type, mode, slotno, named, regbase)
{
HOST_WIDE_INT typesize = int_size_in_bytes (type);
struct function_arg_record_value_parms parms;
- int nregs;
+ unsigned int nregs;
parms.ret = NULL_RTX;
parms.slotno = slotno;
@@ -5046,7 +5059,7 @@ sparc_emit_float_lib_cmp (x, y, comparison)
rtx x, y;
enum rtx_code comparison;
{
- char *qpfunc;
+ const char *qpfunc;
rtx slot0, slot1, result, tem, tem2;
enum machine_mode mode;
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index c9368ebe060..5b226578d8b 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1454,6 +1454,8 @@ extern char leaf_reg_remap[];
/* - We can't load constants into FP registers.
- We can't load FP constants into integer registers when soft-float,
because there is no soft-float pattern with a r/F constraint.
+ - We can't load FP constants into integer registers for TFmode unless
+ it is 0.0L, because there is no movtf pattern with a r/F constraint.
- Try and reload integer constants (symbolic or otherwise) back into
registers directly, rather than having them dumped to memory. */
@@ -1461,7 +1463,9 @@ extern char leaf_reg_remap[];
(CONSTANT_P (X) \
? ((FP_REG_CLASS_P (CLASS) \
|| (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \
- && ! TARGET_FPU)) \
+ && ! TARGET_FPU) \
+ || (GET_MODE (X) == TFmode \
+ && ! fp_zero_operand (X, TFmode))) \
? NO_REGS \
: (!FP_REG_CLASS_P (CLASS) \
&& GET_MODE_CLASS (GET_MODE (X)) == MODE_INT) \
@@ -1606,7 +1610,7 @@ extern char leaf_reg_remap[];
This is both an optimization and a necessity: longjmp
doesn't behave itself when the stack pointer moves within
the function! */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
@@ -2298,7 +2302,7 @@ LFLGRET"ID":\n\
#define REG_OK_FOR_BASE_P(X) \
(((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
-/* 'T', 'U' are for aligned memory loads which aren't needed for v9. */
+/* 'T', 'U' are for aligned memory loads which aren't needed for arch64. */
#define EXTRA_CONSTRAINT(OP, C) \
(EXTRA_CONSTRAINT_BASE(OP, C) \
@@ -2359,7 +2363,7 @@ LFLGRET"ID":\n\
&& REG_OK_FOR_INDEX_P (SUBREG_REG (X))))
#define RTX_OK_FOR_OFFSET_P(X) \
- (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000)
+ (GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0x1000 - 8)
#define RTX_OK_FOR_OLO10_P(X) \
(GET_CODE (X) == CONST_INT && INTVAL (X) >= -0x1000 && INTVAL (X) < 0xc00 - 8)
@@ -2396,10 +2400,19 @@ LFLGRET"ID":\n\
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))) \
+ && (MODE != TFmode \
+ || (TARGET_FPU && TARGET_ARCH64 \
+ && TARGET_V9 \
+ && TARGET_HARD_QUAD)) \
+ /* We prohibit REG + REG on ARCH32 if \
+ not optimizing for DFmode/DImode \
+ because then mem_min_alignment is \
+ likely to be zero after reload and the \
+ forced split would lack a matching \
+ splitter pattern. */ \
+ && (TARGET_ARCH64 || optimize \
+ || (MODE != DFmode \
+ && MODE != DImode))) \
|| RTX_OK_FOR_OFFSET_P (op1)) \
goto ADDR; \
} \
@@ -2407,10 +2420,13 @@ LFLGRET"ID":\n\
{ \
if ((RTX_OK_FOR_INDEX_P (op0) \
/* See the previous comment. */ \
- && (MODE != TFmode \
+ && (MODE != TFmode \
|| (TARGET_FPU && TARGET_ARCH64 \
&& TARGET_V9 \
- && TARGET_HARD_QUAD))) \
+ && TARGET_HARD_QUAD)) \
+ && (TARGET_ARCH64 || optimize \
+ || (MODE != DFmode \
+ && MODE != DImode))) \
|| RTX_OK_FOR_OFFSET_P (op0)) \
goto ADDR; \
} \
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 3b62a5eff7d..9b91c3090a3 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -1187,7 +1187,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(ne:DI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
(const_int 0))
@@ -1208,7 +1209,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(neg:DI (ne:DI (match_operand:DI 1 "register_operand" "")
(const_int 0))))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (ne:DI (match_dup 1)
(const_int 0))
@@ -1229,7 +1231,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(ne:SI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:SI (ne:DI (match_dup 1)
(const_int 0))
@@ -1314,7 +1317,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(eq:DI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
(const_int 0))
@@ -1335,7 +1339,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(neg:DI (eq:DI (match_operand:DI 1 "register_operand" "")
(const_int 0))))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:DI (eq:DI (match_dup 1)
(const_int 0))
@@ -1356,7 +1361,8 @@
[(set (match_operand:SI 0 "register_operand" "")
(eq:SI (match_operand:DI 1 "register_operand" "")
(const_int 0)))]
- "TARGET_ARCH64"
+ "TARGET_ARCH64
+ && ! reg_overlap_mentioned_p (operands[1], operands[0])"
[(set (match_dup 0) (const_int 0))
(set (match_dup 0) (if_then_else:SI (eq:DI (match_dup 1)
(const_int 0))
@@ -2568,10 +2574,28 @@
[(set_attr "type" "move")
(set_attr "length" "1")])
-(define_insn "*movdi_insn_sp64"
+(define_insn "*movdi_insn_sp64_novis"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
+ (match_operand:DI 1 "input_operand" "rI,K,J,m,rJ,e,m,e"))]
+ "TARGET_ARCH64 && ! TARGET_VIS &&
+ (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"
+ [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
+ (set_attr "length" "1")])
+
+(define_insn "*movdi_insn_sp64_vis"
[(set (match_operand:DI 0 "nonimmediate_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 &&
+ "TARGET_ARCH64 && TARGET_VIS &&
(register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
"@
@@ -3127,14 +3151,20 @@
if (GET_CODE (operands[0]) == REG
&& CONSTANT_P (operands[1]))
{
- if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
- 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);
+
+ if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
+ goto movsf_is_ok;
+
+ /* We are able to build any SF constant in integer registers
+ with at most 2 instructions. */
+ if (REGNO (operands[0]) < 32)
+ goto movsf_is_ok;
+
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
operands[1]));
}
@@ -3174,101 +3204,6 @@
;
}")
-(define_insn "*clear_df"
- [(set (match_operand:DF 0 "register_operand" "=e")
- (match_operand:DF 1 "fp_zero_operand" ""))]
- "TARGET_VIS"
- "fzero\\t%0"
- [(set_attr "type" "fpmove")
- (set_attr "length" "1")])
-
-(define_insn "*clear_dfp"
- [(set (match_operand:DF 0 "memory_operand" "=m")
- (match_operand:DF 1 "fp_zero_operand" ""))]
- "TARGET_V9"
- "stx\\t%%g0, %0"
- [(set_attr "type" "store")
- (set_attr "length" "1")])
-
-(define_insn "*movdf_const_intreg_sp32"
- [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
- (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
- "TARGET_FPU && ! TARGET_ARCH64"
- "@
- ldd\\t%1, %0
- #
- #"
- [(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 "register_operand" "=e,?r")
- (match_operand:DF 1 "const_double_operand" "m#F,F"))]
- "TARGET_FPU && TARGET_ARCH64"
- "@
- ldd\\t%1, %0
- #"
- [(set_attr "type" "move")
- (set_attr "length" "1,2")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "")
- (match_operand:DF 1 "const_double_operand" ""))]
- "TARGET_FPU
- && (GET_CODE (operands[0]) == REG
- && REGNO (operands[0]) < 32)
- && reload_completed"
- [(clobber (const_int 0))]
- "
-{
- 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)
- {
-#if HOST_BITS_PER_WIDE_INT == 64
- HOST_WIDE_INT val;
-
- val = ((HOST_WIDE_INT)(unsigned long)l[1] |
- ((HOST_WIDE_INT)(unsigned long)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
- {
- emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
- GEN_INT (l[1])));
- }
- }
- DONE;
-}")
-
(define_expand "movdf"
[(set (match_operand:DF 0 "general_operand" "")
(match_operand:DF 1 "general_operand" ""))]
@@ -3279,14 +3214,16 @@
if (GET_CODE (operands[0]) == REG
&& CONSTANT_P (operands[1]))
{
- if (TARGET_VIS && fp_zero_operand (operands[1], DFmode))
- 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);
+
+ if ((TARGET_VIS || REGNO (operands[0]) < 32)
+ && fp_zero_operand (operands[1], DFmode))
+ goto movdf_is_ok;
+
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
operands[1]));
}
@@ -3294,7 +3231,8 @@
/* Handle MEM cases first. */
if (GET_CODE (operands[0]) == MEM)
{
- if (register_operand (operands[1], DFmode))
+ if (register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))
goto movdf_is_ok;
if (! reload_in_progress)
@@ -3327,12 +3265,13 @@
;; Be careful, fmovd does not exist when !v9.
(define_insn "*movdf_insn_sp32"
- [(set (match_operand:DF 0 "nonimmediate_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"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
+ (match_operand:DF 1 "input_operand" "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
"TARGET_FPU
&& ! TARGET_V9
&& (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
"@
ldd\\t%1, %0
std\\t%1, %0
@@ -3348,12 +3287,14 @@
(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 "nonimmediate_operand" "=U,T,r,r,o")
- (match_operand:DF 1 "input_operand" "T,U,r,o,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
+ (match_operand:DF 1 "input_operand" "T,U,G,ro,r"))]
"! TARGET_FPU
+ && ! TARGET_V9
&& ! TARGET_ARCH64
&& (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
"@
ldd\\t%1, %0
std\\t%1, %0
@@ -3363,62 +3304,191 @@
[(set_attr "type" "load,store,*,*,*")
(set_attr "length" "1,1,2,2,2")])
+(define_insn "*movdf_no_e_insn_v9_sp32"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
+ (match_operand:DF 1 "input_operand" "T,U,G,ro,rG"))]
+ "! TARGET_FPU
+ && TARGET_V9
+ && ! TARGET_ARCH64
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
+ "@
+ ldd\\t%1, %0
+ std\\t%1, %0
+ stx\\t%r1, %0
+ #
+ #"
+ [(set_attr "type" "load,store,store,*,*")
+ (set_attr "length" "1,1,1,2,2")])
+
;; We have available v9 double floats but not 64-bit
-;; integer registers.
-(define_insn "*movdf_insn_v9only"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
- (match_operand:DF 1 "input_operand" "e,m,e,T,U,r,o,r"))]
+;; integer registers and no VIS.
+(define_insn "*movdf_insn_v9only_novis"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
+ (match_operand:DF 1 "input_operand" "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
"TARGET_FPU
&& TARGET_V9
+ && ! TARGET_VIS
&& ! TARGET_ARCH64
&& (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
"@
fmovd\\t%1, %0
ldd\\t%1, %0
+ stx\\t%r1, %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")])
+ [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
+ (set_attr "length" "1,1,1,1,1,1,2,2,2")])
+
+;; We have available v9 double floats but not 64-bit
+;; integer registers but we have VIS.
+(define_insn "*movdf_insn_v9only_vis"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
+ (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
+ "TARGET_FPU
+ && TARGET_VIS
+ && ! TARGET_ARCH64
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
+ "@
+ fzero\\t%1, %0
+ fmovd\\t%1, %0
+ ldd\\t%1, %0
+ stx\\t%r1, %0
+ std\\t%1, %0
+ ldd\\t%1, %0
+ std\\t%1, %0
+ #
+ #
+ #"
+ [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
+ (set_attr "length" "1,1,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 "nonimmediate_operand" "=e,e,m,r,r,m")
- (match_operand:DF 1 "input_operand" "e,m,e,r,m,r"))]
+;; integer registers. No VIS though.
+(define_insn "*movdf_insn_sp64_novis"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
+ (match_operand:DF 1 "input_operand" "e,m#F,e,*rG,m,*rG,F"))]
"TARGET_FPU
- && TARGET_V9
+ && ! TARGET_VIS
&& TARGET_ARCH64
&& (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
"@
fmovd\\t%1, %0
ldd\\t%1, %0
std\\t%1, %0
- mov\\t%1, %0
+ mov\\t%r1, %0
ldx\\t%1, %0
- stx\\t%1, %0"
- [(set_attr "type" "fpmove,load,store,move,load,store")
- (set_attr "length" "1")])
+ stx\\t%r1, %0
+ #"
+ [(set_attr "type" "fpmove,load,store,move,load,store,*")
+ (set_attr "length" "1,1,1,1,1,1,2")])
+
+;; We have available both v9 double floats and 64-bit
+;; integer registers. And we have VIS.
+(define_insn "*movdf_insn_sp64_vis"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
+ (match_operand:DF 1 "input_operand" "G,e,m#F,e,*rG,m,*rG,F"))]
+ "TARGET_FPU
+ && TARGET_VIS
+ && TARGET_ARCH64
+ && (register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
+ "@
+ fzero\\t%0
+ fmovd\\t%1, %0
+ ldd\\t%1, %0
+ std\\t%1, %0
+ mov\\t%r1, %0
+ ldx\\t%1, %0
+ stx\\t%r1, %0
+ #"
+ [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
+ (set_attr "length" "1,1,1,1,1,1,1,2")])
(define_insn "*movdf_no_e_insn_sp64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
- (match_operand:DF 1 "input_operand" "r,m,r"))]
+ (match_operand:DF 1 "input_operand" "r,m,rG"))]
"! TARGET_FPU
&& TARGET_ARCH64
&& (register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode))"
+ || register_operand (operands[1], DFmode)
+ || fp_zero_operand (operands[1], DFmode))"
"@
mov\\t%1, %0
ldx\\t%1, %0
- stx\\t%1, %0"
+ stx\\t%r1, %0"
[(set_attr "type" "move,load,store")
(set_attr "length" "1")])
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "const_double_operand" ""))]
+ "TARGET_FPU
+ && (GET_CODE (operands[0]) == REG
+ && REGNO (operands[0]) < 32)
+ && ! fp_zero_operand(operands[1], DFmode)
+ && reload_completed"
+ [(clobber (const_int 0))]
+ "
+{
+ 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)
+ {
+#if HOST_BITS_PER_WIDE_INT == 64
+ HOST_WIDE_INT val;
+
+ val = ((HOST_WIDE_INT)(unsigned long)l[1] |
+ ((HOST_WIDE_INT)(unsigned long)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
+ {
+ emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
+ GEN_INT (l[1])));
+ }
+ }
+ DONE;
+}")
+
;; 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
@@ -3471,17 +3541,11 @@
(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])))"
+ "reload_completed
+ && ! TARGET_ARCH64
+ && (((REGNO (operands[0]) % 2) != 0)
+ || ! mem_min_alignment (operands[1], 8))
+ && offsettable_memref_p (operands[1])"
[(clobber (const_int 0))]
"
{
@@ -3512,17 +3576,11 @@
(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])))"
+ "reload_completed
+ && ! TARGET_ARCH64
+ && (((REGNO (operands[1]) % 2) != 0)
+ || ! mem_min_alignment (operands[0], 8))
+ && offsettable_memref_p (operands[0])"
[(clobber (const_int 0))]
"
{
@@ -3539,45 +3597,51 @@
DONE;
}")
-(define_insn "*clear_tf"
- [(set (match_operand:TF 0 "register_operand" "=e")
- (match_operand:TF 1 "fp_zero_operand" ""))]
- "TARGET_VIS"
- "#"
- [(set_attr "type" "fpmove")
- (set_attr "length" "2")])
-
(define_split
- [(set (match_operand:TF 0 "register_operand" "")
- (match_operand:TF 1 "fp_zero_operand" ""))]
- "TARGET_VIS && reload_completed"
- [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
- (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
+ [(set (match_operand:DF 0 "memory_operand" "")
+ (match_operand:DF 1 "fp_zero_operand" ""))]
+ "reload_completed
+ && (! TARGET_V9
+ || (! TARGET_ARCH64
+ && ! mem_min_alignment (operands[0], 8)))
+ && offsettable_memref_p (operands[0])"
+ [(clobber (const_int 0))]
"
{
- operands[1] = CONST0_RTX (DFmode);
-}
-")
+ rtx dest1, dest2;
-(define_insn "*clear_tfp"
- [(set (match_operand:TF 0 "memory_operand" "=m")
- (match_operand:TF 1 "fp_zero_operand" ""))]
- "TARGET_V9"
- "#"
- [(set_attr "type" "fpmove")
- (set_attr "length" "2")])
+ dest1 = change_address (operands[0], SFmode, NULL_RTX);
+ dest2 = change_address (operands[0], SFmode,
+ plus_constant_for_output (XEXP (dest1, 0), 4));
+ emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
+ emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+ DONE;
+}")
(define_split
- [(set (match_operand:TF 0 "memory_operand" "=m")
- (match_operand:TF 1 "fp_zero_operand" ""))]
- "TARGET_V9 && reload_completed"
- [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
- (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
+ [(set (match_operand:DF 0 "register_operand" "")
+ (match_operand:DF 1 "fp_zero_operand" ""))]
+ "reload_completed
+ && ! 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))"
+ [(clobber (const_int 0))]
"
{
- operands[1] = CONST0_RTX (DFmode);
-}
-")
+ rtx set_dest = operands[0];
+ rtx dest1, dest2;
+
+ if (GET_CODE (set_dest) == SUBREG)
+ set_dest = alter_subreg (set_dest);
+ dest1 = gen_highpart (SFmode, set_dest);
+ dest2 = gen_lowpart (SFmode, set_dest);
+ emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
+ emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+ DONE;
+}")
(define_expand "movtf"
[(set (match_operand:TF 0 "general_operand" "")
@@ -3589,14 +3653,15 @@
if (GET_CODE (operands[0]) == REG
&& CONSTANT_P (operands[1]))
{
- if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
- goto movtf_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 (TFmode);
+
+ if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
+ goto movtf_is_ok;
+
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
operands[1]));
}
@@ -3605,8 +3670,9 @@
full 16-byte alignment for quads. */
if (GET_CODE (operands[0]) == MEM)
{
- if (register_operand (operands[1], TFmode))
- goto movtf_is_ok;
+ if (register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))
+ goto movtf_is_ok;
if (! reload_in_progress)
{
@@ -3639,12 +3705,26 @@
;; 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 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
- (match_operand:TF 1 "input_operand" "o,e,o,U,e,r,o,r"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
+ (match_operand:TF 1 "input_operand" "oe,GeUr,o,roG"))]
+ "TARGET_FPU
+ && ! TARGET_VIS
+ && ! TARGET_ARCH64
+ && (register_operand (operands[0], TFmode)
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
+ "#"
+ [(set_attr "length" "4")])
+
+(define_insn "*movtf_insn_vis_sp32"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,r")
+ (match_operand:TF 1 "input_operand" "Goe,GeUr,o,roG"))]
"TARGET_FPU
+ && TARGET_VIS
&& ! TARGET_ARCH64
&& (register_operand (operands[0], TFmode)
- || register_operand (operands[1], TFmode))"
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
"#"
[(set_attr "length" "4")])
@@ -3653,26 +3733,47 @@
;; when -mno-fpu.
(define_insn "*movtf_no_e_insn_sp32"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
- (match_operand:TF 1 "input_operand" "o,U,r,o,r"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
+ (match_operand:TF 1 "input_operand" "G,o,U,roG,r"))]
"! TARGET_FPU
&& ! TARGET_ARCH64
&& (register_operand (operands[0], TFmode)
- || register_operand (operands[1], TFmode))"
+ || register_operand (operands[1], TFmode)
+ || fp_zero_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 "nonimmediate_operand" "=e,e,m,r,r,o")
- (match_operand:TF 1 "input_operand" "e,m,e,r,o,r"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r")
+ (match_operand:TF 1 "input_operand" "e,m,e,Gr,roG"))]
"TARGET_FPU
+ && ! TARGET_VIS
&& TARGET_ARCH64
- && TARGET_V9
&& TARGET_HARD_QUAD
&& (register_operand (operands[0], TFmode)
- || register_operand (operands[1], TFmode))"
+ || register_operand (operands[1], TFmode)
+ || fp_zero_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")])
+
+(define_insn "*movtf_insn_hq_vis_sp64"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
+ (match_operand:TF 1 "input_operand" "e,m,e,G,roG,r"))]
+ "TARGET_FPU
+ && TARGET_VIS
+ && TARGET_ARCH64
+ && TARGET_HARD_QUAD
+ && (register_operand (operands[0], TFmode)
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
"@
fmovq\\t%1, %0
ldq\\t%1, %0
@@ -3686,23 +3787,39 @@
;; Now we allow the integer register cases even when
;; only arch64 is true.
(define_insn "*movtf_insn_sp64"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
- (match_operand:TF 1 "input_operand" "o,e,o,r,e,r"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
+ (match_operand:TF 1 "input_operand" "oe,Ger,orG"))]
"TARGET_FPU
+ && ! TARGET_VIS
&& TARGET_ARCH64
&& ! TARGET_HARD_QUAD
&& (register_operand (operands[0], TFmode)
- || register_operand (operands[1], TFmode))"
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
+ "#"
+ [(set_attr "length" "2")])
+
+(define_insn "*movtf_insn_vis_sp64"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r")
+ (match_operand:TF 1 "input_operand" "Goe,Ger,orG"))]
+ "TARGET_FPU
+ && TARGET_VIS
+ && TARGET_ARCH64
+ && ! TARGET_HARD_QUAD
+ && (register_operand (operands[0], TFmode)
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
"#"
[(set_attr "length" "2")])
(define_insn "*movtf_no_e_insn_sp64"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
- (match_operand:TF 1 "input_operand" "o,r,r"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
+ (match_operand:TF 1 "input_operand" "orG,rG"))]
"! TARGET_FPU
&& TARGET_ARCH64
&& (register_operand (operands[0], TFmode)
- || register_operand (operands[1], TFmode))"
+ || register_operand (operands[1], TFmode)
+ || fp_zero_operand (operands[1], TFmode))"
"#"
[(set_attr "length" "2")])
@@ -3748,6 +3865,39 @@
}")
(define_split
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "fp_zero_operand" ""))]
+ "reload_completed"
+ [(clobber (const_int 0))]
+ "
+{
+ rtx set_dest = operands[0];
+ rtx dest1, dest2;
+
+ switch (GET_CODE (set_dest))
+ {
+ case SUBREG:
+ set_dest = alter_subreg (set_dest);
+ /* FALLTHROUGH */
+ case REG:
+ dest1 = gen_df_reg (set_dest, 0);
+ dest2 = gen_df_reg (set_dest, 1);
+ break;
+ case MEM:
+ dest1 = change_address (set_dest, DFmode, NULL_RTX);
+ dest2 = change_address (set_dest, DFmode,
+ plus_constant_for_output (XEXP (dest1, 0), 8));
+ break;
+ default:
+ abort ();
+ }
+
+ emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
+ emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
+ DONE;
+}")
+
+(define_split
[(set (match_operand:TF 0 "register_operand" "")
(match_operand:TF 1 "memory_operand" ""))]
"(reload_completed
diff --git a/gcc/config/sparc/t-linux64 b/gcc/config/sparc/t-linux64
index bf81219d07e..2a3ec4b07ec 100644
--- a/gcc/config/sparc/t-linux64
+++ b/gcc/config/sparc/t-linux64
@@ -8,16 +8,3 @@ 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/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index c172c5db309..1badc79e103 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -667,7 +667,7 @@ enum reg_class
#define PROMOTE_PROTOTYPES 1
/* Keep the stack pointer constant throughout the function. */
-#define ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 1
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
diff --git a/gcc/configure b/gcc/configure
index 8e39a5d9658..969317281cc 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -43,9 +43,6 @@ ac_help="$ac_help
ac_help="$ac_help
--disable-cpplib use the old isolated C preprocessor."
ac_help="$ac_help
- --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
--enable-threads enable thread usage for target GCC.
@@ -79,6 +76,9 @@ ac_help="$ac_help
select the new abi for g++. You must select an ABI
at configuration time, so that the correct runtime
support is built. You cannot mix ABIs."
+ac_help="$ac_help
+ --enable-libstdcxx-v3
+ enable libstdc++-v3 for building and installation"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -852,18 +852,6 @@ 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 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.
@@ -980,7 +968,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:984: checking host system type" >&5
+echo "configure:972: checking host system type" >&5
host_alias=$host
case "$host_alias" in
@@ -1001,7 +989,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:1005: checking target system type" >&5
+echo "configure:993: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -1019,7 +1007,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:1023: checking build system type" >&5
+echo "configure:1011: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -1046,7 +1034,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:1050: checking for $ac_word" >&5
+echo "configure:1038: 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
@@ -1076,7 +1064,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:1080: checking for $ac_word" >&5
+echo "configure:1068: 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
@@ -1127,7 +1115,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:1131: checking for $ac_word" >&5
+echo "configure:1119: 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
@@ -1159,7 +1147,7 @@ fi
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:1163: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:1151: 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.
@@ -1170,12 +1158,12 @@ cross_compiling=$ac_cv_prog_cc_cross
cat > conftest.$ac_ext << EOF
-#line 1174 "configure"
+#line 1162 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
-if { (eval echo configure:1179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1167: \"$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
@@ -1201,12 +1189,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:1205: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:1193: 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:1210: checking whether we are using GNU C" >&5
+echo "configure:1198: 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
@@ -1215,7 +1203,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1219: \"$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:1207: \"$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
@@ -1234,7 +1222,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:1238: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:1226: 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
@@ -1266,7 +1254,7 @@ else
fi
echo $ac_n "checking for long double""... $ac_c" 1>&6
-echo "configure:1270: checking for long double" >&5
+echo "configure:1258: checking for long double" >&5
if eval "test \"`echo '$''{'gcc_cv_c_long_double'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1274,7 +1262,7 @@ else
gcc_cv_c_long_double=yes
else
cat > conftest.$ac_ext <<EOF
-#line 1278 "configure"
+#line 1266 "configure"
#include "confdefs.h"
int main() {
@@ -1284,7 +1272,7 @@ long double foo = 0.0;
switch (0) case 0: case (sizeof(long double) >= sizeof(double)):;
; return 0; }
EOF
-if { (eval echo configure:1288: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_long_double=yes
else
@@ -1317,7 +1305,7 @@ fi
echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1321: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1309: 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
@@ -1345,7 +1333,7 @@ fi
echo $ac_n "checking whether a default assembler was specified""... $ac_c" 1>&6
-echo "configure:1349: checking whether a default assembler was specified" >&5
+echo "configure:1337: 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
@@ -1357,7 +1345,7 @@ else
fi
echo $ac_n "checking whether a default linker was specified""... $ac_c" 1>&6
-echo "configure:1361: checking whether a default linker was specified" >&5
+echo "configure:1349: 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
@@ -1374,7 +1362,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:1378: checking for $ac_word" >&5
+echo "configure:1366: 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
@@ -1406,7 +1394,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:1410: checking for $ac_word" >&5
+echo "configure:1398: 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
@@ -1440,7 +1428,7 @@ then
*) ac_lib=l ;;
esac
echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1444: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1432: 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
@@ -1448,7 +1436,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-l$ac_lib $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1452 "configure"
+#line 1440 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1459,7 +1447,7 @@ int main() {
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1463: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1451: \"$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
@@ -1482,7 +1470,7 @@ fi
fi
echo $ac_n "checking whether ln works""... $ac_c" 1>&6
-echo "configure:1486: checking whether ln works" >&5
+echo "configure:1474: 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
@@ -1514,7 +1502,7 @@ else
fi
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1518: checking whether ln -s works" >&5
+echo "configure:1506: 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
@@ -1546,19 +1534,19 @@ else
fi
echo $ac_n "checking for volatile""... $ac_c" 1>&6
-echo "configure:1550: checking for volatile" >&5
+echo "configure:1538: checking for volatile" >&5
if eval "test \"`echo '$''{'gcc_cv_c_volatile'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1555 "configure"
+#line 1543 "configure"
#include "confdefs.h"
int main() {
volatile int foo;
; return 0; }
EOF
-if { (eval echo configure:1562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1550: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_c_volatile=yes
else
@@ -1581,7 +1569,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:1585: checking for $ac_word" >&5
+echo "configure:1573: 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
@@ -1613,7 +1601,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:1617: checking for $ac_word" >&5
+echo "configure:1605: 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
@@ -1654,7 +1642,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:1658: checking for a BSD compatible install" >&5
+echo "configure:1646: 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
@@ -1705,7 +1693,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:1709: checking how to run the C preprocessor" >&5
+echo "configure:1697: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
@@ -1720,13 +1708,13 @@ else
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1724 "configure"
+#line 1712 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1718: \"$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
:
@@ -1737,13 +1725,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
cat > conftest.$ac_ext <<EOF
-#line 1741 "configure"
+#line 1729 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1735: \"$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
:
@@ -1754,13 +1742,13 @@ else
rm -rf conftest*
CPP="${CC-cc} -nologo -E"
cat > conftest.$ac_ext <<EOF
-#line 1758 "configure"
+#line 1746 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1764: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1752: \"$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
:
@@ -1785,12 +1773,12 @@ fi
echo "$ac_t""$CPP" 1>&6
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1789: checking for ANSI C header files" >&5
+echo "configure:1777: 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 <<EOF
-#line 1794 "configure"
+#line 1782 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1798,7 +1786,7 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1790: \"$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*
@@ -1815,7 +1803,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
-#line 1819 "configure"
+#line 1807 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1833,7 +1821,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
-#line 1837 "configure"
+#line 1825 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1854,7 +1842,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1858 "configure"
+#line 1846 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1865,7 +1853,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1889,12 +1877,12 @@ EOF
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1893: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1881: 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 <<EOF
-#line 1898 "configure"
+#line 1886 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1903,7 +1891,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1907: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1895: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1924,12 +1912,12 @@ EOF
fi
echo $ac_n "checking whether string.h and strings.h may both be included""... $ac_c" 1>&6
-echo "configure:1928: checking whether string.h and strings.h may both be included" >&5
+echo "configure:1916: 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 <<EOF
-#line 1933 "configure"
+#line 1921 "configure"
#include "confdefs.h"
#include <string.h>
#include <strings.h>
@@ -1937,7 +1925,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:1941: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1929: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_header_string=yes
else
@@ -1958,12 +1946,12 @@ EOF
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1962: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1950: 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 <<EOF
-#line 1967 "configure"
+#line 1955 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1979,7 +1967,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1971: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -2006,17 +1994,17 @@ for ac_hdr in limits.h stddef.h string.h strings.h stdlib.h time.h \
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2010: checking for $ac_hdr" >&5
+echo "configure:1998: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2015 "configure"
+#line 2003 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2020: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2008: \"$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*
@@ -2046,17 +2034,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:2050: checking for thread.h" >&5
+echo "configure:2038: checking for thread.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2055 "configure"
+#line 2043 "configure"
#include "confdefs.h"
#include <thread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2060: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2048: \"$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*
@@ -2080,17 +2068,17 @@ fi
ac_safe=`echo "pthread.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for pthread.h""... $ac_c" 1>&6
-echo "configure:2084: checking for pthread.h" >&5
+echo "configure:2072: 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
-#line 2089 "configure"
+#line 2077 "configure"
#include "confdefs.h"
#include <pthread.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2082: \"$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*
@@ -2117,7 +2105,7 @@ fi
# 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:2121: checking for $ac_word" >&5
+echo "configure:2109: 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
@@ -2150,12 +2138,12 @@ fi
echo $ac_n "checking for preprocessor stringizing operator""... $ac_c" 1>&6
-echo "configure:2154: checking for preprocessor stringizing operator" >&5
+echo "configure:2142: checking for preprocessor stringizing operator" >&5
if eval "test \"`echo '$''{'ac_cv_c_stringize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2159 "configure"
+#line 2147 "configure"
#include "confdefs.h"
#define x(y) #y
@@ -2188,12 +2176,12 @@ echo "$ac_t""${ac_cv_c_stringize}" 1>&6
# Use <inttypes.h> only if it exists,
# doesn't clash with <sys/types.h>, and declares intmax_t.
echo $ac_n "checking for inttypes.h""... $ac_c" 1>&6
-echo "configure:2192: checking for inttypes.h" >&5
+echo "configure:2180: checking for inttypes.h" >&5
if eval "test \"`echo '$''{'gcc_cv_header_inttypes_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2197 "configure"
+#line 2185 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <inttypes.h>
@@ -2201,7 +2189,7 @@ int main() {
intmax_t i = -1;
; return 0; }
EOF
-if { (eval echo configure:2205: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_header_inttypes_h=yes
else
@@ -2227,12 +2215,12 @@ for ac_func in strtoul bsearch putenv popen bcopy bzero bcmp \
fputs_unlocked getrusage valloc
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2231: checking for $ac_func" >&5
+echo "configure:2219: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2236 "configure"
+#line 2224 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2255,7 +2243,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2247: \"$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
@@ -2284,12 +2272,12 @@ done
#AC_CHECK_TYPE(wchar_t, unsigned int)
echo $ac_n "checking for vprintf""... $ac_c" 1>&6
-echo "configure:2288: checking for vprintf" >&5
+echo "configure:2276: 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 <<EOF
-#line 2293 "configure"
+#line 2281 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vprintf(); below. */
@@ -2312,7 +2300,7 @@ vprintf();
; return 0; }
EOF
-if { (eval echo configure:2316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2304: \"$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
@@ -2336,12 +2324,12 @@ fi
if test "$ac_cv_func_vprintf" != yes; then
echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
-echo "configure:2340: checking for _doprnt" >&5
+echo "configure:2328: 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 <<EOF
-#line 2345 "configure"
+#line 2333 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char _doprnt(); below. */
@@ -2364,7 +2352,7 @@ _doprnt();
; return 0; }
EOF
-if { (eval echo configure:2368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2356: \"$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
@@ -2400,7 +2388,7 @@ fi
echo $ac_n "checking whether the printf functions support %p""... $ac_c" 1>&6
-echo "configure:2404: checking whether the printf functions support %p" >&5
+echo "configure:2392: 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
@@ -2408,7 +2396,7 @@ else
gcc_cv_func_printf_ptr=no
else
cat > conftest.$ac_ext <<EOF
-#line 2412 "configure"
+#line 2400 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2421,7 +2409,7 @@ main()
exit (p != q);
}
EOF
-if { (eval echo configure:2425: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2413: \"$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
@@ -2454,12 +2442,12 @@ case "${host}" in
;;
esac
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2458: checking for pid_t" >&5
+echo "configure:2446: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2463 "configure"
+#line 2451 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2488,17 +2476,17 @@ fi
ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2492: checking for vfork.h" >&5
+echo "configure:2480: 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 <<EOF
-#line 2497 "configure"
+#line 2485 "configure"
#include "confdefs.h"
#include <vfork.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2490: \"$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*
@@ -2523,18 +2511,18 @@ else
fi
echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2527: checking for working vfork" >&5
+echo "configure:2515: 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:2533: checking for vfork" >&5
+echo "configure:2521: checking for vfork" >&5
if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2538 "configure"
+#line 2526 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char vfork(); below. */
@@ -2557,7 +2545,7 @@ vfork();
; return 0; }
EOF
-if { (eval echo configure:2561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2549: \"$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
@@ -2579,7 +2567,7 @@ fi
ac_cv_func_vfork_works=$ac_cv_func_vfork
else
cat > conftest.$ac_ext <<EOF
-#line 2583 "configure"
+#line 2571 "configure"
#include "confdefs.h"
/* Thanks to Paul Eggert for this test. */
#include <stdio.h>
@@ -2674,7 +2662,7 @@ main() {
}
}
EOF
-if { (eval echo configure:2678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2666: \"$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
@@ -2700,17 +2688,17 @@ for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2704: checking for $ac_hdr" >&5
+echo "configure:2692: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2709 "configure"
+#line 2697 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2714: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2702: \"$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*
@@ -2739,12 +2727,12 @@ done
for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2743: checking for $ac_func" >&5
+echo "configure:2731: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2748 "configure"
+#line 2736 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2767,7 +2755,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2759: \"$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
@@ -2792,7 +2780,7 @@ fi
done
echo $ac_n "checking for working mmap from /dev/zero""... $ac_c" 1>&6
-echo "configure:2796: checking for working mmap from /dev/zero" >&5
+echo "configure:2784: checking for working mmap from /dev/zero" >&5
if eval "test \"`echo '$''{'ac_cv_func_mmap_anywhere'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2800,7 +2788,7 @@ else
ac_cv_func_mmap_anywhere=no
else
cat > conftest.$ac_ext <<EOF
-#line 2804 "configure"
+#line 2792 "configure"
#include "confdefs.h"
/* Test by Richard Henderson and Alexandre Oliva.
@@ -2872,7 +2860,7 @@ int main()
exit(0);
}
EOF
-if { (eval echo configure:2876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_mmap_anywhere=yes
else
@@ -2900,12 +2888,12 @@ for ac_func in bcopy bzero bcmp \
strsignal putc_unlocked fputs_unlocked strstr environ
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2904: checking whether $ac_func must be declared" >&5
+echo "configure:2892: 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 <<EOF
-#line 2909 "configure"
+#line 2897 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -2942,7 +2930,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:2946: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2934: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -2971,12 +2959,12 @@ done
for ac_func in malloc realloc calloc free
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:2975: checking whether $ac_func must be declared" >&5
+echo "configure:2963: 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 <<EOF
-#line 2980 "configure"
+#line 2968 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -3016,7 +3004,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:3020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3008: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -3045,12 +3033,12 @@ done
for ac_func in getrlimit setrlimit getrusage
do
echo $ac_n "checking whether $ac_func must be declared""... $ac_c" 1>&6
-echo "configure:3049: checking whether $ac_func must be declared" >&5
+echo "configure:3037: 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 <<EOF
-#line 3054 "configure"
+#line 3042 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -3091,7 +3079,7 @@ int main() {
char *(*pfn) = (char *(*)) $ac_func
; return 0; }
EOF
-if { (eval echo configure:3095: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3083: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "gcc_cv_decl_needed_$ac_func=no"
else
@@ -3119,12 +3107,12 @@ done
# mkdir takes a single argument on some systems.
echo $ac_n "checking if mkdir takes one argument""... $ac_c" 1>&6
-echo "configure:3123: checking if mkdir takes one argument" >&5
+echo "configure:3111: 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 <<EOF
-#line 3128 "configure"
+#line 3116 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -3141,7 +3129,7 @@ int main() {
mkdir ("foo", 0);
; return 0; }
EOF
-if { (eval echo configure:3145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3133: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
gcc_cv_mkdir_takes_one_arg=no
else
@@ -5607,79 +5595,57 @@ for machine in $build $host $target; do
tmake_file=rs6000/t-beos
xmake_file=rs6000/x-beos
;;
- powerpc-*-sysv* | powerpc-*-elf*)
+ powerpc-*-sysv*)
tm_file=rs6000/sysv4.h
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
extra_headers=ppc-asm.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
;;
powerpc-*-eabiaix*)
- tm_file=rs6000/eabiaix.h
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/eabiaix.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-eabisim*)
- tm_file=rs6000/eabisim.h
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ extra_headers=ppc-asm.h
+ ;;
+ powerpc-*-elf*)
+ tm_file="rs6000/sysv4.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-eabi*)
- tm_file=rs6000/eabi.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tm_file="rs6000/sysv4.h rs6000/eabi.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-rtems*)
- tm_file=rs6000/rtems.h
- 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
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h"
+ tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-linux-gnulibc1)
- tm_file=rs6000/linux.h
+ tm_file="rs6000/sysv4.h rs6000/linux.h"
xm_file=rs6000/xm-sysv4.h
out_file=rs6000/rs6000.c
- 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
+ tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm"
xmake_file=x-linux
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-linux-gnu*)
- tm_file=rs6000/linux.h
+ tm_file="rs6000/sysv4.h rs6000/linux.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG ${xm_defines}"
out_file=rs6000/rs6000.c
- 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
+ tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm"
xmake_file=x-linux
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -5689,7 +5655,7 @@ for machine in $build $host $target; do
cpu_type=rs6000
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- tm_file=rs6000/vxppc.h
+ tm_file="rs6000/sysv4.h rs6000/vxppc.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
thread_file='vxworks'
@@ -5698,49 +5664,39 @@ for machine in $build $host $target; do
cpu_type=rs6000
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- tm_file=rs6000/vxppcle.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/vxppc.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
thread_file='vxworks'
;;
- powerpcle-*-sysv* | powerpcle-*-elf*)
- tm_file=rs6000/sysv4le.h
+ powerpcle-*-sysv*)
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
extra_headers=ppc-asm.h
;;
+ powerpcle-*-elf*)
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ extra_headers=ppc-asm.h
+ ;;
powerpcle-*-eabisim*)
- tm_file=rs6000/eabilesim.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/eabisim.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpcle-*-eabi*)
- tm_file=rs6000/eabile.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpcle-*-solaris2*)
- tm_file=rs6000/sol2.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/sol2.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
extra_headers=ppc-asm.h
;;
@@ -6608,7 +6564,7 @@ fi
echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
-echo "configure:6655: checking for strerror in -lcposix" >&5
+echo "configure:6611: 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
@@ -6616,7 +6572,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcposix $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6663 "configure"
+#line 6619 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6627,7 +6583,7 @@ int main() {
strerror()
; return 0; }
EOF
-if { (eval echo configure:6674: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6630: \"$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
@@ -6650,12 +6606,12 @@ fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6697: checking for working const" >&5
+echo "configure:6653: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6702 "configure"
+#line 6658 "configure"
#include "confdefs.h"
int main() {
@@ -6704,7 +6660,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:6751: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -6725,21 +6681,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:6772: checking for inline" >&5
+echo "configure:6728: 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 <<EOF
-#line 6779 "configure"
+#line 6735 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:6786: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6742: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -6765,12 +6721,12 @@ EOF
esac
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6812: checking for off_t" >&5
+echo "configure:6768: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6817 "configure"
+#line 6773 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6798,12 +6754,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6845: checking for size_t" >&5
+echo "configure:6801: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6850 "configure"
+#line 6806 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6833,19 +6789,19 @@ 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:6880: checking for working alloca.h" >&5
+echo "configure:6836: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6885 "configure"
+#line 6841 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
-if { (eval echo configure:6892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6848: \"$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
@@ -6866,12 +6822,12 @@ EOF
fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6913: checking for alloca" >&5
+echo "configure:6869: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6918 "configure"
+#line 6874 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@@ -6899,7 +6855,7 @@ int main() {
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:6946: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6902: \"$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
@@ -6931,12 +6887,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:6978: checking whether alloca needs Cray hooks" >&5
+echo "configure:6934: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6983 "configure"
+#line 6939 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@@ -6961,12 +6917,12 @@ 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:7008: checking for $ac_func" >&5
+echo "configure:6964: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7013 "configure"
+#line 6969 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6989,7 +6945,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6992: \"$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
@@ -7016,7 +6972,7 @@ done
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:7063: checking stack direction for C alloca" >&5
+echo "configure:7019: 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
@@ -7024,7 +6980,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 7071 "configure"
+#line 7027 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@@ -7043,7 +6999,7 @@ main ()
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:7090: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7046: \"$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
@@ -7068,17 +7024,17 @@ for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7115: checking for $ac_hdr" >&5
+echo "configure:7071: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7120 "configure"
+#line 7076 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7125: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7081: \"$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*
@@ -7107,12 +7063,12 @@ done
for ac_func in getpagesize
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7154: checking for $ac_func" >&5
+echo "configure:7110: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7159 "configure"
+#line 7115 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7135,7 +7091,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7138: \"$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
@@ -7160,7 +7116,7 @@ fi
done
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:7207: checking for working mmap" >&5
+echo "configure:7163: 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
@@ -7168,7 +7124,7 @@ else
ac_cv_func_mmap_fixed_mapped=no
else
cat > conftest.$ac_ext <<EOF
-#line 7215 "configure"
+#line 7171 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test.
@@ -7308,7 +7264,7 @@ main()
}
EOF
-if { (eval echo configure:7355: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7311: \"$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
@@ -7336,17 +7292,17 @@ 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:7383: checking for $ac_hdr" >&5
+echo "configure:7339: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7388 "configure"
+#line 7344 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7393: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7349: \"$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*
@@ -7376,12 +7332,12 @@ done
strdup __argz_count __argz_stringify __argz_next
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7423: checking for $ac_func" >&5
+echo "configure:7379: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7428 "configure"
+#line 7384 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7404,7 +7360,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7407: \"$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
@@ -7433,12 +7389,12 @@ done
for ac_func in stpcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7480: checking for $ac_func" >&5
+echo "configure:7436: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7485 "configure"
+#line 7441 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7461,7 +7417,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7464: \"$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
@@ -7495,19 +7451,19 @@ EOF
if test $ac_cv_header_locale_h = yes; then
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:7542: checking for LC_MESSAGES" >&5
+echo "configure:7498: checking for LC_MESSAGES" >&5
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7547 "configure"
+#line 7503 "configure"
#include "confdefs.h"
#include <locale.h>
int main() {
return LC_MESSAGES
; return 0; }
EOF
-if { (eval echo configure:7554: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7510: \"$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
@@ -7528,7 +7484,7 @@ EOF
fi
fi
echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:7575: checking whether NLS is requested" >&5
+echo "configure:7531: 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"
@@ -7548,7 +7504,7 @@ fi
EOF
echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:7595: checking whether included gettext is requested" >&5
+echo "configure:7551: 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"
@@ -7567,17 +7523,17 @@ fi
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:7614: checking for libintl.h" >&5
+echo "configure:7570: checking for libintl.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7619 "configure"
+#line 7575 "configure"
#include "confdefs.h"
#include <libintl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7624: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7580: \"$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*
@@ -7594,19 +7550,19 @@ 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:7641: checking for gettext in libc" >&5
+echo "configure:7597: 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 <<EOF
-#line 7646 "configure"
+#line 7602 "configure"
#include "confdefs.h"
#include <libintl.h>
int main() {
return (int) gettext ("")
; return 0; }
EOF
-if { (eval echo configure:7653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7609: \"$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
@@ -7622,7 +7578,7 @@ 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:7669: checking for bindtextdomain in -lintl" >&5
+echo "configure:7625: 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
@@ -7630,7 +7586,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7677 "configure"
+#line 7633 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7641,7 +7597,7 @@ int main() {
bindtextdomain()
; return 0; }
EOF
-if { (eval echo configure:7688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7644: \"$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
@@ -7657,12 +7613,12 @@ 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:7704: checking for gettext in libintl" >&5
+echo "configure:7660: 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:7709: checking for gettext in -lintl" >&5
+echo "configure:7665: 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
@@ -7670,7 +7626,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7717 "configure"
+#line 7673 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7681,7 +7637,7 @@ int main() {
gettext()
; return 0; }
EOF
-if { (eval echo configure:7728: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7684: \"$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
@@ -7720,7 +7676,7 @@ 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:7767: checking for $ac_word" >&5
+echo "configure:7723: 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
@@ -7754,12 +7710,12 @@ fi
for ac_func in dcgettext
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7801: checking for $ac_func" >&5
+echo "configure:7757: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7806 "configure"
+#line 7762 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7782,7 +7738,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7785: \"$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
@@ -7809,7 +7765,7 @@ 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:7856: checking for $ac_word" >&5
+echo "configure:7812: 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
@@ -7845,7 +7801,7 @@ 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:7892: checking for $ac_word" >&5
+echo "configure:7848: 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
@@ -7877,7 +7833,7 @@ else
fi
cat > conftest.$ac_ext <<EOF
-#line 7924 "configure"
+#line 7880 "configure"
#include "confdefs.h"
int main() {
@@ -7885,7 +7841,7 @@ extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr
; return 0; }
EOF
-if { (eval echo configure:7932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
CATOBJEXT=.gmo
DATADIRNAME=share
@@ -7908,7 +7864,7 @@ fi
if test "$CATOBJEXT" = "NONE"; then
echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
-echo "configure:7955: checking whether catgets can be used" >&5
+echo "configure:7911: 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"
@@ -7921,7 +7877,7 @@ fi
if test "$nls_cv_use_catgets" = "yes"; then
echo $ac_n "checking for main in -li""... $ac_c" 1>&6
-echo "configure:7968: checking for main in -li" >&5
+echo "configure:7924: 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
@@ -7929,14 +7885,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-li $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7976 "configure"
+#line 7932 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:7983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7939: \"$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
@@ -7964,12 +7920,12 @@ else
fi
echo $ac_n "checking for catgets""... $ac_c" 1>&6
-echo "configure:8011: checking for catgets" >&5
+echo "configure:7967: 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 <<EOF
-#line 8016 "configure"
+#line 7972 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char catgets(); below. */
@@ -7992,7 +7948,7 @@ catgets();
; return 0; }
EOF
-if { (eval echo configure:8039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7995: \"$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
@@ -8014,7 +7970,7 @@ EOF
# 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:8061: checking for $ac_word" >&5
+echo "configure:8017: 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
@@ -8050,7 +8006,7 @@ 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:8097: checking for $ac_word" >&5
+echo "configure:8053: 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
@@ -8087,7 +8043,7 @@ fi
# 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:8134: checking for $ac_word" >&5
+echo "configure:8090: 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
@@ -8122,7 +8078,7 @@ 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:8169: checking for $ac_word" >&5
+echo "configure:8125: 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
@@ -8180,7 +8136,7 @@ fi
# 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:8227: checking for $ac_word" >&5
+echo "configure:8183: 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
@@ -8214,7 +8170,7 @@ 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:8261: checking for $ac_word" >&5
+echo "configure:8217: 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
@@ -8250,7 +8206,7 @@ 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:8297: checking for $ac_word" >&5
+echo "configure:8253: 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
@@ -8343,7 +8299,7 @@ fi
LINGUAS=
else
echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:8390: checking for catalogs to be installed" >&5
+echo "configure:8346: checking for catalogs to be installed" >&5
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
@@ -8371,17 +8327,17 @@ echo "configure:8390: checking for catalogs to be installed" >&5
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:8418: checking for linux/version.h" >&5
+echo "configure:8374: 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
-#line 8423 "configure"
+#line 8379 "configure"
#include "confdefs.h"
#include <linux/version.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8428: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8384: \"$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*
@@ -8456,7 +8412,7 @@ fi
echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:8503: checking whether windows registry support is requested" >&5
+echo "configure:8459: checking whether windows registry support is requested" >&5
if test x$enable_win32_registry != xno; then
cat >> confdefs.h <<\EOF
#define ENABLE_WIN32_REGISTRY 1
@@ -8485,7 +8441,7 @@ esac
if test x$enable_win32_registry != xno; then
echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:8532: checking registry key on windows hosts" >&5
+echo "configure:8488: checking registry key on windows hosts" >&5
cat >> confdefs.h <<EOF
#define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
EOF
@@ -8661,7 +8617,7 @@ fi
# Figure out what assembler alignment features are present.
echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:8708: checking assembler alignment features" >&5
+echo "configure:8664: 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
@@ -8782,7 +8738,7 @@ fi
echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:8829: checking assembler subsection support" >&5
+echo "configure:8785: checking assembler subsection support" >&5
gcc_cv_as_subsections=
if test x$gcc_cv_as != x; then
# Check if we have .subsection
@@ -8822,7 +8778,7 @@ fi
echo "$ac_t""$gcc_cv_as_subsections" 1>&6
echo $ac_n "checking assembler weak support""... $ac_c" 1>&6
-echo "configure:8869: checking assembler weak support" >&5
+echo "configure:8825: checking assembler weak support" >&5
gcc_cv_as_weak=
if test x$gcc_cv_as != x; then
# Check if we have .weak
@@ -8838,10 +8794,28 @@ EOF
fi
echo "$ac_t""$gcc_cv_as_weak" 1>&6
+echo $ac_n "checking assembler hidden support""... $ac_c" 1>&6
+echo "configure:8842: checking assembler hidden support" >&5
+gcc_cv_as_hidden=
+if test x$gcc_cv_as != x; then
+ # Check if we have .hidden
+ echo " .hidden foobar" > conftest.s
+ echo "foobar:" >> conftest.s
+ if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_GAS_HIDDEN 1
+EOF
+
+ gcc_cv_as_hidden="yes"
+ fi
+ rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
+fi
+echo "$ac_t""$gcc_cv_as_hidden" 1>&6
+
case "$target" in
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:8888: checking assembler .register pseudo-op support" >&5
+echo "configure:8862: checking assembler .register pseudo-op support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8871,7 +8845,7 @@ EOF
case "$tm_file" in
*64*)
echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8918: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8892: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8916,7 +8890,7 @@ EOF
if test "x$gcc_cv_as_flags64" != xno; then
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8963: checking for assembler offsetable %lo() support" >&5
+echo "configure:8937: checking for assembler offsetable %lo() support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8955,7 +8929,7 @@ EOF
i[34567]86-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:9002: checking assembler instructions" >&5
+echo "configure:8976: checking assembler instructions" >&5
gcc_cv_as_instructions=
if test x$gcc_cv_as != x; then
set "filds fists" "filds mem; fists mem"
@@ -9079,6 +9053,29 @@ fi
+# Build a new-libstdc++ system (ie libstdc++-v3)
+echo $ac_n "checking for libstdc++ to install""... $ac_c" 1>&6
+echo "configure:9102: checking for libstdc++ to install" >&5
+# Check whether --enable-libstdcxx-v3 or --disable-libstdcxx-v3 was given.
+if test "${enable_libstdcxx_v3+set}" = set; then
+ enableval="$enable_libstdcxx_v3"
+ enable_libstdcxx_v3=yes
+else
+ enable_libstdcxx_v3=no
+fi
+
+
+if test x$enable_libstdcxx_v3 = xyes; then
+ echo "$ac_t""v3" 1>&6
+ cat >> confdefs.h <<\EOF
+#define ENABLE_STD_NAMESPACE 1
+EOF
+
+else
+ echo "$ac_t""v2" 1>&6
+fi
+
+
# Make empty files to contain the specs and options for each language.
# Then add #include lines to for a compiler that has specs and/or options.
diff --git a/gcc/configure.in b/gcc/configure.in
index 624c74541c5..b9e147df2ad 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -225,16 +225,17 @@ if test x$enable_cpplib = xno; then
cpp_main=cccp
fi)
-# Link cpplib into the compiler proper, for C/C++/ObjC.
-AC_ARG_ENABLE(c-cpplib,
-[ --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)
+dnl Disable this for the moment; the library interface is changing.
+dnl # Link cpplib into the compiler proper, for C/C++/ObjC.
+dnl AC_ARG_ENABLE(c-cpplib,
+dnl [ --enable-c-cpplib link cpplib directly into C and C++ compilers
+dnl (EXPERIMENTAL) (implies --enable-cpplib).],
+dnl if test x$enable_c_cpplib != xno; then
+dnl extra_c_objs="${extra_c_objs} libcpp.a"
+dnl extra_cxx_objs="${extra_cxx_objs} ../libcpp.a"
+dnl extra_c_flags="${extra_c_flags} -DUSE_CPPLIB=1"
+dnl cpp_main=cppmain
+dnl fi)
# Enable Multibyte Characters for C/C++
AC_ARG_ENABLE(c-mbchar,
@@ -2991,79 +2992,57 @@ changequote([,])dnl
tmake_file=rs6000/t-beos
xmake_file=rs6000/x-beos
;;
- powerpc-*-sysv* | powerpc-*-elf*)
+ powerpc-*-sysv*)
tm_file=rs6000/sysv4.h
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
extra_headers=ppc-asm.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
;;
powerpc-*-eabiaix*)
- tm_file=rs6000/eabiaix.h
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/eabiaix.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-eabisim*)
- tm_file=rs6000/eabisim.h
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ extra_headers=ppc-asm.h
+ ;;
+ powerpc-*-elf*)
+ tm_file="rs6000/sysv4.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-eabi*)
- tm_file=rs6000/eabi.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tm_file="rs6000/sysv4.h rs6000/eabi.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-rtems*)
- tm_file=rs6000/rtems.h
- 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
+ tm_file="rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h"
+ tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpc-*-linux-gnulibc1)
- tm_file=rs6000/linux.h
+ tm_file="rs6000/sysv4.h rs6000/linux.h"
xm_file=rs6000/xm-sysv4.h
out_file=rs6000/rs6000.c
- 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
+ tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm"
xmake_file=x-linux
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
thread_file='posix'
fi
;;
powerpc-*-linux-gnu*)
- tm_file=rs6000/linux.h
+ tm_file="rs6000/sysv4.h rs6000/linux.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG ${xm_defines}"
out_file=rs6000/rs6000.c
- 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
+ tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm"
xmake_file=x-linux
- extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
extra_headers=ppc-asm.h
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -3073,7 +3052,7 @@ changequote([,])dnl
cpu_type=rs6000
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- tm_file=rs6000/vxppc.h
+ tm_file="rs6000/sysv4.h rs6000/vxppc.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
thread_file='vxworks'
@@ -3082,49 +3061,39 @@ changequote([,])dnl
cpu_type=rs6000
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- tm_file=rs6000/vxppcle.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/vxppc.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
thread_file='vxworks'
;;
- powerpcle-*-sysv* | powerpcle-*-elf*)
- tm_file=rs6000/sysv4le.h
+ powerpcle-*-sysv*)
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
extra_headers=ppc-asm.h
;;
+ powerpcle-*-elf*)
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
+ extra_headers=ppc-asm.h
+ ;;
powerpcle-*-eabisim*)
- tm_file=rs6000/eabilesim.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/eabisim.h"
tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpcle-*-eabi*)
- tm_file=rs6000/eabile.h
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h"
+ tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm"
extra_headers=ppc-asm.h
;;
powerpcle-*-solaris2*)
- tm_file=rs6000/sol2.h
+ tm_file="rs6000/sysv4.h rs6000/sysv4le.h rs6000/sol2.h"
xm_file="rs6000/xm-sysv4.h"
xm_defines="USG POSIX"
- if test x$gas = xyes
- then
- tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
- else
- tmake_file="rs6000/t-ppc rs6000/t-ppccomm"
- fi
+ tmake_file="rs6000/t-ppcos rs6000/t-ppccomm"
xmake_file=rs6000/x-sysv4
extra_headers=ppc-asm.h
;;
@@ -4376,6 +4345,20 @@ if test x$gcc_cv_as != x; then
fi
AC_MSG_RESULT($gcc_cv_as_weak)
+AC_MSG_CHECKING(assembler hidden support)
+gcc_cv_as_hidden=
+if test x$gcc_cv_as != x; then
+ # Check if we have .hidden
+ echo " .hidden foobar" > conftest.s
+ echo "foobar:" >> conftest.s
+ if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1; then
+ AC_DEFINE(HAVE_GAS_HIDDEN)
+ gcc_cv_as_hidden="yes"
+ fi
+ rm -f conftest.s conftest.o conftest.nm1 conftest.nm2
+fi
+AC_MSG_RESULT($gcc_cv_as_hidden)
+
case "$target" in
sparc*-*-*)
AC_CACHE_CHECK([assembler .register pseudo-op support],
@@ -4581,6 +4564,21 @@ echo "Building a new-abi g++ compiler."
])
AC_SUBST(GXX_ABI_FLAG)
+# Build a new-libstdc++ system (ie libstdc++-v3)
+AC_MSG_CHECKING([for libstdc++ to install])
+AC_ARG_ENABLE(libstdcxx-v3,
+[ --enable-libstdcxx-v3
+ enable libstdc++-v3 for building and installation],
+ [enable_libstdcxx_v3=yes], [enable_libstdcxx_v3=no])
+
+if test x$enable_libstdcxx_v3 = xyes; then
+ AC_MSG_RESULT(v3)
+ AC_DEFINE(ENABLE_STD_NAMESPACE)
+else
+ AC_MSG_RESULT(v2)
+fi
+
+
# Make empty files to contain the specs and options for each language.
# Then add #include lines to for a compiler that has specs and/or options.
diff --git a/gcc/convert.c b/gcc/convert.c
index 9b43485b3d5..56a9e829e70 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -120,8 +120,8 @@ convert_to_integer (type, expr)
{
enum tree_code ex_form = TREE_CODE (expr);
tree intype = TREE_TYPE (expr);
- int inprec = TYPE_PRECISION (intype);
- int outprec = TYPE_PRECISION (type);
+ unsigned int inprec = TYPE_PRECISION (intype);
+ unsigned 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 };'. */
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ee0f6daecc4..5759cb6604c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,365 @@
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * typeck.c (build_binary_op): Call `tree_expr_nonnegative_p' to elide
+ some sign_compare warnings.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ Rename abi::__vmi_class_type_info members.
+ * inc/cxxabi.h (__vmi_class_type_info): Rename details, n_bases,
+ base_list, detail_masks members to vmi_flags, vmi_base_count,
+ vmi_bases and vmi_flags_masks respectively.
+ (__vmi_class_type_info::vmi_flags_masks): Rename
+ details_unknown_mask to flags_unknown_mask.
+ * tinfo.cc (__class_type_info::do_upcast): Adjust.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * tinfo.cc (convert_to_base): New function.
+ (get_vbase_offset): Remove. Move into convert_to_base.
+ (__vmi_class_type_info::do_find_public_src): Adjust.
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Adjust.
+
+2000-04-06 Jason Merrill <jason@yorick.cygnus.com>
+
+ * tinfo.cc (operator=): Use __builtin_strcmp.
+ * tinfo2.cc (before): Likewise.
+
+2000-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (lang_decl_flags): Rename saved_inline to deferred.
+ (DECL_SAVED_INLINE): Rename to ...
+ (DECL_DEFERRED_FN): ... this.
+ (in_function_p): Remove declaration.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ * decl.c (finish_function): Adjust call to mark_inline_for_output.
+ (in_function_p): Remove definition.
+ * decl2.c (saved_inlines): Rename to ...
+ (deferred_fns): ... this.
+ (saved_inlines_used): Rename to ...
+ (deferred_fns_used): ... this.
+ (mark_inline_for_output): Rename to ...
+ (defer_fn): ... this.
+ (finish_file): Adjust accordingly.
+ (init_decl2): Likewise.
+ * lex.c (cons_up_default_function): Likewise.
+ * pt.c (mark_decl_instantiated): Likewise.
+ (instantiate_decl): Don't set DECL_DEFER_OUTPUT under any
+ circumstances.
+ * rtti.c (get_tinfo_decl): Adjust call to mark_inline_for_output.
+ * semantics.c (expand_body): Defer more functions.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * vec.cc: New file.
+ * Make-lang.in (CXX_LIB2FUNCS): Add it.
+ (vec.o): Build it.
+ * inc/cxxabi.h (__cxa_vec_new, __cxa_vec_ctor, __cxa_vec_dtor,
+ __cxa_vec_delete): Declare.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (dfs_class_hint_mark): New static function.
+ (dfs_class_hint_unmark): New static function.
+ (class_hint_flags): Use them.
+
+2000-04-05 Benjamin Kosnik <bkoz@cygnus.com>
+
+ * decl2.c: Make flag_honor_std dependant on ENABLE_STD_NAMESPACE.
+
+2000-04-05 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (instantiate_decl): Change prototype.
+ * decl2.c (mark_used): Adjust call.
+ * optimize.c (inlinable_function_p): Adjust handling of templates.
+ * pt.c (do_decl_instantiation): Adjust call to instantiate_decl.
+ (do_type_instantiation): Likewise.
+ (instantiate_decl): Defer more templates.
+ (instantiate_pending_templates): Adjust logic to handle inline
+ friend functions.
+
+ * Makefile.in (GGC_H): New variable. Use it throughout in place
+ of ggc.h.
+
+ * call.c: Don't include obstack.h. Include ggc.h.
+ (obstack_chunk_alloc): Don't define.
+ (obstack_chunk_free): Likewise.
+ (add_candidate): Allocate the z_candidate with ggc_alloc_obj.
+ * decl.c (push_switch): Use xmalloc to allocate the cp_switch.
+ (pop_switch): Free it.
+
+ * decl2.c (grokclassfn): Set TREE_READONLY for PARM_DECLs.
+
+ * dump.c (dequeue_and_dump): Don't try to print the bit_position
+ if we don't have a DECL_FIELD_OFFSET.
+
+Wed Apr 5 15:12:18 MET DST 2000 Jan Hubicka <jh@suse.cz>
+
+ * optimize.c (calls_setjmp_r): Use setjmp_call_p instead of
+ special_function_p.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * cfns.gperf (hash, libc_name_p): Prototype.
+
+ * rtti.c (build_dynamic_cast_1): Constification.
+
+ * search.c (dfs_debug_unmarkedp, dfs_debug_mark): Unhide prototypes.
+
+ * semantics.c (deferred_type_access_control): Prototype.
+
+2000-04-04 Mark Mitchell <mark@codesourcery.com>
+
+ Correct many new ABI issues regarding vbase and vcall offset
+ layout.
+ * cp-tree.h (BINFO_VTABLE): Document.
+ (struct lang_type): Tweak formatting.
+ (BINFO_PRIMARY_BINFO): Add to documentation.
+ (CLASSTYPE_VSIZE): Fix typo in comment.
+ (CLASSTYPE_VBASECLASSES): Update documentation.
+ (BINFO_VBASE_MARKED): Remove.
+ (SET_BINFO_VBASE_MARKED): Likewise.
+ (CLEAR_BINFO_VBASE_MARKED): Likewise.
+ (BINFO_FIELDS_MARKED): Remove.
+ (SET_BINFO_FIELDS_MARKED): Likewise.
+ (CLEAR_BINFO_FIELDS_MARKED): Likewise.
+ (enum access_kind): New enumeration.
+ (num_extra_vtbl_entries): Remove declaration.
+ (size_extra_vtbl_entries): Likewise.
+ (get_vtbl_decl_for_binfo): New function.
+ (dfs_vbase_unmark): Remove declaration.
+ (mark_primary_bases): Likewise.
+ * class.c (SAME_FN): Remove.
+ (struct vcall_offset_data_s): Move definition.
+ (build_vbase_pointer): Use `build', not `build_binary_op', to
+ access the vbase pointer under the new ABI.
+ (build_vtable_entry_ref): Use get_vtbl_decl_for_binfo.
+ (build_primary_vtable): Likewise.
+ (dfs_mark_primary_bases): Move here from search.c.
+ (mark_primary_bases): Likewise.
+ (determine_primary_bases): Under the new ABI, don't make a base
+ class a primary base just because we don't yet have any virtual
+ functions.
+ (layout_vtable_decl): Use get_vtbl_decl_for_binfo.
+ (num_vfun_entries): Remove.
+ (dfs_count_virtuals): Likewise.
+ (num_extra_vtbl_entries): Likewise.
+ (size_extra_vtbl_entries): Likewise.
+ (layout_virtual_bases): Iterate in inheritance graph order under
+ the new ABI.
+ (finish_struct_1): Use TYPE_VFIELD, not CLASSTYPE_VSIZE, to
+ indicate that a vfield is present.
+ (init_class_processing): Initialize access_public_node, etc., from
+ ak_public, etc.
+ (get_vtbl_decl_for_binfo): New function.
+ (dump_class_hierarchy_r): Likewise.
+ (dump_class_hierarchy): Use it.
+ (finish_vtbls): Build the vtbls in inheritance graph order.
+ (dfs_finish_vtbls): Adjust call to build_vtbl_initializer.
+ (initialize_vtable): Use get_vtbl_decl_for_binfo.
+ (accumulate_vtbl_inits): Add comments explaining why a pre-order
+ walk is required.
+ (dfs_accumulate_vtbl_inits): Set BINFO_VTABLE to the location
+ where the vptr points, even for primary vtables.
+ (build_vtbl_initializer): Adjust handling of vbase and vcall
+ offsets.
+ (build_vcall_and_vbase_vtable_entries): New function.
+ (dfs_build_vbase_offset_vtbl_entries): Remove.
+ (build_vbase_offset_vtbl_entries): Reimplement.
+ (dfs_build_vcall_offset_vtbl_entries): Don't include virtuals that
+ were already handled in a primary base class vtable.
+ (build_vcall_offset_vtbl_entries): Adjust.
+ (build_rtti_vtbl_entries): Adjust.
+ * decl2.c (output_vtable_inherit): Use get_vtbl_decl_for_binfo.
+ * init.c (expand_virtual_init): Simplify.
+ * repo.c (repo_get_id): Use get_vtbl_decl_for_binfo.
+ * rtti.c (create_pseudo_type_info): Adjust calculation of vptr.
+ * search.c (BINFO_ACCESS): New macro.
+ (SET_BINFO_ACCESS): Likewise.
+ (dfs_access_in_type): Manipulate access_kinds, not access nodes.
+ (access_in_type): Likewise.
+ (dfs_accessible_p): Likewise.
+ (protected_accessible_p): Likewise.
+ (lookup_fnfields_1): Adjust documentation.
+ (dfs_mark_primary_bases): Move to class.c
+ (mark_primary_bases): Likewise.
+ (dfs_vbase_unmark): Remove.
+ (virtual_context): Use BINFO_FOR_VBASE.
+ (dfs_get_vbase_types): Simplify.
+ (dfs_build_inheritance_graph_order): New function.
+ (get_vbase_types): Use it.
+ * tree.c (debug_binfo): Use get_vtbl_decl_for_binfo.
+
+ * tinfo.cc (get_vbase_offset): New function.
+ (__vmi_class_type_info::do_find_public_src): Use it.
+ (__vmi_class_type_info::do_dyncast): Likewise.
+ (__vmi_class_type_info::do_upcast): Likewise.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-30 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (class_hint_flags): Rename flags.
+ (class_initializer): Remove flags.
+ (synthesize_tinfo_var): Combine offset and flags. Add flags
+ for __vmi_class_type_info.
+ (create_tinfo_types): Remove flags from __class_type_info and
+ __si_class_type_info. Merge flags and offset from
+ base_class_type_info.
+ * inc/cxxabi.h (__base_class_info): Merge offset and vmi_flags.
+ (__base_class_info::is_virtual_p): Adjust.
+ (__base_class_info::is_public_p): Adjust.
+ (__base_class_info::offset): New accessor.
+ (__class_type_info::details): Remove member.
+ (__class_type_info::__class_type_info): Lose details.
+ (__class_type_info::detail_masks): Remove.
+ (__si_class_type_info::__si_class_type_info): Lose details.
+ (__vmi_class_type_info::details): New member.
+ (__vmi_class_type_info::__vmi_class_type_info): Adjust.
+ (__vmi_class_type_info::detail_masks): New member.
+ * tinfo.cc (__class_type_info::do_upcast): Initialize result
+ with unknown_details_mask.
+ (__vmi_class_type_info::do_find_public_src): Adjust
+ (__vmi_class_type_info::do_dyncast): Adjust.
+ (__vmi_class_type_info::do_upcast): Set result details, if
+ needed. Adjust.
+ (__dynamic_cast): Temporarily #if out optimization.
+
+2000-03-29 Nathan Sidwell <nathan@codesourcery.com>
+
+ * rtti.c (get_tinfo_decl): Mark used.
+ (emit_tinfo_decl): Don't optimize polymorphic type_info. Only
+ mark as dealt with, if we output it.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c: Reorganize to put virtual function table initialization
+ machinery at the end of the file.
+
+2000-03-28 Jason Merrill <jason@casey.cygnus.com>
+
+ * class.c (finish_struct): Use bitsize_zero_node.
+ * pt.c (instantiate_class_template): Likewise.
+
+2000-03-28 Mark Mitchell <mark@codesourcery.com>
+
+ Put RTTI entries at negative offsets in new ABI.
+ * class.c (dfs_build_vbase_offset_vtbl_entries): Put the first
+ vbase offset at index -3, not -1.
+ (build_vtabe_offset_vtbl_entries): Use unmarked_vtable_pathp, not
+ dfs_vtable_path_unmarked_real_bases_queue_p to walk bases.
+ (dfs_build_vcall_offset_vtbl_entries): Don't use skip_rtti_stuff.
+ (build_rtti_vtbl_entries): New function.
+ (set_rtti_entry): Remove.
+ (build_primary_vtable): Don't use it.
+ (build_secondary_vtable): Likewise.
+ (start_vtable): Remove.
+ (first_vfun_index): New function.
+ (set_vindex): Likewise.
+ (add_virtual_function): Don't call start_vtable. Do call
+ set_vindex.
+ (set_primary_base): Rename parameter.
+ (determine_primary_base): Likewise.
+ (num_vfun_entries): Don't use skip_rtti_stuff.
+ (num_extra_vtbl_entries): Include RTTI information.
+ (build_vtbl_initializer): Use build_rtti_vtbl_entries.
+ (skip_rtti_stuff): Remove.
+ (dfs_modify_vtables): Don't use it.
+ (modify_all_vtables): Don't use start_vtable. Do use set_vindex.
+ (layout_nonempty_base_or_field): Update size handling.
+ (create_vtable_ptr): Tweak.
+ (layout_class_type): Adjust parameter names.
+ (finish_struct_1): Simplify.
+ * cp-tree.h (CLASSTYPE_VSIZE): Tweak documentation.
+ (skip_rtti_stuff): Remove.
+ (first_vfun_index): New function.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Remove.
+ (marked_vtable_pathp): Declare.
+ (unmarked_vtable_pathp): Likewise.
+ * error.c (dump_expr): Use first_vfun_index to calculate vtable
+ offsets.
+ * rtti.c (build_headof): Look for RTTI at negative offsets.
+ (get_tinfo_decl_dynamic): Likewise.
+ (tinfo_base_init): Don't take the address of the TINFO_VTABLE_DECL
+ here.
+ (create_pseudo_type_info): Do it here instead. Adjust so that
+ vptr points at first virtual function.
+ * search.c (marked_vtable_pathp): Make it global.
+ (unmarked_vtable_pathp): Likewise.
+ (dfs_vtable_path_unmarked_real_bases_queue_p): Remove.
+ (dfs_vtable_path_marked_real_bases_queue_p): Likewise.
+ (dfs_get_pure_virtuals): Don't use skip_rtti_stuff.
+ (get_pure_virtuals): Likewise.
+ (expand_upcast_fixups): Likewise.
+ * tree.c (debug_binfo): Likewise.
+ * tinfo.cc (__dynamic_cast): Look for vtable_prefix at appropriate
+ negative offset.
+
+Sun Mar 26 20:15:26 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (check_field_decl): Fix typo.
+ (build_vtbl_or_vbase_field): Don't clear DECL_SAVED_INSNS.
+ (check_methods): Likewise.
+ (check_field_decls): Likewise.
+ Use DECL_CONTEXT, not DECL_FIELD_CONTEXT.
+ * cp-tree.h (DECL_SHADOWED_FOR_VAR, DECL_TEMPLATE_RESULT):
+ Use DECL_RESULT_FLD, not DECL_RESULT.
+ * decl.c (xref_tag): Use DECL_TEMPLATE_RESULT.
+ * lex.c (identifier_type): Likewise.
+ * pt.c (determine_specialization, lookup_template_class): Likewise.
+ (tsubst_friend_function, tsubst_decl, instantiate_template): Likewise.
+ (resolve_overloaded_unification, more_specialized): Likewise.
+ * semantics.c (finish_member_declaration): Likewise.
+ * typeck.c (build_x_function_call): Likewise.
+
+2000-03-26 Mark Mitchell <mark@codesourcery.com>
+
+ * class.c (layout_empty_base): Handle empty bases with non-byte
+ alignment.
+ (build_base_field): Likewise.
+ (layout_virtual_bases): Likewise.
+
+ * class.c (finish_struct_1): Fix typo in this change:
+
+ Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+2000-03-25 Mark Mitchell <mark@codesourcery.com>
+
+ * decl.c (grokdeclarator): Count partial specializations when
+ keeping track of how many template classes have been seen.
+
+ * dump.c (dequeue_and_dump): Dump DECL_TEMPLATE_RESULT.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (build_vbase_pointer_fields): layout_field now place_field.
+ (get_vfield_offset): Use byte_position.
+ (set_rtti_entry): Set OFFSET to ssizetype zero.
+ (get_binfo_offset_as_int): Deleted.
+ (dfs_record_base_offsets): Use tree_low_cst.
+ (dfs_search_base_offsets): Likewise.
+ (layout_nonempty_base_or_field): Reflect changes in RLI format
+ and call byte_position.
+ (layout_empty_base): Convert offset to ssizetype.
+ (build_base_field): use rli_size_unit_so_far.
+ (dfs_propagate_binfo_offsets): Do computation in proper type.
+ (layout_virtual_bases): Pass ssizetype to propagate_binfo_offsets.
+ (layout_class_type): Reflect changes in RLI names and fields.
+ (finish_struct_1): Set DECL_FIELD_OFFSET.
+ * dump.c (dequeue_and_dump): Call bit_position.
+ * expr.c (cplus_expand_constant): Use byte_position.
+ * rtti.c (expand_class_desc): Use bitsize_one_node.
+ * typeck.c (build_component_addr): Use byte_position and don't
+ special case for zero offset.
+
2000-03-24 Nathan Sidwell <nathan@codesourcery.com>
* decl.c (vtype_decl_p): Use TYPE_POLYMORPHIC_P.
@@ -9,30 +371,32 @@
2000-03-20 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
- * call.c (check_dtor_name,build_new_method_call): Use DECL_P and
- TYPE_P macros.
- * decl.c (push_class_binding,poplevel,pushtag,lookup_namespace_name,
- make_typename_type,check_initializer,cp_finish_decl,xref_tag): Likewise.
- * decl2.c (grokfield,build_expr_from_tree,build_expr_from_tree,
- decl_namespace,arg_assoc_template_arg,arg_assoc,
- validate_nonmember_using_decl,do_class_using_decl): Likewise.
- * error.c (dump_template_argument,dump_expr,cp_file_of,cp_line_of,
+ * call.c (check_dtor_name, build_new_method_call): Use TYPE_P and
+ DECL_P macros.
+ * decl.c (push_class_binding, poplevel, pushtag, lookup_namespace_name,
+ make_typename_type, check_initializer, cp_finish_decl,
+ xref_tag): Likewise.
+ * decl2.c (grokfield, build_expr_from_tree, build_expr_from_tree,
+ decl_namespace, arg_assoc_template_arg, arg_assoc,
+ validate_nonmember_using_decl, do_class_using_decl): Likewise.
+ * error.c (dump_template_argument, dump_expr, cp_file_of, cp_line_of,
args_to_string): Likewise.
* friend.c (is_friend): Likewise.
- * lex.c (note_got_semicolon,note_list_got_semicolon,is_global): Likewise.
- * method.c (build_overload_nested_name,build_overload_value,
- build_qualified_name,build_qualified_name,hack_identifier): Likewise.
- * parse.y (typename_sub,typename_sub1): Likewise.
- * pt.c (push_inline_template_parms_recursive,check_template_shadow,
- process_partial_specialization,convert_template_argument,
- template_args_equal,add_pending_template,lookup_template_class,
- for_each_template_parm_r,maybe_fold_nontype_arg,
- tsubst,instantiate_template,type_unification_real,unify,
- instantiate_pending_templates,set_mangled_name_for_template_decl):
+ * lex.c (note_got_semicolon, note_list_got_semicolon,
+ is_global): Likewise.
+ * method.c (build_overload_nested_name, build_overload_value,
+ build_qualified_name, build_qualified_name, hack_identifier): Likewise.
+ * parse.y (typename_sub, typename_sub1): Likewise.
+ * pt.c (push_inline_template_parms_recursive, check_template_shadow,
+ process_partial_specialization, convert_template_argument,
+ template_args_equal, add_pending_template, lookup_template_class,
+ for_each_template_parm_r, maybe_fold_nontype_arg,
+ tsubst, instantiate_template, type_unification_real, unify,
+ instantiate_pending_templates, set_mangled_name_for_template_decl):
Likewise.
- * repo.c (repo_get_id,repo_template_used): Likewise.
+ * repo.c (repo_get_id, repo_template_used): Likewise.
* search.c (lookup_field_1): Likewise.
- * tree.c (walk_tree,get_type_decl,cp_tree_equal,member_p): Likewise.
+ * tree.c (walk_tree, get_type_decl, cp_tree_equal, member_p): Likewise.
* xref.c (classname): Likewise.
2000-03-22 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index fb8ce9f8b84..fe8eb4a974d 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -62,7 +62,7 @@ CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \
# Extra code to include in libgcc2.
CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o opnew.o opnewnt.o opvnew.o opvnewnt.o \
- opdel.o opdelnt.o opvdel.o opvdelnt.o exception.o
+ opdel.o opdelnt.o opvdel.o opvdelnt.o exception.o vec.o
CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \
$(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \
$(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h
@@ -173,6 +173,9 @@ opvdel.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc
opvdelnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc
$(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(GXX_ABI_FLAG) $(CXXFLAGS) $(INCLUDES) \
-c $(srcdir)/cp/new2.cc -DL_op_vdelnt -o opvdelnt.o
+vec.o: cc1plus$(exeext) $(srcdir)/cp/vec.cc
+ $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(GXX_ABI_FLAG) $(CXXFLAGS) $(INCLUDES) \
+ -c $(srcdir)/cp/vec.cc -o vec.o
# We want to update cplib2.txt if any of the source files change...
cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index 43bebf53a9a..647c1fa06ed 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -209,10 +209,11 @@ CXX_TREE_H = $(TREE_H) cp-tree.h $(srcdir)/../c-common.h cp-tree.def \
PARSE_H = $(srcdir)/parse.h
PARSE_C = $(srcdir)/parse.c
EXPR_H = $(srcdir)/../expr.h ../insn-codes.h
+GGC_H = $(srcdir)/../ggc.h $(srcdir)/../varray.h
parse.o : $(PARSE_C) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \
$(srcdir)/../except.h $(srcdir)/../output.h $(srcdir)/../system.h \
- $(srcdir)/../toplev.h $(srcdir)/../ggc.h
+ $(srcdir)/../toplev.h $(GGC_H)
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \
`echo $(PARSE_C) | sed 's,^\./,,'`
@@ -251,16 +252,16 @@ spew.o : spew.c $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \
lex.o : lex.c $(CXX_TREE_H) \
$(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \
$(srcdir)/../c-pragma.h $(srcdir)/../toplev.h \
- $(srcdir)/../output.h $(srcdir)/../mbchar.h $(srcdir)/../ggc.h \
+ $(srcdir)/../output.h $(srcdir)/../mbchar.h $(GGC_H) \
$(srcdir)/../input.h
decl.o : decl.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \
$(srcdir)/../except.h $(srcdir)/../toplev.h \
- $(srcdir)/../hash.h $(srcdir)/../ggc.h $(RTL_H)
+ $(srcdir)/../hash.h $(GGC_H) $(RTL_H)
decl2.o : decl2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
lex.h decl.h $(EXPR_H) $(srcdir)/../output.h $(srcdir)/../except.h \
$(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h \
- $(srcdir)/../ggc.h $(RTL_H)
+ $(GGC_H) $(RTL_H)
typeck2.o : typeck2.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(srcdir)/../output.h
typeck.o : typeck.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
@@ -268,20 +269,20 @@ typeck.o : typeck.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
class.o : class.c $(CXX_TREE_H) $(srcdir)/../flags.h \
$(srcdir)/../toplev.h $(RTL_H)
call.o : call.c $(CXX_TREE_H) $(srcdir)/../flags.h \
- $(srcdir)/../toplev.h $(RTL_H) $(EXPR_H)
+ $(srcdir)/../toplev.h $(RTL_H) $(EXPR_H) $(GGC_H)
friend.o : friend.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
$(srcdir)/../toplev.h
init.o : init.c $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \
- $(EXPR_H) $(srcdir)/../toplev.h $(srcdir)/../ggc.h \
+ $(EXPR_H) $(srcdir)/../toplev.h $(GGC_H) \
$(srcdir)/../except.h
method.o : method.c $(CXX_TREE_H) \
- $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H)
+ $(srcdir)/../toplev.h $(GGC_H) $(RTL_H)
cvt.o : cvt.c $(CXX_TREE_H) decl.h \
$(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h
search.o : search.c $(CXX_TREE_H) $(srcdir)/../stack.h \
$(srcdir)/../flags.h $(srcdir)/../toplev.h $(RTL_H)
tree.o : tree.c $(CXX_TREE_H) $(srcdir)/../flags.h \
- $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
+ $(srcdir)/../toplev.h $(GGC_H) $(RTL_H) \
../insn-config.h $(srcdir)/../integrate.h
ptree.o : ptree.c $(CXX_TREE_H) $(srcdir)/../system.h
rtti.o : rtti.c $(CXX_TREE_H) $(srcdir)/../flags.h \
@@ -293,17 +294,17 @@ expr.o : expr.c $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \
xref.o : xref.c $(CXX_TREE_H) $(srcdir)/../input.h \
$(srcdir)/../toplev.h
pt.o : pt.c $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \
- $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
+ $(srcdir)/../toplev.h $(GGC_H) $(RTL_H) \
$(srcdir)/../except.h
error.o : error.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h
errfn.o : errfn.c $(CXX_TREE_H) \
$(srcdir)/../toplev.h
repo.o : repo.c $(CXX_TREE_H) \
- $(srcdir)/../toplev.h $(srcdir)/../ggc.h
+ $(srcdir)/../toplev.h $(GGC_H)
semantics.o: semantics.c $(CXX_TREE_H) lex.h \
$(srcdir)/../except.h $(srcdir)/../toplev.h \
- $(srcdir)/../flags.h $(srcdir)/../ggc.h \
+ $(srcdir)/../flags.h $(GGC_H) \
$(srcdir)/../output.h $(RTL_H)
dump.o: dump.c $(CXX_TREE_H)
optimize.o: optimize.c $(CXX_TREE_H) \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6e7c4fb6670..ef559185adb 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -34,10 +34,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "defaults.h"
#include "expr.h"
-
-#include "obstack.h"
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
+#include "ggc.h"
extern int inhibit_warnings;
@@ -1232,18 +1229,12 @@ add_candidate (candidates, fn, convs, viable)
tree fn, convs;
int viable;
{
- /* FIXME: This is a memory leak. Presumably, we should use
- ggc_alloc instead. */
struct z_candidate *cand
- = (struct z_candidate *) expralloc (sizeof (struct z_candidate));
+ = (struct z_candidate *) ggc_alloc_obj (sizeof (struct z_candidate), 1);
cand->fn = fn;
cand->convs = convs;
- cand->second_conv = NULL_TREE;
cand->viable = viable;
- cand->basetype_path = NULL_TREE;
- cand->template = NULL_TREE;
- cand->warnings = NULL_TREE;
cand->next = candidates;
return cand;
diff --git a/gcc/cp/cfns.gperf b/gcc/cp/cfns.gperf
index d7a530a6d4b..0d1e71b9a8d 100644
--- a/gcc/cp/cfns.gperf
+++ b/gcc/cp/cfns.gperf
@@ -1,3 +1,13 @@
+%{
+#ifdef __GNUC__
+__inline
+#endif
+static unsigned int hash PARAMS ((const char *, unsigned int));
+#ifdef __GNUC__
+__inline
+#endif
+const char * libc_name_p PARAMS ((const char *, unsigned int));
+%}
# The standard C library functions, for feeding to gperf; the result is used
# by nothrow_libfn_p.
#
diff --git a/gcc/cp/cfns.h b/gcc/cp/cfns.h
index df8c7b58be2..c7e6a9d9412 100644
--- a/gcc/cp/cfns.h
+++ b/gcc/cp/cfns.h
@@ -1,5 +1,13 @@
/* C code produced by gperf version 2.7 */
-/* Command-line: gperf -o -C -E -k 1-6,$ -j1 -D -N libc_name_p /home/jason/eg/gcc/cp/cfns.gperf */
+/* Command-line: gperf -o -C -E -k 1-6,$ -j1 -D -N libc_name_p ../../../egcs-CVS20000404/gcc/cp/cfns.gperf */
+#ifdef __GNUC__
+__inline
+#endif
+static unsigned int hash PARAMS ((const char *, unsigned int));
+#ifdef __GNUC__
+__inline
+#endif
+const char * libc_name_p PARAMS ((const char *, unsigned int));
/* maximum key range = 1020, duplicates = 1 */
#ifdef __GNUC__
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 216d7e3cfea..a9f35951375 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -38,12 +38,6 @@ Boston, MA 02111-1307, USA. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-/* 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 PARAMS ((tree));
-
/* The number of nested classes being processed. If we are not in the
scope of any class, this is zero. */
@@ -68,6 +62,22 @@ typedef struct class_stack_node {
splay_tree names_used;
}* class_stack_node_t;
+typedef struct vcall_offset_data_s
+{
+ /* The binfo for the most-derived type. */
+ tree derived;
+ /* The binfo for the virtual base for which we're building
+ initializers. */
+ tree vbase;
+ /* The vcall offset initializers built up so far. */
+ tree inits;
+ /* The vtable index of the next vcall or vbase offset. */
+ tree index;
+ /* Nonzero if we are building the initializer for the primary
+ vtable. */
+ int primary_p;
+} vcall_offset_data;
+
/* 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;
@@ -80,7 +90,6 @@ static tree build_vtable_entry PARAMS ((tree, tree, tree));
static tree get_vtable_name PARAMS ((tree));
static tree get_derived_offset PARAMS ((tree, tree));
static tree get_basefndecls PARAMS ((tree, tree));
-static void set_rtti_entry PARAMS ((tree, tree, tree));
static int build_primary_vtable PARAMS ((tree, tree));
static int build_secondary_vtable PARAMS ((tree, tree));
static tree dfs_finish_vtbls PARAMS ((tree, void *));
@@ -109,7 +118,7 @@ static tree fixed_type_or_null PARAMS ((tree, int *));
static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
int, tree));
static void build_vtable_entry_ref PARAMS ((tree, tree, tree));
-static tree build_vtbl_initializer PARAMS ((tree, tree));
+static tree build_vtbl_initializer PARAMS ((tree, tree, int *));
static int count_fields PARAMS ((tree));
static int add_fields_to_vec PARAMS ((tree, tree, int));
static void check_bitfield_decl PARAMS ((tree));
@@ -136,20 +145,17 @@ static void propagate_binfo_offsets PARAMS ((tree, tree));
static void layout_virtual_bases PARAMS ((tree, varray_type *));
static tree dfs_set_offset_for_shared_vbases PARAMS ((tree, void *));
static tree dfs_set_offset_for_unshared_vbases PARAMS ((tree, void *));
-static tree dfs_build_vbase_offset_vtbl_entries PARAMS ((tree, void *));
-static tree build_vbase_offset_vtbl_entries PARAMS ((tree, tree));
+static void build_vbase_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *));
static tree dfs_vcall_offset_queue_p PARAMS ((tree, void *));
static tree dfs_build_vcall_offset_vtbl_entries PARAMS ((tree, void *));
-static tree build_vcall_offset_vtbl_entries PARAMS ((tree, tree));
-static tree dfs_count_virtuals PARAMS ((tree, void *));
-static void start_vtable PARAMS ((tree, int *));
+static void build_vcall_offset_vtbl_entries PARAMS ((tree, vcall_offset_data *));
static void layout_vtable_decl PARAMS ((tree, int));
-static int num_vfun_entries PARAMS ((tree));
static tree dfs_find_final_overrider PARAMS ((tree, void *));
static tree find_final_overrider PARAMS ((tree, tree, tree));
static tree dfs_find_base PARAMS ((tree, void *));
static int make_new_vtable PARAMS ((tree, tree));
-extern void dump_class_hierarchy PARAMS ((tree, int));
+static void dump_class_hierarchy_r PARAMS ((tree, tree, int));
+extern void dump_class_hierarchy PARAMS ((tree));
static tree build_vtable PARAMS ((tree, tree, tree));
static void initialize_vtable PARAMS ((tree, tree));
static void layout_nonempty_base_or_field PARAMS ((record_layout_info,
@@ -162,6 +168,12 @@ static int layout_conflict_p PARAMS ((tree, varray_type));
static unsigned HOST_WIDE_INT end_of_class PARAMS ((tree, int));
static void layout_empty_base PARAMS ((tree, tree, varray_type));
static void accumulate_vtbl_inits PARAMS ((tree, tree));
+static void set_vindex PARAMS ((tree, tree, int *));
+static tree build_rtti_vtbl_entries PARAMS ((tree, tree));
+static void build_vcall_and_vbase_vtbl_entries PARAMS ((tree,
+ vcall_offset_data *));
+static tree dfs_mark_primary_bases PARAMS ((tree, void *));
+static void mark_primary_bases PARAMS ((tree));
/* Variables shared between class.c and call.c. */
@@ -243,7 +255,7 @@ build_vbase_pointer_fields (rli, empty_p)
empty_p);
BINFO_VPTR_FIELD (base_binfo) = decl;
TREE_CHAIN (decl) = vbase_decls;
- layout_field (rli, decl);
+ place_field (rli, decl);
vbase_decls = decl;
*empty_p = 0;
@@ -256,236 +268,6 @@ build_vbase_pointer_fields (rli, empty_p)
return vbase_decls;
}
-/* Called from build_vbase_offset_vtbl_entries via dfs_walk. */
-
-static tree
-dfs_build_vbase_offset_vtbl_entries (binfo, data)
- tree binfo;
- void *data;
-{
- tree list = (tree) data;
-
- if (TREE_TYPE (list) == binfo)
- /* The TREE_TYPE of LIST is the base class from which we started
- walking. If that BINFO is virtual it's not a virtual baseclass
- of itself. */
- ;
- else if (TREE_VIA_VIRTUAL (binfo))
- {
- tree init;
- tree vbase;
-
- /* Remember the index to the vbase offset for this virtual
- base. */
- vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), TREE_PURPOSE (list));
- if (!TREE_VALUE (list))
- BINFO_VPTR_FIELD (vbase) = build_int_2 (-1, 0);
- else
- {
- BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list));
- BINFO_VPTR_FIELD (vbase)
- = fold (build (MINUS_EXPR, integer_type_node,
- BINFO_VPTR_FIELD (vbase), integer_one_node));
- }
-
- /* And record the offset at which this virtual base lies in the
- vtable. */
- init = BINFO_OFFSET (binfo);
- TREE_VALUE (list) = tree_cons (BINFO_VPTR_FIELD (vbase),
- init, TREE_VALUE (list));
- }
-
- SET_BINFO_VTABLE_PATH_MARKED (binfo);
-
- return NULL_TREE;
-}
-
-/* Returns the initializers for the vbase offset entries in the vtable
- for BINFO (which is part of the class hierarchy dominated by T), in
- reverse order. */
-
-static tree
-build_vbase_offset_vtbl_entries (binfo, t)
- tree binfo;
- tree t;
-{
- tree inits;
- tree init;
- tree list;
-
- /* Under the old ABI, pointers to virtual bases are stored in each
- object. */
- if (!vbase_offsets_in_vtable_p ())
- return NULL_TREE;
-
- /* If there are no virtual baseclasses, then there is nothing to
- do. */
- if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
- return NULL_TREE;
-
- inits = NULL_TREE;
-
- /* The offsets are allocated in the reverse order of a
- depth-first left-to-right traversal of the hierarchy. We use
- BINFO_VTABLE_PATH_MARKED because we are ourselves during a
- dfs_walk, and so BINFO_MARKED is already in use. */
- list = build_tree_list (t, NULL_TREE);
- TREE_TYPE (list) = binfo;
- dfs_walk (binfo,
- dfs_build_vbase_offset_vtbl_entries,
- dfs_vtable_path_unmarked_real_bases_queue_p,
- list);
- dfs_walk (binfo,
- dfs_vtable_path_unmark,
- dfs_vtable_path_marked_real_bases_queue_p,
- list);
- inits = nreverse (TREE_VALUE (list));
-
- /* We've now got offsets in the right order. However, the offsets
- we've stored are offsets from the beginning of the complete
- object, and we need offsets from this BINFO. */
- for (init = inits; init; init = TREE_CHAIN (init))
- {
- /* The dfs_build_vbase_offset_vtbl_entries routine uses the
- TREE_PURPOSE to scribble in. But, we need to clear it now so
- that the values are not perceived as labeled initializers. */
- TREE_PURPOSE (init) = NULL_TREE;
- TREE_VALUE (init)
- = fold (build1 (NOP_EXPR, vtable_entry_type,
- size_diffop (TREE_VALUE (init),
- BINFO_OFFSET (binfo))));
- }
-
- return inits;
-}
-
-typedef struct vcall_offset_data_s
-{
- /* The binfo for the most-derived type. */
- tree derived;
- /* The binfo for the virtual base for which we're building
- initializers. */
- tree vbase;
- /* The vcall offset initializers built up so far. */
- tree inits;
- /* The number of vcall offsets accumulated. */
- int offsets;
-} vcall_offset_data;
-
-/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
-
-static tree
-dfs_vcall_offset_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- vcall_offset_data* vod = (vcall_offset_data *) data;
-
- return (binfo == vod->vbase) ? binfo : dfs_skip_vbases (binfo, NULL);
-}
-
-/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
-
-static tree
-dfs_build_vcall_offset_vtbl_entries (binfo, data)
- tree binfo;
- void *data;
-{
- vcall_offset_data* vod;
- tree virtuals;
- tree binfo_inits;
-
- /* Primary bases are not interesting; all of the virtual
- function table entries have been overridden. */
- if (BINFO_PRIMARY_MARKED_P (binfo))
- return NULL_TREE;
-
- vod = (vcall_offset_data *) data;
- binfo_inits = NULL_TREE;
-
- /* We chain the offsets on in reverse order. That's correct --
- build_vtbl_initializer will straighten them out. */
- for (virtuals = skip_rtti_stuff (binfo,
- BINFO_TYPE (binfo),
- NULL);
- virtuals;
- virtuals = TREE_CHAIN (virtuals))
- {
- /* Figure out what function we're looking at. */
- tree fn = TREE_VALUE (virtuals);
- tree base = DECL_CONTEXT (fn);
- /* The FN comes from BASE. So, we must caculate the adjustment
- from the virtual base that derived from BINFO to BASE. */
- tree base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
-
- binfo_inits
- = tree_cons (NULL_TREE,
- fold (build1 (NOP_EXPR, vtable_entry_type,
- size_diffop (BINFO_OFFSET (base_binfo),
- BINFO_OFFSET (vod->vbase)))),
- binfo_inits);
- }
-
- /* Now add the initializers we've just created to the list that will
- be returned to our caller. */
- vod->inits = chainon (vod->inits, binfo_inits);
-
- return NULL_TREE;
-}
-
-/* Returns the initializers for the vcall offset entries in the vtable
- for BINFO (which is part of the class hierarchy dominated by T), in
- reverse order. */
-
-static tree
-build_vcall_offset_vtbl_entries (binfo, t)
- tree binfo;
- tree t;
-{
- vcall_offset_data vod;
-
- /* Under the old ABI, the adjustments to the `this' pointer were made
- elsewhere. */
- if (!vcall_offsets_in_vtable_p ())
- return NULL_TREE;
-
- /* We only need these entries if this base is a virtual base. */
- if (!TREE_VIA_VIRTUAL (binfo))
- return NULL_TREE;
-
- /* We need a vcall offset for each of the virtual functions in this
- vtable. For example:
-
- class A { virtual void f (); };
- class B : virtual public A { };
- class C: virtual public A, public B {};
-
- Now imagine:
-
- B* b = new C;
- b->f();
-
- The location of `A' is not at a fixed offset relative to `B'; the
- offset depends on the complete object derived from `B'. So,
- `B' vtable contains an entry for `f' that indicates by what
- amount the `this' pointer for `B' needs to be adjusted to arrive
- at `A'.
-
- We need entries for all the functions in our primary vtable and
- in our non-virtual bases vtables. For each base, the entries
- appear in the same order as in the base; but the bases themselves
- appear in reverse depth-first, left-to-right order. */
- vod.derived = t;
- vod.vbase = binfo;
- vod.inits = NULL_TREE;
- dfs_walk (binfo,
- dfs_build_vcall_offset_vtbl_entries,
- dfs_vcall_offset_queue_p,
- &vod);
-
- return vod.inits;
-}
-
/* Returns a pointer to the virtual base class of EXP that has the
indicated TYPE. EXP is of class type, not a pointer type. */
@@ -504,9 +286,10 @@ build_vbase_pointer (exp, type)
/* Find the virtual function table pointer. */
vbase_ptr = build_vfield_ref (exp, TREE_TYPE (exp));
/* Compute the location where the offset will lie. */
- vbase_ptr = build_binary_op (PLUS_EXPR,
- vbase_ptr,
- BINFO_VPTR_FIELD (vbase));
+ vbase_ptr = build (PLUS_EXPR,
+ TREE_TYPE (vbase_ptr),
+ vbase_ptr,
+ BINFO_VPTR_FIELD (vbase));
vbase_ptr = build1 (NOP_EXPR,
build_pointer_type (ptrdiff_type_node),
vbase_ptr);
@@ -678,75 +461,6 @@ build_vbase_path (code, type, expr, path, nonnull)
/* Virtual function things. */
-/* Build an entry in the virtual function table. DELTA is the offset
- for the `this' pointer. VCALL_INDEX is the vtable index containing
- the vcall offset; zero if none. ENTRY is the virtual function
- table entry itself. It's TREE_TYPE must be VFUNC_PTR_TYPE_NODE,
- but it may not actually be a virtual function table pointer. (For
- example, it might be the address of the RTTI object, under the new
- ABI.) */
-
-static tree
-build_vtable_entry (delta, vcall_index, entry)
- tree delta;
- tree vcall_index;
- tree entry;
-{
- if (flag_vtable_thunks)
- {
- HOST_WIDE_INT idelta;
- HOST_WIDE_INT ivindex;
-
- idelta = tree_low_cst (delta, 0);
- ivindex = tree_low_cst (vcall_index, 0);
- if ((idelta || ivindex)
- && ! DECL_PURE_VIRTUAL_P (TREE_OPERAND (entry, 0)))
- {
- entry = make_thunk (entry, idelta, ivindex);
- entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
- TREE_READONLY (entry) = 1;
- TREE_CONSTANT (entry) = 1;
- }
-#ifdef GATHER_STATISTICS
- n_vtable_entries += 1;
-#endif
- return entry;
- }
- else
- {
- extern int flag_huge_objects;
- tree elems = tree_cons (NULL_TREE, delta,
- tree_cons (NULL_TREE, integer_zero_node,
- build_tree_list (NULL_TREE, entry)));
- tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
-
- /* We don't use vcall offsets when not using vtable thunks. */
- my_friendly_assert (integer_zerop (vcall_index), 20000125);
-
- /* DELTA used to be constructed by `size_int' and/or size_binop,
- which caused overflow problems when it was negative. That should
- be fixed now. */
-
- if (! int_fits_type_p (delta, delta_type_node))
- {
- if (flag_huge_objects)
- sorry ("object size exceeds built-in limit for virtual function table implementation");
- else
- sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
- }
-
- TREE_CONSTANT (entry) = 1;
- TREE_STATIC (entry) = 1;
- TREE_READONLY (entry) = 1;
-
-#ifdef GATHER_STATISTICS
- n_vtable_entries += 1;
-#endif
-
- return entry;
- }
-}
-
/* We want to give the assembler the vtable identifier as well as
the offset to the function pointer. So we generate
@@ -761,7 +475,7 @@ build_vtable_entry_ref (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_unary_op (ADDR_EXPR, get_vtbl_decl_for_binfo (basetype), 0);
s = build_tree_list (build_string (1, "s"), s);
i = build_array_ref (vtbl, idx);
@@ -832,7 +546,23 @@ build_vtbl_ref (instance, idx)
&& (TREE_CODE (instance) == RESULT_DECL
|| TREE_CODE (instance) == PARM_DECL
|| TREE_CODE (instance) == VAR_DECL))
- vtbl = TYPE_BINFO_VTABLE (basetype);
+ {
+ vtbl = TYPE_BINFO_VTABLE (basetype);
+ /* Knowing the dynamic type of INSTANCE we can easily obtain
+ the correct vtable entry. In the new ABI, we resolve
+ this back to be in terms of the primary vtable. */
+ if (TREE_CODE (vtbl) == PLUS_EXPR)
+ {
+ idx = fold (build (PLUS_EXPR,
+ TREE_TYPE (idx),
+ idx,
+ build (EXACT_DIV_EXPR,
+ TREE_TYPE (idx),
+ TREE_OPERAND (vtbl, 1),
+ TYPE_SIZE_UNIT (vtable_entry_type))));
+ vtbl = get_vtbl_decl_for_binfo (TYPE_BINFO (basetype));
+ }
+ }
else
vtbl = build_vfield_ref (instance, basetype);
}
@@ -912,13 +642,9 @@ tree
get_vfield_offset (binfo)
tree binfo;
{
- tree tmp
- = size_binop (FLOOR_DIV_EXPR,
- bit_position (TYPE_VFIELD (BINFO_TYPE (binfo))),
- bitsize_int (BITS_PER_UNIT));
-
- return size_binop (PLUS_EXPR, convert (sizetype, tmp),
- BINFO_OFFSET (binfo));
+ return
+ size_binop (PLUS_EXPR, byte_position (TYPE_VFIELD (BINFO_TYPE (binfo))),
+ BINFO_OFFSET (binfo));
}
/* Get the offset to the start of the original binfo that we derived
@@ -949,47 +675,6 @@ get_derived_offset (binfo, type)
return size_binop (MINUS_EXPR, offset1, offset2);
}
-/* Update the rtti info for this class. */
-
-static void
-set_rtti_entry (virtuals, offset, type)
- tree virtuals, offset, type;
-{
- tree decl;
-
- if (CLASSTYPE_COM_INTERFACE (type))
- return;
-
- if (flag_rtti)
- decl = get_tinfo_decl (type);
- else if (!new_abi_rtti_p ())
- /* If someone tries to get RTTI information for a type compiled
- without RTTI, they're out of luck. By calling __pure_virtual
- in this case, we give a small clue as to what went wrong. We
- could consider having a __no_typeinfo function as well, for a
- more specific hint. */
- decl = abort_fndecl;
- else
- /* For the new-abi, we just point to the type_info object. */
- decl = NULL_TREE;
-
- if (flag_vtable_thunks)
- {
- /* The first slot holds the offset. */
- BV_DELTA (virtuals) = offset;
- BV_VCALL_INDEX (virtuals) = integer_zero_node;
-
- /* The next node holds the decl. */
- virtuals = TREE_CHAIN (virtuals);
- offset = integer_zero_node;
- }
-
- /* This slot holds the function to call. */
- BV_DELTA (virtuals) = offset;
- BV_VCALL_INDEX (virtuals) = integer_zero_node;
- BV_FN (virtuals) = decl;
-}
-
/* Create a VAR_DECL for a primary or secondary vtable for
CLASS_TYPE. Use NAME for the name of the vtable, and VTABLE_TYPE
for its type. */
@@ -1071,23 +756,15 @@ build_primary_vtable (binfo, type)
if (binfo)
{
- tree offset;
-
if (BINFO_NEW_VTABLE_MARKED (binfo, type))
/* We have already created a vtable for this base, so there's
no need to do it again. */
return 0;
virtuals = copy_list (BINFO_VIRTUALS (binfo));
- TREE_TYPE (decl) = TREE_TYPE (BINFO_VTABLE (binfo));
- DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (BINFO_VTABLE (binfo)));
- DECL_SIZE_UNIT (decl)
- = TYPE_SIZE_UNIT (TREE_TYPE (BINFO_VTABLE (binfo)));
-
- /* Now do rtti stuff. */
- offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE);
- offset = size_diffop (size_zero_node, offset);
- set_rtti_entry (virtuals, offset, type);
+ TREE_TYPE (decl) = TREE_TYPE (get_vtbl_decl_for_binfo (binfo));
+ DECL_SIZE (decl) = TYPE_SIZE (TREE_TYPE (decl));
+ DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (TREE_TYPE (decl));
}
else
{
@@ -1175,10 +852,6 @@ build_secondary_vtable (binfo, for_type)
else
offset = BINFO_OFFSET (binfo);
- set_rtti_entry (BINFO_VIRTUALS (binfo),
- size_diffop (size_zero_node, offset),
- for_type);
-
/* In the new ABI, secondary vtables are laid out as part of the
same structure as the primary vtable. */
if (merge_primary_and_secondary_vtables_p ())
@@ -1353,42 +1026,52 @@ modify_vtable_entry (t, binfo, fndecl, delta, virtuals)
}
}
-/* Call this function whenever its known that a vtable for T is going
- to be needed. It's safe to call it more than once. *HAS_VIRTUAL_P
- is initialized to the number of slots that are reserved at the
- beginning of the vtable for RTTI information. */
+/* Return the index (in the virtual function table) of the first
+ virtual function. */
+
+int
+first_vfun_index (t)
+ tree t;
+{
+ /* Under the old ABI, the offset-to-top and RTTI entries are at
+ indices zero and one; under the new ABI, the first virtual
+ function is at index zero. */
+ if (!CLASSTYPE_COM_INTERFACE (t) && !flag_new_abi)
+ return flag_vtable_thunks ? 2 : 1;
+
+ return 0;
+}
+
+/* Set DECL_VINDEX for DECL. VINDEX_P is the number of virtual
+ functions present in the vtable so far. */
static void
-start_vtable (t, has_virtual_p)
+set_vindex (t, decl, vfuns_p)
tree t;
- int *has_virtual_p;
+ tree decl;
+ int *vfuns_p;
{
- if (*has_virtual_p == 0 && ! CLASSTYPE_COM_INTERFACE (t))
- {
- /* If we are using thunks, use two slots at the front, one
- for the offset pointer, one for the tdesc pointer.
- For ARM-style vtables, use the same slot for both. */
- if (flag_vtable_thunks)
- *has_virtual_p = 2;
- else
- *has_virtual_p = 1;
- }
+ int vindex;
+
+ vindex = (*vfuns_p)++;
+ vindex += first_vfun_index (t);
+ DECL_VINDEX (decl) = build_shared_int_cst (vindex);
}
/* Add a virtual function to all the appropriate vtables for the class
T. DECL_VINDEX(X) should be error_mark_node, if we want to
allocate a new slot in our table. If it is error_mark_node, we
know that no other function from another vtable is overridden by X.
- HAS_VIRTUAL keeps track of how many virtuals there are in our main
- vtable for the type, and we build upon the NEW_VIRTUALS list
+ VFUNS_P keeps track of how many virtuals there are in our
+ main vtable for the type, and we build upon the NEW_VIRTUALS list
and return it. */
static void
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
- has_virtual, fndecl, t)
+ vfuns_p, fndecl, t)
tree *new_virtuals_p;
tree *overridden_virtuals_p;
- int *has_virtual;
+ int *vfuns_p;
tree fndecl;
tree t; /* Structure type. */
{
@@ -1413,10 +1096,8 @@ add_virtual_function (new_virtuals_p, overridden_virtuals_p,
/* We remember that this was the base sub-object for rtti. */
CLASSTYPE_RTTI (t) = t;
- start_vtable (t, has_virtual);
-
/* Now assign virtual dispatch information. */
- DECL_VINDEX (fndecl) = build_shared_int_cst ((*has_virtual)++);
+ set_vindex (t, fndecl, vfuns_p);
DECL_VIRTUAL_CONTEXT (fndecl) = t;
/* Save the state we've computed on the NEW_VIRTUALS list. */
@@ -1970,13 +1651,104 @@ check_bases (t, cant_have_default_ctor_p, cant_have_const_ctor_p,
}
}
+/* Called via dfs_walk from mark_primary_bases. Sets
+ BINFO_PRIMARY_MARKED_P for BINFO, if appropriate. */
+
+static tree
+dfs_mark_primary_bases (binfo, data)
+ tree binfo;
+ void *data;
+{
+ int i;
+ tree base_binfo;
+
+ if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
+ return NULL_TREE;
+
+ i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
+ base_binfo = BINFO_BASETYPE (binfo, i);
+
+ if (!TREE_VIA_VIRTUAL (base_binfo))
+ /* Non-virtual base classes are easy. */
+ BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
+ else
+ {
+ tree shared_binfo;
+
+ shared_binfo
+ = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data);
+
+ /* If this virtual base is not already primary somewhere else in
+ the hiearchy, then we'll be using this copy. */
+ if (!BINFO_VBASE_PRIMARY_P (shared_binfo))
+ {
+ BINFO_VBASE_PRIMARY_P (shared_binfo) = 1;
+ BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
+ }
+ }
+
+ return NULL_TREE;
+}
+
+/* Set BINFO_PRIMARY_MARKED_P for all binfos in the hierarchy
+ dominated by BINFO that are primary bases. */
+
+static void
+mark_primary_bases (type)
+ tree type;
+{
+ tree vbases;
+
+ /* Mark the TYPE_BINFO hierarchy. We need to mark primary bases in
+ pre-order to deal with primary virtual bases. (The virtual base
+ would be skipped if it were not marked as primary, and that
+ requires getting to dfs_mark_primary_bases before
+ dfs_skip_nonprimary_vbases_unmarkedp has a chance to skip the
+ virtual base.) */
+ dfs_walk_real (TYPE_BINFO (type), dfs_mark_primary_bases, NULL,
+ dfs_skip_nonprimary_vbases_unmarkedp, type);
+
+ /* Now go through the virtual base classes in inheritance graph
+ order. Any that are not already primary will need to be
+ allocated in TYPE, and so we need to mark their primary bases. */
+ for (vbases = TYPE_BINFO (type); vbases; vbases = TREE_CHAIN (vbases))
+ {
+ tree vbase;
+
+ /* Make sure that only BINFOs appear on this list.
+ Historically, the TREE_CHAIN was used for other purposes, and
+ we want to make sure that none of those uses remain. */
+ my_friendly_assert (TREE_CODE (vbases) == TREE_VEC, 20000402);
+
+ if (!TREE_VIA_VIRTUAL (vbases))
+ continue;
+
+ vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbases), type);
+ if (BINFO_VBASE_PRIMARY_P (vbase))
+ /* This virtual base was already included in the hierarchy, so
+ there's nothing to do here. */
+ continue;
+
+ /* Temporarily pretend that VBASE is primary so that its bases
+ will be walked; this is the real copy of VBASE. */
+ BINFO_PRIMARY_MARKED_P (vbase) = 1;
+
+ /* Now, walk its bases. */
+ dfs_walk_real (vbase, dfs_mark_primary_bases, NULL,
+ dfs_skip_nonprimary_vbases_unmarkedp, type);
+
+ /* VBASE wasn't really primary. */
+ BINFO_PRIMARY_MARKED_P (vbase) = 0;
+ }
+}
+
/* Make the Ith baseclass of T its primary base. */
static void
-set_primary_base (t, i, has_virtual_p)
+set_primary_base (t, i, vfuns_p)
tree t;
int i;
- int *has_virtual_p;
+ int *vfuns_p;
{
tree basetype;
@@ -1986,15 +1758,15 @@ set_primary_base (t, i, has_virtual_p)
TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype);
TYPE_VFIELD (t) = TYPE_VFIELD (basetype);
CLASSTYPE_RTTI (t) = CLASSTYPE_RTTI (basetype);
- *has_virtual_p = CLASSTYPE_VSIZE (basetype);
+ *vfuns_p = CLASSTYPE_VSIZE (basetype);
}
/* Determine the primary class for T. */
static void
-determine_primary_base (t, has_virtual_p)
+determine_primary_base (t, vfuns_p)
tree t;
- int *has_virtual_p;
+ int *vfuns_p;
{
int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t);
@@ -2002,7 +1774,7 @@ determine_primary_base (t, has_virtual_p)
if (n_baseclasses == 0)
return;
- *has_virtual_p = 0;
+ *vfuns_p = 0;
for (i = 0; i < n_baseclasses; i++)
{
@@ -2025,7 +1797,7 @@ determine_primary_base (t, has_virtual_p)
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
{
- set_primary_base (t, i, has_virtual_p);
+ set_primary_base (t, i, vfuns_p);
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
}
else
@@ -2043,8 +1815,8 @@ determine_primary_base (t, has_virtual_p)
VF_BASETYPE_VALUE (vfields),
CLASSTYPE_VFIELDS (t));
- if (*has_virtual_p == 0)
- set_primary_base (t, i, has_virtual_p);
+ if (!flag_new_abi && *vfuns_p == 0)
+ set_primary_base (t, i, vfuns_p);
}
}
}
@@ -2064,7 +1836,7 @@ determine_primary_base (t, has_virtual_p)
if (TREE_VIA_VIRTUAL (base_binfo)
&& CLASSTYPE_NEARLY_EMPTY_P (basetype))
{
- set_primary_base (t, i, has_virtual_p);
+ set_primary_base (t, i, vfuns_p);
CLASSTYPE_VFIELDS (t) = copy_list (CLASSTYPE_VFIELDS (basetype));
break;
}
@@ -2531,6 +2303,7 @@ layout_vtable_decl (binfo, n)
{
tree itype;
tree atype;
+ tree vtable;
itype = size_int (n);
atype = build_cplus_array_type (vtable_entry_type,
@@ -2538,12 +2311,11 @@ layout_vtable_decl (binfo, n)
layout_type (atype);
/* We may have to grow the vtable. */
- if (!same_type_p (TREE_TYPE (BINFO_VTABLE (binfo)), atype))
+ vtable = get_vtbl_decl_for_binfo (binfo);
+ if (!same_type_p (TREE_TYPE (vtable), atype))
{
- tree vtable = BINFO_VTABLE (binfo);
-
TREE_TYPE (vtable) = atype;
- DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = 0;
+ DECL_SIZE (vtable) = DECL_SIZE_UNIT (vtable) = NULL_TREE;
layout_decl (vtable, 0);
/* At one time the vtable info was grabbed 2 words at a time. This
@@ -2553,328 +2325,6 @@ layout_vtable_decl (binfo, n)
}
}
-/* Returns the number of virtual function table entries (excluding
- RTTI information, vbase and vcall offests, etc.) in the vtable for
- BINFO. */
-
-static int
-num_vfun_entries (binfo)
- tree binfo;
-{
- return list_length (skip_rtti_stuff (binfo,
- BINFO_TYPE (binfo),
- NULL));
-}
-
-/* Called from num_extra_vtbl_entries via dfs_walk. */
-
-static tree
-dfs_count_virtuals (binfo, data)
- tree binfo;
- void *data;
-{
- /* Non-primary bases are not interesting; all of the virtual
- function table entries have been overridden. */
- if (!BINFO_PRIMARY_MARKED_P (binfo))
- ((vcall_offset_data *) data)->offsets += num_vfun_entries (binfo);
-
- return NULL_TREE;
-}
-
-/* Returns the number of extra entries (at negative indices) required
- for BINFO's vtable. */
-
-tree
-num_extra_vtbl_entries (binfo)
- tree binfo;
-{
- tree type;
- int entries;
-
- type = BINFO_TYPE (binfo);
- entries = 0;
-
- /* There is an entry for the offset to each virtual base. */
- if (vbase_offsets_in_vtable_p ())
- entries += list_length (CLASSTYPE_VBASECLASSES (type));
-
- /* If this is a virtual base, there are entries for each virtual
- function defined in this class or its bases. */
- if (vcall_offsets_in_vtable_p () && TREE_VIA_VIRTUAL (binfo))
- {
- vcall_offset_data vod;
-
- vod.vbase = binfo;
- vod.offsets = 0;
- dfs_walk (binfo,
- dfs_count_virtuals,
- dfs_vcall_offset_queue_p,
- &vod);
- entries += vod.offsets;
- }
-
- return entries ? size_int (entries) : size_zero_node;
-}
-
-/* Returns the offset (in bytes) from the beginning of BINFO's vtable
- where the vptr should actually point. */
-
-tree
-size_extra_vtbl_entries (binfo)
- tree binfo;
-{
- tree offset = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (vtable_entry_type),
- num_extra_vtbl_entries (binfo));
- return fold (offset);
-}
-
-/* Construct the initializer for BINFOs virtual function table. BINFO
- is part of the hierarchy dominated by T. The value returned is a
- TREE_LIST suitable for wrapping in a CONSTRUCTOR to use as the
- DECL_INITIAL for a vtable. */
-
-static tree
-build_vtbl_initializer (binfo, t)
- tree binfo;
- tree t;
-{
- tree v = BINFO_VIRTUALS (binfo);
- tree inits = NULL_TREE;
- tree type = BINFO_TYPE (binfo);
-
- /* Add entries to the vtable that indicate how to adjust the this
- pointer when calling a virtual function in this class. */
- inits = build_vcall_offset_vtbl_entries (binfo, t);
-
- /* Add entries to the vtable for offsets to our virtual bases. */
- inits = chainon (build_vbase_offset_vtbl_entries (binfo, t),
- inits);
-
- /* Process the RTTI stuff at the head of the list. If we're not
- using vtable thunks, then the RTTI entry is just an ordinary
- function, and we can process it just like the other virtual
- function entries. */
- if (!CLASSTYPE_COM_INTERFACE (type) && flag_vtable_thunks)
- {
- tree offset;
- tree init;
-
- /* The first entry is an offset. */
- offset = TREE_PURPOSE (v);
- my_friendly_assert (TREE_CODE (offset) == INTEGER_CST,
- 19990727);
-
- /* Convert the offset to look like a function pointer, so that
- we can put it in the vtable. */
- init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
- TREE_CONSTANT (init) = 1;
- inits = tree_cons (NULL_TREE, init, inits);
-
- v = TREE_CHAIN (v);
-
- if (new_abi_rtti_p ())
- {
- tree decl = TREE_VALUE (v);
-
- if (decl)
- decl = build_unary_op (ADDR_EXPR, decl, 0);
- else
- decl = integer_zero_node;
- decl = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
- TREE_CONSTANT (decl) = 1;
- decl = build_vtable_entry (integer_zero_node, integer_zero_node,
- decl);
- inits = tree_cons (NULL_TREE, decl, inits);
-
- v = TREE_CHAIN (v);
- }
- /* In the old abi the second entry (the tdesc pointer) is
- just an ordinary function, so it can be dealt with like the
- virtual functions. */
- }
-
- /* Go through all the ordinary virtual functions, building up
- initializers. */
- while (v)
- {
- tree delta;
- tree vcall_index;
- tree fn;
- tree pfn;
- tree init;
-
- /* Pull the offset for `this', and the function to call, out of
- the list. */
- delta = BV_DELTA (v);
- vcall_index = BV_VCALL_INDEX (v);
- fn = BV_FN (v);
- my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727);
- my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727);
-
- /* You can't call an abstract virtual function; it's abstract.
- So, we replace these functions with __pure_virtual. */
- if (DECL_PURE_VIRTUAL_P (fn))
- fn = abort_fndecl;
-
- /* Take the address of the function, considering it to be of an
- appropriate generic type. */
- pfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
- /* The address of a function can't change. */
- TREE_CONSTANT (pfn) = 1;
- /* Enter it in the vtable. */
- init = build_vtable_entry (delta, vcall_index, pfn);
- /* And add it to the chain of initializers. */
- inits = tree_cons (NULL_TREE, init, inits);
-
- /* Keep going. */
- v = TREE_CHAIN (v);
- }
-
- /* The initializers were built up in reverse order; straighten them
- out now. */
- return nreverse (inits);
-}
-
-/* Initialize the vtable for BINFO with the INITS. */
-
-static void
-initialize_vtable (binfo, inits)
- tree binfo;
- tree inits;
-{
- tree context;
- tree decl;
-
- layout_vtable_decl (binfo, list_length (inits));
- decl = BINFO_VTABLE (binfo);
- context = DECL_CONTEXT (decl);
- DECL_CONTEXT (decl) = 0;
- DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
- cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
- DECL_CONTEXT (decl) = context;
-}
-
-/* Called from finish_vtbls via dfs_walk. */
-
-static tree
-dfs_finish_vtbls (binfo, data)
- tree binfo;
- void *data;
-{
- tree t = (tree) data;
-
- if (!BINFO_PRIMARY_MARKED_P (binfo)
- && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
- && BINFO_NEW_VTABLE_MARKED (binfo, t))
- initialize_vtable (binfo,
- build_vtbl_initializer (binfo, t));
-
- CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
- SET_BINFO_MARKED (binfo);
-
- return NULL_TREE;
-}
-
-/* Called from finish_vtbls via dfs_walk when using the new ABI.
- Accumulates the vtable initializers for all of the vtables into
- TREE_VALUE (DATA). */
-
-static tree
-dfs_accumulate_vtbl_inits (binfo, data)
- tree binfo;
- void *data;
-{
- tree l;
- tree t;
-
- l = (tree) data;
- t = TREE_PURPOSE (l);
-
- if (!BINFO_PRIMARY_MARKED_P (binfo)
- && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
- && BINFO_NEW_VTABLE_MARKED (binfo, t))
- {
-
- /* If this is a secondary vtable, record its location. */
- if (binfo != TYPE_BINFO (t))
- {
- tree vtbl;
-
- vtbl = TYPE_BINFO_VTABLE (t);
- vtbl = build1 (ADDR_EXPR,
- build_pointer_type (TREE_TYPE (vtbl)),
- vtbl);
- BINFO_VTABLE (binfo)
- = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
- size_binop (MULT_EXPR,
- TYPE_SIZE_UNIT (TREE_TYPE (vtbl)),
- size_int (list_length (TREE_VALUE (l)))));
- }
-
- /* Add the initializers for this vtable to the initializers for
- the other vtables we've already got. */
- TREE_VALUE (l)
- = chainon (TREE_VALUE (l),
- build_vtbl_initializer (binfo, t));
- }
-
- CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
-
- return NULL_TREE;
-}
-
-/* Add the vtbl initializers for BINFO (and its non-primary,
- non-virtual bases) to the list of INITS. */
-
-static void
-accumulate_vtbl_inits (binfo, inits)
- tree binfo;
- tree inits;
-{
- /* Walk the BINFO and its bases. */
- dfs_walk_real (binfo,
- dfs_accumulate_vtbl_inits,
- NULL,
- dfs_skip_vbases,
- inits);
-}
-
-/* Create all the necessary vtables for T and its base classes. */
-
-static void
-finish_vtbls (t)
- tree t;
-{
- if (merge_primary_and_secondary_vtables_p ())
- {
- tree list;
- tree vbase;
-
- /* Under the new ABI, we lay out the primary and secondary
- vtables in one contiguous vtable. The primary vtable is
- first, followed by the non-virtual secondary vtables in
- inheritance graph order. */
- list = build_tree_list (t, NULL_TREE);
- accumulate_vtbl_inits (TYPE_BINFO (t), list);
- /* Then come the virtual bases, also in inheritance graph
- order. */
- for (vbase = CLASSTYPE_VBASECLASSES (t);
- vbase;
- vbase = TREE_CHAIN (vbase))
- accumulate_vtbl_inits (vbase, list);
-
- if (TYPE_BINFO_VTABLE (t))
- initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
- }
- else
- {
- dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
- dfs_unmarked_real_bases_queue_p, t);
- dfs_walk (TYPE_BINFO (t), dfs_unmark,
- dfs_marked_real_bases_queue_p, t);
- }
-}
-
/* True if we should override the given BASE_FNDECL with the given
FNDECL. */
@@ -3053,43 +2503,6 @@ find_final_overrider (t, binfo, fn)
return build_tree_list (ffod.overriding_fn, ffod.overriding_base);
}
-/* Return the BINFO_VIRTUALS list for BINFO, without the RTTI stuff at
- the front. If non-NULL, N is set to the number of entries
- skipped. */
-
-tree
-skip_rtti_stuff (binfo, t, n)
- tree binfo;
- tree t;
- HOST_WIDE_INT *n;
-{
- tree virtuals;
-
- if (CLASSTYPE_COM_INTERFACE (t))
- return 0;
-
- if (n)
- *n = 0;
- virtuals = BINFO_VIRTUALS (binfo);
- if (virtuals)
- {
- /* We always reserve a slot for the offset/tdesc entry. */
- if (n)
- ++*n;
- virtuals = TREE_CHAIN (virtuals);
- }
- if (flag_vtable_thunks && virtuals)
- {
- /* The second slot is reserved for the tdesc pointer when thunks
- are used. */
- if (n)
- ++*n;
- virtuals = TREE_CHAIN (virtuals);
- }
-
- return virtuals;
-}
-
/* Called via dfs_walk. Returns BINFO if BINFO has the same type as
DATA (which is really an _TYPE node). */
@@ -3130,10 +2543,8 @@ dfs_modify_vtables (binfo, data)
/* Now, go through each of the virtual functions in the virtual
function table for BINFO. Find the final overrider, and
update the BINFO_VIRTUALS list appropriately. */
- for (virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), NULL),
- old_virtuals = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (binfo)),
- BINFO_TYPE (binfo),
- NULL);
+ for (virtuals = BINFO_VIRTUALS (binfo),
+ old_virtuals = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (binfo)));
virtuals;
virtuals = TREE_CHAIN (virtuals),
old_virtuals = TREE_CHAIN (old_virtuals))
@@ -3143,17 +2554,16 @@ dfs_modify_vtables (binfo, data)
tree overrider;
tree vindex;
tree delta;
- HOST_WIDE_INT vindex_val, i;
-
+ HOST_WIDE_INT vindex_val;
+ HOST_WIDE_INT i;
/* Find the function which originally caused this vtable
entry to be present. */
fn = BV_FN (old_virtuals);
vindex = DECL_VINDEX (fn);
b = dfs_walk (binfo, dfs_find_base, NULL, DECL_VIRTUAL_CONTEXT (fn));
- fn = skip_rtti_stuff (TYPE_BINFO (BINFO_TYPE (b)),
- BINFO_TYPE (b),
- &i);
+ fn = BINFO_VIRTUALS (TYPE_BINFO (BINFO_TYPE (b)));
+ i = first_vfun_index (BINFO_TYPE (b));
vindex_val = tree_low_cst (vindex, 0);
while (i < vindex_val)
{
@@ -3200,9 +2610,9 @@ dfs_modify_vtables (binfo, data)
which should therefore be appended to the end of the vtable for T. */
static tree
-modify_all_vtables (t, has_virtual_p, overridden_virtuals)
+modify_all_vtables (t, vfuns_p, overridden_virtuals)
tree t;
- int *has_virtual_p;
+ int *vfuns_p;
tree overridden_virtuals;
{
tree binfo;
@@ -3229,11 +2639,8 @@ modify_all_vtables (t, has_virtual_p, overridden_virtuals)
if (BINFO_VIRTUALS (binfo)
&& !value_member (fn, BINFO_VIRTUALS (binfo)))
{
- /* We know we need a vtable for this class now. */
- start_vtable (t, has_virtual_p);
/* Set the vtable index. */
- DECL_VINDEX (fn)
- = build_shared_int_cst ((*has_virtual_p)++);
+ set_vindex (t, fn, vfuns_p);
/* We don't need to convert to a base class when calling
this function. */
DECL_VIRTUAL_CONTEXT (fn) = t;
@@ -3763,7 +3170,7 @@ check_field_decl (field, t, cant_have_const_ctor,
tree fields;
for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))
- if (TREE_CODE (field) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
+ if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))
check_field_decl (fields, t, cant_have_const_ctor,
cant_have_default_ctor, no_const_asn_ref,
any_default_members);
@@ -3927,7 +3334,7 @@ check_field_decls (t, access_decls, empty_p,
/* If we've gotten this far, it's a data member, possibly static,
or an enumerator. */
- DECL_FIELD_CONTEXT (x) = t;
+ DECL_CONTEXT (x) = t;
/* ``A local class cannot have static data members.'' ARM 9.4 */
if (current_function_decl && TREE_STATIC (x))
@@ -3958,8 +3365,6 @@ check_field_decls (t, access_decls, empty_p,
if (type == error_mark_node)
continue;
- DECL_SAVED_INSNS (x) = 0;
-
/* When this goes into scope, it will be a non-local reference. */
DECL_NONLOCAL (x) = 1;
@@ -4115,29 +3520,12 @@ build_vtbl_or_vbase_field (name, assembler_name, type, class_type, fcontext,
DECL_ARTIFICIAL (field) = 1;
DECL_FIELD_CONTEXT (field) = class_type;
DECL_FCONTEXT (field) = fcontext;
- DECL_SAVED_INSNS (field) = 0;
DECL_ALIGN (field) = TYPE_ALIGN (type);
/* Return it. */
return field;
}
-/* Return the BINFO_OFFSET for BINFO as a native integer, not an
- INTEGER_CST. */
-
-static unsigned HOST_WIDE_INT
-get_binfo_offset_as_int (binfo)
- tree binfo;
-{
- tree offset;
-
- offset = BINFO_OFFSET (binfo);
- my_friendly_assert (TREE_CODE (offset) == INTEGER_CST, 20000313);
- my_friendly_assert (TREE_INT_CST_HIGH (offset) == 0, 20000313);
-
- return (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (offset);
-}
-
/* Record the type of BINFO in the slot in DATA (which is really a
`varray_type *') corresponding to the BINFO_OFFSET. */
@@ -4147,7 +3535,7 @@ dfs_record_base_offsets (binfo, data)
void *data;
{
varray_type *v;
- unsigned HOST_WIDE_INT offset = get_binfo_offset_as_int (binfo);
+ unsigned HOST_WIDE_INT offset = tree_low_cst (BINFO_OFFSET (binfo), 1);
v = (varray_type *) data;
while (VARRAY_SIZE (*v) <= offset)
@@ -4184,11 +3572,10 @@ dfs_search_base_offsets (binfo, data)
if (is_empty_class (BINFO_TYPE (binfo)))
{
varray_type v = (varray_type) data;
- unsigned HOST_WIDE_INT offset;
+ /* Find the offset for this BINFO. */
+ unsigned HOST_WIDE_INT offset = tree_low_cst (BINFO_OFFSET (binfo), 1);
tree t;
- /* Find the offset for this BINFO. */
- offset = get_binfo_offset_as_int (binfo);
/* If we haven't yet encountered any objects at offsets that
big, then there's no conflict. */
if (VARRAY_SIZE (v) <= offset)
@@ -4238,16 +3625,17 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
while (1)
{
tree offset;
+ struct record_layout_info old_rli = *rli;
- /* Layout this field. */
- layout_field (rli, decl);
+ /* Place this field. */
+ place_field (rli, decl);
/* Now that we know where it wil be placed, update its
BINFO_OFFSET. */
- offset = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (decl)),
- BITS_PER_UNIT));
+ offset = byte_position (decl);
if (binfo)
- propagate_binfo_offsets (binfo, offset);
+ propagate_binfo_offsets (binfo,
+ convert (ssizetype, offset));
/* We have to check to see whether or not there is already
something of the same type at the offset we're about to use.
@@ -4267,17 +3655,20 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
if (binfo && flag_new_abi && layout_conflict_p (binfo, v))
{
/* Undo the propogate_binfo_offsets call. */
- offset = convert (sizetype,
- size_diffop (size_zero_node, offset));
- propagate_binfo_offsets (binfo, offset);
-
+ offset = size_diffop (size_zero_node, offset);
+ propagate_binfo_offsets (binfo, convert (ssizetype, offset));
+
/* Strip off the size allocated to this field. That puts us
at the first place we could have put the field with
proper alignment. */
- rli->const_size -= TREE_INT_CST_LOW (DECL_SIZE (decl));
- /* Bump up by th alignment required for the type, without
+ *rli = old_rli;
+
+ /* Bump up by the alignment required for the type, without
virtual base classes. */
- rli->const_size += CLASSTYPE_ALIGN (BINFO_TYPE (binfo));
+ rli->bitpos
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ bitsize_int (CLASSTYPE_ALIGN (BINFO_TYPE (binfo))));
+ normalize_rli (rli);
}
else
/* There was no conflict. We're done laying out this field. */
@@ -4286,8 +3677,9 @@ layout_nonempty_base_or_field (rli, decl, binfo, v)
}
/* Layout the empty base BINFO. EOC indicates the byte currently just
- past the end of the class; BINFO_OFFSETS gives the offsets of the
- other bases allocated so far. */
+ past the end of the class, and should be correctly aligned for a
+ class of the type indicated by BINFO; BINFO_OFFSETS gives the
+ offsets of the other bases allocated so far. */
static void
layout_empty_base (binfo, eoc, binfo_offsets)
@@ -4295,16 +3687,12 @@ layout_empty_base (binfo, eoc, binfo_offsets)
tree eoc;
varray_type binfo_offsets;
{
+ tree alignment;
tree basetype = BINFO_TYPE (binfo);
/* This routine should only be used for empty classes. */
my_friendly_assert (is_empty_class (basetype), 20000321);
-
- /* This code assumes that zero-sized classes have one-byte
- alignment. There might someday be a system where that's not
- true. */
- my_friendly_assert (TYPE_ALIGN (basetype) == BITS_PER_UNIT,
- 20000314);
+ alignment = ssize_int (CLASSTYPE_ALIGN (basetype));
/* This is an empty base class. We first try to put it at offset
zero. */
@@ -4312,7 +3700,7 @@ layout_empty_base (binfo, eoc, binfo_offsets)
{
/* That didn't work. Now, we move forward from the next
available spot in the class. */
- propagate_binfo_offsets (binfo, eoc);
+ propagate_binfo_offsets (binfo, convert (ssizetype, eoc));
while (1)
{
if (!layout_conflict_p (binfo, binfo_offsets))
@@ -4320,7 +3708,7 @@ layout_empty_base (binfo, eoc, binfo_offsets)
break;
/* There's overlap here, too. Bump along to the next spot. */
- propagate_binfo_offsets (binfo, size_one_node);
+ propagate_binfo_offsets (binfo, alignment);
}
}
}
@@ -4379,9 +3767,15 @@ build_base_field (rli, binfo, empty_p, base_align, v)
layout_nonempty_base_or_field (rli, decl, binfo, *v);
}
else
- layout_empty_base (binfo,
- size_int (CEIL (rli->const_size, BITS_PER_UNIT)),
- *v);
+ {
+ unsigned HOST_WIDE_INT eoc;
+
+ /* On some platforms (ARM), even empty classes will not be
+ byte-aligned. */
+ eoc = tree_low_cst (rli_size_unit_so_far (rli), 0);
+ eoc = CEIL (eoc, DECL_ALIGN (decl)) * DECL_ALIGN (decl);
+ layout_empty_base (binfo, size_int (eoc), *v);
+ }
/* Check for inaccessible base classes. If the same base class
appears more than once in the hierarchy, but isn't virtual, then
@@ -4463,7 +3857,6 @@ check_methods (t)
if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x)))
continue;
- DECL_SAVED_INSNS (x) = 0;
check_for_override (x, t);
if (DECL_PURE_VIRTUAL_P (x) && ! DECL_VINDEX (x))
cp_error_at ("initializer specified for non-virtual method `%D'", x);
@@ -4617,15 +4010,15 @@ check_bases_and_members (t, empty_p)
/* If T needs a pointer to its virtual function table, set TYPE_VFIELD
accordingly. If a new vfield was created (because T doesn't have a
primary base class), then the newly created field is returned. It
- is not added to the TYPE_FIELDS list; it is the callers
+ is not added to the TYPE_FIELDS list; it is the caller's
responsibility to do that. */
static tree
-create_vtable_ptr (t, empty_p, has_virtual_p,
+create_vtable_ptr (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p)
tree t;
int *empty_p;
- int *has_virtual_p;
+ int *vfuns_p;
tree *new_virtuals_p;
tree *overridden_virtuals_p;
{
@@ -4636,17 +4029,15 @@ create_vtable_ptr (t, empty_p, has_virtual_p,
for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn))
if (DECL_VINDEX (fn))
add_virtual_function (new_virtuals_p, overridden_virtuals_p,
- has_virtual_p, fn, t);
+ vfuns_p, fn, t);
- /* Even if there weren't any new virtual functions, we might need a
+ /* If we couldn't find an appropriate base class, create a new field
+ here. Even if there weren't any new virtual functions, we might need a
new virtual function table if we're supposed to include vptrs in
all classes that need them. */
- if (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())
- start_vtable (t, has_virtual_p);
-
- /* If we couldn't find an appropriate base class, create a new field
- here. */
- if (*has_virtual_p && !TYPE_VFIELD (t))
+ if (!TYPE_VFIELD (t)
+ && (*vfuns_p
+ || (TYPE_CONTAINS_VPTR_P (t) && vptrs_present_everywhere_p ())))
{
/* We build this decl with vtbl_ptr_type_node, which is a
`vtable_entry_type*'. It might seem more precise to use
@@ -4749,12 +4140,12 @@ dfs_propagate_binfo_offsets (binfo, data)
{
tree offset = (tree) data;
- /* Update the BINFO_OFFSET for this base. */
- BINFO_OFFSET (binfo) = fold (build (PLUS_EXPR,
- sizetype,
- BINFO_OFFSET (binfo),
- offset));
-
+ /* Update the BINFO_OFFSET for this base. Allow for the case where it
+ might be negative. */
+ BINFO_OFFSET (binfo)
+ = convert (sizetype, size_binop (PLUS_EXPR,
+ convert (ssizetype, BINFO_OFFSET (binfo)),
+ offset));
SET_BINFO_MARKED (binfo);
return NULL_TREE;
@@ -4835,7 +4226,7 @@ layout_virtual_bases (t, base_offsets)
tree t;
varray_type *base_offsets;
{
- tree vbase;
+ tree vbases;
unsigned HOST_WIDE_INT dsize;
unsigned HOST_WIDE_INT eoc;
@@ -4855,52 +4246,70 @@ layout_virtual_bases (t, base_offsets)
TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), BITS_PER_UNIT);
/* Go through the virtual bases, allocating space for each virtual
- base that is not already a primary base class. */
- for (vbase = CLASSTYPE_VBASECLASSES (t);
- vbase;
- vbase = TREE_CHAIN (vbase))
- if (!BINFO_VBASE_PRIMARY_P (vbase))
- {
- /* This virtual base is not a primary base of any class in the
- hierarchy, so we have to add space for it. */
- tree basetype;
- unsigned int desired_align;
-
- basetype = BINFO_TYPE (vbase);
-
- /* Under the new ABI, we try to squish empty virtual bases in
- just like ordinary empty bases. */
- if (flag_new_abi && is_empty_class (basetype))
- layout_empty_base (vbase,
- size_int (CEIL (dsize, BITS_PER_UNIT)),
- *base_offsets);
- else
- {
- if (flag_new_abi)
- desired_align = CLASSTYPE_ALIGN (basetype);
- else
- /* Under the old ABI, virtual bases were aligned as for
- the entire base object (including its virtual bases).
- That's wasteful, in general. */
- desired_align = TYPE_ALIGN (basetype);
- TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
-
- /* Add padding so that we can put the virtual base class at an
- appropriately aligned offset. */
- dsize = CEIL (dsize, desired_align) * desired_align;
- /* And compute the offset of the virtual base. */
- propagate_binfo_offsets (vbase,
- size_int (CEIL (dsize, BITS_PER_UNIT)));
- /* Every virtual baseclass takes a least a UNIT, so that
- we can take it's address and get something different
- for each base. */
- dsize += MAX (BITS_PER_UNIT,
- tree_low_cst (CLASSTYPE_SIZE (basetype), 0));
- }
+ base that is not already a primary base class. Under the new
+ ABI, these are allocated according to a depth-first left-to-right
+ postorder traversal; in the new ABI, inheritance graph order is
+ used instead. */
+ for (vbases = (flag_new_abi
+ ? TYPE_BINFO (t)
+ : CLASSTYPE_VBASECLASSES (t));
+ vbases;
+ vbases = TREE_CHAIN (vbases))
+ {
+ tree vbase;
- /* Keep track of the offsets assigned to this virtual base. */
- record_base_offsets (vbase, base_offsets);
- }
+ if (!TREE_VIA_VIRTUAL (vbases))
+ continue;
+
+ if (flag_new_abi)
+ vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbases), t);
+ else
+ vbase = vbases;
+
+ if (!BINFO_VBASE_PRIMARY_P (vbase))
+ {
+ /* This virtual base is not a primary base of any class in the
+ hierarchy, so we have to add space for it. */
+ tree basetype;
+ unsigned int desired_align;
+
+ basetype = BINFO_TYPE (vbase);
+
+ if (flag_new_abi)
+ desired_align = CLASSTYPE_ALIGN (basetype);
+ else
+ /* Under the old ABI, virtual bases were aligned as for the
+ entire base object (including its virtual bases). That's
+ wasteful, in general. */
+ desired_align = TYPE_ALIGN (basetype);
+ TYPE_ALIGN (t) = MAX (TYPE_ALIGN (t), desired_align);
+
+ /* Add padding so that we can put the virtual base class at an
+ appropriately aligned offset. */
+ dsize = CEIL (dsize, desired_align) * desired_align;
+
+ /* Under the new ABI, we try to squish empty virtual bases in
+ just like ordinary empty bases. */
+ if (flag_new_abi && is_empty_class (basetype))
+ layout_empty_base (vbase,
+ size_int (CEIL (dsize, BITS_PER_UNIT)),
+ *base_offsets);
+ else
+ {
+ /* And compute the offset of the virtual base. */
+ propagate_binfo_offsets (vbase,
+ ssize_int (CEIL (dsize, BITS_PER_UNIT)));
+ /* Every virtual baseclass takes a least a UNIT, so that
+ we can take it's address and get something different
+ for each base. */
+ dsize += MAX (BITS_PER_UNIT,
+ tree_low_cst (CLASSTYPE_SIZE (basetype), 0));
+ }
+
+ /* Keep track of the offsets assigned to this virtual base. */
+ record_base_offsets (vbase, base_offsets);
+ }
+ }
/* Make sure that all of the CLASSTYPE_VBASECLASSES have their
BINFO_OFFSET set correctly. Those we just allocated certainly
@@ -4917,10 +4326,10 @@ layout_virtual_bases (t, base_offsets)
in get_base_distance depend on the BINFO_OFFSETs being set
correctly. */
dfs_walk (TYPE_BINFO (t), dfs_set_offset_for_unshared_vbases, NULL, t);
- for (vbase = CLASSTYPE_VBASECLASSES (t);
- vbase;
- vbase = TREE_CHAIN (vbase))
- dfs_walk (vbase, dfs_set_offset_for_unshared_vbases, NULL, t);
+ for (vbases = CLASSTYPE_VBASECLASSES (t);
+ vbases;
+ vbases = TREE_CHAIN (vbases))
+ dfs_walk (vbases, dfs_set_offset_for_unshared_vbases, NULL, t);
/* If we had empty base classes that protruded beyond the end of the
class, we didn't update DSIZE above; we were hoping to overlay
@@ -4934,16 +4343,16 @@ layout_virtual_bases (t, base_offsets)
dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t);
TYPE_SIZE (t) = bitsize_int (dsize);
TYPE_SIZE_UNIT (t) = convert (sizetype,
- size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t),
- bitsize_int (BITS_PER_UNIT)));
+ size_binop (CEIL_DIV_EXPR, TYPE_SIZE (t),
+ bitsize_unit_node));
/* Check for ambiguous virtual bases. */
if (extra_warnings)
- for (vbase = CLASSTYPE_VBASECLASSES (t);
- vbase;
- vbase = TREE_CHAIN (vbase))
+ for (vbases = CLASSTYPE_VBASECLASSES (t);
+ vbases;
+ vbases = TREE_CHAIN (vbases))
{
- tree basetype = BINFO_TYPE (vbase);
+ tree basetype = BINFO_TYPE (vbases);
if (get_base_distance (basetype, t, 0, (tree*)0) == -2)
cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity",
basetype, t);
@@ -4991,11 +4400,11 @@ end_of_class (t, include_virtuals_p)
pointer. */
static void
-layout_class_type (t, empty_p, has_virtual_p,
+layout_class_type (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p)
tree t;
int *empty_p;
- int *has_virtual_p;
+ int *vfuns_p;
tree *new_virtuals_p;
tree *overridden_virtuals_p;
{
@@ -5009,15 +4418,15 @@ layout_class_type (t, empty_p, has_virtual_p,
/* Keep track of the first non-static data member. */
non_static_data_members = TYPE_FIELDS (t);
- /* Initialize the layout information. */
- rli = new_record_layout_info (t);
+ /* Start laying out the record. */
+ rli = start_record_layout (t);
/* If possible, we reuse the virtual function table pointer from one
of our base classes. */
- determine_primary_base (t, has_virtual_p);
+ determine_primary_base (t, vfuns_p);
/* Create a pointer to our virtual function table. */
- vptr = create_vtable_ptr (t, empty_p, has_virtual_p,
+ vptr = create_vtable_ptr (t, empty_p, vfuns_p,
new_virtuals_p, overridden_virtuals_p);
/* Under the new ABI, the vptr is always the first thing in the
@@ -5025,7 +4434,7 @@ layout_class_type (t, empty_p, has_virtual_p,
if (flag_new_abi && vptr)
{
TYPE_FIELDS (t) = chainon (vptr, TYPE_FIELDS (t));
- layout_field (rli, vptr);
+ place_field (rli, vptr);
}
/* Add pointers to all of our virtual base-classes. */
@@ -5040,9 +4449,7 @@ layout_class_type (t, empty_p, has_virtual_p,
fixup_inline_methods (t);
/* Layout the non-static data members. */
- for (field = non_static_data_members;
- field;
- field = TREE_CHAIN (field))
+ for (field = non_static_data_members; field; field = TREE_CHAIN (field))
{
tree binfo;
tree type;
@@ -5052,7 +4459,7 @@ layout_class_type (t, empty_p, has_virtual_p,
the back-end, in case it wants to do something with them. */
if (TREE_CODE (field) != FIELD_DECL)
{
- layout_field (rli, field);
+ place_field (rli, field);
continue;
}
@@ -5067,9 +4474,9 @@ layout_class_type (t, empty_p, has_virtual_p,
&& ((flag_new_abi
&& INT_CST_LT (TYPE_SIZE (type), DECL_SIZE (field)))
|| (!flag_new_abi
- && compare_tree_int (DECL_SIZE (field),
- TYPE_PRECISION
- (long_long_unsigned_type_node)) > 0)))
+ && 0 < compare_tree_int (DECL_SIZE (field),
+ TYPE_PRECISION
+ (long_long_unsigned_type_node)))))
{
integer_type_kind itk;
tree integer_type;
@@ -5087,8 +4494,8 @@ layout_class_type (t, empty_p, has_virtual_p,
field. We have to back up by one to find the largest
type that fits. */
integer_type = integer_types[itk - 1];
- padding = size_diffop (DECL_SIZE (field),
- TYPE_SIZE (integer_type));
+ padding = size_binop (MINUS_EXPR, DECL_SIZE (field),
+ TYPE_SIZE (integer_type));
DECL_SIZE (field) = TYPE_SIZE (integer_type);
DECL_ALIGN (field) = TYPE_ALIGN (integer_type);
}
@@ -5122,13 +4529,15 @@ layout_class_type (t, empty_p, has_virtual_p,
offset. However, now we need to make sure that RLI is big enough
to reflect the entire class. */
eoc = end_of_class (t, /*include_virtuals_p=*/0);
- if (eoc * BITS_PER_UNIT > rli->const_size)
+ if (TREE_CODE (rli_size_unit_so_far (rli)) == INTEGER_CST
+ && compare_tree_int (rli_size_unit_so_far (rli), eoc) < 0)
{
/* We don't handle zero-sized base classes specially under the
old ABI, so if we get here, we had better be operating under
the new ABI rules. */
my_friendly_assert (flag_new_abi, 20000321);
- rli->const_size = (eoc + 1) * BITS_PER_UNIT;
+ rli->offset = size_binop (MAX_EXPR, rli->offset, size_int (eoc + 1));
+ rli->bitpos = bitsize_zero_node;
}
/* We make all structures have at least one element, so that they
@@ -5141,7 +4550,7 @@ layout_class_type (t, empty_p, has_virtual_p,
tree padding;
padding = build_lang_decl (FIELD_DECL, NULL_TREE, char_type_node);
- layout_field (rli, padding);
+ place_field (rli, padding);
TYPE_NONCOPIED_PARTS (t)
= tree_cons (NULL_TREE, padding, TYPE_NONCOPIED_PARTS (t));
TREE_STATIC (TYPE_NONCOPIED_PARTS (t)) = 1;
@@ -5151,7 +4560,7 @@ layout_class_type (t, empty_p, has_virtual_p,
class. */
if (!flag_new_abi && vptr)
{
- layout_field (rli, vptr);
+ place_field (rli, vptr);
TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), vptr);
}
@@ -5170,7 +4579,7 @@ layout_class_type (t, empty_p, has_virtual_p,
the virtual bases. */
if (*empty_p && flag_new_abi)
{
- CLASSTYPE_SIZE (t) = bitsize_int (0);
+ CLASSTYPE_SIZE (t) = bitsize_zero_node;
CLASSTYPE_SIZE_UNIT (t) = size_zero_node;
}
else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t)
@@ -5201,7 +4610,7 @@ layout_class_type (t, empty_p, has_virtual_p,
/* Clean up. */
VARRAY_FREE (v);
}
-
+
/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration
(or C++ class declaration).
@@ -5234,7 +4643,7 @@ finish_struct_1 (t)
tree t;
{
tree x;
- int has_virtual;
+ int vfuns;
/* The NEW_VIRTUALS is a TREE_LIST. The TREE_VALUE of each node is
a FUNCTION_DECL. Each of these functions is a virtual function
declared in T that does not override any virtual function from a
@@ -5265,7 +4674,7 @@ finish_struct_1 (t)
TYPE_SIZE (t) = NULL_TREE;
CLASSTYPE_GOT_SEMICOLON (t) = 0;
CLASSTYPE_VFIELD_PARENT (t) = -1;
- has_virtual = 0;
+ vfuns = 0;
CLASSTYPE_RTTI (t) = NULL_TREE;
/* Do end-of-class semantic processing: checking the validity of the
@@ -5273,7 +4682,7 @@ finish_struct_1 (t)
check_bases_and_members (t, &empty);
/* Layout the class itself. */
- layout_class_type (t, &empty, &has_virtual,
+ layout_class_type (t, &empty, &vfuns,
&new_virtuals, &overridden_virtuals);
/* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we
@@ -5284,22 +4693,20 @@ finish_struct_1 (t)
&& DECL_FIELD_CONTEXT (vfield) != t)
{
tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0);
- tree offset = convert (bitsizetype, BINFO_OFFSET (binfo));
vfield = copy_node (vfield);
copy_lang_decl (vfield);
- if (! integer_zerop (offset))
- offset = size_binop (MULT_EXPR, offset, bitsize_int (BITS_PER_UNIT));
-
DECL_FIELD_CONTEXT (vfield) = t;
- DECL_FIELD_BITPOS (vfield)
- = size_binop (PLUS_EXPR, offset, bit_position (vfield));
+ DECL_FIELD_OFFSET (vfield)
+ = size_binop (PLUS_EXPR,
+ BINFO_OFFSET (binfo),
+ DECL_FIELD_OFFSET (vfield));
TYPE_VFIELD (t) = vfield;
}
overridden_virtuals
- = modify_all_vtables (t, &has_virtual, nreverse (overridden_virtuals));
+ = modify_all_vtables (t, &vfuns, nreverse (overridden_virtuals));
/* If necessary, create the primary vtable for this class. */
if (new_virtuals
@@ -5309,22 +4716,7 @@ finish_struct_1 (t)
new_virtuals = nreverse (new_virtuals);
/* We must enter these virtuals into the table. */
if (!CLASSTYPE_HAS_PRIMARY_BASE_P (t))
- {
- if (! CLASSTYPE_COM_INTERFACE (t))
- {
- /* The second slot is for the tdesc pointer when thunks
- are used. */
- if (flag_vtable_thunks)
- new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
-
- /* The first slot is for the rtti offset. */
- new_virtuals = tree_cons (NULL_TREE, NULL_TREE, new_virtuals);
-
- set_rtti_entry (new_virtuals,
- convert (ssizetype, integer_zero_node), t);
- }
- build_primary_vtable (NULL_TREE, t);
- }
+ build_primary_vtable (NULL_TREE, t);
else if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t), t))
/* Here we know enough to change the type of our virtual
function table, but we will wait until later this function. */
@@ -5367,7 +4759,7 @@ finish_struct_1 (t)
my_friendly_assert (TYPE_BINFO_VIRTUALS (t) == NULL_TREE,
20000116);
- CLASSTYPE_VSIZE (t) = has_virtual;
+ CLASSTYPE_VSIZE (t) = vfuns;
/* Entries for virtual functions defined in the primary base are
followed by entries for new functions unique to this class. */
TYPE_BINFO_VIRTUALS (t)
@@ -5380,7 +4772,7 @@ finish_struct_1 (t)
/* If we created a new vtbl pointer for this class, add it to the
list. */
- if (TYPE_VFIELD (t) && CLASSTYPE_VFIELD_PARENT (t) == -1)
+ if (TYPE_VFIELD (t) && !CLASSTYPE_HAS_PRIMARY_BASE_P (t))
CLASSTYPE_VFIELDS (t)
= chainon (CLASSTYPE_VFIELDS (t), build_tree_list (NULL_TREE, t));
@@ -5437,7 +4829,7 @@ finish_struct_1 (t)
the base types we marked. */
finish_vtbls (t);
- if (CLASSTYPE_VSIZE (t) != 0)
+ if (TYPE_VFIELD (t))
{
/* 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
@@ -5511,7 +4903,7 @@ finish_struct (t, attributes)
if (processing_template_decl)
{
finish_struct_methods (t);
- TYPE_SIZE (t) = integer_zero_node;
+ TYPE_SIZE (t) = bitsize_zero_node;
}
else
finish_struct_1 (t);
@@ -5676,13 +5068,13 @@ init_class_processing ()
* sizeof (struct class_stack_node));
access_default_node = build_int_2 (0, 0);
- access_public_node = build_int_2 (1, 0);
- access_protected_node = build_int_2 (2, 0);
- access_private_node = build_int_2 (3, 0);
+ access_public_node = build_int_2 (ak_public, 0);
+ access_protected_node = build_int_2 (ak_protected, 0);
+ access_private_node = build_int_2 (ak_private, 0);
access_default_virtual_node = build_int_2 (4, 0);
- access_public_virtual_node = build_int_2 (5, 0);
- access_protected_virtual_node = build_int_2 (6, 0);
- access_private_virtual_node = build_int_2 (7, 0);
+ access_public_virtual_node = build_int_2 (4 | ak_public, 0);
+ access_protected_virtual_node = build_int_2 (4 | ak_protected, 0);
+ access_private_virtual_node = build_int_2 (4 | ak_private, 0);
}
/* Set current scope to NAME. CODE tells us if this is a
@@ -6693,12 +6085,36 @@ note_name_declared_in_class (name, decl)
}
}
-/* Dump the offsets of all the bases rooted at BINFO to stderr.
- INDENT should be zero when called from the top level; it is
- incremented recursively. */
+/* Returns the VAR_DECL for the complete vtable associated with
+ BINFO. (Under the new ABI, secondary vtables are merged with
+ primary vtables; this function will return the VAR_DECL for the
+ primary vtable.) */
-void
-dump_class_hierarchy (binfo, indent)
+tree
+get_vtbl_decl_for_binfo (binfo)
+ tree binfo;
+{
+ tree decl;
+
+ decl = BINFO_VTABLE (binfo);
+ if (decl && TREE_CODE (decl) == PLUS_EXPR)
+ {
+ my_friendly_assert (TREE_CODE (TREE_OPERAND (decl, 0)) == ADDR_EXPR,
+ 2000403);
+ decl = TREE_OPERAND (TREE_OPERAND (decl, 0), 0);
+ }
+ if (decl)
+ my_friendly_assert (TREE_CODE (decl) == VAR_DECL, 20000403);
+ return decl;
+}
+
+/* Dump the offsets of all the bases rooted at BINFO (in the hierarchy
+ dominated by T) to stderr. INDENT should be zero when called from
+ the top level; it is incremented recursively. */
+
+static void
+dump_class_hierarchy_r (t, binfo, indent)
+ tree t;
tree binfo;
int indent;
{
@@ -6709,9 +6125,661 @@ dump_class_hierarchy (binfo, indent)
type_as_string (binfo, TS_PLAIN));
fprintf (stderr, HOST_WIDE_INT_PRINT_DEC,
tree_low_cst (BINFO_OFFSET (binfo), 0));
- fprintf (stderr, " %s\n",
- BINFO_PRIMARY_MARKED_P (binfo) ? "primary" : "");
+ if (TREE_VIA_VIRTUAL (binfo))
+ fprintf (stderr, " virtual");
+ if (BINFO_PRIMARY_MARKED_P (binfo)
+ || (TREE_VIA_VIRTUAL (binfo)
+ && BINFO_VBASE_PRIMARY_P (BINFO_FOR_VBASE (BINFO_TYPE (binfo),
+ t))))
+ fprintf (stderr, " primary");
+ fprintf (stderr, "\n");
for (i = 0; i < BINFO_N_BASETYPES (binfo); ++i)
- dump_class_hierarchy (BINFO_BASETYPE (binfo, i), indent + 2);
+ dump_class_hierarchy_r (t, BINFO_BASETYPE (binfo, i), indent + 2);
+}
+
+/* Dump the BINFO hierarchy for T. */
+
+void
+dump_class_hierarchy (t)
+ tree t;
+{
+ tree vbase;
+
+ dump_class_hierarchy_r (t, TYPE_BINFO (t), 0);
+ fprintf (stderr, "virtual bases\n");
+ for (vbase = CLASSTYPE_VBASECLASSES (t); vbase; vbase = TREE_CHAIN (vbase))
+ dump_class_hierarchy_r (t, vbase, 0);
+}
+
+/* Virtual function table initialization. */
+
+/* Create all the necessary vtables for T and its base classes. */
+
+static void
+finish_vtbls (t)
+ tree t;
+{
+ if (merge_primary_and_secondary_vtables_p ())
+ {
+ tree list;
+ tree vbase;
+
+ /* Under the new ABI, we lay out the primary and secondary
+ vtables in one contiguous vtable. The primary vtable is
+ first, followed by the non-virtual secondary vtables in
+ inheritance graph order. */
+ list = build_tree_list (TYPE_BINFO_VTABLE (t), NULL_TREE);
+ TREE_TYPE (list) = t;
+ accumulate_vtbl_inits (TYPE_BINFO (t), list);
+ /* Then come the virtual bases, also in inheritance graph
+ order. */
+ for (vbase = TYPE_BINFO (t); vbase; vbase = TREE_CHAIN (vbase))
+ {
+ if (!TREE_VIA_VIRTUAL (vbase))
+ continue;
+ accumulate_vtbl_inits (BINFO_FOR_VBASE (BINFO_TYPE (vbase), t),
+ list);
+ }
+
+ if (TYPE_BINFO_VTABLE (t))
+ initialize_vtable (TYPE_BINFO (t), TREE_VALUE (list));
+ }
+ else
+ {
+ dfs_walk (TYPE_BINFO (t), dfs_finish_vtbls,
+ dfs_unmarked_real_bases_queue_p, t);
+ dfs_walk (TYPE_BINFO (t), dfs_unmark,
+ dfs_marked_real_bases_queue_p, t);
+ }
+}
+
+/* Called from finish_vtbls via dfs_walk. */
+
+static tree
+dfs_finish_vtbls (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree t = (tree) data;
+
+ if (!BINFO_PRIMARY_MARKED_P (binfo)
+ && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
+ && BINFO_NEW_VTABLE_MARKED (binfo, t))
+ initialize_vtable (binfo,
+ build_vtbl_initializer (binfo, t, NULL));
+
+ CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
+ SET_BINFO_MARKED (binfo);
+
+ return NULL_TREE;
+}
+
+/* Initialize the vtable for BINFO with the INITS. */
+
+static void
+initialize_vtable (binfo, inits)
+ tree binfo;
+ tree inits;
+{
+ tree context;
+ tree decl;
+
+ layout_vtable_decl (binfo, list_length (inits));
+ decl = get_vtbl_decl_for_binfo (binfo);
+ context = DECL_CONTEXT (decl);
+ DECL_CONTEXT (decl) = 0;
+ DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, inits);
+ cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0);
+ DECL_CONTEXT (decl) = context;
+}
+
+/* Add the vtbl initializers for BINFO (and its non-primary,
+ non-virtual bases) to the list of INITS. */
+
+static void
+accumulate_vtbl_inits (binfo, inits)
+ tree binfo;
+ tree inits;
+{
+ /* Walk the BINFO and its bases. We walk in preorder so that as we
+ initialize each vtable we can figure out at what offset the
+ secondary vtable lies from the primary vtable. */
+ dfs_walk_real (binfo,
+ dfs_accumulate_vtbl_inits,
+ NULL,
+ dfs_skip_vbases,
+ inits);
+}
+
+/* Called from finish_vtbls via dfs_walk when using the new ABI.
+ Accumulates the vtable initializers for all of the vtables into
+ TREE_VALUE (DATA). */
+
+static tree
+dfs_accumulate_vtbl_inits (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree l;
+ tree t;
+
+ l = (tree) data;
+ t = TREE_TYPE (l);
+
+ if (!BINFO_PRIMARY_MARKED_P (binfo)
+ && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))
+ && BINFO_NEW_VTABLE_MARKED (binfo, t))
+ {
+ tree inits;
+ tree vtbl;
+ tree index;
+ int non_fn_entries;
+
+ /* Compute the initializer for this vtable. */
+ inits = build_vtbl_initializer (binfo, t, &non_fn_entries);
+
+ /* Set BINFO_VTABLE to the address where the VPTR should point. */
+ vtbl = TREE_PURPOSE (l);
+ vtbl = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (vtbl)),
+ vtbl);
+ index = size_binop (PLUS_EXPR,
+ size_int (non_fn_entries),
+ size_int (list_length (TREE_VALUE (l))));
+ BINFO_VTABLE (binfo)
+ = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
+ size_binop (MULT_EXPR,
+ TYPE_SIZE_UNIT (TREE_TYPE (vtbl)),
+ index));
+
+ /* Add the initializers for this vtable to the initializers for
+ the other vtables we've already got. */
+ TREE_VALUE (l) = chainon (TREE_VALUE (l), inits);
+ }
+
+ CLEAR_BINFO_NEW_VTABLE_MARKED (binfo, t);
+
+ return NULL_TREE;
+}
+
+/* Construct the initializer for BINFOs virtual function table. BINFO
+ is part of the hierarchy dominated by T. The value returned is a
+ TREE_LIST suitable for wrapping in a CONSTRUCTOR to use as the
+ DECL_INITIAL for a vtable. If NON_FN_ENTRIES_P is not NULL,
+ *NON_FN_ENTRIES_P is set to the number of non-function entries in
+ the vtable. */
+
+static tree
+build_vtbl_initializer (binfo, t, non_fn_entries_p)
+ tree binfo;
+ tree t;
+ int *non_fn_entries_p;
+{
+ tree v = BINFO_VIRTUALS (binfo);
+ tree inits = NULL_TREE;
+ tree vfun_inits;
+ tree vbase;
+ vcall_offset_data vod;
+
+ /* Initialize those parts of VOD that matter. */
+ vod.derived = t;
+ vod.inits = NULL_TREE;
+ vod.primary_p = (binfo == TYPE_BINFO (t));
+ /* The first vbase or vcall offset is at index -3 in the vtable. */
+ vod.index = build_int_2 (-3, -1);
+
+ /* Add the vcall and vbase offset entries. */
+ build_vcall_and_vbase_vtbl_entries (binfo, &vod);
+ inits = vod.inits;
+ /* Clear BINFO_VTABLE_PAATH_MARKED; it's set by
+ build_vbase_offset_vtbl_entries. */
+ for (vbase = CLASSTYPE_VBASECLASSES (t);
+ vbase;
+ vbase = TREE_CHAIN (vbase))
+ CLEAR_BINFO_VTABLE_PATH_MARKED (vbase);
+
+ /* Add entries to the vtable for RTTI. */
+ inits = chainon (inits, build_rtti_vtbl_entries (binfo, t));
+
+ if (non_fn_entries_p)
+ *non_fn_entries_p = list_length (inits);
+
+ /* Go through all the ordinary virtual functions, building up
+ initializers. */
+ vfun_inits = NULL_TREE;
+ while (v)
+ {
+ tree delta;
+ tree vcall_index;
+ tree fn;
+ tree pfn;
+ tree init;
+
+ /* Pull the offset for `this', and the function to call, out of
+ the list. */
+ delta = BV_DELTA (v);
+ vcall_index = BV_VCALL_INDEX (v);
+ fn = BV_FN (v);
+ my_friendly_assert (TREE_CODE (delta) == INTEGER_CST, 19990727);
+ my_friendly_assert (TREE_CODE (fn) == FUNCTION_DECL, 19990727);
+
+ /* You can't call an abstract virtual function; it's abstract.
+ So, we replace these functions with __pure_virtual. */
+ if (DECL_PURE_VIRTUAL_P (fn))
+ fn = abort_fndecl;
+
+ /* Take the address of the function, considering it to be of an
+ appropriate generic type. */
+ pfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fn);
+ /* The address of a function can't change. */
+ TREE_CONSTANT (pfn) = 1;
+ /* Enter it in the vtable. */
+ init = build_vtable_entry (delta, vcall_index, pfn);
+ /* And add it to the chain of initializers. */
+ vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
+
+ /* Keep going. */
+ v = TREE_CHAIN (v);
+ }
+
+ /* The initializers for virtual functions were built up in reverse
+ order; straighten them out now. */
+ vfun_inits = nreverse (vfun_inits);
+
+ /* The complete initializer is the INITS, followed by the
+ VFUN_INITS. */
+ return chainon (inits, vfun_inits);
+}
+
+/* Sets vod->inits to be the initializers for the vbase and vcall
+ offsets in BINFO, which is in the hierarchy dominated by T. */
+
+static void
+build_vcall_and_vbase_vtbl_entries (binfo, vod)
+ tree binfo;
+ vcall_offset_data *vod;
+{
+ tree b;
+ tree inits;
+
+ /* If this is a derived class, we must first create entries
+ corresponding to the base class. These entries must go closer to
+ the vptr, so we save them up and add them to the end of the list
+ later. */
+ inits = vod->inits;
+ vod->inits = NULL_TREE;
+ b = BINFO_PRIMARY_BINFO (binfo);
+ if (b)
+ build_vcall_and_vbase_vtbl_entries (b, vod);
+
+ /* Add the vbase entries for this base. */
+ build_vbase_offset_vtbl_entries (binfo, vod);
+ /* Add the vcall entries for this base. */
+ build_vcall_offset_vtbl_entries (binfo, vod);
+
+ vod->inits = chainon (vod->inits, inits);
+}
+
+/* Returns the initializers for the vbase offset entries in the vtable
+ for BINFO (which is part of the class hierarchy dominated by T), in
+ reverse order. VBASE_OFFSET_INDEX gives the vtable index
+ where the next vbase offset will go. */
+
+static void
+build_vbase_offset_vtbl_entries (binfo, vod)
+ tree binfo;
+ vcall_offset_data *vod;
+{
+ tree vbase;
+ tree t;
+
+ /* Under the old ABI, pointers to virtual bases are stored in each
+ object. */
+ if (!vbase_offsets_in_vtable_p ())
+ return;
+
+ /* If there are no virtual baseclasses, then there is nothing to
+ do. */
+ if (!TYPE_USES_VIRTUAL_BASECLASSES (BINFO_TYPE (binfo)))
+ return;
+
+ t = vod->derived;
+
+ /* Go through the virtual bases, adding the offsets. */
+ for (vbase = TYPE_BINFO (BINFO_TYPE (binfo));
+ vbase;
+ vbase = TREE_CHAIN (vbase))
+ {
+ tree b;
+ tree delta;
+
+ if (!TREE_VIA_VIRTUAL (vbase))
+ continue;
+
+ /* Find the instance of this virtual base in the complete
+ object. */
+ b = BINFO_FOR_VBASE (BINFO_TYPE (vbase), t);
+
+ /* If we've already got an offset for this virtual base, we
+ don't need another one. */
+ if (BINFO_VTABLE_PATH_MARKED (b))
+ continue;
+ SET_BINFO_VTABLE_PATH_MARKED (b);
+
+ /* Figure out where we can find this vbase offset. */
+ delta = size_binop (MULT_EXPR,
+ convert (ssizetype, vod->index),
+ convert (ssizetype,
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+ if (vod->primary_p)
+ BINFO_VPTR_FIELD (b) = delta;
+
+ if (binfo != TYPE_BINFO (t))
+ {
+ tree orig_vbase;
+
+ /* Find the instance of this virtual base in the type of BINFO. */
+ orig_vbase = BINFO_FOR_VBASE (BINFO_TYPE (vbase),
+ BINFO_TYPE (binfo));
+
+ /* The vbase offset had better be the same. */
+ if (!tree_int_cst_equal (delta,
+ BINFO_VPTR_FIELD (orig_vbase)))
+ my_friendly_abort (20000403);
+ }
+
+ /* The next vbase will come at a more negative offset. */
+ vod->index = fold (build (MINUS_EXPR, integer_type_node,
+ vod->index, integer_one_node));
+
+ /* The initializer is the delta from BINFO to this virtual base.
+ The vbase offsets go in reverse inheritance-graph order, and
+ we are walking in inheritance graph order so these end up in
+ the right order. */
+ delta = size_diffop (BINFO_OFFSET (b), BINFO_OFFSET (binfo));
+ vod->inits = tree_cons (NULL_TREE,
+ fold (build1 (NOP_EXPR,
+ vtable_entry_type,
+ delta)),
+ vod->inits);
+ }
+}
+
+/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
+
+static tree
+dfs_vcall_offset_queue_p (binfo, data)
+ tree binfo;
+ void *data;
+{
+ vcall_offset_data* vod = (vcall_offset_data *) data;
+
+ return (binfo == vod->vbase) ? binfo : dfs_skip_vbases (binfo, NULL);
+}
+
+/* Called from build_vcall_offset_vtbl_entries via dfs_walk. */
+
+static tree
+dfs_build_vcall_offset_vtbl_entries (binfo, data)
+ tree binfo;
+ void *data;
+{
+ vcall_offset_data* vod;
+ tree virtuals;
+ tree binfo_inits;
+ tree b;
+ int i;
+
+ vod = (vcall_offset_data *) data;
+ binfo_inits = NULL_TREE;
+
+ /* Skip virtuals that we have already handled in a primary base
+ class. */
+ virtuals = BINFO_VIRTUALS (binfo);
+ b = BINFO_PRIMARY_BINFO (binfo);
+ if (b)
+ for (i = 0; i < CLASSTYPE_VSIZE (BINFO_TYPE (b)); ++i)
+ virtuals = TREE_CHAIN (virtuals);
+
+ /* Make entries for the rest of the virtuals. */
+ while (virtuals)
+ {
+ /* Figure out what function we're looking at. */
+ tree fn = TREE_VALUE (virtuals);
+ tree base = DECL_CONTEXT (fn);
+ /* The FN comes from BASE. So, we must caculate the adjustment
+ from the virtual base that derived from BINFO to BASE. */
+ tree base_binfo = get_binfo (base, vod->derived, /*protect=*/0);
+
+ binfo_inits
+ = tree_cons (NULL_TREE,
+ fold (build1 (NOP_EXPR, vtable_entry_type,
+ size_diffop (BINFO_OFFSET (base_binfo),
+ BINFO_OFFSET (vod->vbase)))),
+ binfo_inits);
+ vod->index = fold (build (MINUS_EXPR, integer_type_node,
+ vod->index, integer_one_node));
+ virtuals = TREE_CHAIN (virtuals);
+ }
+
+ /* The offests are built up in reverse order, so we straighten them
+ here. We simultaneously add them to VOD->INITS; we're walking
+ the bases in inheritance graph order, and the initializers are
+ supposed to appear in reverse inheritance order, so that's
+ correct. */
+ while (binfo_inits)
+ {
+ tree next;
+
+ next = TREE_CHAIN (binfo_inits);
+ TREE_CHAIN (binfo_inits) = vod->inits;
+ vod->inits = binfo_inits;
+ binfo_inits = next;
+ }
+
+ return NULL_TREE;
+}
+
+/* Adds the initializers for the vcall offset entries in the vtable
+ for BINFO (which is part of the class hierarchy dominated by T) to
+ VOD->INITS. */
+
+static void
+build_vcall_offset_vtbl_entries (binfo, vod)
+ tree binfo;
+ vcall_offset_data *vod;
+{
+ tree inits;
+
+ /* Under the old ABI, the adjustments to the `this' pointer were made
+ elsewhere. */
+ if (!vcall_offsets_in_vtable_p ())
+ return;
+
+ /* We only need these entries if this base is a virtual base. */
+ if (!TREE_VIA_VIRTUAL (binfo))
+ return;
+
+ /* We need a vcall offset for each of the virtual functions in this
+ vtable. For example:
+
+ class A { virtual void f (); };
+ class B : virtual public A { };
+ class C: virtual public A, public B {};
+
+ Now imagine:
+
+ B* b = new C;
+ b->f();
+
+ The location of `A' is not at a fixed offset relative to `B'; the
+ offset depends on the complete object derived from `B'. So,
+ `B' vtable contains an entry for `f' that indicates by what
+ amount the `this' pointer for `B' needs to be adjusted to arrive
+ at `A'.
+
+ We need entries for all the functions in our primary vtable and
+ in our non-virtual bases vtables. For each base, the entries
+ appear in the same order as in the base; but the bases themselves
+ appear in reverse depth-first, left-to-right order. */
+ vod->vbase = binfo;
+ inits = vod->inits;
+ vod->inits = NULL_TREE;
+ dfs_walk_real (binfo,
+ dfs_build_vcall_offset_vtbl_entries,
+ NULL,
+ dfs_vcall_offset_queue_p,
+ vod);
+ vod->inits = chainon (vod->inits, inits);
+}
+
+/* Return vtbl initializers for the RTTI entries coresponding to the
+ BINFO's vtable. BINFO is a part of the hierarchy dominated by
+ T. */
+
+static tree
+build_rtti_vtbl_entries (binfo, t)
+ tree binfo;
+ tree t;
+{
+ tree b;
+ tree basetype;
+ tree offset;
+ tree decl;
+ tree init;
+ tree inits;
+
+ basetype = BINFO_TYPE (binfo);
+ inits = NULL_TREE;
+
+ /* For a COM object there is no RTTI entry. */
+ if (CLASSTYPE_COM_INTERFACE (basetype))
+ return inits;
+
+ /* To find the complete object, we will first convert to our most
+ primary base, and then add the offset in the vtbl to that value. */
+ b = binfo;
+ while (CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (b)))
+ {
+ tree primary_base;
+
+ primary_base = BINFO_PRIMARY_BINFO (b);
+ if (!BINFO_PRIMARY_MARKED_P (primary_base))
+ break;
+ b = primary_base;
+ }
+ offset = size_diffop (size_zero_node, BINFO_OFFSET (b));
+
+ /* The second entry is, in the case of the new ABI, the address of
+ the typeinfo object, or, in the case of the old ABI, a function
+ which returns a typeinfo object. */
+ if (new_abi_rtti_p ())
+ {
+ if (flag_rtti)
+ decl = build_unary_op (ADDR_EXPR, get_tinfo_decl (t), 0);
+ else
+ decl = integer_zero_node;
+
+ /* Convert the declaration to a type that can be stored in the
+ vtable. */
+ init = build1 (NOP_EXPR, vfunc_ptr_type_node, decl);
+ TREE_CONSTANT (init) = 1;
+ }
+ else
+ {
+ if (flag_rtti)
+ decl = get_tinfo_decl (t);
+ else
+ decl = abort_fndecl;
+
+ /* Convert the declaration to a type that can be stored in the
+ vtable. */
+ init = build1 (ADDR_EXPR, vfunc_ptr_type_node, decl);
+ TREE_CONSTANT (init) = 1;
+ init = build_vtable_entry (offset, integer_zero_node, init);
+ }
+ inits = tree_cons (NULL_TREE, init, inits);
+
+ /* Add the offset-to-top entry. It comes earlier in the vtable that
+ the the typeinfo entry. */
+ if (flag_vtable_thunks)
+ {
+ /* Convert the offset to look like a function pointer, so that
+ we can put it in the vtable. */
+ init = build1 (NOP_EXPR, vfunc_ptr_type_node, offset);
+ TREE_CONSTANT (init) = 1;
+ inits = tree_cons (NULL_TREE, init, inits);
+ }
+
+ return inits;
+}
+
+/* Build an entry in the virtual function table. DELTA is the offset
+ for the `this' pointer. VCALL_INDEX is the vtable index containing
+ the vcall offset; zero if none. ENTRY is the virtual function
+ table entry itself. It's TREE_TYPE must be VFUNC_PTR_TYPE_NODE,
+ but it may not actually be a virtual function table pointer. (For
+ example, it might be the address of the RTTI object, under the new
+ ABI.) */
+
+static tree
+build_vtable_entry (delta, vcall_index, entry)
+ tree delta;
+ tree vcall_index;
+ tree entry;
+{
+ if (flag_vtable_thunks)
+ {
+ HOST_WIDE_INT idelta;
+ HOST_WIDE_INT ivindex;
+
+ idelta = tree_low_cst (delta, 0);
+ ivindex = tree_low_cst (vcall_index, 0);
+ if ((idelta || ivindex)
+ && ! DECL_PURE_VIRTUAL_P (TREE_OPERAND (entry, 0)))
+ {
+ entry = make_thunk (entry, idelta, ivindex);
+ entry = build1 (ADDR_EXPR, vtable_entry_type, entry);
+ TREE_READONLY (entry) = 1;
+ TREE_CONSTANT (entry) = 1;
+ }
+#ifdef GATHER_STATISTICS
+ n_vtable_entries += 1;
+#endif
+ return entry;
+ }
+ else
+ {
+ extern int flag_huge_objects;
+ tree elems = tree_cons (NULL_TREE, delta,
+ tree_cons (NULL_TREE, integer_zero_node,
+ build_tree_list (NULL_TREE, entry)));
+ tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems);
+
+ /* We don't use vcall offsets when not using vtable thunks. */
+ my_friendly_assert (integer_zerop (vcall_index), 20000125);
+
+ /* DELTA used to be constructed by `size_int' and/or size_binop,
+ which caused overflow problems when it was negative. That should
+ be fixed now. */
+
+ if (! int_fits_type_p (delta, delta_type_node))
+ {
+ if (flag_huge_objects)
+ sorry ("object size exceeds built-in limit for virtual function table implementation");
+ else
+ sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects");
+ }
+
+ TREE_CONSTANT (entry) = 1;
+ TREE_STATIC (entry) = 1;
+ TREE_READONLY (entry) = 1;
+
+#ifdef GATHER_STATISTICS
+ n_vtable_entries += 1;
+#endif
+
+ return entry;
+ }
}
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9ccd28a529b..64bc894b74d 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -55,8 +55,6 @@ Boston, MA 02111-1307, USA. */
ICS_ELLIPSIS_FLAG (in _CONV)
STMT_IS_FULL_EXPR_P (in _STMT)
2: IDENTIFIER_OPNAME_P.
- BINFO_VBASE_MARKED.
- BINFO_FIELDS_MARKED.
TYPE_POLYMORHPIC_P (in _TYPE)
ICS_THIS_FLAG (in _CONV)
STMT_LINENO_FOR_FN_P (in _STMT)
@@ -130,6 +128,13 @@ Boston, MA 02111-1307, USA. */
this function. (This binfo's BINFO_TYPE will always be the same
as the DECL_CLASS_CONTEXT for the function.)
+ BINFO_VTABLE
+ Sometimes this is a VAR_DECL. Under the new ABI, it is instead
+ an expression with POINTER_TYPE pointing that gives the value
+ to which the vptr should be initialized. Use get_vtbl_decl_for_binfo
+ to extract the VAR_DECL for the complete vtable; that macro works
+ in both ABIs.
+
DECL_ARGUMENTS
For a VAR_DECL this is DECL_ANON_UNION_ELEMS.
@@ -1356,24 +1361,17 @@ struct lang_type
int vsize;
int vfield_parent;
- union tree_node *vfields;
- union tree_node *vbases;
-
- union tree_node *tags;
-
- union tree_node *search_slot;
-
- union tree_node *size;
- union tree_node *size_unit;
-
- union tree_node *pure_virtuals;
- union tree_node *friend_classes;
-
- union tree_node *rtti;
-
- union tree_node *methods;
-
- union tree_node *template_info;
+ tree vfields;
+ tree vbases;
+ tree tags;
+ tree search_slot;
+ tree size;
+ tree size_unit;
+ tree pure_virtuals;
+ tree friend_classes;
+ tree rtti;
+ tree methods;
+ tree template_info;
tree befriending_classes;
};
@@ -1538,21 +1536,29 @@ struct lang_type
#define CLASSTYPE_PRIMARY_BINFO(NODE) \
(BINFO_PRIMARY_BINFO (TYPE_BINFO (NODE)))
-/* If non-NULL, this is the binfo for the primary base of BINFO. */
+/* If non-NULL, this is the binfo for the primary base of BINFO. Note
+ that in a complex hierarchy the resulting BINFO may not actually
+ *be* primary. In particular if the resulting BINFO is a virtual
+ base, and it occurs elsewhere in the hierarchy, then this
+ occurrence may not actually be a primary base in the complete
+ object. Check BINFO_PRIMARY_MARKED_P to be sure. */
#define BINFO_PRIMARY_BINFO(NODE) \
(CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (NODE)) \
? BINFO_BASETYPE (NODE, \
CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (NODE))) \
: NULL_TREE)
-/* The number of virtual functions defined for this
- _CLASSTYPE node. */
+/* The number of virtual functions present in this class' virtual
+ function table. */
#define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize)
/* A chain of BINFOs for the direct and indirect virtual base classes
- that this type uses in depth-first left-to-right order. These
- BINFOs are distinct from those in the TYPE_BINFO hierarchy. So,
- given:
+ that this type uses in a post-order depth-first left-to-right
+ order. (In other words, these bases appear in the order that they
+ should be initialized.)
+
+ These BINFOs are distinct from those in the TYPE_BINFO hierarchy.
+ So, given:
struct A {};
struct B : public A {};
@@ -1683,9 +1689,7 @@ struct lang_type
We use TREE_VIA_PROTECTED and TREE_VIA_PUBLIC, but private
inheritance is indicated by the absence of the other two flags, not
- by TREE_VIA_PRIVATE, which is unused.
-
- The TREE_CHAIN is for scratch space in search.c. */
+ by TREE_VIA_PRIVATE, which is unused. */
/* Nonzero means marked by DFS or BFS search, including searches
by `get_binfo' and `get_base_distance'. */
@@ -1695,18 +1699,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 search through virtual inheritance hierarchy. */
-#define BINFO_VBASE_MARKED(NODE) CLASSTYPE_MARKED2 (BINFO_TYPE (NODE))
-/* Modifier macros */
-#define SET_BINFO_VBASE_MARKED(NODE) SET_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE))
-#define CLEAR_BINFO_VBASE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE))
-
-/* Nonzero means marked in search for members or member functions. */
-#define BINFO_FIELDS_MARKED(NODE) \
- (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)):TREE_LANG_FLAG_2(NODE))
-#define SET_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=1))
-#define CLEAR_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=0))
-
/* Nonzero means that this class is on a path leading to a new vtable. */
#define BINFO_VTABLE_PATH_MARKED(NODE) \
(TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):TREE_LANG_FLAG_3(NODE))
@@ -1838,7 +1830,7 @@ struct lang_decl_flags
unsigned constructor_for_vbase_attr : 1;
unsigned mutable_flag : 1;
- unsigned saved_inline : 1;
+ unsigned deferred : 1;
unsigned use_template : 2;
unsigned nonconverting : 1;
unsigned declared_inline : 1;
@@ -2091,7 +2083,7 @@ struct lang_decl
/* In a VAR_DECL for a variable declared in a for statement,
this is the shadowed (local) variable. */
-#define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(VAR_DECL_CHECK (NODE))
+#define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT_FLD(VAR_DECL_CHECK (NODE))
/* Points back to the decl which caused this lang_decl to be allocated. */
#define DECL_MAIN_VARIANT(NODE) (DECL_LANG_SPECIFIC(NODE)->main_decl_variant)
@@ -2112,9 +2104,9 @@ struct lang_decl
#define DECL_SORTED_FIELDS(NODE) \
(DECL_LANG_SPECIFIC (TYPE_DECL_CHECK (NODE))->u.sorted_fields)
-/* True if on the saved_inlines (see decl2.c) list. */
-#define DECL_SAVED_INLINE(DECL) \
- (DECL_LANG_SPECIFIC(DECL)->decl_flags.saved_inline)
+/* True if on the deferred_fns (see decl2.c) list. */
+#define DECL_DEFERRED_FN(DECL) \
+ (DECL_LANG_SPECIFIC(DECL)->decl_flags.deferred)
/* For a VAR_DECL, FUNCTION_DECL, TYPE_DECL or TEMPLATE_DECL:
template-specific information. */
@@ -2709,7 +2701,7 @@ extern int flag_new_for_scope;
#define DECL_NTPARMS(NODE) \
TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE))
/* For function, method, class-data templates. */
-#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE)
+#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT_FLD(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
@@ -3081,6 +3073,17 @@ typedef enum tmpl_spec_kind {
tsk_expl_inst /* An explicit instantiation. */
} tmpl_spec_kind;
+/* The various kinds of access. BINFO_ACCESS depends on these being
+ two bit quantities. The numerical values are important; they are
+ used to initialize RTTI data structures, so chaning them changes
+ the ABI. */
+typedef enum access_kind {
+ ak_none = 0, /* Inaccessible. */
+ ak_public = 1, /* Accessible, as a `public' thing. */
+ ak_protected = 2, /* Accessible, as a `protected' thing. */
+ ak_private = 3 /* Accessible, as a `private' thing. */
+} access_kind;
+
/* Zero means prototype weakly, as in ANSI C (no args means nothing).
Each language context defines how this variable should be set. */
extern int strict_prototype;
@@ -3685,8 +3688,7 @@ extern void push_lang_context PARAMS ((tree));
extern void pop_lang_context PARAMS ((void));
extern tree instantiate_type PARAMS ((tree, tree, int));
extern void print_class_statistics PARAMS ((void));
-extern tree skip_rtti_stuff PARAMS ((tree, tree,
- HOST_WIDE_INT *));
+extern int first_vfun_index PARAMS ((tree));
extern void build_self_reference PARAMS ((void));
extern void warn_hidden PARAMS ((tree));
extern tree get_enclosing_class PARAMS ((tree));
@@ -3695,8 +3697,7 @@ extern void unreverse_member_declarations PARAMS ((tree));
extern void invalidate_class_lookup_cache PARAMS ((void));
extern void maybe_note_name_used_in_class PARAMS ((tree, tree));
extern void note_name_declared_in_class PARAMS ((tree, tree));
-extern tree num_extra_vtbl_entries PARAMS ((tree));
-extern tree size_extra_vtbl_entries PARAMS ((tree));
+extern tree get_vtbl_decl_for_binfo PARAMS ((tree));
/* in cvt.c */
extern tree convert_to_reference PARAMS ((tree, tree, int, int, tree));
@@ -3836,7 +3837,6 @@ extern tree maybe_build_cleanup_and_delete PARAMS ((tree));
extern tree maybe_build_cleanup PARAMS ((tree));
extern void cplus_expand_expr_stmt PARAMS ((tree));
extern void finish_stmt PARAMS ((void));
-extern int in_function_p PARAMS ((void));
extern void replace_defarg PARAMS ((tree, tree));
extern void print_other_binding_stack PARAMS ((struct binding_level *));
extern void revert_static_member_fn PARAMS ((tree));
@@ -3897,7 +3897,7 @@ extern void cplus_decl_attributes PARAMS ((tree, tree, tree));
extern tree constructor_name_full PARAMS ((tree));
extern tree constructor_name PARAMS ((tree));
extern void setup_vtbl_ptr PARAMS ((void));
-extern void mark_inline_for_output PARAMS ((tree));
+extern void defer_fn PARAMS ((tree));
extern tree get_temp_name PARAMS ((tree, int));
extern void finish_anon_union PARAMS ((tree));
extern tree finish_table PARAMS ((tree, tree, tree, int));
@@ -4122,7 +4122,7 @@ extern int more_specialized PARAMS ((tree, tree, tree));
extern void mark_class_instantiated PARAMS ((tree, int));
extern void do_decl_instantiation PARAMS ((tree, tree, tree));
extern void do_type_instantiation PARAMS ((tree, tree));
-extern tree instantiate_decl PARAMS ((tree));
+extern tree instantiate_decl PARAMS ((tree, int));
extern tree get_bindings PARAMS ((tree, tree, tree));
extern void add_tree PARAMS ((tree));
extern void add_maybe_template PARAMS ((tree, tree));
@@ -4204,7 +4204,6 @@ extern tree dfs_walk_real PARAMS ((tree,
tree (*) (tree, void *),
void *));
extern tree dfs_unmark PARAMS ((tree, void *));
-extern tree dfs_vbase_unmark PARAMS ((tree, void *));
extern tree dfs_vtable_path_unmark PARAMS ((tree, void *));
extern tree markedp PARAMS ((tree, void *));
extern tree unmarkedp PARAMS ((tree, void *));
@@ -4212,12 +4211,9 @@ extern tree dfs_skip_nonprimary_vbases_unmarkedp PARAMS ((tree, void *));
extern tree dfs_skip_nonprimary_vbases_markedp PARAMS ((tree, void *));
extern tree dfs_unmarked_real_bases_queue_p PARAMS ((tree, void *));
extern tree dfs_marked_real_bases_queue_p PARAMS ((tree, void *));
-extern tree dfs_vtable_path_unmarked_real_bases_queue_p
- PARAMS ((tree, void *));
-extern tree dfs_vtable_path_marked_real_bases_queue_p
- PARAMS ((tree, void *));
extern tree dfs_skip_vbases PARAMS ((tree, void *));
-extern void mark_primary_bases PARAMS ((tree));
+extern tree marked_vtable_pathp PARAMS ((tree, void *));
+extern tree unmarked_vtable_pathp PARAMS ((tree, void *));
extern tree convert_pointer_to_vbase PARAMS ((tree, tree));
extern tree find_vbase_instance PARAMS ((tree, tree));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ff2cf407dac..b2f753e0fe7 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4051,12 +4051,12 @@ pushdecl (x)
if (oldlocal)
{
tree d = oldlocal;
+
while (oldlocal
&& TREE_CODE (oldlocal) == VAR_DECL
&& DECL_DEAD_FOR_LOCAL (oldlocal))
- {
- oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
- }
+ oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
+
if (oldlocal == NULL_TREE)
oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
}
@@ -4452,8 +4452,8 @@ push_using_directive (used)
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.
+ DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its
+ DECL_TEMPLATE_RESULT. It is dealt with the same way.
FLAGS is a bitwise-or of the following values:
PUSH_LOCAL: Bind DECL in the current scope, rather than at
@@ -4938,7 +4938,7 @@ void
push_switch ()
{
struct cp_switch *p
- = (struct cp_switch *) oballoc (sizeof (struct cp_switch));
+ = (struct cp_switch *) xmalloc (sizeof (struct cp_switch));
p->level = current_binding_level;
p->next = switch_stack;
switch_stack = p;
@@ -4947,7 +4947,11 @@ push_switch ()
void
pop_switch ()
{
+ struct cp_switch *cs;
+
+ cs = switch_stack;
switch_stack = switch_stack->next;
+ free (cs);
}
/* Note that we've seen a definition of a case label, and complain if this
@@ -10647,9 +10651,21 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
t = ctype;
while (t != NULL_TREE && CLASS_TYPE_P (t))
{
- if (CLASSTYPE_TEMPLATE_INFO (t) &&
- !CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
+ /* You're supposed to have one `template <...>'
+ for every template class, but you don't need one
+ for a full specialization. For example:
+
+ template <class T> struct S{};
+ template <> struct S<int> { void f(); };
+ void S<int>::f () {}
+
+ is correct; there shouldn't be a `template <>' for
+ the definition of `S<int>::f'. */
+ if (CLASSTYPE_TEMPLATE_INFO (t)
+ && (CLASSTYPE_TEMPLATE_INSTANTIATION (t)
+ || uses_template_parms (CLASSTYPE_TI_ARGS (t))))
template_count += 1;
+
t = TYPE_MAIN_DECL (t);
if (DECL_LANG_SPECIFIC (t))
t = DECL_CONTEXT (t);
@@ -12424,7 +12440,7 @@ xref_tag (code_type_node, name, globalize)
&& template_class_depth (current_class_type) == 0)
/* Since GLOBALIZE is true, we're declaring a global
template, so we want this type. */
- ref = DECL_RESULT (ref);
+ ref = DECL_TEMPLATE_RESULT (ref);
if (ref && TREE_CODE (ref) == TYPE_DECL
&& TREE_CODE (TREE_TYPE (ref)) == code)
@@ -14137,7 +14153,7 @@ finish_function (lineno, flags)
if (! DECL_EXTERNAL (fndecl))
DECL_NOT_REALLY_EXTERN (fndecl) = 1;
DECL_EXTERNAL (fndecl) = 1;
- mark_inline_for_output (fndecl);
+ defer_fn (fndecl);
}
#if 0
@@ -14654,13 +14670,6 @@ mark_cp_function_context (f)
mark_lang_function (f->language);
}
-int
-in_function_p ()
-{
- return function_depth != 0;
-}
-
-
void
lang_mark_false_label_stack (l)
struct label_node *l;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 5c1f7f8bb30..49bf040280d 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -108,9 +108,9 @@ static varray_type pending_statics;
/* A list of functions which were declared inline, but which we
may need to emit outline anyway. */
-static varray_type saved_inlines;
-#define saved_inlines_used \
- (saved_inlines ? saved_inlines->elements_used : 0)
+static varray_type deferred_fns;
+#define deferred_fns_used \
+ (deferred_fns ? deferred_fns->elements_used : 0)
/* Same, but not reset. Local temp variables and global temp variables
can have the same name. */
@@ -452,7 +452,7 @@ int flag_use_cxa_atexit;
/* Nonzero to not ignore namespace std. */
-int flag_honor_std;
+int flag_honor_std = ENABLE_STD_NAMESPACE;
/* Nonzero if we should expand functions calls inline at the tree
level, rather than at the RTL level. */
@@ -572,7 +572,6 @@ lang_decode_option (argc, argv)
#endif
;
char **argv;
-
{
int strings_processed;
char *p = argv[0];
@@ -1010,9 +1009,16 @@ grokclassfn (ctype, function, flags, quals)
/* Right now we just make this a pointer. But later
we may wish to make it special. */
tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (function)));
+ tree qual_type;
+ tree parm;
+
+ /* The `this' parameter is implicitly `const'; it cannot be
+ assigned to. */
+ this_quals |= TYPE_QUAL_CONST;
+ qual_type = cp_build_qualified_type (type, this_quals);
+ parm = build_decl (PARM_DECL, this_identifier, qual_type);
+ c_apply_type_quals_to_decl (this_quals, parm);
- tree parm = build_decl (PARM_DECL, this_identifier,
- cp_build_qualified_type (type, this_quals | TYPE_QUAL_CONST));
/* Mark the artificial `this' parameter as "artificial". */
SET_DECL_ARTIFICIAL (parm);
DECL_ARG_TYPE (parm) = type;
@@ -1970,20 +1976,20 @@ constructor_name (thing)
return t;
}
-/* Record the existence of an addressable inline function. */
+/* Defer the compilation of the FN until the end of compilation. */
void
-mark_inline_for_output (decl)
- tree decl;
+defer_fn (fn)
+ tree fn;
{
- decl = DECL_MAIN_VARIANT (decl);
- if (DECL_SAVED_INLINE (decl))
+ fn = DECL_MAIN_VARIANT (fn);
+ if (DECL_DEFERRED_FN (fn))
return;
- DECL_SAVED_INLINE (decl) = 1;
- if (!saved_inlines)
- VARRAY_TREE_INIT (saved_inlines, 32, "saved_inlines");
+ DECL_DEFERRED_FN (fn) = 1;
+ if (!deferred_fns)
+ VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
- VARRAY_PUSH_TREE (saved_inlines, decl);
+ VARRAY_PUSH_TREE (deferred_fns, fn);
}
/* Hand off a unique name which can be used for variable we don't really
@@ -2545,7 +2551,7 @@ output_vtable_inherit (vars)
op[1] = const0_rtx;
else if (parent)
{
- parent = TYPE_BINFO_VTABLE (BINFO_TYPE (parent));
+ parent = get_vtbl_decl_for_binfo (TYPE_BINFO (BINFO_TYPE (parent)));
op[1] = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */
}
else
@@ -3531,9 +3537,9 @@ finish_file ()
/* Go through the various inline functions, and see if any need
synthesizing. */
- for (i = 0; i < saved_inlines_used; ++i)
+ for (i = 0; i < deferred_fns_used; ++i)
{
- tree decl = VARRAY_TREE (saved_inlines, i);
+ tree decl = VARRAY_TREE (deferred_fns, i);
import_export_decl (decl);
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl)
&& TREE_USED (decl)
@@ -3563,9 +3569,9 @@ finish_file ()
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)
+ for (i = 0; i < deferred_fns_used; ++i)
{
- tree decl = VARRAY_TREE (saved_inlines, i);
+ tree decl = VARRAY_TREE (deferred_fns, i);
if (DECL_NOT_REALLY_EXTERN (decl)
&& DECL_INITIAL (decl)
@@ -3603,9 +3609,9 @@ finish_file ()
}
}
- if (saved_inlines_used
- && wrapup_global_declarations (&VARRAY_TREE (saved_inlines, 0),
- saved_inlines_used))
+ if (deferred_fns_used
+ && wrapup_global_declarations (&VARRAY_TREE (deferred_fns, 0),
+ deferred_fns_used))
reconsider = 1;
if (walk_namespaces (wrapup_globals_for_namespace, /*data=*/0))
reconsider = 1;
@@ -5231,7 +5237,7 @@ mark_used (decl)
&& DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)
&& (!DECL_EXPLICIT_INSTANTIATION (decl)
|| (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))))
- instantiate_decl (decl);
+ instantiate_decl (decl, /*defer_ok=*/1);
}
/* Helper function for named_class_head_sans_basetype nonterminal. We
@@ -5296,7 +5302,7 @@ void
init_decl2 ()
{
ggc_add_tree_root (&decl_namespace_list, 1);
- ggc_add_tree_varray_root (&saved_inlines, 1);
+ ggc_add_tree_varray_root (&deferred_fns, 1);
ggc_add_tree_varray_root (&pending_statics, 1);
ggc_add_tree_varray_root (&ssdf_decls, 1);
ggc_add_tree_root (&ssdf_decl, 1);
diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c
index c8152d5336f..7f81094d4b0 100644
--- a/gcc/cp/dump.c
+++ b/gcc/cp/dump.c
@@ -550,7 +550,8 @@ dequeue_and_dump (di)
{
if (DECL_C_BIT_FIELD (t))
dump_string (di, "bitfield");
- dump_child ("bpos", DECL_FIELD_BITPOS (t));
+ if (DECL_FIELD_OFFSET (t))
+ dump_child ("bpos", bit_position (t));
}
break;
@@ -609,6 +610,7 @@ dequeue_and_dump (di)
break;
case TEMPLATE_DECL:
+ dump_child ("rslt", DECL_TEMPLATE_RESULT (t));
dump_child ("inst", DECL_TEMPLATE_INSTANTIATIONS (t));
dump_child ("spcs", DECL_TEMPLATE_SPECIALIZATIONS (t));
break;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index a0be98f8f5f..5600176d1c0 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -1857,7 +1857,7 @@ dump_expr (t, flags)
t = TYPE_METHOD_BASETYPE (t);
virtuals = TYPE_BINFO_VIRTUALS (TYPE_MAIN_VARIANT (t));
- n = tree_low_cst (idx, 0);
+ n = tree_low_cst (idx, 0) - first_vfun_index (t);
/* Map vtable index back one, to allow for the null pointer to
member. */
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 230fa6a154b..ebf7c94f946 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -52,7 +52,6 @@ cplus_expand_constant (cst)
{
tree type = TREE_TYPE (cst);
tree member;
- tree offset;
/* Find the member. */
member = PTRMEM_CST_MEMBER (cst);
@@ -60,10 +59,7 @@ cplus_expand_constant (cst)
if (TREE_CODE (member) == FIELD_DECL)
{
/* Find the offset for the field. */
- offset = convert (sizetype,
- size_binop (EASY_DIV_EXPR,
- bit_position (member),
- bitsize_int (BITS_PER_UNIT)));
+ tree offset = byte_position (member);
if (flag_new_abi)
/* Under the new ABI, we use -1 to represent the NULL
@@ -80,15 +76,10 @@ cplus_expand_constant (cst)
}
else
{
- tree delta;
- tree idx;
- tree pfn;
- tree delta2;
+ tree delta, idx, pfn, delta2;
expand_ptrmemfunc_cst (cst, &delta, &idx, &pfn, &delta2);
-
- cst = build_ptrmemfunc1 (type, delta, idx,
- pfn, delta2);
+ cst = build_ptrmemfunc1 (type, delta, idx, pfn, delta2);
}
}
break;
diff --git a/gcc/cp/inc/cxxabi.h b/gcc/cp/inc/cxxabi.h
index b140a15f648..e0c15317f7a 100644
--- a/gcc/cp/inc/cxxabi.h
+++ b/gcc/cp/inc/cxxabi.h
@@ -160,52 +160,41 @@ class __base_class_info
/* abi defined member variables */
public:
const __class_type_info *base; /* base class type */
- std::ptrdiff_t offset; /* offset to the sub object */
- int vmi_flags; /* about the base */
+ long vmi_offset_flags; /* offset and info */
/* implementation defined types */
public:
enum vmi_masks {
virtual_mask = 0x1,
public_mask = 0x2,
- hwm_bit = 2
+ hwm_bit = 2,
+ offset_shift = 8 /* bits to shift offset by */
};
/* implementation defined member functions */
public:
bool is_virtual_p () const
- { return vmi_flags & virtual_mask; }
+ { return vmi_offset_flags & virtual_mask; }
bool is_public_p () const
- { return vmi_flags & public_mask; }
+ { return vmi_offset_flags & public_mask; }
+ std::ptrdiff_t offset () const
+ { return std::ptrdiff_t (vmi_offset_flags) >> offset_shift; }
};
/* type information for a class */
class __class_type_info
: public std::type_info
{
-/* abi defined member variables */
-public:
- int details; /* details about the class heirarchy */
-
/* abi defined member functions */
public:
virtual ~__class_type_info ();
public:
- explicit __class_type_info (const char *n_,
- int details_)
- : type_info (n_), details (details_)
+ explicit __class_type_info (const char *n_)
+ : type_info (n_)
{ }
/* implementation defined types */
public:
- enum detail_masks {
- multiple_base_mask = 0x1, /* multiple inheritance of the same base type */
- polymorphic_mask = 0x2, /* is a polymorphic type */
- virtual_base_mask = 0x4, /* has virtual bases (direct or indirect) */
- private_base_mask = 0x8 /* has private bases (direct or indirect) */
- };
-
-public:
/* sub_kind tells us about how a base object is contained within a derived
object. We often do this lazily, hence the UNKNOWN value. At other times
we may use NOT_CONTAINED to mean not publicly contained. */
@@ -230,7 +219,7 @@ public:
{
const void *dst_ptr; /* pointer to caught object */
sub_kind whole2dst; /* path from most derived object to target */
- int src_details; /* hints about the source type */
+ int src_details; /* hints about the source type heirarchy */
const __class_type_info *base_type; /* where we found the target, */
/* if in vbase the __class_type_info of vbase */
/* if a non-virtual base then 1 */
@@ -320,9 +309,8 @@ public:
virtual ~__si_class_type_info ();
public:
explicit __si_class_type_info (const char *n_,
- int details_,
const __class_type_info *base_)
- : __class_type_info (n_, details_), base (base_)
+ : __class_type_info (n_), base (base_)
{ }
/* implementation defined member functions */
@@ -342,9 +330,10 @@ protected:
/* type information for a class with multiple and/or virtual bases */
class __vmi_class_type_info : public __class_type_info {
/* abi defined member variables */
-protected:
- int n_bases; /* number of direct bases */
- __base_class_info base_list[1]; /* array of bases */
+public:
+ int vmi_flags; /* details about the class heirarchy */
+ int vmi_base_count; /* number of direct bases */
+ __base_class_info vmi_bases[1]; /* array of bases */
/* The array of bases uses the trailing array struct hack
so this class is not constructable with a normal constructor. It is
internally generated by the compiler. */
@@ -354,10 +343,21 @@ public:
virtual ~__vmi_class_type_info ();
public:
explicit __vmi_class_type_info (const char *n_,
- int details_)
- : __class_type_info (n_, details_), n_bases (0)
+ int flags_)
+ : __class_type_info (n_), vmi_flags (flags_), vmi_base_count (0)
{ }
+/* implementation defined types */
+public:
+ enum vmi_flags_masks {
+ non_diamond_repeat_mask = 0x1, /* distinct instance of repeated base */
+ diamond_shaped_mask = 0x2, /* diamond shaped multiple inheritance */
+ non_public_base_mask = 0x4, /* has non-public direct or indirect base */
+ public_base_mask = 0x8, /* has public base (direct) */
+
+ flags_unknown_mask = 0x10
+ };
+
/* implementation defined member functions */
protected:
virtual bool do_dyncast (std::ptrdiff_t src2dst, sub_kind access_path,
@@ -385,7 +385,33 @@ void *__dynamic_cast (const void *src_ptr, /* object started from */
-2: src_type is not a public base of dst_type
-3: src_type is a multiple public non-virtual base of dst_type */
-
+/* array ctor/dtor routines */
+
+/* allocate and construct array */
+void *__cxa_vec_new (size_t __element_count,
+ size_t __element_size,
+ size_t __padding_size,
+ void (*__constructor) (void *),
+ void (*__destructor) (void *));
+
+/* construct array */
+void __cxa_vec_ctor (void *__array_address,
+ size_t __element_count,
+ size_t __element_size,
+ void (*__constructor) (void *),
+ void (*__destructor) (void *));
+
+/* destruct array */
+void __cxa_vec_dtor (void *__array_address,
+ size_t __element_count,
+ size_t __element_size,
+ void (*__destructor) (void *));
+
+/* destruct and release array */
+void __cxa_vec_delete (void *__array_address,
+ size_t __element_size,
+ size_t __padding_size,
+ void (*__destructor) (void *));
} /* namespace __cxxabiv1 */
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ff8e0583434..4623abf6fa9 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -653,31 +653,23 @@ expand_virtual_init (binfo, decl)
tree type = BINFO_TYPE (binfo);
tree vtbl, vtbl_ptr;
tree vtype, vtype_binfo;
+ tree b;
/* Compute the location of the vtable. */
vtype = DECL_CONTEXT (TYPE_VFIELD (type));
vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0);
- vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (TYPE_VFIELD (type)), binfo));
+ b = binfo_value (DECL_FIELD_CONTEXT (TYPE_VFIELD (type)), binfo);
+ /* Figure out what vtable BINFO's vtable is based on, and mark it as
+ used. */
+ vtbl = get_vtbl_decl_for_binfo (b);
+ assemble_external (vtbl);
+ TREE_USED (vtbl) = 1;
+
+ /* Now compute the address to use when initializing the vptr. */
+ vtbl = BINFO_VTABLE (b);
if (TREE_CODE (vtbl) == VAR_DECL)
- {
- assemble_external (vtbl);
- TREE_USED (vtbl) = 1;
- vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
- }
- else
- /* Under the new ABI, secondary vtables are stored with the
- primary vtable. So, the BINFO_VTABLE may be an expression for
- computing the secondary vtable, rather than the secondary
- vtable itself. */
- my_friendly_assert (merge_primary_and_secondary_vtables_p (),
- 20000220);
-
- /* Under the new ABI, we need to point into the middle of the
- vtable. */
- if (vbase_offsets_in_vtable_p ())
- vtbl = build (PLUS_EXPR, TREE_TYPE (vtbl), vtbl,
- size_extra_vtbl_entries (binfo));
+ vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
/* Compute the location of the vtpr. */
decl = convert_pointer_to_real (vtype_binfo, decl);
diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h
index c3a81b142df..804a079d574 100644
--- a/gcc/cp/lang-specs.h
+++ b/gcc/cp/lang-specs.h
@@ -78,6 +78,7 @@ Boston, MA 02111-1307, USA. */
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\
%{ffast-math:-D__FAST_MATH__}\
%{fshort-wchar:-D__WCHAR_TYPE__=short\\ unsigned\\ int}\
+ %{fshow-column} %{fno-show-column}\
%{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\
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index d90f4723d46..41080b43163 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -2085,7 +2085,7 @@ cons_up_default_function (type, full_name, kind)
#endif
DECL_NOT_REALLY_EXTERN (fn) = 1;
- mark_inline_for_output (fn);
+ defer_fn (fn);
#ifdef DEBUG_DEFAULT_FUNCTIONS
{ char *fn_type = NULL;
@@ -3344,9 +3344,10 @@ identifier_type (decl)
tree decl;
{
tree t;
+
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
- if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL)
+ if (TREE_CODE (DECL_TEMPLATE_RESULT (decl)) == TYPE_DECL)
return PTYPENAME;
else if (looking_for_template)
return PFUNCNAME;
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 9d5defcf09b..e35acc9889d 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1228,7 +1228,7 @@ build_mangled_name (parmtypes, begin, end)
if (end)
OB_FINISH ();
- return (char *)obstack_base (&scratch_obstack);
+ return (char *) obstack_base (&scratch_obstack);
}
/* Emit modifiers such as constant, read-only, and volatile. */
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index f5db6a10082..63ec81a26ab 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -463,10 +463,6 @@ inlinable_function_p (fn, id)
it. */
else if (!DECL_INLINE (fn))
;
- /* If we don't have the function body available, we can't inline
- it. */
- else if (!DECL_SAVED_TREE (fn))
- ;
/* We can't inline varargs functions. */
else if (varargs_function_p (fn))
;
@@ -481,6 +477,21 @@ inlinable_function_p (fn, id)
/* Squirrel away the result so that we don't have to check again. */
DECL_UNINLINABLE (fn) = !inlinable;
+ /* We can inline a template instantiation only if it's fully
+ instantiated. */
+ if (inlinable
+ && DECL_TEMPLATE_INFO (fn)
+ && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
+ {
+ fn = instantiate_decl (fn, /*defer_ok=*/0);
+ inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
+ }
+
+ /* If we don't have the function body available, we can't inline
+ it. */
+ if (!DECL_SAVED_TREE (fn))
+ inlinable = 0;
+
/* Don't do recursive inlining, either. We don't record this in
DECL_UNLINABLE; we may be able to inline this function later. */
if (inlinable)
@@ -492,16 +503,6 @@ inlinable_function_p (fn, id)
inlinable = 0;
}
- /* We can inline a template instantiation only if it's fully
- instantiated. */
- if (inlinable
- && DECL_TEMPLATE_INFO (fn)
- && TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn)))
- {
- fn = instantiate_decl (fn);
- inlinable = !TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (fn));
- }
-
/* Return the result. */
return inlinable;
}
@@ -748,20 +749,11 @@ calls_setjmp_r (tp, walk_subtrees, data)
int *walk_subtrees ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
{
- int setjmp_p;
- int longjmp_p;
- int fork_or_exec_p;
- int malloc_p;
- int alloca_p;
-
/* We're only interested in FUNCTION_DECLS. */
if (TREE_CODE (*tp) != FUNCTION_DECL)
return NULL_TREE;
- special_function_p (*tp, &setjmp_p, &longjmp_p, &fork_or_exec_p, &malloc_p,
- &alloca_p);
-
- return setjmp_p ? *tp : NULL_TREE;
+ return setjmp_call_p (*tp) ? *tp : NULL_TREE;
}
/* Returns non-zero if FN calls `setjmp' or some other function that
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0978ec9e363..1c5238b450b 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1105,7 +1105,7 @@ determine_specialization (template_id, decl, targs_out,
}
/* It was a specialization of a template. */
- targs = DECL_TI_ARGS (DECL_RESULT (TREE_VALUE (templates)));
+ targs = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (TREE_VALUE (templates)));
if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs))
{
*targs_out = copy_node (targs);
@@ -3699,7 +3699,7 @@ lookup_template_class (d1, arglist, in_decl, context, entering_scope)
d1 = DECL_NAME (template);
}
else if (TREE_CODE (d1) == TEMPLATE_DECL
- && TREE_CODE (DECL_RESULT (d1)) == TYPE_DECL)
+ && TREE_CODE (DECL_TEMPLATE_RESULT (d1)) == TYPE_DECL)
{
template = d1;
d1 = DECL_NAME (template);
@@ -4460,9 +4460,9 @@ tsubst_friend_function (decl, args)
DECL_PRIMARY_TEMPLATE (new_friend) = new_friend;
new_friend_is_defn
- = DECL_INITIAL (DECL_RESULT (new_friend)) != NULL_TREE;
+ = DECL_INITIAL (DECL_TEMPLATE_RESULT (new_friend)) != NULL_TREE;
new_friend_result_template_info
- = DECL_TEMPLATE_INFO (DECL_RESULT (new_friend));
+ = DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (new_friend));
}
else
{
@@ -4535,7 +4535,7 @@ tsubst_friend_function (decl, args)
tree t;
tree new_friend_args;
- DECL_TEMPLATE_INFO (DECL_RESULT (old_decl))
+ DECL_TEMPLATE_INFO (DECL_TEMPLATE_RESULT (old_decl))
= new_friend_result_template_info;
new_friend_args = TI_ARGS (new_friend_template_info);
@@ -4757,7 +4757,7 @@ instantiate_class_template (type)
CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern);
/* Pretend that the type is complete, so that we will look
inside it during name lookup and such. */
- TYPE_SIZE (type) = integer_zero_node;
+ TYPE_SIZE (type) = bitsize_zero_node;
return type;
}
@@ -5416,7 +5416,7 @@ tsubst_decl (t, args, type, in_decl)
plus the innermost args from the template decl. */
tree tmpl_args = DECL_CLASS_TEMPLATE_P (t)
? CLASSTYPE_TI_ARGS (TREE_TYPE (t))
- : DECL_TI_ARGS (DECL_RESULT (t));
+ : DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
tree full_args;
full_args = tsubst_template_arg_vector (tmpl_args, args,
@@ -5448,7 +5448,7 @@ tsubst_decl (t, args, type, in_decl)
if (is_template_template_parm)
{
tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
- DECL_RESULT (r) = new_decl;
+ DECL_TEMPLATE_RESULT (r) = new_decl;
TREE_TYPE (r) = TREE_TYPE (new_decl);
break;
}
@@ -5469,13 +5469,14 @@ tsubst_decl (t, args, type, in_decl)
/*complain=*/1, in_decl);
TREE_TYPE (r) = new_type;
CLASSTYPE_TI_TEMPLATE (new_type) = r;
- DECL_RESULT (r) = TYPE_MAIN_DECL (new_type);
+ DECL_TEMPLATE_RESULT (r) = TYPE_MAIN_DECL (new_type);
DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type);
}
else
{
tree new_decl = tsubst (decl, args, /*complain=*/1, in_decl);
- DECL_RESULT (r) = new_decl;
+
+ DECL_TEMPLATE_RESULT (r) = new_decl;
DECL_TI_TEMPLATE (new_decl) = r;
TREE_TYPE (r) = TREE_TYPE (new_decl);
DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl);
@@ -5546,8 +5547,9 @@ tsubst_decl (t, args, type, in_decl)
spec_args = tsubst (DECL_TI_ARGS (fn), args,
/*complain=*/1, in_decl);
- new_fn = tsubst (DECL_RESULT (most_general_template (fn)),
- spec_args, /*complain=*/1, in_decl);
+ new_fn
+ = tsubst (DECL_TEMPLATE_RESULT (most_general_template (fn)),
+ spec_args, /*complain=*/1, in_decl);
DECL_TI_TEMPLATE (new_fn) = fn;
register_specialization (new_fn, r,
innermost_args (spec_args));
@@ -5555,7 +5557,7 @@ tsubst_decl (t, args, type, in_decl)
/* Record this partial instantiation. */
register_specialization (r, t,
- DECL_TI_ARGS (DECL_RESULT (r)));
+ DECL_TI_ARGS (DECL_TEMPLATE_RESULT (r)));
}
break;
@@ -5699,7 +5701,7 @@ tsubst_decl (t, args, type, in_decl)
DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args,
/*complain=*/1, t);
DECL_MAIN_VARIANT (r) = r;
- DECL_RESULT (r) = NULL_TREE;
+ DECL_TEMPLATE_RESULT (r) = NULL_TREE;
TREE_STATIC (r) = 0;
TREE_PUBLIC (r) = TREE_PUBLIC (t);
@@ -7434,7 +7436,8 @@ instantiate_template (tmpl, targ_ptr)
}
/* substitute template parameters */
- fndecl = tsubst (DECL_RESULT (gen_tmpl), targ_ptr, /*complain=*/1, gen_tmpl);
+ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl),
+ targ_ptr, /*complain=*/1, gen_tmpl);
/* The DECL_TI_TEMPLATE should always be the immediate parent
template, not the most general template. */
DECL_TI_TEMPLATE (fndecl) = tmpl;
@@ -7860,7 +7863,8 @@ resolve_overloaded_unification (tparms, targs, parm, arg, strict,
if (TREE_CODE (fn) != TEMPLATE_DECL)
continue;
- subargs = get_bindings_overload (fn, DECL_RESULT (fn), expl_subargs);
+ subargs = get_bindings_overload (fn, DECL_TEMPLATE_RESULT (fn),
+ expl_subargs);
if (subargs)
{
elem = tsubst (TREE_TYPE (fn), subargs, /*complain=*/0,
@@ -8684,7 +8688,7 @@ mark_decl_instantiated (result, extern_p)
maybe_make_one_only (result);
}
else if (TREE_CODE (result) == FUNCTION_DECL)
- mark_inline_for_output (result);
+ defer_fn (result);
}
/* Given two function templates PAT1 and PAT2, and explicit template
@@ -8701,11 +8705,13 @@ more_specialized (pat1, pat2, explicit_args)
tree targs;
int winner = 0;
- targs = get_bindings_overload (pat1, DECL_RESULT (pat2), explicit_args);
+ targs
+ = get_bindings_overload (pat1, DECL_TEMPLATE_RESULT (pat2), explicit_args);
if (targs)
--winner;
- targs = get_bindings_overload (pat2, DECL_RESULT (pat1), explicit_args);
+ targs
+ = get_bindings_overload (pat2, DECL_TEMPLATE_RESULT (pat1), explicit_args);
if (targs)
++winner;
@@ -9123,7 +9129,7 @@ do_decl_instantiation (declspecs, declarator, storage)
mark_decl_instantiated (result, extern_p);
repo_template_instantiated (result, extern_p);
if (! extern_p)
- instantiate_decl (result);
+ instantiate_decl (result, /*defer_ok=*/1);
}
void
@@ -9259,7 +9265,7 @@ do_type_instantiation (t, storage)
mark_decl_instantiated (tmp, extern_p);
repo_template_instantiated (tmp, extern_p);
if (! extern_p)
- instantiate_decl (tmp);
+ instantiate_decl (tmp, /*defer_ok=*/1);
}
for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp))
@@ -9268,7 +9274,7 @@ do_type_instantiation (t, storage)
mark_decl_instantiated (tmp, extern_p);
repo_template_instantiated (tmp, extern_p);
if (! extern_p)
- instantiate_decl (tmp);
+ instantiate_decl (tmp, /*defer_ok=*/1);
}
for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp))
@@ -9370,11 +9376,14 @@ regenerate_decl_from_template (decl, tmpl)
register_specialization (decl, gen_tmpl, args);
}
-/* Produce the definition of D, a _DECL generated from a template. */
+/* Produce the definition of D, a _DECL generated from a template. If
+ DEFER_OK is non-zero, then we don't have to actually do the
+ instantiation now; we just have to do it sometime. */
tree
-instantiate_decl (d)
+instantiate_decl (d, defer_ok)
tree d;
+ int defer_ok;
{
tree tmpl = DECL_TI_TEMPLATE (d);
tree args = DECL_TI_ARGS (d);
@@ -9382,11 +9391,9 @@ instantiate_decl (d)
tree code_pattern;
tree spec;
tree gen_tmpl;
- int nested = in_function_p ();
int pattern_defined;
int line = lineno;
char *file = input_filename;
- tree old_fn = current_function_decl;
/* This function should only be used to instantiate templates for
functions and static member variables. */
@@ -9507,20 +9514,18 @@ instantiate_decl (d)
&& ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d)))
goto out;
+ /* We need to set up DECL_INITIAL regardless of pattern_defined if
+ the variable is a static const initialized in the class body. */
if (TREE_CODE (d) == VAR_DECL
&& TREE_READONLY (d)
&& DECL_INITIAL (d) == NULL_TREE
&& DECL_INITIAL (code_pattern) != NULL_TREE)
- /* We need to set up DECL_INITIAL regardless of pattern_defined if
- the variable is a static const initialized in the class body. */;
- else if (pattern_defined && nested
- && TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))
- /* An inline function used in another function; instantiate it now so
- we can inline it. */;
- else if (! pattern_defined || ! at_eof)
- {
- /* Defer all other templates. We restore the source position
- here because it's used by add_pending_template. */
+ ;
+ /* Defer all other templates, unless we have been explicitly
+ forbidden from doing so. We restore the source position here
+ because it's used by add_pending_template. */
+ else if (! pattern_defined || defer_ok)
+ {
lineno = line;
input_filename = file;
@@ -9540,25 +9545,6 @@ instantiate_decl (d)
goto out;
}
- /* If this instantiation is COMDAT, we don't know whether or not we
- will really need to write it out. If we can't be sure, mark it
- DECL_DEFER_OUTPUT. NOTE: This increases memory consumption,
- since we keep some instantiations in memory rather than write
- them out immediately and forget them. A better approach would be
- to wait until we know we need them to do the instantiation, but
- that would break templates with static locals, because we
- generate the functions to destroy statics before we determine
- which functions are needed. A better solution would be to
- generate the ctor and dtor functions as we go. */
-
- if (TREE_CODE (d) == FUNCTION_DECL
- && DECL_COMDAT (d)
- && ! DECL_NEEDED_P (d)
- /* If the function that caused us to be instantiated is needed, we
- will be needed, too. */
- && (! nested || (old_fn && ! DECL_NEEDED_P (old_fn))))
- DECL_DEFER_OUTPUT (d) = 1;
-
/* We're now committed to instantiating this template. Mark it as
instantiated so that recursive calls to instantiate_decl do not
try to instantiate it again. */
@@ -9651,7 +9637,7 @@ instantiate_pending_templates ()
fn;
fn = TREE_CHAIN (fn))
if (! DECL_ARTIFICIAL (fn))
- instantiate_decl (fn);
+ instantiate_decl (fn, /*defer_ok=*/0);
if (COMPLETE_TYPE_P (instantiation))
{
instantiated_something = 1;
@@ -9668,10 +9654,11 @@ instantiate_pending_templates ()
}
else
{
- if (DECL_TEMPLATE_INSTANTIATION (instantiation)
+ if (!DECL_TEMPLATE_SPECIALIZATION (instantiation)
&& !DECL_TEMPLATE_INSTANTIATED (instantiation))
{
- instantiation = instantiate_decl (instantiation);
+ instantiation = instantiate_decl (instantiation,
+ /*defer_ok=*/0);
if (DECL_TEMPLATE_INSTANTIATED (instantiation))
{
instantiated_something = 1;
@@ -9679,7 +9666,7 @@ instantiate_pending_templates ()
}
}
- if (!DECL_TEMPLATE_INSTANTIATION (instantiation)
+ if (DECL_TEMPLATE_SPECIALIZATION (instantiation)
|| DECL_TEMPLATE_INSTANTIATED (instantiation))
/* If INSTANTIATION has been instantiated, then we don't
need to consider it again in the future. */
@@ -9711,7 +9698,7 @@ instantiate_pending_templates ()
template = TREE_PURPOSE (*t);
args = get_bindings (template, fn, NULL_TREE);
fn = instantiate_template (template, args);
- instantiate_decl (fn);
+ instantiate_decl (fn, /*defer_ok=*/0);
reconsider = 1;
}
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index 99d53f089d1..0d3879eebb2 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -103,7 +103,7 @@ repo_get_id (t)
if (!COMPLETE_TYPE_P (t) || TYPE_BEING_DEFINED (t))
my_friendly_abort (981113);
- t = TYPE_BINFO_VTABLE (t);
+ t = get_vtbl_decl_for_binfo (TYPE_BINFO (t));
if (t == NULL_TREE)
return t;
}
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index 5ee1d119418..3a0a484e8ad 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -66,6 +66,8 @@ static tree tinfo_base_init PARAMS((tree, tree));
static tree generic_initializer PARAMS((tree, tree));
static tree ptr_initializer PARAMS((tree, tree));
static tree ptmd_initializer PARAMS((tree, tree));
+static tree dfs_class_hint_mark PARAMS ((tree, void *));
+static tree dfs_class_hint_unmark PARAMS ((tree, void *));
static int class_hint_flags PARAMS((tree));
static tree class_initializer PARAMS((tree, tree, tree));
static tree synthesize_tinfo_var PARAMS((tree, tree));
@@ -132,6 +134,7 @@ build_headof (exp)
tree type = TREE_TYPE (exp);
tree aref;
tree offset;
+ tree index;
my_friendly_assert (TREE_CODE (type) == POINTER_TYPE, 20000112);
type = TREE_TYPE (type);
@@ -151,7 +154,15 @@ build_headof (exp)
/* We use this a couple of times below, protect it. */
exp = save_expr (exp);
- aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node);
+ /* Under the new ABI, the offset-to-top field is at index -2 from
+ the vptr. */
+ if (new_abi_rtti_p ())
+ index = build_int_2 (-2, -1);
+ /* But under the old ABI, it is at offset zero. */
+ else
+ index = integer_zero_node;
+
+ aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), index);
if (flag_vtable_thunks)
offset = aref;
@@ -230,6 +241,7 @@ get_tinfo_decl_dynamic (exp)
{
/* build reference to type_info from vtable. */
tree t;
+ tree index;
if (! flag_rtti)
error ("taking dynamic typeid of object with -fno-rtti");
@@ -247,10 +259,15 @@ get_tinfo_decl_dynamic (exp)
exp = build_indirect_ref (exp, NULL_PTR);
}
- if (flag_vtable_thunks)
- t = build_vfn_ref ((tree *) 0, exp, integer_one_node);
+ /* The RTTI information is always in the vtable, but it's at
+ different indices depending on the ABI. */
+ if (new_abi_rtti_p ())
+ index = minus_one_node;
+ else if (flag_vtable_thunks)
+ index = integer_one_node;
else
- t = build_vfn_ref ((tree *) 0, exp, integer_zero_node);
+ index = integer_zero_node;
+ t = build_vfn_ref ((tree *) 0, exp, index);
TREE_TYPE (t) = build_pointer_type (tinfo_decl_type);
return t;
}
@@ -396,7 +413,7 @@ get_tinfo_decl (type)
DECL_NOT_REALLY_EXTERN (d) = 1;
SET_DECL_TINFO_FN_P (d);
TREE_TYPE (name) = type;
- mark_inline_for_output (d);
+ defer_fn (d);
}
else
{
@@ -420,6 +437,7 @@ get_tinfo_decl (type)
pushdecl_top_level (d);
/* Remember the type it is for. */
TREE_TYPE (name) = type;
+ TREE_USED (name) = 1;
}
return d;
}
@@ -513,30 +531,23 @@ get_base_offset (binfo, parent)
tree binfo;
tree parent;
{
- tree offset;
-
- if (!TREE_VIA_VIRTUAL (binfo))
- offset = BINFO_OFFSET (binfo);
- else if (!vbase_offsets_in_vtable_p ())
+ if (! TREE_VIA_VIRTUAL (binfo))
+ return BINFO_OFFSET (binfo);
+ else if (! vbase_offsets_in_vtable_p ())
{
- tree t = BINFO_TYPE (binfo);
const char *name;
- tree field;
- FORMAT_VBASE_NAME (name, t);
- field = lookup_field (parent, get_identifier (name), 0, 0);
- offset = size_binop (FLOOR_DIV_EXPR, bit_position (field),
- bitsize_int (BITS_PER_UNIT));
- offset = convert (sizetype, offset);
+ FORMAT_VBASE_NAME (name, BINFO_TYPE (binfo));
+ return byte_position (lookup_field (parent, get_identifier (name),
+ 0, 0));
}
else
- {
- /* Under the new ABI, we store the vtable offset at which
- the virtual base offset can be found. */
- tree vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), parent);
- offset = convert (sizetype, BINFO_VPTR_FIELD (vbase));
- }
- return offset;
+ /* Under the new ABI, we store the vtable offset at which
+ the virtual base offset can be found. */
+ return convert (sizetype,
+ BINFO_VPTR_FIELD (BINFO_FOR_VBASE (BINFO_TYPE (binfo),
+ parent)));
+
}
/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working
@@ -550,7 +561,7 @@ build_dynamic_cast_1 (type, expr)
tree exprtype;
tree dcast_fn;
tree old_expr = expr;
- char* errstr = NULL;
+ const char *errstr = NULL;
/* T shall be a pointer or reference to a complete class type, or
`pointer to cv void''. */
@@ -941,7 +952,7 @@ expand_class_desc (tdecl, type)
fields [2] = build_lang_decl (FIELD_DECL, NULL_TREE, boolean_type_node);
DECL_BIT_FIELD (fields[2]) = 1;
- DECL_SIZE (fields[2]) = bitsize_int (1);
+ DECL_SIZE (fields[2]) = bitsize_one_node;
/* Actually enum access */
fields [3] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node);
@@ -1291,8 +1302,7 @@ tinfo_base_init (desc, target)
if (TINFO_VTABLE_DECL (desc))
{
- tree vtbl_ptr = build_unary_op (ADDR_EXPR, TINFO_VTABLE_DECL (desc), 0);
-
+ tree vtbl_ptr = TINFO_VTABLE_DECL (desc);
init = tree_cons (NULL_TREE, vtbl_ptr, init);
}
@@ -1373,23 +1383,71 @@ ptmd_initializer (desc, target)
return init;
}
-/* Determine the hint flags describing the features of a class's heirarchy.
- FIXME: better set the hint_flags here! For now set them
- to safe 'don't know' values. The specification is under
- review. Don't forget to check the runtime dynamic_cast and
- catch machinery if these change. */
+/* Check base BINFO to set hint flags in *DATA, which is really an int.
+ We use CLASSTYPE_MARKED to tag types we've found as non-virtual bases and
+ CLASSTYPE_MARKED2 to tag those which are virtual bases. Remember it is
+ possible for a type to be both a virtual and non-virtual base. */
+
+static tree
+dfs_class_hint_mark (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree basetype = BINFO_TYPE (binfo);
+ int *hint = (int *) data;
+
+ if (TREE_VIA_VIRTUAL (binfo))
+ {
+ if (CLASSTYPE_MARKED (basetype))
+ *hint |= 1;
+ if (CLASSTYPE_MARKED2 (basetype))
+ *hint |= 2;
+ SET_CLASSTYPE_MARKED2 (basetype);
+ }
+ else
+ {
+ if (CLASSTYPE_MARKED (basetype) || CLASSTYPE_MARKED2 (basetype))
+ *hint |= 1;
+ SET_CLASSTYPE_MARKED (basetype);
+ }
+ if (!TREE_VIA_PUBLIC (binfo) && TYPE_BINFO (basetype) != binfo)
+ *hint |= 4;
+ return NULL_TREE;
+};
+
+/* Clear the base's dfs marks, after searching for duplicate bases. */
+
+static tree
+dfs_class_hint_unmark (binfo, data)
+ tree binfo;
+ void *data ATTRIBUTE_UNUSED;
+{
+ tree basetype = BINFO_TYPE (binfo);
+
+ CLEAR_CLASSTYPE_MARKED (basetype);
+ CLEAR_CLASSTYPE_MARKED2 (basetype);
+ return NULL_TREE;
+}
+
+/* Determine the hint flags describing the features of a class's heirarchy. */
static int
class_hint_flags (type)
tree type;
{
int hint_flags = 0;
- hint_flags |= 0x1; /* contains multiply inherited sub object */
- hint_flags |= 0x4; /* has virtual bases */
- hint_flags |= 0x8; /* has private base */
- if (TYPE_POLYMORPHIC_P (type))
- hint_flags |= 0x2;
+ int i;
+
+ dfs_walk (TYPE_BINFO (type), dfs_class_hint_mark, NULL, &hint_flags);
+ dfs_walk (TYPE_BINFO (type), dfs_class_hint_unmark, NULL, NULL);
+ for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); ++i)
+ {
+ tree base_binfo = BINFO_BASETYPE (TYPE_BINFO (type), i);
+
+ if (TREE_VIA_PUBLIC (base_binfo))
+ hint_flags |= 0x8;
+ }
return hint_flags;
}
@@ -1404,9 +1462,7 @@ class_initializer (desc, target, trail)
tree trail;
{
tree init = tinfo_base_init (desc, target);
- int flags = class_hint_flags (target);
- trail = tree_cons (NULL_TREE, build_int_2 (flags, 0), trail);
TREE_CHAIN (init) = trail;
init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, init);
TREE_HAS_CONSTRUCTOR (init) = TREE_CONSTANT (init) = TREE_STATIC (init) = 1;
@@ -1512,8 +1568,11 @@ synthesize_tinfo_var (target_type, real_name)
}
is_simple = 0;
- base_init = tree_cons
- (NULL_TREE, build_int_2 (flags, 0), base_init);
+ /* combine offset and flags into one field */
+ offset = build_binary_op (LSHIFT_EXPR, offset,
+ build_int_2 (8, 0));
+ offset = build_binary_op (BIT_IOR_EXPR, offset,
+ build_int_2 (flags, 0));
base_init = tree_cons (NULL_TREE, offset, base_init);
base_init = tree_cons (NULL_TREE, tinfo, base_init);
base_init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_init);
@@ -1524,12 +1583,16 @@ synthesize_tinfo_var (target_type, real_name)
var_type = si_class_desc_type_node;
else
{
- /* Prepend the number of bases. */
+ int hint = class_hint_flags (target_type);
+
base_inits = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, base_inits);
base_inits = tree_cons (NULL_TREE, base_inits, NULL_TREE);
+ /* Prepend the number of bases. */
base_inits = tree_cons (NULL_TREE,
build_int_2 (nbases, 0), base_inits);
-
+ /* Prepend the hint flags. */
+ base_inits = tree_cons (NULL_TREE,
+ build_int_2 (hint, 0), base_inits);
var_type = get_vmi_pseudo_type_info (nbases);
}
var_init = class_initializer (var_type, target_type, base_inits);
@@ -1623,7 +1686,21 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
/* Get the vtable decl. */
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
-
+ vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
+
+ /* Under the new ABI, we need to point into the middle of the
+ vtable. */
+ if (flag_new_abi)
+ {
+ vtable_decl = build (PLUS_EXPR,
+ TREE_TYPE (vtable_decl),
+ vtable_decl,
+ size_binop (MULT_EXPR,
+ size_int (2),
+ TYPE_SIZE_UNIT (vtable_entry_type)));
+ TREE_CONSTANT (vtable_decl) = 1;
+ }
+
/* First field is the pseudo type_info base class. */
fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
@@ -1742,27 +1819,24 @@ create_tinfo_types ()
/* Class type_info. Add a flags field. */
class_desc_type_node = create_pseudo_type_info
("__class_type_info", 0,
- build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
NULL);
/* Single public non-virtual base class. Add pointer to base class. */
si_class_desc_type_node = create_pseudo_type_info
("__si_class_type_info", 0,
- build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
NULL);
/* Base class internal helper. Pointer to base type, offset to base,
flags. */
{
- tree fields[3];
+ tree fields[2];
- fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info),
- fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, ptrdiff_type_node),
- fields[2] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_type_node),
+ fields[0] = build_lang_decl (FIELD_DECL, NULL_TREE, ptr_type_info);
+ fields[1] = build_lang_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
base_desc_type_node = make_aggr_type (RECORD_TYPE);
finish_builtin_type (base_desc_type_node, "__base_class_type_info_pseudo",
- fields, 2, ptr_type_node);
+ fields, 1, ptr_type_node);
TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
}
@@ -1795,9 +1869,9 @@ emit_support_tinfos ()
&void_type_node,
&boolean_type_node,
&wchar_type_node,
- #if 0
+#if 0
&signed_wchar_type_node, &unsigned_wchar_type_node,
- #endif
+#endif
&char_type_node, &signed_char_type_node, &unsigned_char_type_node,
&short_integer_type_node, &short_unsigned_type_node,
&integer_type_node, &unsigned_type_node,
@@ -1806,11 +1880,11 @@ emit_support_tinfos ()
&float_type_node, &double_type_node, &long_double_type_node,
/* GCC extension types */
- #if 0
+#if 0
&complex_integer_type_node,
&complex_float_type_node, &complex_double_type_node,
&complex_long_double_type_node,
- #endif
+#endif
0
};
@@ -1915,16 +1989,11 @@ emit_tinfo_decl (decl_ptr, data)
tinfo_type = TREE_TYPE (DECL_NAME (tinfo_decl));
my_friendly_assert (tinfo_type != NULL_TREE, 20000120);
+ if (!DECL_NEEDED_P (tinfo_decl))
+ return 0;
/* Say we've dealt with it. */
TREE_TYPE (DECL_NAME (tinfo_decl)) = NULL_TREE;
- if (!DECL_NEEDED_P (tinfo_decl))
- return 0;
- if (TREE_CODE (tinfo_type) == RECORD_TYPE && TYPE_POLYMORPHIC_P (tinfo_type)
- && !CLASSTYPE_VTABLE_NEEDS_WRITING (tinfo_type))
- /* A polymorphic type only needs its type_info emitted when the vtable
- is. */
- return 0;
create_tinfo_types ();
decl = synthesize_tinfo_var (tinfo_type, DECL_ASSEMBLER_NAME (tinfo_decl));
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index cafdfc2ee63..616933bb2fb 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -104,16 +104,12 @@ static void expand_upcast_fixups
static void fixup_virtual_upcast_offsets
PARAMS ((tree, tree, int, int, tree, tree, tree, tree,
tree *));
-static tree marked_vtable_pathp PARAMS ((tree, void *));
-static tree unmarked_vtable_pathp PARAMS ((tree, void *));
static tree marked_new_vtablep PARAMS ((tree, void *));
static tree unmarked_new_vtablep PARAMS ((tree, void *));
static tree marked_pushdecls_p PARAMS ((tree, void *));
static tree unmarked_pushdecls_p PARAMS ((tree, void *));
-#if 0
static tree dfs_debug_unmarkedp PARAMS ((tree, void *));
static tree dfs_debug_mark PARAMS ((tree, void *));
-#endif
static tree dfs_find_vbases PARAMS ((tree, void *));
static tree dfs_clear_vbase_slots PARAMS ((tree, void *));
static tree dfs_init_vbase_pointers PARAMS ((tree, void *));
@@ -145,7 +141,7 @@ static int dependent_base_p PARAMS ((tree));
static tree dfs_accessible_queue_p PARAMS ((tree, void *));
static tree dfs_accessible_p PARAMS ((tree, void *));
static tree dfs_access_in_type PARAMS ((tree, void *));
-static tree access_in_type PARAMS ((tree, tree));
+static access_kind access_in_type PARAMS ((tree, tree));
static tree dfs_canonical_queue PARAMS ((tree, void *));
static tree dfs_assert_unmarked_p PARAMS ((tree, void *));
static void assert_canonical_unmarked PARAMS ((tree));
@@ -154,7 +150,6 @@ static int friend_accessible_p PARAMS ((tree, tree, tree));
static void setup_class_bindings PARAMS ((tree, int));
static int template_self_reference_p PARAMS ((tree, tree));
static void fixup_all_virtual_upcast_offsets PARAMS ((tree, tree));
-static tree dfs_mark_primary_bases PARAMS ((tree, void *));
static tree get_shared_vbase_if_not_primary PARAMS ((tree, void *));
static tree dfs_find_vbase_instance PARAMS ((tree, void *));
static tree dfs_get_pure_virtuals PARAMS ((tree, void *));
@@ -813,6 +808,18 @@ shared_unmarked_p (binfo, data)
return unmarkedp (binfo, data);
}
+/* The accessibility routines use BINFO_ACCESS for scratch space
+ during the computation of the accssibility of some declaration. */
+
+#define BINFO_ACCESS(NODE) \
+ ((access_kind) ((TREE_LANG_FLAG_1 (NODE) << 1) | TREE_LANG_FLAG_6 (NODE)))
+
+/* Set the access associated with NODE to ACCESS. */
+
+#define SET_BINFO_ACCESS(NODE, ACCESS) \
+ ((TREE_LANG_FLAG_1 (NODE) = (ACCESS & 2) != 0), \
+ (TREE_LANG_FLAG_6 (NODE) = (ACCESS & 1) != 0))
+
/* Called from access_in_type via dfs_walk. Calculate the access to
DATA (which is really a DECL) in BINFO. */
@@ -823,18 +830,18 @@ dfs_access_in_type (binfo, data)
{
tree decl = (tree) data;
tree type = BINFO_TYPE (binfo);
- tree access = NULL_TREE;
+ access_kind access = ak_none;
if (context_for_name_lookup (decl) == type)
{
/* If we have desceneded to the scope of DECL, just note the
appropriate access. */
if (TREE_PRIVATE (decl))
- access = access_private_node;
+ access = ak_private;
else if (TREE_PROTECTED (decl))
- access = access_protected_node;
+ access = ak_protected;
else
- access = access_public_node;
+ access = ak_public;
}
else
{
@@ -844,9 +851,10 @@ dfs_access_in_type (binfo, data)
DECL_ACCESS. */
if (DECL_LANG_SPECIFIC (decl))
{
- access = purpose_member (type, DECL_ACCESS (decl));
- if (access)
- access = TREE_VALUE (access);
+ tree decl_access = purpose_member (type, DECL_ACCESS (decl));
+ if (decl_access)
+ access = ((access_kind)
+ TREE_INT_CST_LOW (TREE_VALUE (decl_access)));
}
if (!access)
@@ -862,35 +870,36 @@ dfs_access_in_type (binfo, data)
for (i = 0; i < n_baselinks; ++i)
{
tree base_binfo = TREE_VEC_ELT (binfos, i);
- tree base_access = TREE_CHAIN (canonical_binfo (base_binfo));
+ access_kind base_access
+ = BINFO_ACCESS (canonical_binfo (base_binfo));
- if (!base_access || base_access == access_private_node)
+ if (base_access == ak_none || base_access == ak_private)
/* If it was not accessible in the base, or only
accessible as a private member, we can't access it
all. */
- base_access = NULL_TREE;
+ base_access = ak_none;
else if (TREE_VIA_PROTECTED (base_binfo))
/* Public and protected members in the base are
protected here. */
- base_access = access_protected_node;
+ base_access = ak_protected;
else if (!TREE_VIA_PUBLIC (base_binfo))
/* Public and protected members in the base are
private here. */
- base_access = access_private_node;
+ base_access = ak_private;
/* See if the new access, via this base, gives more
access than our previous best access. */
- if (base_access &&
- (base_access == access_public_node
- || (base_access == access_protected_node
- && access != access_public_node)
- || (base_access == access_private_node
- && !access)))
+ if (base_access != ak_none
+ && (base_access == ak_public
+ || (base_access == ak_protected
+ && access != ak_public)
+ || (base_access == ak_private
+ && access == ak_none)))
{
access = base_access;
/* If the new access is public, we can't do better. */
- if (access == access_public_node)
+ if (access == ak_public)
break;
}
}
@@ -898,7 +907,7 @@ dfs_access_in_type (binfo, data)
}
/* Note the access to DECL in TYPE. */
- TREE_CHAIN (binfo) = access;
+ SET_BINFO_ACCESS (binfo, access);
/* Mark TYPE as visited so that if we reach it again we do not
duplicate our efforts here. */
@@ -909,7 +918,7 @@ dfs_access_in_type (binfo, data)
/* Return the access to DECL in TYPE. */
-static tree
+static access_kind
access_in_type (type, decl)
tree type;
tree decl;
@@ -931,7 +940,7 @@ access_in_type (type, decl)
dfs_walk (binfo, dfs_unmark, shared_marked_p, 0);
assert_canonical_unmarked (binfo);
- return TREE_CHAIN (binfo);
+ return BINFO_ACCESS (binfo);
}
/* Called from dfs_accessible_p via dfs_walk. */
@@ -962,17 +971,14 @@ dfs_accessible_p (binfo, data)
void *data;
{
int protected_ok = data != 0;
- tree access;
+ access_kind access;
- /* We marked the binfos while computing the access in each type.
- So, we unmark as we go now. */
SET_BINFO_MARKED (binfo);
-
- access = TREE_CHAIN (binfo);
- if (access == access_public_node
- || (access == access_protected_node && protected_ok))
+ access = BINFO_ACCESS (binfo);
+ if (access == ak_public || (access == ak_protected && protected_ok))
return binfo;
- else if (access && is_friend (BINFO_TYPE (binfo), current_scope ()))
+ else if (access != ak_none
+ && is_friend (BINFO_TYPE (binfo), current_scope ()))
return binfo;
return NULL_TREE;
@@ -987,7 +993,7 @@ protected_accessible_p (decl, derived, binfo)
tree derived;
tree binfo;
{
- tree access;
+ access_kind access;
/* We're checking this clause from [class.access.base]
@@ -1012,7 +1018,7 @@ protected_accessible_p (decl, derived, binfo)
access = access_in_type (derived, decl);
/* If m is inaccessible in DERIVED, then it's not a P. */
- if (access == NULL_TREE)
+ if (access == ak_none)
return 0;
/* [class.protected]
@@ -1754,12 +1760,11 @@ lookup_fnfields_1 (type, name)
If it ever returns a non-NULL value, that value is immediately
returned and the walk is terminated. At each node FN, is passed a
BINFO indicating the path from the curently visited base-class to
- TYPE. The TREE_CHAINs of the BINFOs may be used for scratch space;
- they are otherwise unused. Before each base-class is walked QFN is
- called. If the value returned is non-zero, the base-class is
- walked; otherwise it is not. If QFN is NULL, it is treated as a
- function which always returns 1. Both FN and QFN are passed the
- DATA whenever they are called. */
+ TYPE. Before each base-class is walked QFN is called. If the
+ value returned is non-zero, the base-class is walked; otherwise it
+ is not. If QFN is NULL, it is treated as a function which always
+ returns 1. Both FN and QFN are passed the DATA whenever they are
+ called. */
static tree
bfs_walk (binfo, fn, qfn, data)
@@ -2196,97 +2201,6 @@ dfs_skip_nonprimary_vbases_markedp (binfo, data)
return markedp (binfo, NULL);
}
-/* Called via dfs_walk from mark_primary_bases. */
-
-static tree
-dfs_mark_primary_bases (binfo, data)
- tree binfo;
- void *data;
-{
- int i;
- tree base_binfo;
-
- if (!CLASSTYPE_HAS_PRIMARY_BASE_P (BINFO_TYPE (binfo)))
- return NULL_TREE;
-
- i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
- base_binfo = BINFO_BASETYPE (binfo, i);
-
- if (!TREE_VIA_VIRTUAL (base_binfo))
- /* Non-virtual base classes are easy. */
- BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
- else
- {
- tree shared_binfo;
-
- shared_binfo
- = BINFO_FOR_VBASE (BINFO_TYPE (base_binfo), (tree) data);
-
- /* If this virtual base is not already primary somewhere else in
- the hiearchy, then we'll be using this copy. */
- if (!BINFO_VBASE_PRIMARY_P (shared_binfo)
- && !BINFO_VBASE_MARKED (shared_binfo))
- {
- BINFO_VBASE_PRIMARY_P (shared_binfo) = 1;
- BINFO_PRIMARY_MARKED_P (base_binfo) = 1;
- }
- }
-
- return NULL_TREE;
-}
-
-/* Set BINFO_PRIMARY_MARKED_P for all binfos in the hierarchy
- dominated by BINFO that are primary bases. */
-
-void
-mark_primary_bases (type)
- tree type;
-{
- tree vbase;
-
- /* Mark the TYPE_BINFO hierarchy. We need to mark primary bases in
- pre-order to deal with primary virtual bases. (The virtual base
- would be skipped if it were not marked as primary, and that
- requires getting to dfs_mark_primary_bases before
- dfs_skip_nonprimary_vbases_unmarkedp has a chance to skip the
- virtual base.) */
- dfs_walk_real (TYPE_BINFO (type), dfs_mark_primary_bases, NULL,
- dfs_skip_nonprimary_vbases_unmarkedp, type);
-
- /* Now go through the virtual base classes. Any that are not
- already primary will need to be allocated in TYPE, and so we need
- to mark their primary bases. */
- for (vbase = CLASSTYPE_VBASECLASSES (type);
- vbase;
- vbase = TREE_CHAIN (vbase))
- {
- if (BINFO_VBASE_PRIMARY_P (vbase))
- /* This virtual base was already included in the hierarchy, so
- there's nothing to do here. */
- continue;
-
- /* Temporarily pretend that VBASE is primary so that its bases
- will be walked; this is the real copy of VBASE. */
- BINFO_PRIMARY_MARKED_P (vbase) = 1;
-
- /* Now, walk its bases. */
- dfs_walk (vbase, dfs_mark_primary_bases,
- dfs_skip_nonprimary_vbases_unmarkedp, type);
-
- /* VBASE wasn't really primary. */
- BINFO_PRIMARY_MARKED_P (vbase) = 0;
- /* And we don't want to allow it to *become* primary if it is a
- base of some subsequent base class. */
- SET_BINFO_VBASE_MARKED (vbase);
- }
-
- /* Clear the VBASE_MARKED bits we set above. */
- for (vbase = CLASSTYPE_VBASECLASSES (type);
- vbase;
- vbase = TREE_CHAIN (vbase))
- CLEAR_BINFO_VBASE_MARKED (vbase);
-}
-
/* If BINFO is a non-primary virtual baseclass (in the hierarchy
dominated by TYPE), and no primary copy appears anywhere in the
hierarchy, return the shared copy. If a primary copy appears
@@ -2346,30 +2260,6 @@ dfs_marked_real_bases_queue_p (binfo, data)
return binfo ? markedp (binfo, NULL) : NULL_TREE;
}
-/* Like dfs_unmarked_real_bases_queue_p but walks only into things
- that are not BINFO_VTABLE_PATH_MARKED. */
-
-tree
-dfs_vtable_path_unmarked_real_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- binfo = get_shared_vbase_if_not_primary (binfo, data);
- return binfo ? unmarked_vtable_pathp (binfo, NULL): NULL_TREE;
-}
-
-/* Like dfs_unmarked_real_bases_queue_p but walks only into things
- that are BINFO_VTABLE_PATH_MARKED. */
-
-tree
-dfs_vtable_path_marked_real_bases_queue_p (binfo, data)
- tree binfo;
- void *data;
-{
- binfo = get_shared_vbase_if_not_primary (binfo, data);
- return binfo ? marked_vtable_pathp (binfo, NULL): NULL_TREE;
-}
-
/* A queue function that skips all virtual bases (and their
bases). */
@@ -2400,9 +2290,7 @@ dfs_get_pure_virtuals (binfo, data)
{
tree virtuals;
- for (virtuals = skip_rtti_stuff (binfo,
- BINFO_TYPE (binfo),
- NULL);
+ for (virtuals = BINFO_VIRTUALS (binfo);
virtuals;
virtuals = TREE_CHAIN (virtuals))
if (DECL_PURE_VIRTUAL_P (TREE_VALUE (virtuals)))
@@ -2447,7 +2335,7 @@ get_pure_virtuals (type)
{
tree virtuals;
- for (virtuals = skip_rtti_stuff (vbases, BINFO_TYPE (vbases), NULL);
+ for (virtuals = BINFO_VIRTUALS (vbases);
virtuals;
virtuals = TREE_CHAIN (virtuals))
{
@@ -2527,7 +2415,7 @@ unmarkedp (binfo, data)
return !BINFO_MARKED (binfo) ? binfo : NULL_TREE;
}
-static tree
+tree
marked_vtable_pathp (binfo, data)
tree binfo;
void *data ATTRIBUTE_UNUSED;
@@ -2535,7 +2423,7 @@ marked_vtable_pathp (binfo, data)
return BINFO_VTABLE_PATH_MARKED (binfo) ? binfo : NULL_TREE;
}
-static tree
+tree
unmarked_vtable_pathp (binfo, data)
tree binfo;
void *data ATTRIBUTE_UNUSED;
@@ -2605,17 +2493,6 @@ dfs_unmark (binfo, data)
return NULL_TREE;
}
-/* Clear both BINFO_MARKED and BINFO_VBASE_MARKED. */
-
-tree
-dfs_vbase_unmark (binfo, data)
- tree binfo;
- void *data ATTRIBUTE_UNUSED;
-{
- CLEAR_BINFO_VBASE_MARKED (binfo);
- return dfs_unmark (binfo, data);
-}
-
/* Clear BINFO_VTABLE_PATH_MARKED. */
tree
@@ -2809,7 +2686,7 @@ virtual_context (fndecl, t, vbase)
while (path)
{
if (TREE_VIA_VIRTUAL (path))
- return binfo_member (BINFO_TYPE (path), CLASSTYPE_VBASECLASSES (t));
+ return BINFO_FOR_VBASE (BINFO_TYPE (path), t);
path = BINFO_INHERITANCE_CHAIN (path);
}
return 0;
@@ -2863,9 +2740,10 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
*vbase_offsets = delta;
}
- virtuals = skip_rtti_stuff (binfo, BINFO_TYPE (binfo), &n);
-
- while (virtuals)
+ for (virtuals = BINFO_VIRTUALS (binfo),
+ n = first_vfun_index (BINFO_TYPE (binfo));
+ virtuals;
+ virtuals = TREE_CHAIN (virtuals), ++n)
{
tree current_fndecl = TREE_VALUE (virtuals);
@@ -2956,8 +2834,6 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t,
finish_expr_stmt (build_modify_expr (new_delta, NOP_EXPR,
old_delta));
}
- ++n;
- virtuals = TREE_CHAIN (virtuals);
}
}
@@ -3101,7 +2977,7 @@ dfs_get_vbase_types (binfo, data)
{
tree type = (tree) data;
- if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo))
+ if (TREE_VIA_VIRTUAL (binfo))
{
tree new_vbase = make_binfo (size_zero_node,
BINFO_TYPE (binfo),
@@ -3112,24 +2988,50 @@ dfs_get_vbase_types (binfo, data)
BINFO_INHERITANCE_CHAIN (new_vbase) = TYPE_BINFO (type);
TREE_CHAIN (new_vbase) = CLASSTYPE_VBASECLASSES (type);
CLASSTYPE_VBASECLASSES (type) = new_vbase;
- SET_BINFO_VBASE_MARKED (binfo);
}
SET_BINFO_MARKED (binfo);
return NULL_TREE;
}
+/* Called via dfs_walk from mark_primary_bases. Builds the
+ inheritance graph order list of BINFOs. */
+
+static tree
+dfs_build_inheritance_graph_order (binfo, data)
+ tree binfo;
+ void *data;
+{
+ tree *last_binfo = (tree *) data;
+
+ if (*last_binfo)
+ TREE_CHAIN (*last_binfo) = binfo;
+ *last_binfo = binfo;
+ SET_BINFO_MARKED (binfo);
+ return NULL_TREE;
+}
+
/* Set CLASSTYPE_VBASECLASSES for TYPE. */
void
get_vbase_types (type)
tree type;
{
+ tree last_binfo;
+
CLASSTYPE_VBASECLASSES (type) = NULL_TREE;
dfs_walk (TYPE_BINFO (type), dfs_get_vbase_types, unmarkedp, type);
/* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now
reverse it so that we get normal dfs ordering. */
CLASSTYPE_VBASECLASSES (type) = nreverse (CLASSTYPE_VBASECLASSES (type));
- dfs_walk (TYPE_BINFO (type), dfs_vbase_unmark, markedp, 0);
+ dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, 0);
+ /* Thread the BINFOs in inheritance-graph order. */
+ last_binfo = NULL;
+ dfs_walk_real (TYPE_BINFO (type),
+ dfs_build_inheritance_graph_order,
+ NULL,
+ unmarkedp,
+ &last_binfo);
+ dfs_walk (TYPE_BINFO (type), dfs_unmark, markedp, NULL);
}
/* Called from find_vbase_instance via dfs_walk. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 9b2fa8763d6..b2aef8ad65d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -48,6 +48,7 @@
static tree expand_cond PARAMS ((tree));
static tree maybe_convert_cond PARAMS ((tree));
static tree simplify_aggr_init_exprs_r PARAMS ((tree *, int *, void *));
+static void deferred_type_access_control PARAMS ((void));
/* Record the fact that STMT was the last statement added to the
statement tree. */
@@ -1990,8 +1991,8 @@ finish_member_declaration (decl)
= (current_access_specifier == access_protected_node);
if (TREE_CODE (decl) == TEMPLATE_DECL)
{
- TREE_PRIVATE (DECL_RESULT (decl)) = TREE_PRIVATE (decl);
- TREE_PROTECTED (DECL_RESULT (decl)) = TREE_PROTECTED (decl);
+ TREE_PRIVATE (DECL_TEMPLATE_RESULT (decl)) = TREE_PRIVATE (decl);
+ TREE_PROTECTED (DECL_TEMPLATE_RESULT (decl)) = TREE_PROTECTED (decl);
}
/* Mark the DECL as a member of the current class. */
@@ -2726,17 +2727,12 @@ expand_body (fn)
/* If possible, avoid generating RTL for this function. Instead,
just record it as an inline function, and wait until end-of-file
to decide whether to write it out or not. */
- if (/* We have to generate RTL if we can't inline trees. */
- flag_inline_trees
- /* Or if it's not an inline function. */
- && DECL_INLINE (fn)
+ if (/* We have to generate RTL if it's not an inline function. */
+ (DECL_INLINE (fn) || DECL_COMDAT (fn))
/* Or if we have to keep all inline functions anyhow. */
&& !flag_keep_inline_functions
/* Or if we actually have a reference to the function. */
&& !DECL_NEEDED_P (fn)
- /* Or if we're at the end-of-file, and this function is not
- DECL_COMDAT. */
- && (!at_eof || DECL_COMDAT (fn))
/* Or if this is a nested function. */
&& !decl_function_context (fn))
{
@@ -2752,7 +2748,7 @@ expand_body (fn)
}
/* Remember this function. In finish_file we'll decide if
we actually need to write this function out. */
- mark_inline_for_output (fn);
+ defer_fn (fn);
/* Let the back-end know that this funtion exists. */
note_deferral_of_defined_inline_function (fn);
return;
diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc
index 90c3058abaa..0bf9cfe57c6 100644
--- a/gcc/cp/tinfo.cc
+++ b/gcc/cp/tinfo.cc
@@ -66,7 +66,7 @@ convert_to_base (void *addr, bool is_virtual, myint32 offset)
bool std::type_info::
operator== (const std::type_info& arg) const
{
- return (&arg == this) || (strcmp (name (), arg.name ()) == 0);
+ return (&arg == this) || (__builtin_strcmp (name (), arg.name ()) == 0);
}
extern "C" void
@@ -590,6 +590,21 @@ adjust_pointer (const void *base, ptrdiff_t offset)
(reinterpret_cast <const char *> (base) + offset);
}
+// ADDR is a pointer to an object. Convert it to a pointer to a base,
+// using OFFSET. IS_VIRTUAL is true, if we are getting a virtual base.
+inline void const *
+convert_to_base (void const *addr, bool is_virtual, ptrdiff_t offset)
+{
+ if (is_virtual)
+ {
+ const void *vtable = *static_cast <const void *const *> (addr);
+
+ offset = *adjust_pointer<ptrdiff_t> (vtable, offset);
+ }
+
+ return adjust_pointer<void> (addr, offset);
+}
+
// some predicate functions for __class_type_info::sub_kind
inline bool contained_p (__class_type_info::sub_kind access_path)
{
@@ -652,7 +667,7 @@ do_catch (const type_info *thr_type, void **thr_obj,
bool __class_type_info::
do_upcast (const __class_type_info *dst_type, void **obj_ptr) const
{
- upcast_result result (details);
+ upcast_result result (__vmi_class_type_info::flags_unknown_mask);
if (do_upcast (contained_public, dst_type, *obj_ptr, result))
return false;
@@ -706,29 +721,27 @@ do_find_public_src (ptrdiff_t src2dst,
if (obj_ptr == src_ptr && *this == *src_type)
return contained_public;
- for (size_t i = n_bases; i--;)
+ for (size_t i = vmi_base_count; i--;)
{
- if (!base_list[i].is_public_p ())
+ if (!vmi_bases[i].is_public_p ())
continue; // Not public, can't be here.
const void *base = obj_ptr;
- ptrdiff_t offset = base_list[i].offset;
+ ptrdiff_t offset = vmi_bases[i].offset ();
+ bool is_virtual = vmi_bases[i].is_virtual_p ();
- if (base_list[i].is_virtual_p ())
+ if (is_virtual)
{
if (src2dst == -3)
continue; // Not a virtual base, so can't be here.
- const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
-
- offset = vtable[offset];
}
- base = adjust_pointer <void> (base, offset);
+ base = convert_to_base (base, is_virtual, offset);
- sub_kind base_kind = base_list[i].base->do_find_public_src
+ sub_kind base_kind = vmi_bases[i].base->do_find_public_src
(src2dst, base, src_type, src_ptr);
if (contained_p (base_kind))
{
- if (base_list[i].is_virtual_p ())
+ if (is_virtual)
base_kind = sub_kind (base_kind | contained_virtual_mask);
return base_kind;
}
@@ -831,27 +844,23 @@ do_dyncast (ptrdiff_t src2dst,
return false;
}
bool result_ambig = false;
- for (size_t i = n_bases; i--;)
+ for (size_t i = vmi_base_count; i--;)
{
dyncast_result result2;
void const *base = obj_ptr;
sub_kind base_access = access_path;
- ptrdiff_t offset = base_list[i].offset;
+ ptrdiff_t offset = vmi_bases[i].offset ();
+ bool is_virtual = vmi_bases[i].is_virtual_p ();
- if (base_list[i].is_virtual_p ())
- {
- base_access = sub_kind (base_access | contained_virtual_mask);
- const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
-
- offset = vtable[offset];
- }
- base = adjust_pointer <void> (base, offset);
+ if (is_virtual)
+ base_access = sub_kind (base_access | contained_virtual_mask);
+ base = convert_to_base (base, is_virtual, offset);
- if (!base_list[i].is_public_p ())
+ if (!vmi_bases[i].is_public_p ())
base_access = sub_kind (base_access & ~contained_public_mask);
bool result2_ambig
- = base_list[i].base->do_dyncast (src2dst, base_access,
+ = vmi_bases[i].base->do_dyncast (src2dst, base_access,
dst_type, base,
src_type, src_ptr, result2);
result.whole2src = sub_kind (result.whole2src | result2.whole2src);
@@ -1018,44 +1027,40 @@ do_upcast (sub_kind access_path,
return contained_nonpublic_p (access_path);
}
- for (size_t i = n_bases; i--;)
+ int src_details = result.src_details;
+ if (src_details & flags_unknown_mask)
+ src_details = vmi_flags;
+
+ for (size_t i = vmi_base_count; i--;)
{
- upcast_result result2 (result.src_details);
+ upcast_result result2 (src_details);
const void *base = obj_ptr;
sub_kind sub_access = access_path;
- ptrdiff_t offset = base_list[i].offset;
+ ptrdiff_t offset = vmi_bases[i].offset ();
+ bool is_virtual = vmi_bases[i].is_virtual_p ();
- if (!base_list[i].is_public_p ())
+ if (!vmi_bases[i].is_public_p ())
{
- if (!(result.src_details & multiple_base_mask))
+ if (!(src_details & non_diamond_repeat_mask))
// original cannot have an ambiguous base
continue;
sub_access = sub_kind (sub_access & ~contained_public_mask);
}
- if (base_list[i].is_virtual_p ())
- {
- sub_access = sub_kind (sub_access | contained_virtual_mask);
-
- if (base)
- {
- const ptrdiff_t *vtable = *static_cast <const ptrdiff_t *const *> (base);
- offset = vtable[offset];
- }
- }
+ if (is_virtual)
+ sub_access = sub_kind (sub_access | contained_virtual_mask);
if (base)
- base = adjust_pointer <void> (base, offset);
+ base = convert_to_base (base, is_virtual, offset);
- if (base_list[i].base->do_upcast (sub_access, dst, base, result2))
+ if (vmi_bases[i].base->do_upcast (sub_access, dst, base, result2))
return true; // must fail
if (result2.base_type)
{
- if (result2.base_type == nonvirtual_base_type
- && base_list[i].is_virtual_p ())
- result2.base_type = base_list[i].base;
+ if (result2.base_type == nonvirtual_base_type && is_virtual)
+ result2.base_type = vmi_bases[i].base;
if (!result.base_type)
{
result = result2;
- if (!(details & multiple_base_mask))
+ if (!(vmi_flags & non_diamond_repeat_mask))
// cannot have an ambiguous other base
return false;
}
@@ -1100,9 +1105,8 @@ __dynamic_cast (const void *src_ptr, // object started from
{
const void *vtable = *static_cast <const void *const *> (src_ptr);
const vtable_prefix *prefix =
- adjust_pointer <vtable_prefix> (vtable, 0);
- // FIXME: the above offset should be -offsetof (vtable_prefix, origin));
- // but we don't currently layout vtables correctly.
+ adjust_pointer <vtable_prefix> (vtable,
+ -offsetof (vtable_prefix, origin));
const void *whole_ptr =
adjust_pointer <void> (src_ptr, prefix->whole_object);
const __class_type_info *whole_type = prefix->whole_type;
@@ -1120,9 +1124,11 @@ __dynamic_cast (const void *src_ptr, // object started from
if (contained_nonvirtual_p (result.whole2src))
// Found an invalid cross cast, which cannot also be a down cast
return NULL;
+ #if 0 // FIXME: we need to discover this lazily
if (!(whole_type->details & __class_type_info::private_base_mask))
// whole type has no private bases
return const_cast <void *> (result.dst_ptr);
+ #endif
if (result.dst2src == __class_type_info::unknown)
result.dst2src = dst_type->find_public_src (src2dst, result.dst_ptr,
src_type, src_ptr);
diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc
index 1eb3502880e..d137408fb0b 100644
--- a/gcc/cp/tinfo2.cc
+++ b/gcc/cp/tinfo2.cc
@@ -35,7 +35,7 @@ using std::type_info;
bool
type_info::before (const type_info &arg) const
{
- return strcmp (name (), arg.name ()) < 0;
+ return __builtin_strcmp (name (), arg.name ()) < 0;
}
// type info for pointer type.
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d1c7d2d54ae..d5e0a5d667a 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -921,11 +921,12 @@ debug_binfo (elem)
debug_tree (BINFO_TYPE (elem));
if (BINFO_VTABLE (elem))
fprintf (stderr, "vtable decl \"%s\"\n",
- IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem))));
+ IDENTIFIER_POINTER (DECL_NAME (get_vtbl_decl_for_binfo (elem))));
else
fprintf (stderr, "no vtable decl yet\n");
fprintf (stderr, "virtuals:\n");
- virtuals = skip_rtti_stuff (elem, BINFO_TYPE (elem), &n);
+ virtuals = BINFO_VIRTUALS (elem);
+ n = first_vfun_index (BINFO_TYPE (elem));
while (virtuals)
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index fe6d2664b90..74f16b7a8ad 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2577,11 +2577,11 @@ build_x_function_call (function, params, decl)
if ((TREE_CODE (function) == FUNCTION_DECL
&& DECL_STATIC_FUNCTION_P (function))
|| (TREE_CODE (function) == TEMPLATE_DECL
- && DECL_STATIC_FUNCTION_P (DECL_RESULT (function))))
- return build_member_call(DECL_CONTEXT (function),
- template_id
- ? template_id : DECL_NAME (function),
- params);
+ && DECL_STATIC_FUNCTION_P (DECL_TEMPLATE_RESULT (function))))
+ return build_member_call (DECL_CONTEXT (function),
+ template_id
+ ? template_id : DECL_NAME (function),
+ params);
is_method = ((TREE_CODE (function) == TREE_LIST
&& current_class_type != NULL_TREE
@@ -3960,11 +3960,10 @@ build_binary_op (code, orig_op0, orig_op1)
/* OK */;
/* Do not warn if the signed quantity is an unsuffixed
integer literal (or some static constant expression
+ involving such literals or a conditional expression
involving such literals) and it is non-negative. */
- else if ((op0_signed && TREE_CODE (orig_op0) == INTEGER_CST
- && tree_int_cst_sgn (orig_op0) >= 0)
- || (op1_signed && TREE_CODE (orig_op1) == INTEGER_CST
- && tree_int_cst_sgn (orig_op1) >= 0))
+ else if ((op0_signed && tree_expr_nonnegative_p (orig_op0))
+ || (op1_signed && tree_expr_nonnegative_p (orig_op1)))
/* OK */;
/* Do not warn if the comparison is an equality operation,
the unsigned quantity is an integral constant and it does
@@ -4279,18 +4278,8 @@ build_component_addr (arg, argtype)
/* This conversion is harmless. */
rval = convert_force (argtype, rval, 0);
- if (! integer_zerop (bit_position (field)))
- {
- tree offset = size_binop (EASY_DIV_EXPR, bit_position (field),
- bitsize_int (BITS_PER_UNIT));
- int flag = TREE_CONSTANT (rval);
-
- offset = convert (sizetype, offset);
- rval = fold (build (PLUS_EXPR, argtype,
- rval, cp_convert (argtype, offset)));
- TREE_CONSTANT (rval) = flag;
- }
- return rval;
+ return fold (build (PLUS_EXPR, argtype, rval,
+ cp_convert (argtype, byte_position (field))));
}
/* Construct and perhaps optimize a tree representation
diff --git a/gcc/cpp.texi b/gcc/cpp.texi
index 0d2b2ee335f..e0442a1c46c 100644
--- a/gcc/cpp.texi
+++ b/gcc/cpp.texi
@@ -138,6 +138,7 @@ and this may cause problems with other languages.
@node Global Actions, Directives, Top, Top
@section Transformations Made Globally
+@cindex ASCII NUL handling
Most C preprocessor features are inactive unless you give specific directives
to request their use. (Preprocessing directives are lines starting with
@@ -214,6 +215,43 @@ This exception is relevant only if you use the @samp{-trigraphs}
option to enable trigraph processing. @xref{Invocation}.
@end itemize
+The preprocessor handles null characters embedded in the input file
+depending upon the context in which the null appears. Note that here we
+are referring not to the two-character escape sequence "\0", but to the
+single character ASCII NUL.
+
+There are three different contexts in which a null character may
+appear:-
+
+@itemize @bullet
+@item
+Within comments. Here, null characters are silently ignored.
+
+@item
+Within a string or character constant. Here the preprocessor emits a
+warning, but preserves the null character and passes it through to the
+output file.
+
+@item
+In any other context, the preprocessor issues a warning, and discards
+the null character. In all other respects the preprocessor treats it
+like whitespace, combining it with any surrounding whitespace to become
+a single whitespace token. Representing the null character by "^@@",
+this means that code like
+
+@example
+#define X^@@1
+@end example
+
+is equivalent to
+
+@example
+#define X 1
+@end example
+
+and X is defined with replacement text "1".
+@end itemize
+
@node Directives, Header Files, Global Actions, Top
@section Preprocessing Directives
diff --git a/gcc/cpperror.c b/gcc/cpperror.c
index bbb29ed2304..0da2c57075d 100644
--- a/gcc/cpperror.c
+++ b/gcc/cpperror.c
@@ -121,7 +121,8 @@ v_message (pfile, is_error, file, line, col, msg, ap)
cpp_buf_line_and_col (ip, &line, &col);
print_containing_files (pfile, ip);
- print_file_and_line (file, line, col);
+ print_file_and_line (file, line,
+ CPP_OPTION (pfile, show_column) ? col : 0);
}
else
fprintf (stderr, "%s: ", progname);
@@ -217,7 +218,7 @@ cpp_error VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->inhibit_errors)
+ if (CPP_OPTION (pfile, inhibit_errors))
return;
v_message (pfile, 1, NULL, -1, -1, msgid, ap);
@@ -245,7 +246,7 @@ cpp_error_with_line VPARAMS ((cpp_reader *pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->inhibit_errors)
+ if (CPP_OPTION (pfile, inhibit_errors))
return;
v_message (pfile, 1, NULL, line, column, msgid, ap);
@@ -277,7 +278,7 @@ cpp_warning VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->inhibit_warnings)
+ if (CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, 0, NULL, -1, -1, msgid, ap);
@@ -305,7 +306,7 @@ cpp_warning_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->inhibit_warnings)
+ if (CPP_OPTION (pfile, inhibit_warnings))
return;
v_message (pfile, 0, NULL, line, column, msgid, ap);
@@ -328,12 +329,12 @@ cpp_pedwarn VPARAMS ((cpp_reader * pfile, const char *msgid, ...))
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->pedantic_errors
- ? CPP_OPTIONS (pfile)->inhibit_errors
- : CPP_OPTIONS (pfile)->inhibit_warnings)
+ if (CPP_OPTION (pfile, pedantic_errors)
+ ? CPP_OPTION (pfile, inhibit_errors)
+ : CPP_OPTION (pfile, inhibit_warnings))
return;
- v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
+ v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
NULL, -1, -1, msgid, ap);
va_end(ap);
}
@@ -359,12 +360,12 @@ cpp_pedwarn_with_line VPARAMS ((cpp_reader * pfile, int line, int column,
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->pedantic_errors
- ? CPP_OPTIONS (pfile)->inhibit_errors
- : CPP_OPTIONS (pfile)->inhibit_warnings)
+ if (CPP_OPTION (pfile, pedantic_errors)
+ ? CPP_OPTION (pfile, inhibit_errors)
+ : CPP_OPTION (pfile, inhibit_warnings))
return;
- v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
+ v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
NULL, line, column, msgid, ap);
va_end(ap);
}
@@ -396,12 +397,12 @@ cpp_pedwarn_with_file_and_line VPARAMS ((cpp_reader *pfile,
msgid = va_arg (ap, const char *);
#endif
- if (CPP_OPTIONS (pfile)->pedantic_errors
- ? CPP_OPTIONS (pfile)->inhibit_errors
- : CPP_OPTIONS (pfile)->inhibit_warnings)
+ if (CPP_OPTION (pfile, pedantic_errors)
+ ? CPP_OPTION (pfile, inhibit_errors)
+ : CPP_OPTION (pfile, inhibit_warnings))
return;
- v_message (pfile, CPP_OPTIONS (pfile)->pedantic_errors,
+ v_message (pfile, CPP_OPTION (pfile, pedantic_errors),
file, line, col, msgid, ap);
va_end(ap);
}
diff --git a/gcc/cppexp.c b/gcc/cppexp.c
index 4d1cf10eeb6..31790999eef 100644
--- a/gcc/cppexp.c
+++ b/gcc/cppexp.c
@@ -62,8 +62,8 @@ Written by Per Bothner 1994. */
#endif
#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)
+ ? (~(~(HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \
+ : ~ (HOST_WIDEST_INT) 0)
#define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \
? ~(~(HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \
@@ -73,6 +73,8 @@ Written by Per Bothner 1994. */
number with SUM's sign, where A, B, and SUM are all C integers. */
#define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0)
+typedef short op_t;
+
static void integer_overflow PARAMS ((cpp_reader *));
static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT,
unsigned int,
@@ -88,7 +90,7 @@ static struct operation parse_defined PARAMS ((cpp_reader *));
static HOST_WIDEST_INT parse_escape PARAMS ((cpp_reader *, U_CHAR **,
HOST_WIDEST_INT));
static struct operation lex PARAMS ((cpp_reader *, int));
-
+static const char * op_to_str PARAMS ((op_t, char *));
#define ERROR 299
#define OROR 300
@@ -102,21 +104,15 @@ static struct operation lex PARAMS ((cpp_reader *, int));
#define NAME 308
#define INT 309
#define CHAR 310
-
-#define LEFT_OPERAND_REQUIRED 1
-#define RIGHT_OPERAND_REQUIRED 2
-#define HAVE_VALUE 4
-/* SKIP_OPERAND is set for '&&' '||' '?' and ':' when the
- following operand should be short-circuited instead of evaluated. */
-#define SKIP_OPERAND 8
+#define FINISHED 311
struct operation
{
- short op;
- U_CHAR rprio; /* Priority of op (relative to it right operand). */
+ op_t op;
+ U_CHAR prio; /* Priority of op. */
U_CHAR flags;
- U_CHAR unsignedp; /* true if value should be treated as unsigned */
- HOST_WIDEST_INT value; /* The value logically "right" of op. */
+ U_CHAR unsignedp; /* True if value should be treated as unsigned. */
+ HOST_WIDEST_INT value; /* The value logically "right" of op. */
};
/* Parse and convert an integer for #if. Accepts decimal, hex, or octal
@@ -163,7 +159,8 @@ parse_number (pfile, start, end)
if (c >= '0' && c <= '9')
digit = c - '0';
- else if (base == 16 && c >= 'a' && c <= 'f') /* FIXME: assumes ASCII */
+ /* FIXME: assumes ASCII */
+ else if (base == 16 && c >= 'a' && c <= 'f')
digit = c - 'a' + 10;
else if (base == 16 && c >= 'A' && c <= 'F')
digit = c - 'A' + 10;
@@ -171,7 +168,7 @@ parse_number (pfile, start, end)
{
/* It's a float since it contains a point. */
cpp_error (pfile,
- "floating point numbers are not allowed in #if expressions");
+ "floating point numbers are not allowed in #if expressions");
goto error;
}
else
@@ -185,9 +182,9 @@ parse_number (pfile, start, end)
op.unsignedp++;
else
{
- /* Decrement p here so that the error for an invalid number
- will be generated below in the case where this is the
- last character in the buffer. */
+ /* Decrement p here so that the error for an invalid
+ number will be generated below in the case where
+ this is the last character in the buffer. */
p--;
break;
}
@@ -211,19 +208,20 @@ parse_number (pfile, start, end)
cpp_error (pfile, "invalid number in #if expression");
goto error;
}
- else if (spec_long > (CPP_OPTIONS (pfile)->c89 ? 1 : 2))
+ else if (spec_long > (CPP_OPTION (pfile, c89) ? 1 : 2))
{
- cpp_error (pfile, "too many `l' suffixes in integer constant");
+ cpp_error (pfile, "too many 'l' suffixes in integer constant");
goto error;
}
else if (op.unsignedp > 1)
{
- cpp_error (pfile, "too many `u' suffixes in integer constant");
+ cpp_error (pfile, "too many 'u' suffixes in integer constant");
goto error;
}
if (base <= largest_digit)
- cpp_pedwarn (pfile, "integer constant contains digits beyond the radix");
+ cpp_pedwarn (pfile,
+ "integer constant contains digits beyond the radix");
if (overflow)
cpp_pedwarn (pfile, "integer constant out of range");
@@ -276,14 +274,15 @@ parse_charconst (pfile, start, end)
while (ptr < end)
{
c = *ptr++;
- if (c == '\'' || c == '\0')
+ if (c == '\'')
break;
else if (c == '\\')
{
c = parse_escape (pfile, &ptr, mask);
if (width < HOST_BITS_PER_INT
&& (unsigned int) c >= (unsigned int)(1 << width))
- cpp_pedwarn (pfile, "escape sequence out of range for character");
+ cpp_pedwarn (pfile,
+ "escape sequence out of range for character");
}
/* Merge character into result; ignore excess chars. */
@@ -379,19 +378,20 @@ parse_defined (pfile)
oops:
CPP_SET_WRITTEN (pfile, old_written);
pfile->no_macro_expand--;
- cpp_error (pfile, "`defined' without an identifier");
+ cpp_error (pfile, "'defined' without an identifier");
op.op = ERROR;
return op;
}
-
-struct token {
+struct token
+{
const char *operator;
- int token;
+ op_t token;
};
-static const struct token tokentab2[] = {
+static const struct token tokentab2[] =
+{
{"&&", ANDAND},
{"||", OROR},
{"<<", LSH},
@@ -434,7 +434,8 @@ lex (pfile, skip_evaluation)
return parse_number (pfile, tok_start, tok_end);
case CPP_STRING:
case CPP_WSTRING:
- cpp_error (pfile, "string constants are not allowed in #if expressions");
+ cpp_error (pfile,
+ "string constants are not allowed in #if expressions");
op.op = ERROR;
return op;
@@ -450,8 +451,8 @@ lex (pfile, skip_evaluation)
op.unsignedp = 0;
op.value = 0;
- if (CPP_OPTIONS (pfile)->warn_undef && !skip_evaluation)
- cpp_warning (pfile, "`%.*s' is not defined",
+ if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation)
+ cpp_warning (pfile, "'%.*s' is not defined",
(int) (tok_end - tok_start), tok_start);
return op;
@@ -470,7 +471,7 @@ lex (pfile, skip_evaluation)
&& tok_start[1] == toktab->operator[1])
break;
if (toktab->token == ERROR)
- cpp_error (pfile, "`%s' not allowed in operand of `#if'",
+ cpp_error (pfile, "'%s' not allowed in operand of #if",
tok_start);
op.op = toktab->token;
return op;
@@ -482,6 +483,27 @@ lex (pfile, skip_evaluation)
}
}
+/* Convert an operator ID to a string. BUFF is a buffer at least 5
+ characters long which might be used to store the string. */
+/* XXX FIXME: Remove BUFF when new lexer is implemented. */
+static const char *
+op_to_str (op, buff)
+ op_t op;
+ char *buff;
+{
+ const struct token *toktab;
+
+ /* See if it is a special token of length 2. */
+ for (toktab = tokentab2; toktab->operator != NULL; toktab++)
+ if (op == toktab->token)
+ return toktab->operator;
+
+ if (ISGRAPH (op))
+ sprintf (buff, "%c", (int) op);
+ else
+ sprintf (buff, "\\%03o", (int) op);
+ return buff;
+}
/* Parse a C escape sequence. STRING_PTR points to a variable
containing a pointer to the string to parse. That pointer
@@ -512,8 +534,8 @@ parse_escape (pfile, string_ptr, result_mask)
return TARGET_BS;
case 'e':
case 'E':
- if (CPP_OPTIONS (pfile)->pedantic)
- cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, `\\%c'", c);
+ if (CPP_PEDANTIC (pfile))
+ cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, '\\%c'", c);
return TARGET_ESC;
case 'f':
return TARGET_FF;
@@ -643,27 +665,88 @@ right_shift (pfile, a, unsignedp, b)
return a >> b;
}
-/* These priorities are all even, so we can handle associatively. */
-#define PAREN_INNER_PRIO 0
-#define COMMA_PRIO 4
-#define COND_PRIO (COMMA_PRIO+2)
-#define OROR_PRIO (COND_PRIO+2)
-#define ANDAND_PRIO (OROR_PRIO+2)
-#define OR_PRIO (ANDAND_PRIO+2)
-#define XOR_PRIO (OR_PRIO+2)
-#define AND_PRIO (XOR_PRIO+2)
-#define EQUAL_PRIO (AND_PRIO+2)
-#define LESS_PRIO (EQUAL_PRIO+2)
-#define SHIFT_PRIO (LESS_PRIO+2)
-#define PLUS_PRIO (SHIFT_PRIO+2)
-#define MUL_PRIO (PLUS_PRIO+2)
-#define UNARY_PRIO (MUL_PRIO+2)
-#define PAREN_OUTER_PRIO (UNARY_PRIO+2)
+/* Operator precedence and flags table.
+
+After an operator is returned from the lexer, if it has priority less
+than or equal to the operator on the top of the stack, we reduce the
+stack by one operator and repeat the test. Since equal priorities
+reduce, this is naturally left-associative.
+
+We handle right-associative operators by clearing the lower bit of all
+left-associative operators, and setting it for right-associative ones.
+After the reduction phase of a new operator, just before it is pushed
+onto the stack, its RIGHT_ASSOC bit is cleared. The effect is that
+during the reduction phase, the current right-associative operator has
+a priority one greater than any other operator of otherwise equal
+precedence that has been pushed on the top of the stack. This avoids
+a reduction pass, and effectively makes the logic right-associative.
+
+The remaining cases are '(' and ')'. We handle '(' by skipping the
+reduction phase completely. ')' is given lower priority than
+everything else, including '(', effectively forcing a reduction of the
+parenthesised expression. If there is no matching '(', the stack will
+be reduced all the way to the beginning, exiting the parser in the
+same way as the ultra-low priority end-of-expression dummy operator.
+The exit code checks to see if the operator that caused it is ')', and
+if so outputs an appropriate error message.
+
+The parser assumes all shifted operators require a right operand
+unless the flag NO_R_OPERAND is set, and similarly for NO_L_OPERAND.
+These semantics are automatically checked, any extra semantics need to
+be handled with operator-specific code. */
+
+#define FLAG_BITS 8
+#define FLAG_MASK ((1 << FLAG_BITS) - 1)
+#define PRIO_SHIFT (FLAG_BITS + 1)
+#define EXTRACT_PRIO(cnst) (cnst >> FLAG_BITS)
+#define EXTRACT_FLAGS(cnst) (cnst & FLAG_MASK)
+
+/* Flags. */
+#define HAVE_VALUE (1 << 0)
+#define NO_L_OPERAND (1 << 1)
+#define NO_R_OPERAND (1 << 2)
+#define SHORT_CIRCUIT (1 << 3)
+
+/* Priority and flag combinations. */
+#define RIGHT_ASSOC (1 << FLAG_BITS)
+#define FORCE_REDUCE_PRIO (0 << PRIO_SHIFT)
+#define CLOSE_PAREN_PRIO (1 << PRIO_SHIFT)
+#define OPEN_PAREN_PRIO ((2 << PRIO_SHIFT) | NO_L_OPERAND)
+#define COMMA_PRIO (3 << PRIO_SHIFT)
+#define COND_PRIO ((4 << PRIO_SHIFT) | RIGHT_ASSOC | SHORT_CIRCUIT)
+#define COLON_PRIO ((5 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define OROR_PRIO ((6 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define ANDAND_PRIO ((7 << PRIO_SHIFT) | SHORT_CIRCUIT)
+#define OR_PRIO (8 << PRIO_SHIFT)
+#define XOR_PRIO (9 << PRIO_SHIFT)
+#define AND_PRIO (10 << PRIO_SHIFT)
+#define EQUAL_PRIO (11 << PRIO_SHIFT)
+#define LESS_PRIO (12 << PRIO_SHIFT)
+#define SHIFT_PRIO (13 << PRIO_SHIFT)
+#define PLUS_PRIO (14 << PRIO_SHIFT)
+#define MUL_PRIO (15 << PRIO_SHIFT)
+#define UNARY_PRIO ((16 << PRIO_SHIFT) | RIGHT_ASSOC | NO_L_OPERAND)
#define COMPARE(OP) \
- top->unsignedp = 0;\
- top->value = (unsigned1 || unsigned2) \
- ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 : (v1 OP v2)
+ top->unsignedp = 0; \
+ top->value = (unsigned1 | unsigned2) \
+ ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 \
+ : (v1 OP v2)
+#define EQUALITY(OP) \
+ top->value = v1 OP v2; \
+ top->unsignedp = 0;
+#define LOGICAL(OP) \
+ top->value = v1 OP v2; \
+ top->unsignedp = unsigned1 | unsigned2;
+
+/* With -O2, gcc appears to produce nice code, moving the error
+ message load and subsequent jump completely out of the main path. */
+#define CPP_ICE(msgid) \
+ do { cpp_ice (pfile, msgid); goto syntax_error; } while(0)
+#define SYNTAX_ERROR(msgid) \
+ do { cpp_error (pfile, msgid); goto syntax_error; } while(0)
+#define SYNTAX_ERROR2(msgid, arg) \
+ do { cpp_error (pfile, msgid, arg); goto syntax_error; } while(0)
/* Parse and evaluate a C expression, reading from PFILE.
Returns the truth value of the expression. */
@@ -672,8 +755,8 @@ int
_cpp_parse_expr (pfile)
cpp_reader *pfile;
{
- /* The implementation is an operator precedence parser,
- i.e. a bottom-up parser, using a stack for not-yet-reduced tokens.
+ /* The implementation is an operator precedence parser, i.e. a
+ bottom-up parser, using a stack for not-yet-reduced tokens.
The stack base is 'stack', and the current stack pointer is 'top'.
There is a stack element for each operator (only),
@@ -686,117 +769,115 @@ _cpp_parse_expr (pfile)
struct operation init_stack[INIT_STACK_SIZE];
struct operation *stack = init_stack;
struct operation *limit = stack + INIT_STACK_SIZE;
- register struct operation *top = stack;
- unsigned int lprio, rprio = 0;
- int skip_evaluation = 0;
+ register struct operation *top = stack + 1;
long old_written = CPP_WRITTEN (pfile);
+ int skip_evaluation = 0;
int result;
+ char buff[5];
pfile->parsing_if_directive++;
- top->rprio = 0;
- top->flags = 0;
+ /* We've finished when we try to reduce this. */
+ top->op = FINISHED;
+ /* Nifty way to catch missing '('. */
+ top->prio = EXTRACT_PRIO(CLOSE_PAREN_PRIO);
+ /* Avoid missing right operand checks. */
+ top->flags = NO_R_OPERAND;
+
for (;;)
{
+ unsigned int prio;
+ unsigned int flags;
struct operation op;
- U_CHAR flags = 0;
/* Read a token */
- op = lex (pfile, skip_evaluation);
-
- /* See if the token is an operand, in which case go to set_value.
- If the token is an operator, figure out its left and right
- priorities, and then goto maybe_reduce. */
+ op = lex (pfile, skip_evaluation);
+ /* If the token is an operand, push its value and get next
+ token. If it is an operator, get its priority and flags, and
+ try to reduce the expression on the stack. */
switch (op.op)
{
case NAME:
- cpp_ice (pfile, "lex returns a NAME");
- goto syntax_error;
- case INT: case CHAR:
- goto set_value;
- case 0:
- lprio = 0; goto maybe_reduce;
- case '+': case '-':
- if (top->flags & HAVE_VALUE)
- {
- lprio = PLUS_PRIO;
- goto binop;
- }
- /* else fall through */
- case '!': case '~':
- flags = RIGHT_OPERAND_REQUIRED;
- rprio = UNARY_PRIO; lprio = rprio + 1; goto maybe_reduce;
- case '*': case '/': case '%':
- lprio = MUL_PRIO; goto binop;
- case '<': case '>': case LEQ: case GEQ:
- lprio = LESS_PRIO; goto binop;
- case EQUAL: case NOTEQUAL:
- lprio = EQUAL_PRIO; goto binop;
- case LSH: case RSH:
- lprio = SHIFT_PRIO; goto binop;
- case '&': lprio = AND_PRIO; goto binop;
- case '^': lprio = XOR_PRIO; goto binop;
- case '|': lprio = OR_PRIO; goto binop;
- case ANDAND: lprio = ANDAND_PRIO; goto binop;
- case OROR: lprio = OROR_PRIO; goto binop;
- case ',':
- lprio = COMMA_PRIO; goto binop;
- case '(':
- lprio = PAREN_OUTER_PRIO; rprio = PAREN_INNER_PRIO;
- goto maybe_reduce;
- case ')':
- lprio = PAREN_INNER_PRIO; rprio = PAREN_OUTER_PRIO;
- goto maybe_reduce;
- case ':':
- lprio = COND_PRIO; rprio = COND_PRIO;
- goto maybe_reduce;
- case '?':
- lprio = COND_PRIO + 1; rprio = COND_PRIO;
- goto maybe_reduce;
+ CPP_ICE ("lex returns a NAME");
case ERROR:
goto syntax_error;
- default:
- cpp_error (pfile, "invalid character in #if");
+ case '#':
+ /* We get '#' when get_directive_token hits a syntactically
+ invalid assertion predicate. _cpp_parse_assertion has
+ already issued an error. */
goto syntax_error;
- }
+ default:
+ SYNTAX_ERROR ("invalid character in #if");
- set_value:
- /* Push a value onto the stack. */
- if (top->flags & HAVE_VALUE)
- {
- cpp_error (pfile, "syntax error in #if");
- goto syntax_error;
+ push_immediate:
+ case INT:
+ case CHAR:
+ /* Push a value onto the stack. */
+ if (top->flags & HAVE_VALUE)
+ SYNTAX_ERROR ("missing binary operator");
+ top->value = op.value;
+ top->unsignedp = op.unsignedp;
+ top->flags |= HAVE_VALUE;
+ continue;
+
+ case '+':
+ case '-': prio = PLUS_PRIO; if (top->flags & HAVE_VALUE) break;
+ /* else unary; fall through */
+ case '!':
+ case '~': prio = UNARY_PRIO; break;
+
+ case '*':
+ case '/':
+ case '%': prio = MUL_PRIO; break;
+ case '<':
+ case '>':
+ case LEQ:
+ case GEQ: prio = LESS_PRIO; break;
+ case NOTEQUAL:
+ case EQUAL: prio = EQUAL_PRIO; break;
+ case LSH:
+ case RSH: prio = SHIFT_PRIO; break;
+ case '&': prio = AND_PRIO; break;
+ case '^': prio = XOR_PRIO; break;
+ case '|': prio = OR_PRIO; break;
+ case ANDAND: prio = ANDAND_PRIO; break;
+ case OROR: prio = OROR_PRIO; break;
+ case ',': prio = COMMA_PRIO; break;
+ case '(': prio = OPEN_PAREN_PRIO; break;
+ case ')': prio = CLOSE_PAREN_PRIO; break;
+ case ':': prio = COLON_PRIO; break;
+ case '?': prio = COND_PRIO; break;
+ case 0: prio = FORCE_REDUCE_PRIO; break;
}
- top->value = op.value;
- top->unsignedp = op.unsignedp;
- top->flags |= HAVE_VALUE;
- continue;
-
- binop:
- flags = LEFT_OPERAND_REQUIRED|RIGHT_OPERAND_REQUIRED;
- rprio = lprio + 1;
-
- maybe_reduce:
- /* Push an operator, and check if we can reduce now. */
- while (top->rprio > lprio)
+
+ /* Separate the operator's code into priority and flags. */
+ flags = EXTRACT_FLAGS(prio);
+ prio = EXTRACT_PRIO(prio);
+ if (op.op == '(')
+ goto skip_reduction;
+
+ /* Check for reductions. Then push the operator. */
+ while (prio <= top->prio)
{
- HOST_WIDEST_INT v1 = top[-1].value, v2 = top[0].value;
- unsigned int unsigned1 = top[-1].unsignedp;
- unsigned int unsigned2 = top[0].unsignedp;
- top--;
- if ((top[1].flags & LEFT_OPERAND_REQUIRED)
- && ! (top[0].flags & HAVE_VALUE))
- {
- cpp_error (pfile, "syntax error - missing left operand");
- goto syntax_error;
- }
- if ((top[1].flags & RIGHT_OPERAND_REQUIRED)
- && ! (top[1].flags & HAVE_VALUE))
+ HOST_WIDEST_INT v1, v2;
+ unsigned int unsigned1, unsigned2;
+
+ /* Most operators that can appear on the stack require a
+ right operand. Check this before trying to reduce. */
+ if ((top->flags & (HAVE_VALUE | NO_R_OPERAND)) == 0)
{
- cpp_error (pfile, "syntax error - missing right operand");
- goto syntax_error;
+ if (top->op == '(')
+ SYNTAX_ERROR ("void expression between '(' and ')'");
+ else
+ SYNTAX_ERROR2 ("operator '%s' has no right operand",
+ op_to_str (top->op, buff));
}
- /* top[0].value = (top[1].op)(v1, v2);*/
+
+ unsigned2 = top->unsignedp, v2 = top->value;
+ top--;
+ unsigned1 = top->unsignedp, v1 = top->value;
+
+ /* Now set top->value = (top[1].op)(v1, v2); */
switch (top[1].op)
{
case '+':
@@ -809,7 +890,7 @@ _cpp_parse_expr (pfile)
else
{
top->value = v1 + v2;
- top->unsignedp = unsigned1 || unsigned2;
+ top->unsignedp = unsigned1 | unsigned2;
if (! top->unsignedp && ! skip_evaluation
&& ! possible_sum_sign (v1, v2, top->value))
integer_overflow (pfile);
@@ -819,7 +900,8 @@ _cpp_parse_expr (pfile)
if (!(top->flags & HAVE_VALUE))
{ /* Unary '-' */
top->value = - v2;
- if (!skip_evaluation && (top->value & v2) < 0 && !unsigned2)
+ if (!skip_evaluation && (top->value & v2) < 0
+ && !unsigned2)
integer_overflow (pfile);
top->unsignedp = unsigned2;
top->flags |= HAVE_VALUE;
@@ -827,89 +909,66 @@ _cpp_parse_expr (pfile)
else
{ /* Binary '-' */
top->value = v1 - v2;
- top->unsignedp = unsigned1 || unsigned2;
+ top->unsignedp = unsigned1 | unsigned2;
if (! top->unsignedp && ! skip_evaluation
&& ! possible_sum_sign (top->value, v2, v1))
integer_overflow (pfile);
}
break;
case '*':
- top->unsignedp = unsigned1 || unsigned2;
+ top->unsignedp = unsigned1 | unsigned2;
if (top->unsignedp)
top->value = (unsigned HOST_WIDEST_INT) v1 * v2;
else if (!skip_evaluation)
{
top->value = v1 * v2;
- if (v1
- && (top->value / v1 != v2
- || (top->value & v1 & v2) < 0))
+ if (v1 && (top->value / v1 != v2
+ || (top->value & v1 & v2) < 0))
integer_overflow (pfile);
}
break;
case '/':
+ case '%':
if (skip_evaluation)
break;
if (v2 == 0)
+ SYNTAX_ERROR ("division by zero in #if");
+ top->unsignedp = unsigned1 | unsigned2;
+ if (top[1].op == '/')
{
- cpp_error (pfile, "division by zero in #if");
- v2 = 1;
+ if (top->unsignedp)
+ top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
+ else
+ {
+ top->value = v1 / v2;
+ if ((top->value & v1 & v2) < 0)
+ integer_overflow (pfile);
+ }
}
- top->unsignedp = unsigned1 || unsigned2;
- if (top->unsignedp)
- top->value = (unsigned HOST_WIDEST_INT) v1 / v2;
else
{
- top->value = v1 / v2;
- if ((top->value & v1 & v2) < 0)
- integer_overflow (pfile);
- }
- break;
- case '%':
- if (skip_evaluation)
- break;
- if (v2 == 0)
- {
- cpp_error (pfile, "division by zero in #if");
- v2 = 1;
+ if (top->unsignedp)
+ top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
+ else
+ top->value = v1 % v2;
}
- top->unsignedp = unsigned1 || unsigned2;
- if (top->unsignedp)
- top->value = (unsigned HOST_WIDEST_INT) v1 % v2;
- else
- top->value = v1 % v2;
break;
case '!':
- if (top->flags & HAVE_VALUE)
- {
- cpp_error (pfile, "syntax error");
- goto syntax_error;
- }
top->value = ! v2;
top->unsignedp = 0;
top->flags |= HAVE_VALUE;
break;
case '~':
- if (top->flags & HAVE_VALUE)
- {
- cpp_error (pfile, "syntax error");
- goto syntax_error;
- }
top->value = ~ v2;
top->unsignedp = unsigned2;
top->flags |= HAVE_VALUE;
break;
case '<': COMPARE(<); break;
case '>': COMPARE(>); break;
- case LEQ: COMPARE(<=); break;
- case GEQ: COMPARE(>=); break;
- case EQUAL:
- top->value = (v1 == v2);
- top->unsignedp = 0;
- break;
- case NOTEQUAL:
- top->value = (v1 != v2);
- top->unsignedp = 0;
- break;
+ case LEQ: COMPARE(<=); break;
+ case GEQ: COMPARE(>=); break;
+ case EQUAL: EQUALITY(==); break;
+ case NOTEQUAL: EQUALITY(!=); break;
case LSH:
if (skip_evaluation)
break;
@@ -928,9 +987,6 @@ _cpp_parse_expr (pfile)
else
top->value = right_shift (pfile, v1, unsigned1, v2);
break;
-#define LOGICAL(OP) \
- top->value = v1 OP v2;\
- top->unsignedp = unsigned1 || unsigned2;
case '&': LOGICAL(&); break;
case '^': LOGICAL(^); break;
case '|': LOGICAL(|); break;
@@ -944,70 +1000,68 @@ _cpp_parse_expr (pfile)
break;
case ',':
if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "comma operator in operand of `#if'");
+ cpp_pedwarn (pfile, "comma operator in operand of #if");
top->value = v2;
top->unsignedp = unsigned2;
break;
- case '(': case '?':
- cpp_error (pfile, "syntax error in #if");
- goto syntax_error;
+ case '?':
+ SYNTAX_ERROR ("syntax error '?' without following ':'");
case ':':
if (top[0].op != '?')
- {
- cpp_error (pfile,
- "syntax error ':' without preceding '?'");
- goto syntax_error;
- }
- else if (! (top[1].flags & HAVE_VALUE)
- || !(top[-1].flags & HAVE_VALUE)
- || !(top[0].flags & HAVE_VALUE))
- {
- cpp_error (pfile, "bad syntax for ?: operator");
- goto syntax_error;
- }
- else
- {
- top--;
- if (top->value) skip_evaluation--;
- top->value = top->value ? v1 : v2;
- top->unsignedp = unsigned1 || unsigned2;
- }
- break;
- case ')':
- if ((top[1].flags & HAVE_VALUE)
- || ! (top[0].flags & HAVE_VALUE)
- || top[0].op != '('
- || (top[-1].flags & HAVE_VALUE))
- {
- cpp_error (pfile, "mismatched parentheses in #if");
- goto syntax_error;
- }
- else
- {
- top--;
- top->value = v1;
- top->unsignedp = unsigned1;
- top->flags |= HAVE_VALUE;
- }
+ SYNTAX_ERROR ("syntax error ':' without preceding '?'");
+ top--;
+ if (top->value) skip_evaluation--;
+ top->value = top->value ? v1 : v2;
+ top->unsignedp = unsigned1 | unsigned2;
break;
+ case '(':
+ if (op.op != ')')
+ SYNTAX_ERROR ("missing ')' in expression");
+ op.value = v2;
+ op.unsignedp = unsigned2;
+ goto push_immediate;
default:
- if (ISGRAPH (top[1].op))
- cpp_error (pfile, "unimplemented operator '%c'\n", top[1].op);
- else
- cpp_error (pfile, "unimplemented operator '\\%03o'\n",
- top[1].op);
+ SYNTAX_ERROR2 ("unimplemented operator '%s'",
+ op_to_str (top[1].op, buff));
+ case FINISHED:
+ /* Reducing this dummy operator indicates we've finished. */
+ if (op.op == ')')
+ SYNTAX_ERROR ("missing '(' in expression");
+ goto done;
}
}
- if (op.op == 0)
+
+ /* Handle short-circuit evaluations. */
+ if (flags & SHORT_CIRCUIT)
+ switch (op.op)
+ {
+ case OROR: if (top->value) skip_evaluation++; break;
+ case ANDAND:
+ case '?': if (!top->value) skip_evaluation++; break;
+ case ':':
+ if (top[-1].value) /* Was '?' condition true? */
+ skip_evaluation++;
+ else
+ skip_evaluation--;
+ }
+
+ skip_reduction:
+ /* Check we have a left operand iff we need one. */
+ if (flags & NO_L_OPERAND)
{
- if (top != stack)
- cpp_ice (pfile, "unbalanced stack in #if expression");
- result = (top->value != 0);
- goto done;
+ if (top->flags & HAVE_VALUE)
+ SYNTAX_ERROR2 ("missing binary operator before '%s'",
+ op_to_str (op.op, buff));
}
- top++;
-
+ else
+ {
+ if (!(top->flags & HAVE_VALUE))
+ SYNTAX_ERROR2 ("operator '%s' has no left operand",
+ op_to_str (op.op, buff));
+ }
+
/* Check for and handle stack overflow. */
+ top++;
if (top == limit)
{
struct operation *new_stack;
@@ -1026,29 +1080,26 @@ _cpp_parse_expr (pfile)
}
top->flags = flags;
- top->rprio = rprio;
+ top->prio = prio & ~EXTRACT_PRIO(RIGHT_ASSOC);
top->op = op.op;
- if ((op.op == OROR && top[-1].value)
- || (op.op == ANDAND && !top[-1].value)
- || (op.op == '?' && !top[-1].value))
- {
- skip_evaluation++;
- }
- else if (op.op == ':')
- {
- if (top[-2].value) /* Was condition true? */
- skip_evaluation++;
- else
- skip_evaluation--;
- }
}
- syntax_error:
- _cpp_skip_rest_of_line (pfile);
- result = 0;
+
done:
- pfile->parsing_if_directive--;
- CPP_SET_WRITTEN (pfile, old_written);
+ result = (top[1].value != 0);
+ if (top != stack)
+ CPP_ICE ("unbalanced stack in #if expression");
+ else if (!(top[1].flags & HAVE_VALUE))
+ {
+ SYNTAX_ERROR ("#if with no expression");
+ syntax_error:
+ _cpp_skip_rest_of_line (pfile);
+ result = 0; /* Return 0 on syntax error. */
+ }
+
+ /* Free dynamic stack if we allocated one. */
if (stack != init_stack)
free (stack);
+ pfile->parsing_if_directive--;
+ CPP_SET_WRITTEN (pfile, old_written);
return result;
}
diff --git a/gcc/cppfiles.c b/gcc/cppfiles.c
index bc137a93708..2be195aa90c 100644
--- a/gcc/cppfiles.c
+++ b/gcc/cppfiles.c
@@ -66,18 +66,8 @@ static unsigned int
hash_IHASH (x)
const void *x;
{
- IHASH *i = (IHASH *)x;
- unsigned int r = 0, len = 0;
- const U_CHAR *s = i->nshort;
-
- if (i->hash != (unsigned long)-1)
- return i->hash;
-
- do
- len++, r = r * 67 + (*s++ - 113);
- while (*s && *s != '.');
- i->hash = r + len;
- return r + len;
+ const IHASH *i = (const IHASH *)x;
+ return i->hash;
}
/* Compare an existing IHASH structure with a potential one. */
@@ -158,8 +148,9 @@ cpp_included (pfile, fname)
{
IHASH dummy, *ptr;
dummy.nshort = fname;
- dummy.hash = -1;
- ptr = htab_find (pfile->all_include_files, (const void *)&dummy);
+ dummy.hash = _cpp_calc_hash (fname, strlen (fname));
+ ptr = htab_find_with_hash (pfile->all_include_files,
+ (const void *)&dummy, dummy.hash);
return (ptr != NULL);
}
@@ -219,11 +210,12 @@ find_include_file (pfile, fname, search_start, ihash, before)
int f;
char *name;
- dummy.hash = -1;
dummy.nshort = fname;
+ dummy.hash = _cpp_calc_hash (fname, strlen (fname));
path = (fname[0] == '/') ? ABSOLUTE_PATH : search_start;
- slot = (IHASH **) htab_find_slot (pfile->all_include_files,
- (const void *)&dummy, 1);
+ slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
+ (const void *)&dummy,
+ dummy.hash, 1);
if (*slot && (ih = redundant_include_p (pfile, *slot, path)))
{
@@ -251,7 +243,7 @@ find_include_file (pfile, fname, search_start, ihash, before)
name[path->nlen] = '/';
strcpy (&name[path->nlen+1], fname);
_cpp_simplify_pathname (name);
- if (CPP_OPTIONS (pfile)->remap)
+ if (CPP_OPTION (pfile, remap))
name = remap_filename (pfile, name, path);
f = open_include_file (pfile, name);
@@ -280,10 +272,20 @@ find_include_file (pfile, fname, search_start, ihash, before)
}
else
{
- ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
- + strlen (fname) + 1);
- ih->nshort = ih->name + strlen (fname) + 1;
- strcpy ((char *)ih->nshort, fname);
+ char *s;
+
+ if ((s = strstr (name, fname)) != NULL)
+ {
+ ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name));
+ ih->nshort = ih->name + (s - name);
+ }
+ else
+ {
+ ih = (IHASH *) xmalloc (sizeof (IHASH) + strlen (name)
+ + strlen (fname) + 1);
+ ih->nshort = ih->name + strlen (name) + 1;
+ strcpy ((char *)ih->nshort, fname);
+ }
}
strcpy ((char *)ih->name, name);
ih->foundhere = path;
@@ -367,7 +369,7 @@ read_name_map (pfile, dirname)
char *name;
FILE *f;
- for (map_list_ptr = CPP_OPTIONS (pfile)->map_list; map_list_ptr;
+ for (map_list_ptr = CPP_OPTION (pfile, map_list); map_list_ptr;
map_list_ptr = map_list_ptr->map_list_next)
if (! strcmp (map_list_ptr->map_list_name, dirname))
return map_list_ptr->map_list_map;
@@ -427,8 +429,8 @@ read_name_map (pfile, dirname)
fclose (f);
}
- map_list_ptr->map_list_next = CPP_OPTIONS (pfile)->map_list;
- CPP_OPTIONS (pfile)->map_list = map_list_ptr;
+ map_list_ptr->map_list_next = CPP_OPTION (pfile, map_list);
+ CPP_OPTION (pfile, map_list) = map_list_ptr;
return map_list_ptr->map_list_map;
}
@@ -509,9 +511,9 @@ _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
if (!search_start)
{
if (angle_brackets)
- search_start = CPP_OPTIONS (pfile)->bracket_include;
- else if (CPP_OPTIONS (pfile)->ignore_srcdir)
- search_start = CPP_OPTIONS (pfile)->quote_include;
+ search_start = CPP_OPTION (pfile, bracket_include);
+ else if (CPP_OPTION (pfile, ignore_srcdir))
+ search_start = CPP_OPTION (pfile, quote_include);
else
search_start = CPP_BUFFER (pfile)->actual_dir;
}
@@ -534,7 +536,7 @@ _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
if (fd == -1)
{
- if (CPP_OPTIONS (pfile)->print_deps_missing_files
+ if (CPP_OPTION (pfile, print_deps_missing_files)
&& CPP_PRINT_DEPS (pfile) > (angle_brackets ||
(pfile->system_include_depth > 0)))
{
@@ -546,10 +548,10 @@ _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
struct file_name_list *ptr;
/* If requested as a system header, assume it belongs in
the first system header directory. */
- if (CPP_OPTIONS (pfile)->bracket_include)
- ptr = CPP_OPTIONS (pfile)->bracket_include;
+ if (CPP_OPTION (pfile, bracket_include))
+ ptr = CPP_OPTION (pfile, bracket_include);
else
- ptr = CPP_OPTIONS (pfile)->quote_include;
+ ptr = CPP_OPTION (pfile, quote_include);
p = (char *) alloca (strlen (ptr->name)
+ strlen (fname) + 2);
@@ -584,7 +586,7 @@ _cpp_execute_include (pfile, fname, len, no_reinclude, search_start)
deps_add_dep (pfile->deps, ihash->name);
/* Handle -H option. */
- if (CPP_OPTIONS(pfile)->print_include_names)
+ if (CPP_OPTION (pfile, print_include_names))
{
cpp_buffer *fp = CPP_BUFFER (pfile);
while ((fp = CPP_PREV_BUFFER (fp)) != NULL)
@@ -620,10 +622,15 @@ cpp_read_file (pfile, fname)
if (fname == NULL)
fname = "";
- dummy.hash = -1;
dummy.nshort = fname;
- slot = (IHASH **) htab_find_slot (pfile->all_include_files,
- (const void *) &dummy, 1);
+ /* _cpp_calc_hash doesn't like zero-length strings. */
+ if (*fname == 0)
+ dummy.hash = 0;
+ else
+ dummy.hash = _cpp_calc_hash (fname, strlen (fname));
+ slot = (IHASH **) htab_find_slot_with_hash (pfile->all_include_files,
+ (const void *) &dummy,
+ dummy.hash, 1);
if (*slot && (ih = redundant_include_p (pfile, *slot, ABSOLUTE_PATH)))
{
if (ih == (IHASH *)-1)
@@ -735,18 +742,17 @@ read_include_file (pfile, fd, ihash)
ihash->control_macro = (const U_CHAR *) ""; /* never re-include */
close (fd);
- fp->rlimit = fp->alimit = fp->buf + length;
+ fp->rlimit = fp->buf + length;
fp->cur = fp->buf;
if (ihash->foundhere != ABSOLUTE_PATH)
fp->system_header_p = ihash->foundhere->sysp;
fp->lineno = 1;
- fp->colno = 1;
fp->line_base = fp->buf;
fp->cleanup = file_cleanup;
/* The ->actual_dir field is only used when ignore_srcdir is not in effect;
see do_include */
- if (!CPP_OPTIONS (pfile)->ignore_srcdir)
+ if (!CPP_OPTION (pfile, ignore_srcdir))
fp->actual_dir = actual_directory (pfile, ihash->name);
pfile->input_stack_listing_current = 0;
@@ -812,7 +818,7 @@ actual_directory (pfile, fname)
x = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
x->name = dir;
x->nlen = dlen;
- x->next = CPP_OPTIONS (pfile)->quote_include;
+ x->next = CPP_OPTION (pfile, quote_include);
x->alloc = pfile->actual_dirs;
x->sysp = CPP_BUFFER (pfile)->system_header_p;
x->name_map = NULL;
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index 236a94273fa..4578ca728f2 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -45,10 +45,6 @@ static enum cpp_token macarg PARAMS ((cpp_reader *, int));
static struct tm *timestamp PARAMS ((cpp_reader *));
static void special_symbol PARAMS ((HASHNODE *, cpp_reader *));
-#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
-#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
-#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
-
/* Initial hash table size. (It can grow if necessary - see hashtab.c.) */
#define HASHSIZE 500
@@ -99,26 +95,30 @@ struct argdata
int stringified_length;
};
-/* Calculate hash of a HASHNODE structure. */
-static unsigned int
-hash_HASHNODE (x)
- const void *x;
+/* Calculate hash of a string of length LEN. */
+unsigned int
+_cpp_calc_hash (str, len)
+ const U_CHAR *str;
+ size_t len;
{
- HASHNODE *h = (HASHNODE *)x;
- const U_CHAR *s = h->name;
- unsigned int len = h->length;
- unsigned int n = len, r = 0;
+ size_t n = len;
+ unsigned int r = 0;
- if (h->hash != (unsigned long)-1)
- return h->hash;
-
do
- r = r * 67 + (*s++ - 113);
+ r = r * 67 + (*str++ - 113);
while (--n);
- h->hash = r + len;
return r + len;
}
+/* Calculate hash of a HASHNODE structure. */
+static unsigned int
+hash_HASHNODE (x)
+ const void *x;
+{
+ const HASHNODE *h = (const HASHNODE *)x;
+ return h->hash;
+}
+
/* Compare two HASHNODE structures. */
static int
eq_HASHNODE (x, y)
@@ -192,9 +192,10 @@ _cpp_lookup (pfile, name, len)
dummy.name = name;
dummy.length = len;
- dummy.hash = -1;
+ dummy.hash = _cpp_calc_hash (name, len);
- return (HASHNODE *) htab_find (pfile->hashtab, (void *)&dummy);
+ return (HASHNODE *) htab_find_with_hash (pfile->hashtab,
+ (void *)&dummy, dummy.hash);
}
/* Find the hashtable slot for name "name". Used to insert or delete. */
@@ -218,9 +219,11 @@ _cpp_lookup_slot (pfile, name, len, insert, hash)
dummy.name = name;
dummy.length = len;
- dummy.hash = -1;
+ dummy.hash = _cpp_calc_hash (name, len);
- slot = (HASHNODE **) htab_find_slot (pfile->hashtab, (void *)&dummy, insert);
+ slot = (HASHNODE **) htab_find_slot_with_hash (pfile->hashtab,
+ (void *)&dummy,
+ dummy.hash, insert);
if (insert)
*hash = dummy.hash;
return slot;
@@ -249,7 +252,7 @@ _cpp_free_definition (d)
nextap = ap->next;
free (ap);
}
- if (d->nargs >= 0)
+ if (d->argnames)
free (d->argnames);
free (d);
}
@@ -259,7 +262,7 @@ macro_cleanup (pbuf, pfile)
cpp_buffer *pbuf;
cpp_reader *pfile ATTRIBUTE_UNUSED;
{
- HASHNODE *macro = (HASHNODE *) pbuf->data;
+ HASHNODE *macro = pbuf->macro;
if (macro->type == T_DISABLED)
macro->type = T_MACRO;
if (macro->type != T_MACRO || pbuf->buf != macro->value.defn->expansion)
@@ -307,26 +310,18 @@ collect_expansion (pfile, arglist)
last -= 2; /* two extra chars for the leading escape */
for (;;)
{
- /* We use cpp_get_token because _cpp_get_directive_token would
- discard whitespace and we can't cope with that yet. Macro
- expansion is off, so we are guaranteed not to see POP or EOF. */
-
- while (PEEKC () == '\r')
- {
- FORWARD (1);
- CPP_BUMP_LINE (pfile);
- }
- if (PEEKC () == '\n')
- goto done;
+ /* Macro expansion is off, so we are guaranteed not to see POP
+ or EOF. */
here = CPP_WRITTEN (pfile);
- token = cpp_get_token (pfile);
+ token = _cpp_get_define_token (pfile);
tok = pfile->token_buffer + here;
switch (token)
{
case CPP_POP:
case CPP_EOF:
+ cpp_ice (pfile, "EOF in collect_expansion");
+ /* fall through */
case CPP_VSPACE:
- cpp_ice (pfile, "EOF or VSPACE in collect_expansion");
goto done;
case CPP_HSPACE:
@@ -336,8 +331,13 @@ collect_expansion (pfile, arglist)
break;
case CPP_STRINGIZE:
+ /* # is not special in object-like macros. It is special in
+ function-like macros with no args. (6.10.3.2 para 1.) */
+ if (arglist == NULL)
+ goto norm;
+ /* # is not special immediately after PASTE.
+ (Implied by 6.10.3.3 para 4.) */
if (last_token == PASTE)
- /* Not really a stringifier. */
goto norm;
last_token = STRIZE;
CPP_SET_WRITTEN (pfile, here); /* delete from replacement text */
@@ -374,11 +374,13 @@ collect_expansion (pfile, arglist)
case CPP_COMMENT:
/* We must be in -traditional mode. Pretend this was a
token paste, but only if there was no leading or
- trailing space. */
+ trailing space and it's in the middle of the line.
+ _cpp_lex_token won't return a COMMENT if there was trailing
+ space. */
CPP_SET_WRITTEN (pfile, here);
- if (is_hspace (pfile->token_buffer[here-1]))
+ if (last_token == START)
break;
- if (is_hspace (PEEKC ()))
+ if (is_hspace (pfile->token_buffer[here-1]))
break;
if (last_token == ARG)
endpat->raw_after = 1;
@@ -390,7 +392,7 @@ collect_expansion (pfile, arglist)
if (last_token == STRIZE)
cpp_error (pfile, "`#' is not followed by a macro argument name");
- if (CPP_TRADITIONAL (pfile) || CPP_OPTIONS (pfile)->warn_stringify)
+ if (CPP_TRADITIONAL (pfile) || CPP_WTRADITIONAL (pfile))
goto maybe_trad_stringify;
else
goto norm;
@@ -464,7 +466,7 @@ collect_expansion (pfile, arglist)
(int) argv[i].len, argv[i].name);
continue;
}
- if (CPP_OPTIONS (pfile)->warn_stringify)
+ if (CPP_WTRADITIONAL (pfile))
cpp_warning (pfile, "macro argument `%.*s' is stringified",
(int) argv[i].len, argv[i].name);
@@ -598,7 +600,7 @@ collect_formal_parameters (pfile)
cpp_error (pfile, "duplicate macro argument name `%s'", tok);
continue;
}
- if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->c99
+ if (CPP_PEDANTIC (pfile) && CPP_OPTION (pfile, c99)
&& len == sizeof "__VA_ARGS__" - 1
&& !strncmp (tok, "__VA_ARGS__", len))
cpp_pedwarn (pfile,
@@ -645,7 +647,7 @@ collect_formal_parameters (pfile)
those elsewhere. */
if (argv[argc].len == 0)
{
- if (CPP_PEDANTIC (pfile) && ! CPP_OPTIONS (pfile)->c99)
+ if (CPP_PEDANTIC (pfile) && ! CPP_OPTION (pfile, c99))
cpp_pedwarn (pfile, "C89 does not permit varargs macros");
len = sizeof "__VA_ARGS__" - 1;
@@ -722,38 +724,21 @@ _cpp_create_definition (pfile, funlike)
cpp_buf_line_and_col (CPP_BUFFER (pfile), &line, &col);
file = CPP_BUFFER (pfile)->nominal_fname;
- pfile->no_macro_expand++;
- pfile->parsing_define_directive++;
- CPP_OPTIONS (pfile)->discard_comments++;
- CPP_OPTIONS (pfile)->no_line_commands++;
-
if (funlike)
{
args = collect_formal_parameters (pfile);
if (args == 0)
- goto err;
+ return 0;
}
defn = collect_expansion (pfile, args);
if (defn == 0)
- goto err;
+ return 0;
defn->line = line;
defn->file = file;
defn->col = col;
-
- pfile->no_macro_expand--;
- pfile->parsing_define_directive--;
- CPP_OPTIONS (pfile)->discard_comments--;
- CPP_OPTIONS (pfile)->no_line_commands--;
return defn;
-
- err:
- pfile->no_macro_expand--;
- pfile->parsing_define_directive--;
- CPP_OPTIONS (pfile)->discard_comments--;
- CPP_OPTIONS (pfile)->no_line_commands--;
- return 0;
}
/*
@@ -1053,8 +1038,8 @@ _cpp_macroexpand (pfile, hp)
rest_args = 0;
/* Skip over the opening parenthesis. */
- CPP_OPTIONS (pfile)->discard_comments++;
- CPP_OPTIONS (pfile)->no_line_commands++;
+ CPP_OPTION (pfile, discard_comments)++;
+ CPP_OPTION (pfile, no_line_commands)++;
pfile->no_macro_expand++;
pfile->no_directives++;
@@ -1086,8 +1071,8 @@ _cpp_macroexpand (pfile, hp)
i++;
}
while (token == CPP_COMMA);
- CPP_OPTIONS (pfile)->discard_comments--;
- CPP_OPTIONS (pfile)->no_line_commands--;
+ CPP_OPTION (pfile, discard_comments)--;
+ CPP_OPTION (pfile, no_line_commands)--;
pfile->no_macro_expand--;
pfile->no_directives--;
if (token != CPP_RPAREN)
@@ -1430,6 +1415,18 @@ unsafe_chars (pfile, c1, c2)
{
switch (c1)
{
+ case EOF:
+ /* We don't know what the previous character was. We do know
+ that it can't have been an idchar (or else it would have been
+ pasted with the idchars of the macro name), and there are a
+ number of second characters for which it doesn't matter what
+ the first was. */
+ if (is_idchar (c2) || c2 == '\'' || c2 == '\"'
+ || c2 == '(' || c2 == '[' || c2 == '{'
+ || c2 == ')' || c2 == ']' || c2 == '}')
+ return 0;
+ return 1;
+
case '+': case '-':
if (c2 == c1 || c2 == '=')
return 1;
@@ -1441,7 +1438,7 @@ unsafe_chars (pfile, c1, c2)
goto letter;
case '$':
- if (CPP_OPTIONS (pfile)->dollars_in_ident)
+ if (CPP_OPTION (pfile, dollars_in_ident))
goto letter;
return 0;
@@ -1472,17 +1469,14 @@ unsafe_chars (pfile, c1, c2)
}
static void
-push_macro_expansion (pfile, xbuf, xbuf_len, hp)
+push_macro_expansion (pfile, xbuf, len, hp)
cpp_reader *pfile;
register U_CHAR *xbuf;
- int xbuf_len;
+ int len;
HASHNODE *hp;
{
- register cpp_buffer *mbuf = cpp_push_buffer (pfile, xbuf, xbuf_len);
- if (mbuf == NULL)
- return;
- mbuf->cleanup = macro_cleanup;
- mbuf->data = hp;
+ cpp_buffer *mbuf;
+ int advance_cur = 0;
/* The first chars of the expansion should be a "\r " added by
collect_expansion. This is to prevent accidental token-pasting
@@ -1491,34 +1485,31 @@ push_macro_expansion (pfile, xbuf, xbuf_len, hp)
We would like to avoid adding unneeded spaces (for the sake of
tools that use cpp, such as imake). In some common cases we can
- tell that it is safe to omit the space.
-
- The character before the macro invocation cannot have been an
- idchar (or else it would have been pasted with the idchars of
- the macro name). Therefore, if the first non-space character
- of the expansion is an idchar, we do not need the extra space
- to prevent token pasting.
-
- Also, we don't need the extra space if the first char is '(',
- or some other (less common) characters. */
+ tell that it is safe to omit the space. */
if (xbuf[0] == '\r' && xbuf[1] == ' '
- && (is_idchar(xbuf[2]) || xbuf[2] == '(' || xbuf[2] == '\''
- || xbuf[2] == '\"'))
- mbuf->cur += 2;
+ && !unsafe_chars (pfile, EOF, xbuf[2]))
+ advance_cur = 1;
/* Likewise, avoid the extra space at the end of the macro expansion
if this is safe. We can do a better job here since we can know
what the next char will be. */
- if (xbuf_len >= 3
- && mbuf->rlimit[-2] == '\r'
- && mbuf->rlimit[-1] == ' ')
+ if (len >= 3
+ && xbuf[len-2] == '\r'
+ && xbuf[len-1] == ' ')
{
- int c1 = mbuf->rlimit[-3];
- int c2 = CPP_BUF_PEEK (CPP_PREV_BUFFER (CPP_BUFFER (pfile)));
- if (c2 == EOF || !unsafe_chars (pfile, c1, c2))
- mbuf->rlimit -= 2;
+ int c = CPP_BUF_PEEK (CPP_BUFFER (pfile));
+ if (c == EOF || !unsafe_chars (pfile, xbuf[len-3], c))
+ len -= 2;
}
+
+ mbuf = cpp_push_buffer (pfile, xbuf, len);
+ if (mbuf == NULL)
+ return;
+ if (advance_cur)
+ mbuf->cur += 2;
+ mbuf->cleanup = macro_cleanup;
+ mbuf->macro = hp;
}
/* Return zero if two DEFINITIONs are isomorphic. */
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index 704cab47d87..abf0d2bc120 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -98,7 +98,7 @@ enum node_type
T_MACRO, /* macro defined by `#define' */
T_DISABLED, /* macro temporarily turned off for rescan */
T_POISON, /* macro defined with `#pragma poison' */
- T_UNUSED /* Used for something not defined. */
+ T_EMPTY /* macro defined to nothing */
};
/* different kinds of things that can appear in the value field
@@ -172,7 +172,7 @@ typedef struct ihash IHASH;
#define IShspace 0x08 /* ' ' \t \f \v */
#define ISspace 0x10 /* ' ' \t \f \v \n */
-#define _dollar_ok(x) ((x) == '$' && CPP_OPTIONS (pfile)->dollars_in_ident)
+#define _dollar_ok(x) ((x) == '$' && CPP_OPTION (pfile, dollars_in_ident))
#define is_idchar(x) ((_cpp_IStable[x] & ISidnum) || _dollar_ok(x))
#define is_idstart(x) ((_cpp_IStable[x] & ISidstart) || _dollar_ok(x))
@@ -192,11 +192,11 @@ extern unsigned char _cpp_IStable[256];
/* Macros. */
+/* One character lookahead in the input buffer. Note that if this
+ returns EOF, it does *not* necessarily mean the file's end has been
+ reached. */
#define CPP_BUF_PEEK(BUFFER) \
((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur : EOF)
-#define CPP_BUF_GET(BUFFER) \
- ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
-#define CPP_FORWARD(BUFFER, N) ((BUFFER)->cur += (N))
/* Make sure PFILE->token_buffer has space for at least N more characters. */
#define CPP_RESERVE(PFILE, N) \
@@ -223,14 +223,21 @@ extern unsigned char _cpp_IStable[256];
#define CPP_BUMP_LINE(PFILE) CPP_BUMP_BUFFER_LINE(CPP_BUFFER(PFILE))
#define CPP_PREV_BUFFER(BUFFER) ((BUFFER)->prev)
-#define CPP_PRINT_DEPS(PFILE) (CPP_OPTIONS (PFILE)->print_deps)
-#define CPP_TRADITIONAL(PFILE) (CPP_OPTIONS(PFILE)->traditional)
+/* Are we in column 1 right now? Used mainly for -traditional handling
+ of directives. */
+#define CPP_IN_COLUMN_1(PFILE) \
+(CPP_BUFFER (PFILE)->cur - CPP_BUFFER (PFILE)->line_base == 1)
+
+#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
+#define CPP_TRADITIONAL(PFILE) CPP_OPTION (PFILE, traditional)
#define CPP_PEDANTIC(PFILE) \
- (CPP_OPTIONS (PFILE)->pedantic && !CPP_BUFFER (pfile)->system_header_p)
+ (CPP_OPTION (PFILE, pedantic) && !CPP_BUFFER (PFILE)->system_header_p)
+#define CPP_WTRADITIONAL(PF) \
+ (CPP_OPTION (PF, warn_traditional) && !CPP_BUFFER (PF)->system_header_p)
/* CPP_IS_MACRO_BUFFER is true if the buffer contains macro expansion.
(Note that it is false while we're expanding macro *arguments*.) */
-#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->data != NULL)
+#define CPP_IS_MACRO_BUFFER(PBUF) ((PBUF)->macro != NULL)
/* Remember the current position of PFILE so it may be returned to
after looking ahead a bit.
@@ -239,14 +246,18 @@ extern unsigned char _cpp_IStable[256];
may not forget about it and continue parsing. You may not pop a
buffer with an active mark. You may not call CPP_BUMP_LINE while a
mark is active. */
-#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur - (IP)->buf)
-#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->buf + (IP)->mark, \
- (IP)->mark = -1)
+#define CPP_SET_BUF_MARK(IP) ((IP)->mark = (IP)->cur)
+#define CPP_GOTO_BUF_MARK(IP) ((IP)->cur = (IP)->mark, (IP)->mark = 0)
#define CPP_SET_MARK(PFILE) CPP_SET_BUF_MARK(CPP_BUFFER(PFILE))
#define CPP_GOTO_MARK(PFILE) CPP_GOTO_BUF_MARK(CPP_BUFFER(PFILE))
/* ACTIVE_MARK_P is true if there's a live mark in the buffer. */
-#define ACTIVE_MARK_P(PFILE) (CPP_BUFFER (PFILE)->mark != -1)
+#define ACTIVE_MARK_P(PFILE) (CPP_BUFFER (PFILE)->mark != 0)
+
+/* Are mark and point adjacent characters? Used mostly to deal with
+ the somewhat annoying semantic of #define. */
+#define ADJACENT_TO_MARK(PFILE) \
+ (CPP_BUFFER(PFILE)->cur - CPP_BUFFER(PFILE)->mark == 1)
/* Last arg to output_line_command. */
enum file_change_code {same_file, rename_file, enter_file, leave_file};
@@ -255,6 +266,7 @@ enum file_change_code {same_file, rename_file, enter_file, leave_file};
extern HASHNODE *_cpp_make_hashnode PARAMS ((const U_CHAR *, size_t,
enum node_type,
unsigned long));
+extern unsigned int _cpp_calc_hash PARAMS ((const U_CHAR *, size_t));
extern HASHNODE *_cpp_lookup PARAMS ((cpp_reader *,
const U_CHAR *, int));
extern HASHNODE **_cpp_lookup_slot PARAMS ((cpp_reader *,
@@ -293,6 +305,8 @@ extern void _cpp_init_input_buffer PARAMS ((cpp_reader *));
extern void _cpp_grow_token_buffer PARAMS ((cpp_reader *, long));
extern enum cpp_token _cpp_get_directive_token
PARAMS ((cpp_reader *));
+extern enum cpp_token _cpp_get_define_token
+ PARAMS ((cpp_reader *));
/* In cpplib.c */
extern int _cpp_handle_directive PARAMS ((cpp_reader *));
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 419257308a4..f4391ff006d 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -92,7 +92,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
It may be overridden by the various -I and -ixxx options.
#include "file" looks in the same directory as the current file,
- then this list.
+ then this list.
#include <file> just looks in this list.
All these directories are treated as `system' include directories
@@ -213,12 +213,12 @@ static void initialize_builtins PARAMS ((cpp_reader *));
static void append_include_chain PARAMS ((cpp_reader *,
struct cpp_pending *,
char *, int, int));
-static void merge_include_chains PARAMS ((struct cpp_options *));
+static void merge_include_chains PARAMS ((cpp_reader *));
static void dump_special_to_buffer PARAMS ((cpp_reader *, const char *));
static void initialize_dependency_output PARAMS ((cpp_reader *));
static void initialize_standard_includes PARAMS ((cpp_reader *));
-static void new_pending_directive PARAMS ((struct cpp_options *,
+static void new_pending_directive PARAMS ((struct cpp_pending *,
const char *,
cl_directive_handler));
#ifdef HOST_EBCDIC
@@ -243,7 +243,7 @@ enum { QUOTE = 0, BRACKET, SYSTEM, AFTER };
#define ISTABLE unsigned char _cpp_IStable[256] = { 0 }; \
static void init_IStable PARAMS ((void)) { \
unsigned char *x = _cpp_IStable;
-#define END }
+#define END }
#define s(p, v) x[p] = v;
#endif
@@ -265,7 +265,7 @@ ISTABLE
N('1') N('2') N('3') N('4') N('5') N('6') N('7') N('8') N('9') N('0')
- H(' ') H('\t') H('\v') H('\f')
+ H('\0') H(' ') H('\t') H('\v') H('\f')
S('\n')
END
@@ -342,7 +342,7 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
/* Dirs that don't exist are silently ignored. */
if (errno != ENOENT)
cpp_notice_from_errno (pfile, dir);
- else if (CPP_OPTIONS (pfile)->verbose)
+ else if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring nonexistent directory `%s'\n"), dir);
return;
}
@@ -356,7 +356,7 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
len = strlen (dir);
if (len > pfile->max_include_len)
pfile->max_include_len = len;
-
+
new = (struct file_name_list *) xmalloc (sizeof (struct file_name_list));
new->name = dir;
new->nlen = len;
@@ -389,22 +389,24 @@ append_include_chain (pfile, pend, dir, path, cxx_aware)
how?) and possibly preload the include hash. */
static void
-merge_include_chains (opts)
- struct cpp_options *opts;
+merge_include_chains (pfile)
+ cpp_reader *pfile;
{
struct file_name_list *prev, *cur, *other;
struct file_name_list *quote, *brack, *systm, *after;
struct file_name_list *qtail, *btail, *stail, *atail;
- qtail = opts->pending->quote_tail;
- btail = opts->pending->brack_tail;
- stail = opts->pending->systm_tail;
- atail = opts->pending->after_tail;
+ struct cpp_pending *pend = CPP_OPTION (pfile, pending);
- quote = opts->pending->quote_head;
- brack = opts->pending->brack_head;
- systm = opts->pending->systm_head;
- after = opts->pending->after_head;
+ qtail = pend->quote_tail;
+ btail = pend->brack_tail;
+ stail = pend->systm_tail;
+ atail = pend->after_tail;
+
+ quote = pend->quote_head;
+ brack = pend->brack_head;
+ systm = pend->systm_head;
+ after = pend->after_head;
/* Paste together bracket, system, and after include chains. */
if (stail)
@@ -437,7 +439,7 @@ merge_include_chains (opts)
if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev)
{
- if (opts->verbose)
+ if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
cur->name);
@@ -457,7 +459,7 @@ merge_include_chains (opts)
if (INO_T_EQ (cur->ino, other->ino)
&& cur->dev == other->dev)
{
- if (opts->verbose)
+ if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
cur->name);
@@ -476,7 +478,7 @@ merge_include_chains (opts)
{
if (quote == qtail)
{
- if (opts->verbose)
+ if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
quote->name);
@@ -490,7 +492,7 @@ merge_include_chains (opts)
while (cur->next != qtail)
cur = cur->next;
cur->next = brack;
- if (opts->verbose)
+ if (CPP_OPTION (pfile, verbose))
fprintf (stderr, _("ignoring duplicate directory `%s'\n"),
qtail->name);
@@ -504,8 +506,8 @@ merge_include_chains (opts)
else
quote = brack;
- opts->quote_include = quote;
- opts->bracket_include = brack;
+ CPP_OPTION (pfile, quote_include) = quote;
+ CPP_OPTION (pfile, bracket_include) = brack;
}
@@ -528,22 +530,6 @@ dump_special_to_buffer (pfile, macro_name)
CPP_PUTC (pfile, '\n');
}
-/* Initialize a cpp_options structure. */
-void
-cpp_options_init (opts)
- cpp_options *opts;
-{
- memset ((char *) opts, 0, sizeof (struct cpp_options));
-
- opts->dollars_in_ident = 1;
- opts->cplusplus_comments = 1;
- opts->warn_import = 1;
- opts->discard_comments = 1;
-
- opts->pending =
- (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
-}
-
/* Initialize a cpp_reader structure. */
void
cpp_reader_init (pfile)
@@ -555,6 +541,15 @@ cpp_reader_init (pfile)
pfile->token_buffer = (U_CHAR *) xmalloc (pfile->token_buffer_size);
CPP_SET_WRITTEN (pfile, 0);
+ CPP_OPTION (pfile, dollars_in_ident) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, warn_import) = 1;
+ CPP_OPTION (pfile, discard_comments) = 1;
+ CPP_OPTION (pfile, show_column) = 1;
+
+ CPP_OPTION (pfile, pending) =
+ (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending));
+
_cpp_init_macro_hash (pfile);
_cpp_init_include_hash (pfile);
}
@@ -577,8 +572,7 @@ cpp_cleanup (pfile)
if (pfile->input_buffer)
{
free (pfile->input_buffer);
- free (pfile->input_speccase);
- pfile->input_buffer = pfile->input_speccase = NULL;
+ pfile->input_buffer = NULL;
pfile->input_buffer_len = 0;
}
@@ -660,11 +654,12 @@ initialize_builtins (pfile)
val = b->value;
len = strlen (b->name);
- hp = _cpp_make_hashnode (b->name, len, b->type, -1);
+ hp = _cpp_make_hashnode (b->name, len, b->type,
+ _cpp_calc_hash (b->name, len));
hp->value.cpval = val;
*(htab_find_slot (pfile->hashtab, (void *)hp, 1)) = hp;
- if ((b->flags & DUMP) && CPP_OPTIONS (pfile)->debug_output)
+ if ((b->flags & DUMP) && CPP_OPTION (pfile, debug_output))
dump_special_to_buffer (pfile, b->name);
}
@@ -680,24 +675,23 @@ static void
initialize_dependency_output (pfile)
cpp_reader *pfile;
{
- cpp_options *opts = CPP_OPTIONS (pfile);
char *spec, *s, *output_file;
-
+
/* Either of two environment variables can specify output of deps.
Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
where OUTPUT_FILE is the file to write deps info to
and DEPS_TARGET is the target to mention in the deps. */
- if (opts->print_deps == 0)
+ if (CPP_OPTION (pfile, print_deps) == 0)
{
spec = getenv ("DEPENDENCIES_OUTPUT");
if (spec)
- opts->print_deps = 1;
+ CPP_OPTION (pfile, print_deps) = 1;
else
{
spec = getenv ("SUNPRO_DEPENDENCIES");
if (spec)
- opts->print_deps = 2;
+ CPP_OPTION (pfile, print_deps) = 2;
else
return;
}
@@ -706,33 +700,33 @@ initialize_dependency_output (pfile)
s = strchr (spec, ' ');
if (s)
{
- opts->deps_target = s + 1;
+ CPP_OPTION (pfile, deps_target) = s + 1;
output_file = (char *) xmalloc (s - spec + 1);
memcpy (output_file, spec, s - spec);
output_file[s - spec] = 0;
}
else
{
- opts->deps_target = 0;
+ CPP_OPTION (pfile, deps_target) = 0;
output_file = spec;
}
- opts->deps_file = output_file;
- opts->print_deps_append = 1;
+ CPP_OPTION (pfile, deps_file) = output_file;
+ CPP_OPTION (pfile, print_deps_append) = 1;
}
pfile->deps = deps_init ();
/* Print the expected object file name as the target of this Make-rule. */
- if (opts->deps_target)
- deps_add_target (pfile->deps, opts->deps_target);
- else if (*opts->in_fname == 0)
+ if (CPP_OPTION (pfile, deps_target))
+ deps_add_target (pfile->deps, CPP_OPTION (pfile, deps_target));
+ else if (*CPP_OPTION (pfile, in_fname) == 0)
deps_add_target (pfile->deps, "-");
else
- deps_calc_target (pfile->deps, opts->in_fname);
+ deps_calc_target (pfile->deps, CPP_OPTION (pfile, in_fname));
- if (opts->in_fname)
- deps_add_dep (pfile->deps, opts->in_fname);
+ if (CPP_OPTION (pfile, in_fname))
+ deps_add_dep (pfile->deps, CPP_OPTION (pfile, in_fname));
}
/* And another subroutine. This one sets up the standard include path. */
@@ -740,10 +734,9 @@ static void
initialize_standard_includes (pfile)
cpp_reader *pfile;
{
- cpp_options *opts = CPP_OPTIONS (pfile);
char *path;
const struct default_include *p;
- const char *specd_prefix = opts->include_prefix;
+ const char *specd_prefix = CPP_OPTION (pfile, include_prefix);
/* Several environment variables may add to the include search path.
CPATH specifies an additional list of directories to be searched
@@ -753,9 +746,9 @@ initialize_standard_includes (pfile)
GET_ENV_PATH_LIST (path, "CPATH");
if (path != 0 && *path != 0)
- path_include (pfile, opts->pending, path, BRACKET);
+ path_include (pfile, CPP_OPTION (pfile, pending), path, BRACKET);
- switch ((opts->objc << 1) + opts->cplusplus)
+ switch ((CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus))
{
case 0:
GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH");
@@ -771,7 +764,7 @@ initialize_standard_includes (pfile)
break;
}
if (path != 0 && *path != 0)
- path_include (pfile, opts->pending, path, SYSTEM);
+ path_include (pfile, CPP_OPTION (pfile, pending), path, SYSTEM);
/* Search "translated" versions of GNU directories.
These have /usr/local/lib/gcc... replaced by specd_prefix. */
@@ -790,8 +783,8 @@ initialize_standard_includes (pfile)
{
/* Some standard dirs are only for C++. */
if (!p->cplusplus
- || (opts->cplusplus
- && !opts->no_standard_cplusplus_includes))
+ || (CPP_OPTION (pfile, cplusplus)
+ && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
{
/* Does this dir start with the prefix? */
if (!strncmp (p->fname, default_prefix, default_len))
@@ -805,7 +798,7 @@ initialize_standard_includes (pfile)
p->fname + default_len,
flen - default_len + 1);
- append_include_chain (pfile, opts->pending,
+ append_include_chain (pfile, CPP_OPTION (pfile, pending),
str, SYSTEM, p->cxx_aware);
}
}
@@ -817,13 +810,13 @@ initialize_standard_includes (pfile)
{
/* Some standard dirs are only for C++. */
if (!p->cplusplus
- || (opts->cplusplus
- && !opts->no_standard_cplusplus_includes))
+ || (CPP_OPTION (pfile, cplusplus)
+ && !CPP_OPTION (pfile, no_standard_cplusplus_includes)))
{
/* XXX Potential memory leak! */
char *str = xstrdup (update_path (p->fname, p->component));
- append_include_chain (pfile, opts->pending, str, SYSTEM,
- p->cxx_aware);
+ append_include_chain (pfile, CPP_OPTION (pfile, pending),
+ str, SYSTEM, p->cxx_aware);
}
}
}
@@ -839,33 +832,37 @@ cpp_start_read (pfile, fname)
cpp_reader *pfile;
const char *fname;
{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
struct pending_option *p, *q;
/* -MG doesn't select the form of output and must be specified with one of
-M or -MM. -MG doesn't make sense with -MD or -MMD since they don't
inhibit compilation. */
- if (opts->print_deps_missing_files
- && (opts->print_deps == 0 || !opts->no_output))
+ if (CPP_OPTION (pfile, print_deps_missing_files)
+ && (CPP_OPTION (pfile, print_deps) == 0
+ || !CPP_OPTION (pfile, no_output)))
{
cpp_fatal (pfile, "-MG must be specified with one of -M or -MM");
return 0;
}
/* Chill should not be used with -trigraphs. */
- if (opts->chill && opts->trigraphs)
+ if (CPP_OPTION (pfile, chill) && CPP_OPTION (pfile, trigraphs))
{
cpp_warning (pfile, "-lang-chill and -trigraphs are mutually exclusive");
- opts->trigraphs = 0;
+ CPP_OPTION (pfile, trigraphs) = 0;
}
+ /* -Wtraditional is not useful in C++ mode. */
+ if (CPP_OPTION (pfile, cplusplus))
+ CPP_OPTION (pfile, warn_traditional) = 0;
+
/* Set this if it hasn't been set already. */
if (user_label_prefix == NULL)
user_label_prefix = USER_LABEL_PREFIX;
/* Don't bother trying to do macro expansion if we've already done
preprocessing. */
- if (opts->preprocessed)
+ if (CPP_OPTION (pfile, preprocessed))
pfile->no_macro_expand++;
/* Set up the IStable. This doesn't do anything if we were compiled
@@ -874,41 +871,44 @@ cpp_start_read (pfile, fname)
/* Set up the tables used by read_and_prescan. */
_cpp_init_input_buffer (pfile);
-
+
/* Set up the include search path now. */
- if (! opts->no_standard_includes)
+ if (! CPP_OPTION (pfile, no_standard_includes))
initialize_standard_includes (pfile);
- merge_include_chains (opts);
+ merge_include_chains (pfile);
/* With -v, print the list of dirs to search. */
- if (opts->verbose)
+ if (CPP_OPTION (pfile, verbose))
{
struct file_name_list *l;
fprintf (stderr, _("#include \"...\" search starts here:\n"));
- for (l = opts->quote_include; l; l = l->next)
+ for (l = CPP_OPTION (pfile, quote_include); l; l = l->next)
{
- if (l == opts->bracket_include)
+ if (l == CPP_OPTION (pfile, bracket_include))
fprintf (stderr, _("#include <...> search starts here:\n"));
fprintf (stderr, " %s\n", l->name);
}
fprintf (stderr, _("End of search list.\n"));
}
- initialize_dependency_output (pfile);
-
- /* Open the main input file. This must be done before -D processing
- so we have a buffer to stand on. */
- if (opts->in_fname == NULL || *opts->in_fname == 0)
+ /* Open the main input file. This must be done early, so we have a
+ buffer to stand on. */
+ if (CPP_OPTION (pfile, in_fname) == NULL
+ || *CPP_OPTION (pfile, in_fname) == 0)
{
- opts->in_fname = fname;
- if (opts->in_fname == NULL)
- opts->in_fname = "";
+ CPP_OPTION (pfile, in_fname) = fname;
+ if (CPP_OPTION (pfile, in_fname) == NULL)
+ CPP_OPTION (pfile, in_fname) = "";
}
+ if (CPP_OPTION (pfile, out_fname) == NULL)
+ CPP_OPTION (pfile, out_fname) = "";
if (!cpp_read_file (pfile, fname))
return 0;
+ initialize_dependency_output (pfile);
+
/* -D and friends may produce output, which should be identified
as line 0. */
@@ -918,7 +918,7 @@ cpp_start_read (pfile, fname)
initialize_builtins (pfile);
/* Do -U's, -D's and -A's in the order they were seen. */
- p = opts->pending->directive_head;
+ p = CPP_OPTION (pfile, pending)->directive_head;
while (p)
{
(*p->handler) (pfile, p->arg);
@@ -927,10 +927,10 @@ cpp_start_read (pfile, fname)
p = q;
}
- opts->done_initializing = 1;
+ pfile->done_initializing = 1;
CPP_BUFFER (pfile)->lineno = 1;
- if (opts->preprocessed)
+ if (CPP_OPTION (pfile, preprocessed))
/* If we've already processed this code, we want to trust the #line
directives in the input. But we still need to update our line
counter accordingly. */
@@ -942,9 +942,9 @@ cpp_start_read (pfile, fname)
/* The -imacros files can be scanned now, but the -include files
have to be pushed onto the include stack and processed later,
in the main loop calling cpp_get_token. */
-
- opts->no_output++;
- p = opts->pending->imacros_head;
+
+ CPP_OPTION (pfile, no_output)++;
+ p = CPP_OPTION (pfile, pending)->imacros_head;
while (p)
{
if (cpp_read_file (pfile, p->arg))
@@ -954,9 +954,9 @@ cpp_start_read (pfile, fname)
free (p);
p = q;
}
- opts->no_output--;
+ CPP_OPTION (pfile, no_output)--;
- p = opts->pending->include_head;
+ p = CPP_OPTION (pfile, pending)->include_head;
while (p)
{
if (cpp_read_file (pfile, p->arg))
@@ -967,8 +967,8 @@ cpp_start_read (pfile, fname)
p = q;
}
- free (opts->pending);
- opts->pending = NULL;
+ free (CPP_OPTION (pfile, pending));
+ CPP_OPTION (pfile, pending) = NULL;
return 1;
}
@@ -981,29 +981,30 @@ void
cpp_finish (pfile)
cpp_reader *pfile;
{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
-
if (CPP_PREV_BUFFER (CPP_BUFFER (pfile)))
cpp_ice (pfile, "buffers still stacked in cpp_finish");
while (CPP_BUFFER (pfile))
cpp_pop_buffer (pfile);
/* Don't write the deps file if preprocessing has failed. */
- if (opts->print_deps && pfile->errors == 0)
+ if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0)
{
/* Stream on which to print the dependency information. */
FILE *deps_stream = 0;
-
- const char *deps_mode = opts->print_deps_append ? "a" : "w";
- if (opts->deps_file == 0)
+ const char *deps_mode
+ = CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
+ if (CPP_OPTION (pfile, deps_file) == 0)
deps_stream = stdout;
- else if ((deps_stream = fopen (opts->deps_file, deps_mode)) == 0)
- cpp_notice_from_errno (pfile, opts->deps_file);
-
+ else
+ {
+ deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode);
+ if (deps_stream == 0)
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, deps_file));
+ }
if (deps_stream)
{
deps_write (pfile->deps, deps_stream, 72);
- if (opts->deps_file)
+ if (CPP_OPTION (pfile, deps_file))
{
if (ferror (deps_stream) || fclose (deps_stream) != 0)
cpp_fatal (pfile, "I/O error on output");
@@ -1011,13 +1012,13 @@ cpp_finish (pfile)
}
}
- if (opts->dump_macros == dump_only)
+ if (CPP_OPTION (pfile, dump_macros) == dump_only)
_cpp_dump_macro_hash (pfile);
}
static void
-new_pending_directive (opts, text, handler)
- struct cpp_options *opts;
+new_pending_directive (pend, text, handler)
+ struct cpp_pending *pend;
const char *text;
cl_directive_handler handler;
{
@@ -1027,34 +1028,92 @@ new_pending_directive (opts, text, handler)
o->arg = text;
o->next = NULL;
o->handler = handler;
- APPEND (opts->pending, directive, o);
+ APPEND (pend, directive, o);
}
+/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string");
+ I.e. a const string initializer with parens around it. That is
+ what N_("string") resolves to, so we make no_* be macros instead. */
+#define no_arg N_("Argument missing after %s")
+#define no_ass N_("Assertion missing after %s")
+#define no_dir N_("Directory name missing after %s")
+#define no_fil N_("File name missing after %s")
+#define no_mac N_("Macro name missing after %s")
+#define no_pth N_("Path name missing after %s")
+
+/* This is the list of all command line options, with the leading
+ "-" removed. It must be sorted in ASCII collating order. */
+#define COMMAND_LINE_OPTIONS \
+ DEF_OPT("", 0, OPT_stdin_stdout) \
+ DEF_OPT("$", 0, OPT_dollar) \
+ DEF_OPT("+", 0, OPT_plus) \
+ DEF_OPT("-help", 0, OPT__help) \
+ DEF_OPT("-version", 0, OPT__version) \
+ DEF_OPT("A", no_ass, OPT_A) \
+ DEF_OPT("C", 0, OPT_C) \
+ DEF_OPT("D", no_mac, OPT_D) \
+ DEF_OPT("H", 0, OPT_H) \
+ DEF_OPT("I", no_dir, OPT_I) \
+ DEF_OPT("M", 0, OPT_M) \
+ DEF_OPT("MD", no_fil, OPT_MD) \
+ DEF_OPT("MG", 0, OPT_MG) \
+ DEF_OPT("MM", 0, OPT_MM) \
+ DEF_OPT("MMD", no_fil, OPT_MMD) \
+ DEF_OPT("P", 0, OPT_P) \
+ DEF_OPT("U", no_mac, OPT_U) \
+ DEF_OPT("W", no_arg, OPT_W) /* arg optional */ \
+ DEF_OPT("d", no_arg, OPT_d) \
+ DEF_OPT("fleading-underscore", 0, OPT_fleading_underscore) \
+ DEF_OPT("fno-leading-underscore", 0, OPT_fno_leading_underscore) \
+ DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed) \
+ DEF_OPT("fno-show-column", 0, OPT_fno_show_column) \
+ DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed) \
+ DEF_OPT("fshow-column", 0, OPT_fshow_column) \
+ DEF_OPT("g", no_arg, OPT_g) /* arg optional */ \
+ DEF_OPT("h", 0, OPT_h) \
+ DEF_OPT("idirafter", no_dir, OPT_idirafter) \
+ DEF_OPT("imacros", no_fil, OPT_imacros) \
+ DEF_OPT("include", no_fil, OPT_include) \
+ DEF_OPT("iprefix", no_pth, OPT_iprefix) \
+ DEF_OPT("isystem", no_dir, OPT_isystem) \
+ DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix) \
+ DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore) \
+ DEF_OPT("lang-asm", 0, OPT_lang_asm) \
+ DEF_OPT("lang-c", 0, OPT_lang_c) \
+ DEF_OPT("lang-c++", 0, OPT_lang_cplusplus) \
+ DEF_OPT("lang-c89", 0, OPT_lang_c89) \
+ DEF_OPT("lang-chill", 0, OPT_lang_chill) \
+ DEF_OPT("lang-fortran", 0, OPT_lang_fortran) \
+ DEF_OPT("lang-objc", 0, OPT_lang_objc) \
+ DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus) \
+ DEF_OPT("nostdinc", 0, OPT_nostdinc) \
+ DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus) \
+ DEF_OPT("o", no_fil, OPT_o) \
+ DEF_OPT("pedantic", 0, OPT_pedantic) \
+ DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors) \
+ DEF_OPT("remap", 0, OPT_remap) \
+ DEF_OPT("std=c89", 0, OPT_std_c89) \
+ DEF_OPT("std=c99", 0, OPT_std_c99) \
+ DEF_OPT("std=c9x", 0, OPT_std_c9x) \
+ DEF_OPT("std=gnu89", 0, OPT_std_gnu89) \
+ DEF_OPT("std=gnu99", 0, OPT_std_gnu99) \
+ DEF_OPT("std=gnu9x", 0, OPT_std_gnu9x) \
+ DEF_OPT("std=iso9899:1990", 0, OPT_std_iso9899_1990) \
+ DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409) \
+ DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999) \
+ DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x) \
+ DEF_OPT("traditional", 0, OPT_traditional) \
+ DEF_OPT("trigraphs", 0, OPT_trigraphs) \
+ DEF_OPT("v", 0, OPT_v) \
+ DEF_OPT("w", 0, OPT_w)
+
+#define DEF_OPT(text, msg, code) code,
enum opt_code
{
- OPT_stdin_stdout = 0, OPT_dollar, OPT_plus,
- OPT__help, OPT__version,
- OPT_A, OPT_C, OPT_D, OPT_H, OPT_I, OPT_M,
- OPT_MD, OPT_MG, OPT_MM, OPT_MMD,
- OPT_P, OPT_U, OPT_W,
- OPT_d,
- OPT_fleading_underscore, OPT_fno_leading_underscore,
- OPT_fpreprocessed, OPT_fno_preprocessed,
- OPT_g, OPT_h,
- OPT_idirafter, OPT_imacros, OPT_include,
- OPT_iprefix, OPT_isystem, OPT_iwithprefix, OPT_iwithprefixbefore,
- OPT_lang_asm, OPT_lang_c, OPT_lang_cplusplus, OPT_lang_c89,
- OPT_lang_chill, OPT_lang_fortran, OPT_lang_objc, OPT_lang_objcplusplus,
- OPT_nostdinc, OPT_nostdincplusplus,
- OPT_o,
- OPT_pedantic, OPT_pedantic_errors, OPT_remap,
- OPT_std_c89, OPT_std_c99, OPT_std_c9x, OPT_std_gnu89, OPT_std_gnu99,
- OPT_std_gnu9x, OPT_std_iso9899_1990, OPT_std_iso9899_199409,
- OPT_std_iso9899_1999, OPT_std_iso9899_199x,
- OPT_traditional, OPT_trigraphs,
- OPT_v, OPT_w,
+ COMMAND_LINE_OPTIONS
N_OPTS
};
+#undef DEF_OPT
struct cl_option
{
@@ -1064,89 +1123,17 @@ struct cl_option
enum opt_code opt_code;
};
-/* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string");
- I.e. a const string initializer with parens around it. That is
- what N_("string") resolves to, so we make no_* be macros instead. */
-#define no_arg N_("Argument missing after `%s' option")
-#define no_ass N_("Assertion missing after `%s' option")
-#define no_dir N_("Directory name missing after `%s' option")
-#define no_fil N_("File name missing after `%s' option")
-#define no_mac N_("Macro name missing after `%s' option")
-#define no_pth N_("Path name missing after `%s' option")
-
-/* This list must be ASCII sorted. Make enum order above match this. */
-#define DEF_OPT(text, msg, code) {text, msg, sizeof(text) - 1, code}
-
+#define DEF_OPT(text, msg, code) { text, msg, sizeof(text) - 1, code },
#ifdef HOST_EBCDIC
static struct cl_option cl_options[] =
#else
static const struct cl_option cl_options[] =
#endif
{
- DEF_OPT("", 0, OPT_stdin_stdout),
- DEF_OPT("$", 0, OPT_dollar),
- DEF_OPT("+", 0, OPT_plus),
- DEF_OPT("-help", 0, OPT__help),
- DEF_OPT("-version", 0, OPT__version),
- DEF_OPT("A", no_ass, OPT_A),
- DEF_OPT("C", 0, OPT_C),
- DEF_OPT("D", no_mac, OPT_D),
- DEF_OPT("H", 0, OPT_H),
- DEF_OPT("I", no_dir, OPT_I),
- DEF_OPT("M", 0, OPT_M),
- DEF_OPT("MD", no_fil, OPT_MD),
- DEF_OPT("MG", 0, OPT_MG),
- DEF_OPT("MM", 0, OPT_MM),
- DEF_OPT("MMD", no_fil, OPT_MMD),
- DEF_OPT("P", 0, OPT_P),
- DEF_OPT("U", no_mac, OPT_U),
- /* NB: Immed arg only, and not reqd */
- DEF_OPT("W", no_arg, OPT_W),
- DEF_OPT("d", no_arg, OPT_d),
- DEF_OPT("fleading-underscore", 0, OPT_fleading_underscore),
- DEF_OPT("fno-leading-underscore", 0, OPT_fno_leading_underscore),
- DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed),
- DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed),
- /* NB: Immed arg only, and not reqd */
- DEF_OPT("g", no_arg, OPT_g),
- DEF_OPT("h", 0, OPT_h),
- DEF_OPT("idirafter", no_dir, OPT_idirafter),
- DEF_OPT("imacros", no_fil, OPT_imacros),
- DEF_OPT("include", no_fil, OPT_include),
- DEF_OPT("iprefix", no_pth, OPT_iprefix),
- DEF_OPT("isystem", no_dir, OPT_isystem),
- DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix),
- DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore),
- DEF_OPT("lang-asm", 0, OPT_lang_asm),
- DEF_OPT("lang-c", 0, OPT_lang_c),
- DEF_OPT("lang-c++", 0, OPT_lang_cplusplus),
- DEF_OPT("lang-c89", 0, OPT_lang_c89),
- DEF_OPT("lang-chill", 0, OPT_lang_chill),
- DEF_OPT("lang-fortran", 0, OPT_lang_fortran),
- DEF_OPT("lang-objc", 0, OPT_lang_objc),
- DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus),
- DEF_OPT("nostdinc", 0, OPT_nostdinc),
- DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus),
- DEF_OPT("o", no_fil, OPT_o),
- DEF_OPT("pedantic", 0, OPT_pedantic),
- DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors),
- DEF_OPT("remap", 0, OPT_remap),
- DEF_OPT("std=c89", 0, OPT_std_c89),
- DEF_OPT("std=c99", 0, OPT_std_c99),
- DEF_OPT("std=c9x", 0, OPT_std_c9x),
- DEF_OPT("std=gnu89", 0, OPT_std_gnu89),
- DEF_OPT("std=gnu99", 0, OPT_std_gnu99),
- DEF_OPT("std=gnu9x", 0, OPT_std_gnu9x),
- DEF_OPT("std=iso9899:1990", 0, OPT_std_iso9899_1990),
- DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409),
- DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999),
- DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x),
- DEF_OPT("traditional", 0, OPT_traditional),
- DEF_OPT("trigraphs", 0, OPT_trigraphs),
- DEF_OPT("v", 0, OPT_v),
- DEF_OPT("w", 0, OPT_w)
+ COMMAND_LINE_OPTIONS
};
#undef DEF_OPT
+#undef COMMAND_LINE_OPTIONS
/* Perform a binary search to find which, if any, option the given
command-line matches. Returns its index in the option array,
@@ -1170,10 +1157,10 @@ parse_option (input)
while (mx > mn)
{
md = (mn + mx) / 2;
-
+
opt_len = cl_options[md].opt_len;
comp = strncmp (input, cl_options[md].opt_text, opt_len);
-
+
if (comp > 0)
mn = md + 1;
else if (comp < 0)
@@ -1222,20 +1209,17 @@ handle_option (pfile, argc, argv)
int argc;
char **argv;
{
- struct cpp_options *opts = CPP_OPTIONS (pfile);
int i = 0;
if (argv[i][0] != '-')
{
- if (opts->out_fname != NULL)
- {
- print_help ();
- cpp_fatal (pfile, "Too many arguments");
- }
- else if (opts->in_fname != NULL)
- opts->out_fname = argv[i];
+ if (CPP_OPTION (pfile, out_fname) != NULL)
+ cpp_fatal (pfile, "Too many arguments. Type %s --help for usage info",
+ progname);
+ else if (CPP_OPTION (pfile, in_fname) != NULL)
+ CPP_OPTION (pfile, out_fname) = argv[i];
else
- opts->in_fname = argv[i];
+ CPP_OPTION (pfile, in_fname) = argv[i];
}
else
{
@@ -1266,7 +1250,7 @@ handle_option (pfile, argc, argv)
}
}
}
-
+
switch (opt_code)
{
case N_OPTS: /* shut GCC up */
@@ -1278,17 +1262,23 @@ handle_option (pfile, argc, argv)
user_label_prefix = "";
break;
case OPT_fpreprocessed:
- opts->preprocessed = 1;
+ CPP_OPTION (pfile, preprocessed) = 1;
break;
case OPT_fno_preprocessed:
- opts->preprocessed = 0;
+ CPP_OPTION (pfile, preprocessed) = 0;
+ break;
+ case OPT_fshow_column:
+ CPP_OPTION (pfile, show_column) = 1;
+ break;
+ case OPT_fno_show_column:
+ CPP_OPTION (pfile, show_column) = 0;
break;
case OPT_w:
- opts->inhibit_warnings = 1;
+ CPP_OPTION (pfile, inhibit_warnings) = 1;
break;
case OPT_g: /* Silently ignore anything but -g3 */
if (!strcmp(&argv[i][2], "3"))
- opts->debug_output = 1;
+ CPP_OPTION (pfile, debug_output) = 1;
break;
case OPT_h:
case OPT__help:
@@ -1300,124 +1290,156 @@ handle_option (pfile, argc, argv)
exit (0); /* XXX */
break;
case OPT_C:
- opts->discard_comments = 0;
+ CPP_OPTION (pfile, discard_comments) = 0;
break;
case OPT_P:
- opts->no_line_commands = 1;
+ CPP_OPTION (pfile, no_line_commands) = 1;
break;
case OPT_dollar: /* Don't include $ in identifiers. */
- opts->dollars_in_ident = 0;
+ CPP_OPTION (pfile, dollars_in_ident) = 0;
break;
case OPT_H:
- opts->print_include_names = 1;
+ CPP_OPTION (pfile, print_include_names) = 1;
break;
case OPT_D:
- new_pending_directive (opts, arg, cpp_define);
+ new_pending_directive (CPP_OPTION (pfile, pending), arg, cpp_define);
break;
case OPT_pedantic_errors:
- opts->pedantic_errors = 1;
+ CPP_OPTION (pfile, pedantic_errors) = 1;
/* fall through */
case OPT_pedantic:
- opts->pedantic = 1;
+ CPP_OPTION (pfile, pedantic) = 1;
break;
case OPT_traditional:
- opts->traditional = 1;
- opts->cplusplus_comments = 0;
- opts->trigraphs = 0;
- opts->warn_trigraphs = 0;
+ CPP_OPTION (pfile, traditional) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+ CPP_OPTION (pfile, trigraphs) = 0;
+ CPP_OPTION (pfile, warn_trigraphs) = 0;
break;
case OPT_trigraphs:
- opts->trigraphs = 1;
+ CPP_OPTION (pfile, trigraphs) = 1;
break;
case OPT_plus:
- opts->cplusplus = 1;
- opts->cplusplus_comments = 1;
+ CPP_OPTION (pfile, cplusplus) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
break;
case OPT_remap:
- opts->remap = 1;
+ CPP_OPTION (pfile, remap) = 1;
break;
case OPT_iprefix:
- opts->include_prefix = arg;
- opts->include_prefix_len = strlen (arg);
+ CPP_OPTION (pfile, include_prefix) = arg;
+ CPP_OPTION (pfile, include_prefix_len) = strlen (arg);
break;
case OPT_lang_c:
- opts->cplusplus = 0, opts->cplusplus_comments = 1;
- opts->c89 = 0, opts->c99 = 1, opts->objc = 0;
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 0;
+ CPP_OPTION (pfile, c99) = 1;
+ CPP_OPTION (pfile, objc) = 0;
break;
case OPT_lang_c89:
- opts->cplusplus = 0, opts->cplusplus_comments = 0;
- opts->c89 = 1, opts->c99 = 0, opts->objc = 0;
- opts->trigraphs = 1;
- new_pending_directive (opts, "__STRICT_ANSI__", cpp_define);
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+ CPP_OPTION (pfile, c89) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, trigraphs) = 1;
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STRICT_ANSI__", cpp_define);
break;
case OPT_lang_cplusplus:
- opts->cplusplus = 1, opts->cplusplus_comments = 1;
- opts->c89 = 0, opts->c99 = 0, opts->objc = 0;
+ CPP_OPTION (pfile, cplusplus) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 0;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 0;
break;
case OPT_lang_objc:
case OPT_lang_objcplusplus:
- opts->cplusplus = opt_code == OPT_lang_objcplusplus;
- opts->cplusplus_comments = 1;
- opts->c89 = 0, opts->c99 = 0, opts->objc = 1;
+ CPP_OPTION (pfile, cplusplus) = opt_code == OPT_lang_objcplusplus;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 0;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 1;
break;
case OPT_lang_asm:
- opts->lang_asm = 1;
+ CPP_OPTION (pfile, lang_asm) = 1;
break;
case OPT_lang_fortran:
- opts->lang_fortran = 1, opts->cplusplus_comments = 0;
+ CPP_OPTION (pfile, lang_fortran) = 1;
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
break;
case OPT_lang_chill:
- opts->objc = 0, opts->cplusplus = 0;
- opts->chill = 1, opts->traditional = 1;
+ CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, chill) = 1;
+ CPP_OPTION (pfile, traditional) = 1;
break;
case OPT_nostdinc:
/* -nostdinc causes no default include directories.
You must specify all include-file directories with -I. */
- opts->no_standard_includes = 1;
+ CPP_OPTION (pfile, no_standard_includes) = 1;
break;
case OPT_nostdincplusplus:
/* -nostdinc++ causes no default C++-specific include directories. */
- opts->no_standard_cplusplus_includes = 1;
+ CPP_OPTION (pfile, no_standard_cplusplus_includes) = 1;
break;
case OPT_std_gnu89:
- opts->cplusplus = 0, opts->cplusplus_comments = 1;
- opts->c89 = 1, opts->c99 = 0, opts->objc = 0;
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 0;
break;
case OPT_std_gnu9x:
case OPT_std_gnu99:
- opts->cplusplus = 0, opts->cplusplus_comments = 1;
- opts->c89 = 0, opts->c99 = 1, opts->objc = 0;
- new_pending_directive (opts, "__STDC_VERSION__=199901L", cpp_define);
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 0;
+ CPP_OPTION (pfile, c99) = 1;
+ CPP_OPTION (pfile, objc) = 0;
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STDC_VERSION__=199901L", cpp_define);
break;
case OPT_std_iso9899_199409:
- new_pending_directive (opts, "__STDC_VERSION__=199409L", cpp_define);
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STDC_VERSION__=199409L", cpp_define);
/* Fall through */
case OPT_std_iso9899_1990:
case OPT_std_c89:
- opts->cplusplus = 0, opts->cplusplus_comments = 0;
- opts->c89 = 1, opts->c99 = 0, opts->objc = 0;
- opts->trigraphs = 1;
- new_pending_directive (opts, "__STRICT_ANSI__", cpp_define);
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 0;
+ CPP_OPTION (pfile, c89) = 1;
+ CPP_OPTION (pfile, c99) = 0;
+ CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, trigraphs) = 1;
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STRICT_ANSI__", cpp_define);
break;
case OPT_std_iso9899_199x:
case OPT_std_iso9899_1999:
case OPT_std_c9x:
case OPT_std_c99:
- opts->cplusplus = 0, opts->cplusplus_comments = 1;
- opts->c89 = 0, opts->c99 = 1, opts->objc = 0;
- opts->trigraphs = 1;
- new_pending_directive (opts, "__STRICT_ANSI__", cpp_define);
- new_pending_directive (opts, "__STDC_VERSION__=199901L", cpp_define);
+ CPP_OPTION (pfile, cplusplus) = 0;
+ CPP_OPTION (pfile, cplusplus_comments) = 1;
+ CPP_OPTION (pfile, c89) = 0;
+ CPP_OPTION (pfile, c99) = 1;
+ CPP_OPTION (pfile, objc) = 0;
+ CPP_OPTION (pfile, trigraphs) = 1;
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STRICT_ANSI__", cpp_define);
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ "__STDC_VERSION__=199901L", cpp_define);
break;
case OPT_o:
- if (opts->out_fname != NULL)
+ if (CPP_OPTION (pfile, out_fname) != NULL)
{
cpp_fatal (pfile, "Output filename specified twice");
return argc;
}
- opts->out_fname = arg;
- if (!strcmp (opts->out_fname, "-"))
- opts->out_fname = "";
+ CPP_OPTION (pfile, out_fname) = arg;
+ if (!strcmp (CPP_OPTION (pfile, out_fname), "-"))
+ CPP_OPTION (pfile, out_fname) = "";
break;
case OPT_v:
fprintf (stderr, _("GNU CPP version %s (cpplib)\n"), version_string);
@@ -1425,14 +1447,14 @@ handle_option (pfile, argc, argv)
TARGET_VERSION;
#endif
fputc ('\n', stderr);
- opts->verbose = 1;
+ CPP_OPTION (pfile, verbose) = 1;
break;
case OPT_stdin_stdout:
/* JF handle '-' as file name meaning stdin or stdout */
- if (opts->in_fname == NULL)
- opts->in_fname = "";
- else if (opts->out_fname == NULL)
- opts->out_fname = "";
+ if (CPP_OPTION (pfile, in_fname) == NULL)
+ CPP_OPTION (pfile, in_fname) = "";
+ else if (CPP_OPTION (pfile, out_fname) == NULL)
+ CPP_OPTION (pfile, out_fname) = "";
break;
case OPT_d:
/* Args to -d specify what parts of macros to dump.
@@ -1440,22 +1462,22 @@ handle_option (pfile, argc, argv)
be aimed at the compiler proper. */
{
char c;
-
+
while ((c = *arg++) != '\0')
switch (c)
{
case 'M':
- opts->dump_macros = dump_only;
- opts->no_output = 1;
+ CPP_OPTION (pfile, dump_macros) = dump_only;
+ CPP_OPTION (pfile, no_output) = 1;
break;
case 'N':
- opts->dump_macros = dump_names;
+ CPP_OPTION (pfile, dump_macros) = dump_names;
break;
case 'D':
- opts->dump_macros = dump_definitions;
+ CPP_OPTION (pfile, dump_macros) = dump_definitions;
break;
case 'I':
- opts->dump_includes = 1;
+ CPP_OPTION (pfile, dump_includes) = 1;
break;
}
}
@@ -1470,27 +1492,27 @@ handle_option (pfile, argc, argv)
/* ??? -MG must be specified in addition to one of -M or -MM.
This can be relaxed in the future without breaking anything.
The converse isn't true. */
-
+
/* -MG isn't valid with -MD or -MMD. This is checked for later. */
case OPT_MG:
- opts->print_deps_missing_files = 1;
+ CPP_OPTION (pfile, print_deps_missing_files) = 1;
break;
case OPT_M:
case OPT_MD:
case OPT_MM:
case OPT_MMD:
if (opt_code == OPT_M || opt_code == OPT_MD)
- opts->print_deps = 2;
+ CPP_OPTION (pfile, print_deps) = 2;
else
- opts->print_deps = 1;
+ CPP_OPTION (pfile, print_deps) = 1;
/* For -MD and -MMD options, write deps on file named by next arg */
/* For -M and -MM, write deps on standard output
and suppress the usual output. */
if (opt_code == OPT_MD || opt_code == OPT_MMD)
- opts->deps_file = arg;
+ CPP_OPTION (pfile, deps_file) = arg;
else
- opts->no_output = 1;
+ CPP_OPTION (pfile, no_output) = 1;
break;
case OPT_A:
if (arg[0] == '-')
@@ -1507,24 +1529,26 @@ handle_option (pfile, argc, argv)
{
struct pending_option *o1, *o2;
- o1 = opts->pending->directive_head;
+ o1 = CPP_OPTION (pfile, pending)->directive_head;
while (o1)
{
o2 = o1->next;
free (o1);
o1 = o2;
}
- opts->pending->directive_head = NULL;
- opts->pending->directive_tail = NULL;
+ CPP_OPTION (pfile, pending)->directive_head = NULL;
+ CPP_OPTION (pfile, pending)->directive_tail = NULL;
}
else
- new_pending_directive (opts, arg + 1, cpp_unassert);
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ arg + 1, cpp_unassert);
}
else
- new_pending_directive (opts, arg, cpp_assert);
+ new_pending_directive (CPP_OPTION (pfile, pending),
+ arg, cpp_assert);
break;
case OPT_U:
- new_pending_directive (opts, arg, cpp_undef);
+ new_pending_directive (CPP_OPTION (pfile, pending), arg, cpp_undef);
break;
case OPT_I: /* Add directory to path for includes. */
if (!strcmp (arg, "-"))
@@ -1535,13 +1559,14 @@ handle_option (pfile, argc, argv)
Don't search the directory of the present file
for #include "...". (Note that -I. -I- is not the same as
the default setup; -I. uses the compiler's working dir.) */
- if (! opts->ignore_srcdir)
+ if (! CPP_OPTION (pfile, ignore_srcdir))
{
- opts->ignore_srcdir = 1;
- opts->pending->quote_head = opts->pending->brack_head;
- opts->pending->quote_tail = opts->pending->brack_tail;
- opts->pending->brack_head = 0;
- opts->pending->brack_tail = 0;
+ struct cpp_pending *pend = CPP_OPTION (pfile, pending);
+ pend->quote_head = pend->brack_head;
+ pend->quote_tail = pend->brack_tail;
+ pend->brack_head = 0;
+ pend->brack_tail = 0;
+ CPP_OPTION (pfile, ignore_srcdir) = 1;
}
else
{
@@ -1550,13 +1575,13 @@ handle_option (pfile, argc, argv)
}
}
else
- append_include_chain (pfile, opts->pending,
+ append_include_chain (pfile, CPP_OPTION (pfile, pending),
xstrdup (arg), BRACKET, 0);
break;
case OPT_isystem:
/* Add directory to beginning of system include path, as a system
include directory. */
- append_include_chain (pfile, opts->pending,
+ append_include_chain (pfile, CPP_OPTION (pfile, pending),
xstrdup (arg), SYSTEM, 0);
break;
case OPT_include:
@@ -1568,8 +1593,8 @@ handle_option (pfile, argc, argv)
/* This list has to be built in reverse order so that
when cpp_start_read pushes all the -include files onto
the buffer stack, they will be scanned in forward order. */
- o->next = opts->pending->include_head;
- opts->pending->include_head = o;
+ o->next = CPP_OPTION (pfile, pending)->include_head;
+ CPP_OPTION (pfile, pending)->include_head = o;
}
break;
case OPT_imacros:
@@ -1578,8 +1603,8 @@ handle_option (pfile, argc, argv)
xmalloc (sizeof (struct pending_option));
o->arg = arg;
o->next = NULL;
-
- APPEND (opts->pending, imacros, o);
+
+ APPEND (CPP_OPTION (pfile, pending), imacros, o);
}
break;
case OPT_iwithprefix:
@@ -1592,14 +1617,15 @@ handle_option (pfile, argc, argv)
{
char *fname;
int len;
-
+
len = strlen (arg);
-
- if (opts->include_prefix != 0)
+
+ if (CPP_OPTION (pfile, include_prefix) != 0)
{
- fname = xmalloc (opts->include_prefix_len + len + 1);
- memcpy (fname, opts->include_prefix, opts->include_prefix_len);
- memcpy (fname + opts->include_prefix_len, arg, len + 1);
+ size_t ipl = CPP_OPTION (pfile, include_prefix_len);
+ fname = xmalloc (ipl + len + 1);
+ memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl);
+ memcpy (fname + ipl, arg, len + 1);
}
else
{
@@ -1607,51 +1633,51 @@ handle_option (pfile, argc, argv)
memcpy (fname, GCC_INCLUDE_DIR, sizeof GCC_INCLUDE_DIR - 9);
memcpy (fname + sizeof GCC_INCLUDE_DIR - 9, arg, len + 1);
}
-
- append_include_chain (pfile, opts->pending, fname,
+
+ append_include_chain (pfile, CPP_OPTION (pfile, pending), fname,
opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0);
}
break;
case OPT_idirafter:
/* Add directory to end of path for includes. */
- append_include_chain (pfile, opts->pending,
+ append_include_chain (pfile, CPP_OPTION (pfile, pending),
xstrdup (arg), AFTER, 0);
break;
case OPT_W:
/* Silently ignore unrecognised options */
if (!strcmp (argv[i], "-Wall"))
{
- opts->warn_trigraphs = 1;
- opts->warn_comments = 1;
+ CPP_OPTION (pfile, warn_trigraphs) = 1;
+ CPP_OPTION (pfile, warn_comments) = 1;
}
else if (!strcmp (argv[i], "-Wtraditional"))
- opts->warn_stringify = 1;
+ CPP_OPTION (pfile, warn_traditional) = 1;
else if (!strcmp (argv[i], "-Wtrigraphs"))
- opts->warn_trigraphs = 1;
+ CPP_OPTION (pfile, warn_trigraphs) = 1;
else if (!strcmp (argv[i], "-Wcomment"))
- opts->warn_comments = 1;
+ CPP_OPTION (pfile, warn_comments) = 1;
else if (!strcmp (argv[i], "-Wcomments"))
- opts->warn_comments = 1;
+ CPP_OPTION (pfile, warn_comments) = 1;
else if (!strcmp (argv[i], "-Wundef"))
- opts->warn_undef = 1;
+ CPP_OPTION (pfile, warn_undef) = 1;
else if (!strcmp (argv[i], "-Wimport"))
- opts->warn_import = 1;
+ CPP_OPTION (pfile, warn_import) = 1;
else if (!strcmp (argv[i], "-Werror"))
- opts->warnings_are_errors = 1;
+ CPP_OPTION (pfile, warnings_are_errors) = 1;
else if (!strcmp (argv[i], "-Wno-traditional"))
- opts->warn_stringify = 0;
+ CPP_OPTION (pfile, warn_traditional) = 0;
else if (!strcmp (argv[i], "-Wno-trigraphs"))
- opts->warn_trigraphs = 0;
+ CPP_OPTION (pfile, warn_trigraphs) = 0;
else if (!strcmp (argv[i], "-Wno-comment"))
- opts->warn_comments = 0;
+ CPP_OPTION (pfile, warn_comments) = 0;
else if (!strcmp (argv[i], "-Wno-comments"))
- opts->warn_comments = 0;
+ CPP_OPTION (pfile, warn_comments) = 0;
else if (!strcmp (argv[i], "-Wno-undef"))
- opts->warn_undef = 0;
+ CPP_OPTION (pfile, warn_undef) = 0;
else if (!strcmp (argv[i], "-Wno-import"))
- opts->warn_import = 0;
+ CPP_OPTION (pfile, warn_import) = 0;
else if (!strcmp (argv[i], "-Wno-error"))
- opts->warnings_are_errors = 0;
+ CPP_OPTION (pfile, warnings_are_errors) = 0;
break;
}
}
diff --git a/gcc/cpplex.c b/gcc/cpplex.c
index 674db90e608..b8a1b071161 100644
--- a/gcc/cpplex.c
+++ b/gcc/cpplex.c
@@ -25,11 +25,16 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpplib.h"
#include "cpphash.h"
-#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \
- ? CPP_BUFFER (pfile)->cur[N] : EOF)
-#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
-#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
-#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
+#define PEEKBUF(BUFFER, N) \
+ ((BUFFER)->rlimit - (BUFFER)->cur > (N) ? (BUFFER)->cur[N] : EOF)
+#define GETBUF(BUFFER) \
+ ((BUFFER)->cur < (BUFFER)->rlimit ? *(BUFFER)->cur++ : EOF)
+#define FORWARDBUF(BUFFER, N) ((BUFFER)->cur += (N))
+
+#define PEEKN(N) PEEKBUF (CPP_BUFFER (pfile), N)
+#define FORWARD(N) FORWARDBUF (CPP_BUFFER (pfile), (N))
+#define GETC() GETBUF (CPP_BUFFER (pfile))
+#define PEEKC() PEEKBUF (CPP_BUFFER (pfile), 0)
static void skip_block_comment PARAMS ((cpp_reader *));
static void skip_line_comment PARAMS ((cpp_reader *));
@@ -40,6 +45,7 @@ static void skip_string PARAMS ((cpp_reader *, int));
static void parse_string PARAMS ((cpp_reader *, int));
static U_CHAR *find_position PARAMS ((U_CHAR *, U_CHAR *, unsigned long *));
static int null_cleanup PARAMS ((cpp_buffer *, cpp_reader *));
+static void null_warning PARAMS ((cpp_reader *, unsigned int));
/* Re-allocates PFILE->token_buffer so it will hold at least N more chars. */
@@ -87,9 +93,9 @@ cpp_push_buffer (pfile, buffer, length)
new->if_stack = pfile->if_stack;
new->cleanup = null_cleanup;
new->buf = new->cur = buffer;
- new->alimit = new->rlimit = buffer + length;
+ new->rlimit = buffer + length;
new->prev = buf;
- new->mark = -1;
+ new->mark = NULL;
new->line_base = NULL;
CPP_BUFFER (pfile) = new;
@@ -119,7 +125,7 @@ cpp_scan_buffer (pfile)
{
cpp_buffer *buffer = CPP_BUFFER (pfile);
enum cpp_token token;
- if (CPP_OPTIONS (pfile)->no_output)
+ if (CPP_OPTION (pfile, no_output))
{
long old_written = CPP_WRITTEN (pfile);
/* In no-output mode, we can ignore everything but directives. */
@@ -193,12 +199,12 @@ cpp_expand_to_buffer (pfile, buf, length)
ip->has_escapes = 1;
/* Scan the input, create the output. */
- save_no_output = CPP_OPTIONS (pfile)->no_output;
- CPP_OPTIONS (pfile)->no_output = 0;
- CPP_OPTIONS (pfile)->no_line_commands++;
+ save_no_output = CPP_OPTION (pfile, no_output);
+ CPP_OPTION (pfile, no_output) = 0;
+ CPP_OPTION (pfile, no_line_commands)++;
cpp_scan_buffer (pfile);
- CPP_OPTIONS (pfile)->no_line_commands--;
- CPP_OPTIONS (pfile)->no_output = save_no_output;
+ CPP_OPTION (pfile, no_line_commands)--;
+ CPP_OPTION (pfile, no_output) = save_no_output;
CPP_NUL_TERMINATE (pfile);
}
@@ -264,7 +270,7 @@ skip_block_comment (pfile)
else if (c == '/' && prev_c == '*')
return;
else if (c == '*' && prev_c == '/'
- && CPP_OPTIONS (pfile)->warn_comments)
+ && CPP_OPTION (pfile, warn_comments))
cpp_warning (pfile, "`/*' within comment");
prev_c = c;
@@ -294,7 +300,7 @@ skip_line_comment (pfile)
/* \r cannot be a macro escape marker here. */
if (!ACTIVE_MARK_P (pfile))
CPP_BUMP_LINE (pfile);
- if (CPP_OPTIONS (pfile)->warn_comments)
+ if (CPP_OPTION (pfile, warn_comments))
cpp_warning (pfile, "backslash-newline within line comment");
}
}
@@ -325,9 +331,9 @@ skip_comment (pfile, m)
skip_line_comment (pfile);
return ' ';
}
- else if (CPP_OPTIONS (pfile)->cplusplus_comments)
+ else if (CPP_OPTION (pfile, cplusplus_comments))
{
- if (CPP_OPTIONS (pfile)->c89
+ if (CPP_OPTION (pfile, c89)
&& CPP_PEDANTIC (pfile)
&& ! CPP_BUFFER (pfile)->warned_cplusplus_comments)
{
@@ -344,7 +350,7 @@ skip_comment (pfile, m)
return m;
}
else if (m == '-' && PEEKC() == '-'
- && CPP_OPTIONS (pfile)->chill)
+ && CPP_OPTION (pfile, chill))
{
skip_line_comment (pfile);
return ' ';
@@ -376,23 +382,38 @@ copy_comment (pfile, m)
return ' ';
}
+static void
+null_warning (pfile, count)
+ cpp_reader *pfile;
+ unsigned int count;
+{
+ if (count == 1)
+ cpp_warning (pfile, "embedded null character ignored");
+ else
+ cpp_warning (pfile, "embedded null characters ignored");
+}
+
/* Skip whitespace \-newline and comments. Does not macro-expand. */
void
_cpp_skip_hspace (pfile)
cpp_reader *pfile;
{
+ unsigned int null_count = 0;
int c;
+
while (1)
{
c = GETC();
if (c == EOF)
- return;
+ goto out;
else if (is_hspace(c))
{
if ((c == '\f' || c == '\v') && CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "%s in preprocessing directive",
c == '\f' ? "formfeed" : "vertical tab");
+ else if (c == '\0')
+ null_count++;
}
else if (c == '\r')
{
@@ -418,6 +439,9 @@ _cpp_skip_hspace (pfile)
break;
}
FORWARD(-1);
+ out:
+ if (null_count)
+ null_warning (pfile, null_count);
}
/* Read and discard the rest of the current line. */
@@ -500,8 +524,9 @@ skip_string (pfile, c)
int c;
{
long start_line, start_column;
- cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
+ unsigned int null_count = 0;
+ cpp_buf_line_and_col (cpp_file_buffer (pfile), &start_line, &start_column);
while (1)
{
int cc = GETC();
@@ -516,19 +541,23 @@ skip_string (pfile, c)
pfile->multiline_string_line, -1,
"possible real start of unterminated constant");
pfile->multiline_string_line = 0;
- return;
+ goto out;
+ case '\0':
+ null_count++;
+ break;
+
case '\n':
CPP_BUMP_LINE (pfile);
/* In Fortran and assembly language, silently terminate
strings of either variety at end of line. This is a
kludge around not knowing where comments are in these
languages. */
- if (CPP_OPTIONS (pfile)->lang_fortran
- || CPP_OPTIONS (pfile)->lang_asm)
+ if (CPP_OPTION (pfile, lang_fortran)
+ || CPP_OPTION (pfile, lang_asm))
{
FORWARD(-1);
- return;
+ goto out;
}
/* Character constants may not extend over multiple lines.
In Standard C, neither may strings. We accept multiline
@@ -538,7 +567,7 @@ skip_string (pfile, c)
cpp_error_with_line (pfile, start_line, start_column,
"unterminated character constant");
FORWARD(-1);
- return;
+ goto out;
}
if (CPP_PEDANTIC (pfile) && pfile->multiline_string_line == 0)
cpp_pedwarn_with_line (pfile, start_line, start_column,
@@ -565,10 +594,16 @@ skip_string (pfile, c)
case '\"':
case '\'':
if (cc == c)
- return;
+ goto out;
break;
}
}
+
+ out:
+ if (null_count == 1)
+ cpp_warning (pfile, "null character in string or character constant");
+ else if (null_count > 1)
+ cpp_warning (pfile, "null characters in string or character constant");
}
/* Parse a string and copy it to the output. */
@@ -604,7 +639,12 @@ _cpp_parse_assertion (pfile)
int c, dropwhite;
_cpp_skip_hspace (pfile);
c = PEEKC();
- if (! is_idstart(c))
+ if (c == '\n')
+ {
+ cpp_error (pfile, "assertion without predicate");
+ return 0;
+ }
+ else if (! is_idstart(c))
{
cpp_error (pfile, "assertion predicate is not an identifier");
return 0;
@@ -662,7 +702,6 @@ _cpp_parse_assertion (pfile)
else
CPP_PUTC (pfile, ')');
- CPP_NUL_TERMINATE (pfile);
return 2;
}
@@ -675,7 +714,6 @@ _cpp_lex_token (pfile)
{
register int c, c2, c3;
enum cpp_token token;
- struct cpp_options *opts = CPP_OPTIONS (pfile);
get_next:
c = GETC();
@@ -689,7 +727,7 @@ _cpp_lex_token (pfile)
goto op2;
comment:
- if (opts->discard_comments)
+ if (CPP_OPTION (pfile, discard_comments))
c = skip_comment (pfile, c);
else
c = copy_comment (pfile, c);
@@ -698,8 +736,16 @@ _cpp_lex_token (pfile)
/* Comments are equivalent to spaces.
For -traditional, a comment is equivalent to nothing. */
- if (opts->traditional || !opts->discard_comments)
+ if (!CPP_OPTION (pfile, discard_comments))
return CPP_COMMENT;
+ else if (CPP_TRADITIONAL (pfile)
+ && ! is_space (PEEKC ()))
+ {
+ if (pfile->parsing_define_directive)
+ return CPP_COMMENT;
+ else
+ goto get_next;
+ }
else
{
CPP_PUTC (pfile, c);
@@ -709,9 +755,9 @@ _cpp_lex_token (pfile)
case '#':
if (pfile->parsing_if_directive)
{
- _cpp_skip_hspace (pfile);
- _cpp_parse_assertion (pfile);
- return CPP_ASSERTION;
+ if (_cpp_parse_assertion (pfile))
+ return CPP_ASSERTION;
+ goto randomchar;
}
if (pfile->parsing_define_directive && ! CPP_TRADITIONAL (pfile))
@@ -730,27 +776,20 @@ _cpp_lex_token (pfile)
if (!pfile->only_seen_white)
goto randomchar;
- /* -traditional directives are recognized only with the # in
- column 1.
- XXX Layering violation. */
- if (CPP_TRADITIONAL (pfile)
- && CPP_BUFFER (pfile)->cur - CPP_BUFFER (pfile)->line_base != 1)
- goto randomchar;
return CPP_DIRECTIVE;
case '\"':
case '\'':
parse_string (pfile, c);
- pfile->only_seen_white = 0;
return c == '\'' ? CPP_CHAR : CPP_STRING;
case '$':
- if (!opts->dollars_in_ident)
+ if (!CPP_OPTION (pfile, dollars_in_ident))
goto randomchar;
goto letter;
case ':':
- if (opts->cplusplus && PEEKC () == ':')
+ if (CPP_OPTION (pfile, cplusplus) && PEEKC () == ':')
goto op2;
goto randomchar;
@@ -775,7 +814,7 @@ _cpp_lex_token (pfile)
c2 = PEEKC ();
if (c2 == '-')
{
- if (opts->chill)
+ if (CPP_OPTION (pfile, chill))
goto comment; /* Chill style comment */
else
goto op2;
@@ -784,11 +823,10 @@ _cpp_lex_token (pfile)
goto op2;
else if (c2 == '>')
{
- if (opts->cplusplus && PEEKN (1) == '*')
+ if (CPP_OPTION (pfile, cplusplus) && PEEKN (1) == '*')
{
/* In C++, there's a ->* operator. */
token = CPP_OTHER;
- pfile->only_seen_white = 0;
CPP_RESERVE (pfile, 4);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, GETC ());
@@ -842,7 +880,7 @@ _cpp_lex_token (pfile)
if (c2 == '=')
goto op2;
/* GNU C++ supports MIN and MAX operators <? and >?. */
- if (c2 != c && (!opts->cplusplus || c2 != '?'))
+ if (c2 != c && (!CPP_OPTION (pfile, cplusplus) || c2 != '?'))
goto randomchar;
FORWARD(1);
CPP_RESERVE (pfile, 4);
@@ -852,7 +890,6 @@ _cpp_lex_token (pfile)
if (c3 == '=')
CPP_PUTC_Q (pfile, GETC ());
CPP_NUL_TERMINATE_Q (pfile);
- pfile->only_seen_white = 0;
return CPP_OTHER;
case '.':
@@ -866,7 +903,7 @@ _cpp_lex_token (pfile)
}
/* In C++ there's a .* operator. */
- if (opts->cplusplus && c2 == '*')
+ if (CPP_OPTION (pfile, cplusplus) && c2 == '*')
goto op2;
if (c2 == '.' && PEEKN(1) == '.')
@@ -877,14 +914,12 @@ _cpp_lex_token (pfile)
CPP_PUTC_Q (pfile, '.');
FORWARD (2);
CPP_NUL_TERMINATE_Q (pfile);
- pfile->only_seen_white = 0;
return CPP_3DOTS;
}
goto randomchar;
op2:
token = CPP_OTHER;
- pfile->only_seen_white = 0;
CPP_RESERVE(pfile, 3);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, GETC ());
@@ -898,7 +933,6 @@ _cpp_lex_token (pfile)
CPP_PUTC (pfile, c);
c = GETC ();
parse_string (pfile, c);
- pfile->only_seen_white = 0;
return c == '\'' ? CPP_WCHAR : CPP_WSTRING;
}
goto letter;
@@ -917,20 +951,18 @@ _cpp_lex_token (pfile)
if (!is_numchar(c) && c != '.'
&& ((c2 != 'e' && c2 != 'E'
&& ((c2 != 'p' && c2 != 'P')
- || CPP_OPTIONS (pfile)->c89))
+ || CPP_OPTION (pfile, c89)))
|| (c != '+' && c != '-')))
break;
FORWARD(1);
c2= c;
}
CPP_NUL_TERMINATE_Q (pfile);
- pfile->only_seen_white = 0;
return CPP_NUMBER;
case 'b': case 'c': case 'd': case 'h': case 'o':
case 'B': case 'C': case 'D': case 'H': case 'O':
- if (opts->chill && PEEKC () == '\'')
+ if (CPP_OPTION (pfile, chill) && PEEKC () == '\'')
{
- pfile->only_seen_white = 0;
CPP_RESERVE (pfile, 2);
CPP_PUTC_Q (pfile, c);
CPP_PUTC_Q (pfile, '\'');
@@ -971,20 +1003,28 @@ _cpp_lex_token (pfile)
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
letter:
- pfile->only_seen_white = 0;
_cpp_parse_name (pfile, c);
return CPP_MACRO;
- case ' ': case '\t': case '\v':
- for (;;)
- {
- CPP_PUTC (pfile, c);
- c = PEEKC ();
- if (c == EOF || !is_hspace(c))
- break;
- FORWARD(1);
- }
- return CPP_HSPACE;
+ case ' ': case '\t': case '\v': case '\f': case '\0':
+ {
+ int null_count = 0;
+
+ for (;;)
+ {
+ if (c == '\0')
+ null_count++;
+ else
+ CPP_PUTC (pfile, c);
+ c = PEEKC ();
+ if (c == EOF || !is_hspace(c))
+ break;
+ FORWARD(1);
+ }
+ if (null_count)
+ null_warning (pfile, null_count);
+ return CPP_HSPACE;
+ }
case '\r':
if (CPP_BUFFER (pfile)->has_escapes)
@@ -999,6 +1039,8 @@ _cpp_lex_token (pfile)
}
else if (c == ' ')
{
+ /* "\r " means a space, but only if necessary to prevent
+ accidental token concatenation. */
CPP_RESERVE (pfile, 2);
if (pfile->output_escapes)
CPP_PUTC_Q (pfile, '\r');
@@ -1020,15 +1062,6 @@ _cpp_lex_token (pfile)
case '\n':
CPP_PUTC (pfile, c);
- if (pfile->only_seen_white == 0)
- pfile->only_seen_white = 1;
- CPP_BUMP_LINE (pfile);
- if (! CPP_OPTIONS (pfile)->no_line_commands)
- {
- pfile->lineno++;
- if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
- _cpp_output_line_command (pfile, same_file);
- }
return CPP_VSPACE;
case '(': token = CPP_LPAREN; goto char1;
@@ -1042,7 +1075,6 @@ _cpp_lex_token (pfile)
default:
token = CPP_OTHER;
char1:
- pfile->only_seen_white = 0;
CPP_PUTC (pfile, c);
return token;
}
@@ -1076,6 +1108,13 @@ maybe_macroexpand (pfile, written)
}
return 0;
}
+ if (hp->type == T_EMPTY)
+ {
+ /* Special case optimization: macro expands to nothing. */
+ CPP_SET_WRITTEN (pfile, written);
+ CPP_PUTC_Q (pfile, ' ');
+ return 1;
+ }
/* If macro wants an arglist, verify that a '(' follows. */
if (hp->type == T_MACRO && hp->value.defn->nargs >= 0)
@@ -1147,9 +1186,28 @@ cpp_get_token (pfile)
switch (token)
{
default:
+ pfile->potential_control_macro = 0;
+ pfile->only_seen_white = 0;
+ return token;
+
+ case CPP_VSPACE:
+ if (pfile->only_seen_white == 0)
+ pfile->only_seen_white = 1;
+ CPP_BUMP_LINE (pfile);
+ if (! CPP_OPTION (pfile, no_line_commands))
+ {
+ pfile->lineno++;
+ if (CPP_BUFFER (pfile)->lineno != pfile->lineno)
+ _cpp_output_line_command (pfile, same_file);
+ }
+ return token;
+
+ case CPP_HSPACE:
+ case CPP_COMMENT:
return token;
case CPP_DIRECTIVE:
+ pfile->potential_control_macro = 0;
if (_cpp_handle_directive (pfile))
return CPP_DIRECTIVE;
pfile->only_seen_white = 0;
@@ -1157,6 +1215,8 @@ cpp_get_token (pfile)
return CPP_OTHER;
case CPP_MACRO:
+ pfile->potential_control_macro = 0;
+ pfile->only_seen_white = 0;
if (! pfile->no_macro_expand
&& maybe_macroexpand (pfile, written))
goto get_next;
@@ -1193,57 +1253,96 @@ cpp_get_non_space_token (pfile)
for (;;)
{
enum cpp_token token = cpp_get_token (pfile);
- if (token != CPP_COMMENT && token != CPP_POP
- && token != CPP_HSPACE && token != CPP_VSPACE)
+ if (token != CPP_COMMENT && token != CPP_HSPACE && token != CPP_VSPACE)
return token;
CPP_SET_WRITTEN (pfile, old_written);
}
}
-/* Like cpp_get_token, except that it does not read past end-of-line.
- Also, horizontal space is skipped, and macros are popped. */
+/* Like cpp_get_token, except that it does not execute directives,
+ does not consume vertical space, and automatically pops off macro
+ buffers.
+ XXX This function will exist only till collect_expansion doesn't
+ need to see whitespace anymore, then it'll be merged with
+ _cpp_get_directive_token (below). */
enum cpp_token
-_cpp_get_directive_token (pfile)
+_cpp_get_define_token (pfile)
cpp_reader *pfile;
{
- long old_written = CPP_WRITTEN (pfile);
+ long old_written;
enum cpp_token token;
- for (;;)
+ get_next:
+ old_written = CPP_WRITTEN (pfile);
+ token = _cpp_lex_token (pfile);
+ switch (token)
{
- _cpp_skip_hspace (pfile);
- if (PEEKC () == '\n')
- return CPP_VSPACE;
+ default:
+ return token;
- token = cpp_get_token (pfile);
- /* token could be hspace at the beginning of a macro. */
- if (token == CPP_HSPACE || token == CPP_COMMENT)
- {
- CPP_SET_WRITTEN (pfile, old_written);
- continue;
- }
+ case CPP_VSPACE:
+ /* Put it back and return VSPACE. */
+ FORWARD(-1);
+ CPP_ADJUST_WRITTEN (pfile, -1);
+ return CPP_VSPACE;
- /* token cannot be vspace, it would have been caught above. */
- if (token == CPP_VSPACE)
+ case CPP_HSPACE:
+ if (CPP_PEDANTIC (pfile))
{
- cpp_ice (pfile, "VSPACE in get_directive_token");
- return token;
+ U_CHAR *p, *limit;
+ p = pfile->token_buffer + old_written;
+ limit = CPP_PWRITTEN (pfile);
+ while (p < limit)
+ {
+ if (*p == '\v' || *p == '\f')
+ cpp_pedwarn (pfile, "%s in preprocessing directive",
+ *p == '\f' ? "formfeed" : "vertical tab");
+ p++;
+ }
}
+ return CPP_HSPACE;
- /* token cannot be POP unless the buffer is a macro buffer. */
- if (token != CPP_POP)
- return token;
+ case CPP_DIRECTIVE:
+ /* Don't execute the directive, but don't smash it to OTHER either. */
+ CPP_PUTC (pfile, '#');
+ return CPP_DIRECTIVE;
+
+ case CPP_MACRO:
+ if (! pfile->no_macro_expand
+ && maybe_macroexpand (pfile, old_written))
+ goto get_next;
+ return CPP_NAME;
- if (! CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
+ case CPP_EOF:
+ if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
{
- cpp_ice (pfile, "POP of file buffer in get_directive_token");
- return token;
+ cpp_pop_buffer (pfile);
+ goto get_next;
}
+ else
+ /* This can happen for files that don't end with a newline,
+ and for cpp_define and friends. Pretend they do, so
+ callers don't have to deal. A warning will be issued by
+ someone else, if necessary. */
+ return CPP_VSPACE;
+ }
+}
- /* We must pop the buffer by hand, or else cpp_get_token might
- hand us white space or newline on the next invocation. */
- cpp_pop_buffer (pfile);
+/* Just like _cpp_get_define_token except that it discards horizontal
+ whitespace. */
+
+enum cpp_token
+_cpp_get_directive_token (pfile)
+ cpp_reader *pfile;
+{
+ int old_written = CPP_WRITTEN (pfile);
+ for (;;)
+ {
+ enum cpp_token token = _cpp_get_define_token (pfile);
+ if (token != CPP_COMMENT && token != CPP_HSPACE)
+ return token;
+ CPP_SET_WRITTEN (pfile, old_written);
}
}
@@ -1269,6 +1368,51 @@ find_position (start, limit, linep)
return lbase;
}
+/* The following table is used by _cpp_read_and_prescan. If we have
+ designated initializers, it can be constant data; otherwise, it is
+ set up at runtime by _cpp_init_input_buffer. */
+
+#ifndef UCHAR_MAX
+#define UCHAR_MAX 255 /* assume 8-bit bytes */
+#endif
+
+#if (GCC_VERSION >= 2007) || (__STDC_VERSION__ >= 199901L)
+#define init_chartab() /* nothing */
+#define CHARTAB static const unsigned char chartab[UCHAR_MAX + 1] = {
+#define END };
+#define s(p, v) [p] = v,
+#else
+#define CHARTAB static unsigned char chartab[UCHAR_MAX + 1] = { 0 }; \
+ static void init_chartab PARAMS ((void)) { \
+ unsigned char *x = chartab;
+#define END }
+#define s(p, v) x[p] = v;
+#endif
+
+/* Table of characters that can't be handled in the inner loop.
+ Also contains the mapping between trigraph third characters and their
+ replacements. */
+#define SPECCASE_CR 1
+#define SPECCASE_BACKSLASH 2
+#define SPECCASE_QUESTION 3
+
+CHARTAB
+ s('\r', SPECCASE_CR)
+ s('\\', SPECCASE_BACKSLASH)
+ s('?', SPECCASE_QUESTION)
+
+ s('=', '#') s(')', ']') s('!', '|')
+ s('(', '[') s('\'', '^') s('>', '}')
+ s('/', '\\') s('<', '{') s('-', '~')
+END
+
+#undef CHARTAB
+#undef END
+#undef s
+
+#define NORMAL(c) ((chartab[c]) == 0 || (chartab[c]) > SPECCASE_QUESTION)
+#define NONTRI(c) ((c) <= SPECCASE_QUESTION)
+
/* Read the entire contents of file DESC into buffer BUF. LEN is how
much memory to allocate initially; more will be allocated if
necessary. Convert end-of-line markers (\n, \r, \r\n, \n\r) to
@@ -1292,17 +1436,19 @@ find_position (start, limit, linep)
at the end of reload1.c is about 60%. (reload1.c is 329k.)
If your file has more than one kind of end-of-line marker, you
- will get messed-up line numbering. */
-
-/* Table of characters that can't be handled in the inner loop.
- Keep these contiguous to optimize the performance of the code generated
- for the switch that uses them. */
-#define SPECCASE_EMPTY 0
-#define SPECCASE_NUL 1
-#define SPECCASE_CR 2
-#define SPECCASE_BACKSLASH 3
-#define SPECCASE_QUESTION 4
-
+ will get messed-up line numbering.
+
+ So that the cases of the switch statement do not have to concern
+ themselves with the complications of reading beyond the end of the
+ buffer, the buffer is guaranteed to have at least 3 characters in
+ it (or however many are left in the file, if less) on entry to the
+ switch. This is enough to handle trigraphs and the "\\\n\r" and
+ "\\\r\n" cases.
+
+ The end of the buffer is marked by a '\\', which, being a special
+ character, guarantees we will exit the fast-scan loops and perform
+ a refill. */
+
long
_cpp_read_and_prescan (pfile, fp, desc, len)
cpp_reader *pfile;
@@ -1313,215 +1459,176 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
U_CHAR *buf = (U_CHAR *) xmalloc (len);
U_CHAR *ip, *op, *line_base;
U_CHAR *ibase;
- U_CHAR *speccase = pfile->input_speccase;
unsigned long line;
unsigned int deferred_newlines;
- int count;
size_t offset;
+ int count = 0;
offset = 0;
+ deferred_newlines = 0;
op = buf;
line_base = buf;
line = 1;
- ibase = pfile->input_buffer + 2;
- deferred_newlines = 0;
+ ibase = pfile->input_buffer + 3;
+ ip = ibase;
+ ip[-1] = '\0'; /* Guarantee no match with \n for SPECCASE_CR */
for (;;)
{
- read_next:
+ U_CHAR *near_buff_end;
+
+ /* Copy previous char plus unprocessed (at most 2) chars
+ to beginning of buffer, refill it with another
+ read(), and continue processing */
+ memcpy(ip - count - 1, ip - 1, 3);
+ ip -= count;
- count = read (desc, pfile->input_buffer + 2, pfile->input_buffer_len);
+ count = read (desc, ibase, pfile->input_buffer_len);
if (count < 0)
goto error;
- else if (count == 0)
- break;
-
- offset += count;
- ip = ibase;
- ibase = pfile->input_buffer + 2;
- ibase[count] = ibase[count+1] = '\0';
-
- if (offset > len)
+
+ ibase[count] = '\\'; /* Marks end of buffer */
+ if (count)
{
- size_t delta_op;
- size_t delta_line_base;
- len *= 2;
+ near_buff_end = pfile->input_buffer + count;
+ offset += count;
if (offset > len)
- /* len overflowed.
- This could happen if the file is larger than half the
- maximum address space of the machine. */
- goto too_big;
-
- delta_op = op - buf;
- delta_line_base = line_base - buf;
- buf = (U_CHAR *) xrealloc (buf, len);
- op = buf + delta_op;
- line_base = buf + delta_line_base;
+ {
+ size_t delta_op;
+ size_t delta_line_base;
+ len *= 2;
+ if (offset > len)
+ /* len overflowed.
+ This could happen if the file is larger than half the
+ maximum address space of the machine. */
+ goto too_big;
+
+ delta_op = op - buf;
+ delta_line_base = line_base - buf;
+ buf = (U_CHAR *) xrealloc (buf, len);
+ op = buf + delta_op;
+ line_base = buf + delta_line_base;
+ }
+ }
+ else
+ {
+ if (ip == ibase)
+ break;
+ /* Allow normal processing of the (at most 2) remaining
+ characters. The end-of-buffer marker is still present
+ and prevents false matches within the switch. */
+ near_buff_end = ibase - 1;
}
for (;;)
{
- unsigned int span = 0;
+ unsigned int span;
- /* Deal with \-newline in the middle of a token. */
+ /* Deal with \-newline, potentially in the middle of a token. */
if (deferred_newlines)
{
- while (speccase[ip[span]] == SPECCASE_EMPTY
- && ip[span] != '\n'
- && ip[span] != '\t'
- && ip[span] != ' ')
- span++;
- memcpy (op, ip, span);
- op += span;
- ip += span;
- /* If ip[0] is SPECCASE_EMPTY, we have hit white space.
- Dump out the remaining deferred \-newlines. */
- if (speccase[ip[0]] == SPECCASE_EMPTY)
- while (deferred_newlines)
- deferred_newlines--, *op++ = '\r';
- span = 0;
+ if (op != buf && ! is_space (op[-1]) && op[-1] != '\r')
+ {
+ /* Previous was not white space. Skip to white
+ space, if we can, before outputting the \r's */
+ span = 0;
+ while (ip[span] != ' '
+ && ip[span] != '\t'
+ && ip[span] != '\n'
+ && NORMAL(ip[span]))
+ span++;
+ memcpy (op, ip, span);
+ op += span;
+ ip += span;
+ if (! NORMAL(ip[0]))
+ goto do_speccase;
+ }
+ while (deferred_newlines)
+ deferred_newlines--, *op++ = '\r';
}
/* Copy as much as we can without special treatment. */
- while (speccase[ip[span]] == SPECCASE_EMPTY) span++;
+ span = 0;
+ while (NORMAL (ip[span])) span++;
memcpy (op, ip, span);
op += span;
ip += span;
- switch (speccase[*ip++])
+ do_speccase:
+ if (ip > near_buff_end) /* Do we have enough chars? */
+ break;
+ switch (chartab[*ip++])
{
- case SPECCASE_NUL: /* \0 */
- ibase[-1] = op[-1];
- goto read_next;
-
case SPECCASE_CR: /* \r */
- if (ip[-2] == '\n')
- continue;
- else if (*ip == '\n')
- ip++;
- else if (*ip == '\0')
+ if (ip[-2] != '\n')
{
- *--ibase = '\r';
- goto read_next;
+ if (*ip == '\n')
+ ip++;
+ *op++ = '\n';
}
- *op++ = '\n';
break;
case SPECCASE_BACKSLASH: /* \ */
- backslash:
- {
- /* If we're at the end of the intermediate buffer,
- we have to shift the backslash down to the start
- and come back next pass. */
- if (*ip == '\0')
- {
- *--ibase = '\\';
- goto read_next;
- }
- else if (*ip == '\n')
+ if (*ip == '\n')
{
+ deferred_newlines++;
ip++;
if (*ip == '\r') ip++;
- if (*ip == '\n' || *ip == '\t' || *ip == ' ')
- *op++ = '\r';
- else if (op[-1] == '\t' || op[-1] == ' '
- || op[-1] == '\r' || op[-1] == '\n')
- *op++ = '\r';
- else
- deferred_newlines++;
}
else if (*ip == '\r')
{
+ deferred_newlines++;
ip++;
if (*ip == '\n') ip++;
- else if (*ip == '\0')
- {
- *--ibase = '\r';
- *--ibase = '\\';
- goto read_next;
- }
- else if (*ip == '\r' || *ip == '\t' || *ip == ' ')
- *op++ = '\r';
- else
- deferred_newlines++;
}
else
*op++ = '\\';
- }
- break;
+ break;
case SPECCASE_QUESTION: /* ? */
{
unsigned int d, t;
- /* If we're at the end of the intermediate buffer,
- we have to shift the ?'s down to the start and
- come back next pass. */
- d = ip[0];
- if (d == '\0')
- {
- *--ibase = '?';
- goto read_next;
- }
- if (d != '?')
- {
- *op++ = '?';
- break;
- }
+
+ *op++ = '?'; /* Normal non-trigraph case */
+ if (ip[0] != '?')
+ break;
+
d = ip[1];
- if (d == '\0')
- {
- *--ibase = '?';
- *--ibase = '?';
- goto read_next;
- }
+ t = chartab[d];
+ if (NONTRI (t))
+ break;
- /* Trigraph map:
- * from to from to from to
- * ?? = # ?? ) ] ?? ! |
- * ?? ( [ ?? ' ^ ?? > }
- * ?? / \ ?? < { ?? - ~
- */
- if (d == '=') t = '#';
- else if (d == ')') t = ']';
- else if (d == '!') t = '|';
- else if (d == '(') t = '[';
- else if (d == '\'') t = '^';
- else if (d == '>') t = '}';
- else if (d == '/') t = '\\';
- else if (d == '<') t = '{';
- else if (d == '-') t = '~';
- else
- {
- *op++ = '?';
- break;
- }
- ip += 2;
- if (CPP_OPTIONS (pfile)->warn_trigraphs)
+ if (CPP_OPTION (pfile, warn_trigraphs))
{
unsigned long col;
line_base = find_position (line_base, op, &line);
col = op - line_base + 1;
- if (CPP_OPTIONS (pfile)->trigraphs)
+ if (CPP_OPTION (pfile, trigraphs))
cpp_warning_with_line (pfile, line, col,
- "trigraph ??%c converted to %c", d, t);
+ "trigraph ??%c converted to %c", d, t);
else
cpp_warning_with_line (pfile, line, col,
- "trigraph ??%c ignored", d);
+ "trigraph ??%c ignored", d);
}
- if (CPP_OPTIONS (pfile)->trigraphs)
+
+ ip += 2;
+ if (CPP_OPTION (pfile, trigraphs))
{
+ op[-1] = t; /* Overwrite '?' */
if (t == '\\')
- goto backslash;
- else
- *op++ = t;
+ {
+ op--;
+ *--ip = '\\';
+ goto do_speccase; /* May need buffer refill */
+ }
}
else
{
*op++ = '?';
- *op++ = '?';
*op++ = d;
}
}
+ break;
}
}
}
@@ -1529,28 +1636,6 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
if (offset == 0)
return 0;
- /* Deal with pushed-back chars at true EOF.
- This may be any of: ?? ? \ \r \n \\r \\n.
- \r must become \n, \\r or \\n must become \r.
- We know we have space already. */
- if (ibase == pfile->input_buffer)
- {
- if (*ibase == '?')
- {
- *op++ = '?';
- *op++ = '?';
- }
- else
- *op++ = '\r';
- }
- else if (ibase == pfile->input_buffer + 1)
- {
- if (*ibase == '\r')
- *op++ = '\n';
- else
- *op++ = *ibase;
- }
-
if (op[-1] != '\n')
{
unsigned long col;
@@ -1582,39 +1667,25 @@ _cpp_read_and_prescan (pfile, fp, desc, len)
return -1;
}
-/* Initialize the `input_buffer' and `input_speccase' tables.
- These are only used by read_and_prescan, but they're large and
- somewhat expensive to set up, so we want them allocated once for
- the duration of the cpp run. */
-
+/* Allocate pfile->input_buffer, and initialize chartab[]
+ if it hasn't happened already. */
+
void
_cpp_init_input_buffer (pfile)
cpp_reader *pfile;
{
U_CHAR *tmp;
- /* Table of characters that cannot be handled by the
- read_and_prescan inner loop. The number of non-EMPTY entries
- should be as small as humanly possible. */
-
- tmp = (U_CHAR *) xmalloc (1 << CHAR_BIT);
- memset (tmp, SPECCASE_EMPTY, 1 << CHAR_BIT);
- tmp['\0'] = SPECCASE_NUL;
- tmp['\r'] = SPECCASE_CR;
- tmp['\\'] = SPECCASE_BACKSLASH;
- if (CPP_OPTIONS (pfile)->trigraphs || CPP_OPTIONS (pfile)->warn_trigraphs)
- tmp['?'] = SPECCASE_QUESTION;
-
- pfile->input_speccase = tmp;
+ init_chartab ();
/* Determine the appropriate size for the input buffer. Normal C
source files are smaller than eight K. */
- /* 8Kbytes of buffer proper, 2 to detect running off the end without
- address arithmetic all the time, and 2 for pushback in the case
- there's a potential trigraph or end-of-line digraph at the end of
- a block. */
+ /* 8Kbytes of buffer proper, 1 to detect running off the end without
+ address arithmetic all the time, and 3 for pushback during buffer
+ refill, in case there's a potential trigraph or end-of-line
+ digraph at the end of a block. */
- tmp = (U_CHAR *) xmalloc (8192 + 2 + 2);
+ tmp = (U_CHAR *) xmalloc (8192 + 1 + 3);
pfile->input_buffer = tmp;
pfile->input_buffer_len = 8192;
}
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index dac186d9904..babd20e8b4c 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -26,21 +26,17 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "cpphash.h"
#include "hashtab.h"
#include "intl.h"
-
-#define PEEKN(N) (CPP_BUFFER (pfile)->rlimit - CPP_BUFFER (pfile)->cur >= (N) \
- ? CPP_BUFFER (pfile)->cur[N] : EOF)
-#define FORWARD(N) CPP_FORWARD (CPP_BUFFER (pfile), (N))
-#define GETC() CPP_BUF_GET (CPP_BUFFER (pfile))
-#define PEEKC() CPP_BUF_PEEK (CPP_BUFFER (pfile))
+#include "symcat.h"
/* `struct directive' defines one #-directive, including how to handle it. */
struct directive
{
- unsigned int length; /* Length of name */
- const char *name; /* Name of directive */
int (*func) /* Function to handle directive */
PARAMS ((cpp_reader *));
+ const char *name; /* Name of directive */
+ unsigned short length; /* Length of name */
+ unsigned short origin; /* Origin of this directive */
};
/* Stack of conditionals currently in progress
@@ -61,9 +57,9 @@ typedef struct if_stack IF_STACK;
static void validate_else PARAMS ((cpp_reader *, const char *));
static int parse_ifdef PARAMS ((cpp_reader *, const char *));
static unsigned int parse_include PARAMS ((cpp_reader *, const char *));
-static void conditional_skip PARAMS ((cpp_reader *, int, int,
+static int conditional_skip PARAMS ((cpp_reader *, int, int,
U_CHAR *));
-static void skip_if_group PARAMS ((cpp_reader *));
+static int skip_if_group PARAMS ((cpp_reader *));
static void pass_thru_directive PARAMS ((const U_CHAR *, size_t,
cpp_reader *, int));
static int read_line_number PARAMS ((cpp_reader *, int *));
@@ -72,6 +68,15 @@ static int consider_directive_while_skipping
PARAMS ((cpp_reader *, IF_STACK *));
static int get_macro_name PARAMS ((cpp_reader *));
+/* Values for the "origin" field of the table below. KANDR and COND
+ directives come from traditional (K&R) C. The difference is, if we
+ care about it while skipping a failed conditional block, its origin
+ is COND. STDC89 directives come from the 1989 C standard.
+ EXTENSION directives are extensions, with origins noted below. */
+enum { KANDR = 0, COND, STDC89, EXTENSION };
+
+#define TRAD_DIRECT_P(x) ((x) == KANDR || (x) == COND)
+
/* This is the table of directive handlers. It is ordered by
frequency of occurrence; the numbers at the end are directive
counts from all the source code I have lying around (egcs and libc
@@ -82,26 +87,33 @@ static int get_macro_name PARAMS ((cpp_reader *));
of which all but #warning and #include_next are deprecated. The name
is where the extension appears to have come from. */
+/* #sccs is not always recognized. */
+#ifdef SCCS_DIRECTIVE
+# define SCCS_ENTRY D(sccs, T_SCCS, EXTENSION) /* 0 - SVR2? */
+#else
+# define SCCS_ENTRY /* nothing */
+#endif
+
#define DIRECTIVE_TABLE \
-D("define", do_define, T_DEFINE) /* 270554 */ \
-D("include", do_include, T_INCLUDE) /* 52262 */ \
-D("endif", do_endif, T_ENDIF) /* 45855 */ \
-D("ifdef", do_ifdef, T_IFDEF) /* 22000 */ \
-D("if", do_if, T_IF) /* 18162 */ \
-D("else", do_else, T_ELSE) /* 9863 */ \
-D("ifndef", do_ifndef, T_IFNDEF) /* 9675 */ \
-D("undef", do_undef, T_UNDEF) /* 4837 */ \
-D("line", do_line, T_LINE) /* 2465 */ \
-D("elif", do_elif, T_ELIF) /* 610 */ \
-D("error", do_error, T_ERROR) /* 475 */ \
-D("pragma", do_pragma, T_PRAGMA) /* 195 */ \
-D("warning", do_warning, T_WARNING) /* 22 - GNU */ \
-D("include_next", do_include_next, T_INCLUDE_NEXT) /* 19 - GNU */ \
-D("ident", do_ident, T_IDENT) /* 11 - SVR4 */ \
-D("import", do_import, T_IMPORT) /* 0 - ObjC */ \
-D("assert", do_assert, T_ASSERT) /* 0 - SVR4 */ \
-D("unassert", do_unassert, T_UNASSERT) /* 0 - SVR4 */ \
-D("sccs", do_sccs, T_SCCS) /* 0 - SVR2? */
+D(define, T_DEFINE = 0, KANDR) /* 270554 */ \
+D(include, T_INCLUDE, KANDR) /* 52262 */ \
+D(endif, T_ENDIF, COND) /* 45855 */ \
+D(ifdef, T_IFDEF, COND) /* 22000 */ \
+D(if, T_IF, COND) /* 18162 */ \
+D(else, T_ELSE, COND) /* 9863 */ \
+D(ifndef, T_IFNDEF, COND) /* 9675 */ \
+D(undef, T_UNDEF, KANDR) /* 4837 */ \
+D(line, T_LINE, KANDR) /* 2465 */ \
+D(elif, T_ELIF, COND) /* 610 */ \
+D(error, T_ERROR, STDC89) /* 475 */ \
+D(pragma, T_PRAGMA, STDC89) /* 195 */ \
+D(warning, T_WARNING, EXTENSION) /* 22 - GNU */ \
+D(include_next, T_INCLUDE_NEXT, EXTENSION) /* 19 - GNU */ \
+D(ident, T_IDENT, EXTENSION) /* 11 - SVR4 */ \
+D(import, T_IMPORT, EXTENSION) /* 0 - ObjC */ \
+D(assert, T_ASSERT, EXTENSION) /* 0 - SVR4 */ \
+D(unassert, T_UNASSERT, EXTENSION) /* 0 - SVR4 */ \
+SCCS_ENTRY
/* Use the table to generate a series of prototypes, an enum for the
directive names, and an array of directive handlers. */
@@ -110,11 +122,12 @@ D("sccs", do_sccs, T_SCCS) /* 0 - SVR2? */
instead of void, because some old compilers have trouble with
pointers to functions returning void. */
-#define D(name, fun, tag) static int fun PARAMS ((cpp_reader *));
+/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
+#define D(name, t, o) static int CONCAT2(do_,name) PARAMS ((cpp_reader *));
DIRECTIVE_TABLE
#undef D
-#define D(name, fun, tag) tag,
+#define D(n, tag, o) tag,
enum
{
DIRECTIVE_TABLE
@@ -122,7 +135,9 @@ enum
};
#undef D
-#define D(name, fun, tag) { sizeof name - 1, name, fun },
+/* Don't invoke CONCAT2 with any whitespace or K&R cc will fail. */
+#define D(name, t, origin) \
+{ CONCAT2(do_,name), STRINGX(name), sizeof STRINGX(name) - 1, origin },
static const struct directive dtable[] =
{
DIRECTIVE_TABLE
@@ -137,10 +152,12 @@ int
_cpp_handle_directive (pfile)
cpp_reader *pfile;
{
- int c, i;
+ int i;
+ int hash_at_bol;
unsigned int len;
U_CHAR *ident;
long old_written = CPP_WRITTEN (pfile);
+ enum cpp_token tok;
if (CPP_IS_MACRO_BUFFER (CPP_BUFFER (pfile)))
{
@@ -148,68 +165,119 @@ _cpp_handle_directive (pfile)
return 0;
}
- _cpp_skip_hspace (pfile);
+ /* -traditional directives are recognized only with the # in column 1. */
+ hash_at_bol = CPP_IN_COLUMN_1 (pfile);
+
+ /* Scan the next token, then pretend we didn't. */
+ CPP_SET_MARK (pfile);
+ pfile->no_macro_expand++;
+ tok = _cpp_get_directive_token (pfile);
+ pfile->no_macro_expand--;
+
+ ident = pfile->token_buffer + old_written;
+ len = CPP_PWRITTEN (pfile) - ident;
+ CPP_SET_WRITTEN (pfile, old_written);
+ CPP_GOTO_MARK (pfile);
- c = PEEKC ();
/* # followed by a number is equivalent to #line. Do not recognize
this form in assembly language source files. Complain about this
form if we're being pedantic, but not if this is regurgitated
input (preprocessed or fed back in by the C++ frontend). */
- if (c >= '0' && c <= '9')
+ if (tok == CPP_NUMBER)
{
- if (CPP_OPTIONS (pfile)->lang_asm)
+ if (CPP_OPTION (pfile, lang_asm))
return 0;
if (CPP_PEDANTIC (pfile)
- && ! CPP_OPTIONS (pfile)->preprocessed
+ && ! CPP_OPTION (pfile, preprocessed)
&& ! CPP_BUFFER (pfile)->manual_pop)
- cpp_pedwarn (pfile, "`#' followed by integer");
+ cpp_pedwarn (pfile, "# followed by integer");
do_line (pfile);
return 1;
}
/* If we are rescanning preprocessed input, don't obey any directives
other than # nnn. */
- if (CPP_OPTIONS (pfile)->preprocessed)
+ else if (CPP_OPTION (pfile, preprocessed))
return 0;
- /* Now find the directive name. */
- CPP_PUTC (pfile, '#');
- _cpp_parse_name (pfile, GETC());
- ident = pfile->token_buffer + old_written + 1;
- len = CPP_PWRITTEN (pfile) - ident;
- if (len == 0)
+ /* A line of just # becomes blank. */
+ else if (tok == CPP_VSPACE)
+ return 1;
+
+ /* A NAME token might in fact be a directive! */
+ else if (tok == CPP_NAME)
{
- /* A line of just `#' becomes blank. A line with something
- other than an identifier after the # is reparsed as a non-
- directive line. */
- CPP_SET_WRITTEN (pfile, old_written);
- return (PEEKC() == '\n');
+ for (i = 0; i < N_DIRECTIVES; i++)
+ {
+ if (dtable[i].length == len
+ && !strncmp (dtable[i].name, ident, len))
+ goto real_directive;
+ }
+ /* Don't complain about invalid directives in assembly source,
+ we don't know where the comments are, and # may introduce
+ assembler pseudo-ops. */
+ if (!CPP_OPTION (pfile, lang_asm))
+ cpp_error (pfile, "invalid preprocessing directive #%s", ident);
+ return 0;
}
+ /* And anything else means the # wasn't a directive marker. */
+ else
+ return 0;
- /* Decode the keyword and call the appropriate expansion routine. */
- for (i = 0; i < N_DIRECTIVES; i++)
+ real_directive:
+
+ /* In -traditional mode, a directive is ignored unless its # is in
+ column 1. */
+ if (CPP_TRADITIONAL (pfile) && !hash_at_bol)
{
- if (dtable[i].length == len
- && !strncmp (dtable[i].name, ident, len))
- break;
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "ignoring #%s because of its indented #",
+ dtable[i].name);
+ return 0;
}
- if (i == N_DIRECTIVES)
- /* # identifier, but not a legit directive. Pass onward as a
- CPP_DIRECTIVE token anyway - let the consumer worry about it. */
- return 1;
-
- CPP_SET_WRITTEN (pfile, old_written);
+ /* no_directives is set when we are parsing macro arguments. Directives
+ in macro arguments are undefined behavior (C99 6.10.3.11); this
+ implementation chooses to make them hard errors. */
if (pfile->no_directives)
{
- cpp_error (pfile, "`#%s' may not be used inside a macro argument",
+ cpp_error (pfile, "#%s may not be used inside a macro argument",
dtable[i].name);
_cpp_skip_rest_of_line (pfile);
+ return 1;
+ }
+
+ /* Issue -pedantic warnings for extended directives. */
+ if (CPP_PEDANTIC (pfile) && dtable[i].origin == EXTENSION)
+ cpp_pedwarn (pfile, "ISO C does not allow #%s", dtable[i].name);
+
+ /* -Wtraditional gives warnings about directives with inappropriate
+ indentation of #. */
+ if (CPP_WTRADITIONAL (pfile))
+ {
+ if (!hash_at_bol && TRAD_DIRECT_P (dtable[i].origin))
+ cpp_warning (pfile, "traditional C ignores #%s with the # indented",
+ dtable[i].name);
+ else if (hash_at_bol && ! TRAD_DIRECT_P (dtable[i].origin))
+ cpp_warning (pfile,
+ "suggest hiding #%s from traditional C with an indented #",
+ dtable[i].name);
}
- else
- (*dtable[i].func) (pfile);
+ /* Unfortunately, it's necessary to scan the directive name again,
+ now we know we're going to consume it. FIXME. */
+
+ pfile->no_macro_expand++;
+ _cpp_get_directive_token (pfile);
+ pfile->no_macro_expand--;
+ CPP_SET_WRITTEN (pfile, old_written);
+
+ /* Some directives (e.g. #if) may return a request to execute
+ another directive handler immediately. No directive ever
+ requests that #define be executed immediately, so it is safe for
+ the loop to terminate when some function returns 0 (== T_DEFINE). */
+ while ((i = dtable[i].func (pfile)));
return 1;
}
@@ -246,7 +314,6 @@ get_macro_name (pfile)
long here, len;
here = CPP_WRITTEN (pfile);
- pfile->no_macro_expand++;
if (_cpp_get_directive_token (pfile) != CPP_NAME)
{
cpp_error (pfile, "`#define' must be followed by an identifier");
@@ -260,12 +327,10 @@ get_macro_name (pfile)
goto invalid;
}
- pfile->no_macro_expand--;
return len;
invalid:
_cpp_skip_rest_of_line (pfile);
- pfile->no_macro_expand--;
return 0;
}
@@ -276,38 +341,52 @@ do_define (pfile)
cpp_reader *pfile;
{
HASHNODE **slot;
- DEFINITION *def;
+ DEFINITION *def = 0;
long here;
unsigned long hash;
- int len, c;
- int funlike = 0;
+ int len;
+ int funlike = 0, empty = 0;
U_CHAR *sym;
+ enum cpp_token token;
+
+ pfile->no_macro_expand++;
+ pfile->parsing_define_directive++;
+ CPP_OPTION (pfile, discard_comments)++;
+ CPP_OPTION (pfile, no_line_commands)++;
here = CPP_WRITTEN (pfile);
len = get_macro_name (pfile);
if (len == 0)
- return 0;
+ goto out;
/* Copy out the name so we can pop the token buffer. */
len = CPP_WRITTEN (pfile) - here;
sym = (U_CHAR *) alloca (len + 1);
memcpy (sym, pfile->token_buffer + here, len);
sym[len] = '\0';
- CPP_SET_WRITTEN (pfile, here);
/* If the next character, with no intervening whitespace, is '(',
- then this is a function-like macro. */
- c = PEEKC ();
- if (c == '(')
+ then this is a function-like macro.
+ XXX Layering violation. */
+ CPP_SET_MARK (pfile);
+ token = _cpp_get_directive_token (pfile);
+ if (token == CPP_VSPACE)
+ empty = 0; /* Empty definition of object like macro. */
+ else if (token == CPP_LPAREN && ADJACENT_TO_MARK (pfile))
funlike = 1;
- else if (c != '\n' && !is_hspace (c))
- /* Otherwise, C99 requires white space after the name. We treat it
- as an object-like macro if this happens, with a warning. */
+ else if (ADJACENT_TO_MARK (pfile))
+ /* If this is an object-like macro, C99 requires white space after
+ the name. */
cpp_pedwarn (pfile, "missing white space after `#define %.*s'", len, sym);
+ CPP_GOTO_MARK (pfile);
+ CPP_SET_WRITTEN (pfile, here);
- def = _cpp_create_definition (pfile, funlike);
- if (def == 0)
- return 0;
+ if (! empty)
+ {
+ def = _cpp_create_definition (pfile, funlike);
+ if (def == 0)
+ goto out;
+ }
slot = _cpp_lookup_slot (pfile, sym, len, 1, &hash);
if (*slot)
@@ -317,10 +396,12 @@ do_define (pfile)
/* Redefining a macro is ok if the definitions are the same. */
if (hp->type == T_MACRO)
- ok = ! _cpp_compare_defs (pfile, def, hp->value.defn);
+ ok = ! empty && ! _cpp_compare_defs (pfile, def, hp->value.defn);
+ else if (hp->type == T_EMPTY)
+ ok = empty;
/* Redefining a constant is ok with -D. */
else if (hp->type == T_CONST || hp->type == T_STDC)
- ok = ! CPP_OPTIONS (pfile)->done_initializing;
+ ok = ! pfile->done_initializing;
/* Otherwise it's not ok. */
else
ok = 0;
@@ -331,7 +412,7 @@ do_define (pfile)
cpp_error (pfile, "redefining poisoned `%.*s'", len, sym);
else
cpp_pedwarn (pfile, "`%.*s' redefined", len, sym);
- if (hp->type == T_MACRO && CPP_OPTIONS (pfile)->done_initializing)
+ if (hp->type == T_MACRO && pfile->done_initializing)
{
DEFINITION *d = hp->value.defn;
cpp_pedwarn_with_file_and_line (pfile, d->file, d->line, d->col,
@@ -343,8 +424,16 @@ do_define (pfile)
/* Replace the old definition. */
if (hp->type == T_MACRO)
_cpp_free_definition (hp->value.defn);
- hp->type = T_MACRO;
- hp->value.defn = def;
+ if (empty)
+ {
+ hp->type = T_EMPTY;
+ hp->value.defn = 0;
+ }
+ else
+ {
+ hp->type = T_MACRO;
+ hp->value.defn = def;
+ }
}
}
else
@@ -354,12 +443,17 @@ do_define (pfile)
*slot = hp;
}
- if (CPP_OPTIONS (pfile)->debug_output
- || CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
+ if (CPP_OPTION (pfile, debug_output)
+ || CPP_OPTION (pfile, dump_macros) == dump_definitions)
_cpp_dump_definition (pfile, sym, len, def);
- else if (CPP_OPTIONS (pfile)->dump_macros == dump_names)
+ else if (CPP_OPTION (pfile, dump_macros) == dump_names)
pass_thru_directive (sym, len, pfile, T_DEFINE);
+ out:
+ pfile->no_macro_expand--;
+ pfile->parsing_define_directive--;
+ CPP_OPTION (pfile, discard_comments)--;
+ CPP_OPTION (pfile, no_line_commands)--;
return 0;
}
@@ -376,8 +470,8 @@ _cpp_output_line_command (pfile, file_change)
long line;
cpp_buffer *ip;
- if (CPP_OPTIONS (pfile)->no_line_commands
- || CPP_OPTIONS (pfile)->no_output)
+ if (CPP_OPTION (pfile, no_line_commands)
+ || CPP_OPTION (pfile, no_output))
return;
ip = cpp_file_buffer (pfile);
@@ -428,7 +522,7 @@ _cpp_output_line_command (pfile, file_change)
}
#ifndef NO_IMPLICIT_EXTERN_C
/* Tell cc1plus if following text should be treated as C. */
- if (ip->system_header_p == 2 && CPP_OPTIONS (pfile)->cplusplus)
+ if (ip->system_header_p == 2 && CPP_OPTION (pfile, cplusplus))
{
CPP_PUTC_Q (pfile, ' ');
CPP_PUTC_Q (pfile, '4');
@@ -508,10 +602,12 @@ do_include (pfile)
char *token;
len = parse_include (pfile, dtable[T_INCLUDE].name);
+ if (len == 0)
+ return 0;
token = alloca (len + 1);
strcpy (token, CPP_PWRITTEN (pfile));
- if (CPP_OPTIONS (pfile)->dump_includes)
+ if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_INCLUDE);
_cpp_execute_include (pfile, token, len, 0, 0);
@@ -525,10 +621,7 @@ do_import (pfile)
unsigned int len;
char *token;
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "ANSI C does not allow `#import'");
-
- if (CPP_OPTIONS (pfile)->warn_import
+ if (CPP_OPTION (pfile, warn_import)
&& !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning)
{
pfile->import_warning = 1;
@@ -537,10 +630,12 @@ do_import (pfile)
}
len = parse_include (pfile, dtable[T_IMPORT].name);
+ if (len == 0)
+ return 0;
token = alloca (len + 1);
strcpy (token, CPP_PWRITTEN (pfile));
- if (CPP_OPTIONS (pfile)->dump_includes)
+ if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_IMPORT);
_cpp_execute_include (pfile, token, len, 1, 0);
@@ -555,15 +650,13 @@ do_include_next (pfile)
char *token;
struct file_name_list *search_start = 0;
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "ANSI C does not allow `#include_next'");
-
len = parse_include (pfile, dtable[T_INCLUDE_NEXT].name);
-
+ if (len == 0)
+ return 0;
token = alloca (len + 1);
strcpy (token, CPP_PWRITTEN (pfile));
- if (CPP_OPTIONS (pfile)->dump_includes)
+ if (CPP_OPTION (pfile, dump_includes))
pass_thru_directive (token, len, pfile, T_INCLUDE_NEXT);
/* For #include_next, skip in the search path past the dir in which the
@@ -739,29 +832,21 @@ do_undef (pfile)
{
int len;
HASHNODE **slot;
- U_CHAR *buf, *name, *limit;
- int c;
+ U_CHAR *name;
long here = CPP_WRITTEN (pfile);
enum cpp_token token;
- _cpp_skip_hspace (pfile);
- c = GETC();
- if (! is_idstart(c))
- {
+ pfile->no_macro_expand++;
+ token = _cpp_get_directive_token (pfile);
+ pfile->no_macro_expand--;
+
+ if (token != CPP_NAME)
+ {
cpp_error (pfile, "token after #undef is not an identifier");
_cpp_skip_rest_of_line (pfile);
- return 1;
- }
-
- _cpp_parse_name (pfile, c);
- buf = pfile->token_buffer + here;
- limit = CPP_PWRITTEN(pfile);
-
- /* Copy out the token so we can pop the token buffer. */
- len = limit - buf;
- name = (U_CHAR *) alloca (len + 1);
- memcpy (name, buf, len);
- name[len] = '\0';
+ return 0;
+ }
+ len = CPP_WRITTEN (pfile) - here;
token = _cpp_get_directive_token (pfile);
if (token != CPP_VSPACE)
@@ -769,20 +854,23 @@ do_undef (pfile)
cpp_pedwarn (pfile, "junk on line after #undef");
_cpp_skip_rest_of_line (pfile);
}
+
+ name = pfile->token_buffer + here;
CPP_SET_WRITTEN (pfile, here);
slot = _cpp_lookup_slot (pfile, name, len, 0, 0);
if (slot)
{
HASHNODE *hp = *slot;
- /* If we are generating additional info for debugging (with -g) we
- need to pass through all effective #undef commands. */
- if (CPP_OPTIONS (pfile)->debug_output)
- pass_thru_directive (name, len, pfile, T_UNDEF);
if (hp->type == T_POISON)
cpp_error (pfile, "cannot undefine poisoned `%s'", hp->name);
- else
+ else
{
+ /* If we are generating additional info for debugging (with -g) we
+ need to pass through all effective #undef commands. */
+ if (CPP_OPTION (pfile, debug_output))
+ pass_thru_directive (hp->name, len, pfile, T_UNDEF);
+
if (hp->type != T_MACRO)
cpp_warning (pfile, "undefining `%s'", hp->name);
@@ -830,9 +918,6 @@ do_warning (pfile)
_cpp_skip_rest_of_line (pfile);
limit = CPP_BUFFER (pfile)->cur;
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "ANSI C does not allow `#warning'");
-
cpp_warning (pfile, "#warning %.*s", (int)(limit - text), text);
return 0;
}
@@ -845,10 +930,6 @@ do_ident (pfile)
{
long old_written = CPP_WRITTEN (pfile);
- /* Allow #ident in system headers, since that's not user's fault. */
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "ANSI C does not allow `#ident'");
-
CPP_PUTS (pfile, "#ident ", 7);
/* Next token should be a string constant. */
@@ -1016,9 +1097,9 @@ do_pragma_poison (pfile)
/* As a rule, don't include #pragma poison commands in output,
unless the user asks for them. */
- writeit = (CPP_OPTIONS (pfile)->debug_output
- || CPP_OPTIONS (pfile)->dump_macros == dump_definitions
- || CPP_OPTIONS (pfile)->dump_macros == dump_names);
+ writeit = (CPP_OPTION (pfile, debug_output)
+ || CPP_OPTION (pfile, dump_macros) == dump_definitions
+ || CPP_OPTION (pfile, dump_macros) == dump_names);
for (;;)
{
@@ -1061,20 +1142,15 @@ do_pragma_poison (pfile)
}
/* Just ignore #sccs, on systems where we define it at all. */
+#ifdef SCCS_DIRECTIVE
static int
do_sccs (pfile)
cpp_reader *pfile;
{
-#ifdef SCCS_DIRECTIVE
- if (CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "ANSI C does not allow `#sccs'");
-#else
- cpp_error (pfile, "undefined or invalid # directive `sccs'");
-#endif
_cpp_skip_rest_of_line (pfile);
return 0;
}
-
+#endif
/* We've found an `#if' directive. If the only thing before it in
this file is white space, and if it is of the form
@@ -1161,8 +1237,7 @@ do_if (pfile)
{
U_CHAR *control_macro = detect_if_not_defined (pfile);
int value = _cpp_parse_expr (pfile);
- conditional_skip (pfile, value == 0, T_IF, control_macro);
- return 0;
+ return conditional_skip (pfile, value == 0, T_IF, control_macro);
}
/*
@@ -1191,17 +1266,14 @@ do_elif (pfile)
}
if (pfile->if_stack->if_succeeded)
- skip_if_group (pfile);
- else
{
- if (_cpp_parse_expr (pfile) == 0)
- skip_if_group (pfile);
- else
- {
- ++pfile->if_stack->if_succeeded; /* continue processing input */
- _cpp_output_line_command (pfile, same_file);
- }
+ _cpp_skip_rest_of_line (pfile);
+ return skip_if_group (pfile);
}
+ if (_cpp_parse_expr (pfile) == 0)
+ return skip_if_group (pfile);
+
+ ++pfile->if_stack->if_succeeded; /* continue processing input */
return 0;
}
@@ -1268,8 +1340,7 @@ do_ifdef (pfile)
cpp_reader *pfile;
{
int skip = ! parse_ifdef (pfile, dtable[T_IFDEF].name);
- conditional_skip (pfile, skip, T_IFDEF, 0);
- return 0;
+ return conditional_skip (pfile, skip, T_IFDEF, 0);
}
/* #ifndef is a tad more complex, because we need to check for a
@@ -1286,10 +1357,9 @@ do_ifndef (pfile)
skip = parse_ifdef (pfile, dtable[T_IFNDEF].name);
if (start_of_file && !skip)
- control_macro = xstrdup (CPP_PWRITTEN (pfile));
+ control_macro = (U_CHAR *) xstrdup (CPP_PWRITTEN (pfile));
- conditional_skip (pfile, skip, T_IFNDEF, control_macro);
- return 0;
+ return conditional_skip (pfile, skip, T_IFNDEF, control_macro);
}
/* Push TYPE on stack; then, if SKIP is nonzero, skip ahead.
@@ -1297,7 +1367,7 @@ do_ifndef (pfile)
CONTROL_MACRO is the macro name tested by the #ifndef.
Otherwise, CONTROL_MACRO is 0. */
-static void
+static int
conditional_skip (pfile, skip, type, control_macro)
cpp_reader *pfile;
int skip;
@@ -1314,19 +1384,19 @@ conditional_skip (pfile, skip, type, control_macro)
pfile->if_stack->type = type;
- if (skip != 0) {
- skip_if_group (pfile);
- return;
- } else {
- ++pfile->if_stack->if_succeeded;
- _cpp_output_line_command (pfile, same_file);
- }
+ if (skip != 0)
+ return skip_if_group (pfile);
+
+ ++pfile->if_stack->if_succeeded;
+ return 0;
}
-/* Subroutine of skip_if_group. Examine one preprocessing directive and
- return 0 if skipping should continue, 1 if it should halt. Also
- adjusts the if_stack as appropriate.
- The `#' has been read, but not the identifier. */
+/* Subroutine of skip_if_group. Examine one preprocessing directive
+ and return 0 if skipping should continue, or the directive number
+ of the directive that ends the block if it should halt.
+
+ Also adjusts the if_stack as appropriate. The `#' has been read,
+ but not the identifier. */
static int
consider_directive_while_skipping (pfile, stack)
@@ -1334,119 +1404,137 @@ consider_directive_while_skipping (pfile, stack)
IF_STACK *stack;
{
long ident;
- const struct directive *kt;
- int i;
+ int i, hash_at_bol;
unsigned int len;
IF_STACK *temp;
-
- _cpp_skip_hspace (pfile);
+
+ /* -traditional directives are recognized only with the # in column 1. */
+ hash_at_bol = CPP_IN_COLUMN_1 (pfile);
ident = CPP_WRITTEN (pfile);
- _cpp_parse_name (pfile, GETC());
+ if (_cpp_get_directive_token (pfile) != CPP_NAME)
+ return 0;
len = CPP_WRITTEN (pfile) - ident;
- CPP_SET_WRITTEN (pfile, ident);
-
for (i = 0; i < N_DIRECTIVES; i++)
{
- kt = &dtable[i];
- if (kt->length == len
- && strncmp (pfile->token_buffer + ident, kt->name, kt->length) == 0)
- switch (i)
- {
- case T_IF:
- case T_IFDEF:
- case T_IFNDEF:
- temp = (IF_STACK *) xmalloc (sizeof (IF_STACK));
- temp->next = pfile->if_stack;
- pfile->if_stack = temp;
- temp->type = i;
- return 0;
-
- case T_ELSE:
- if (pfile->if_stack != stack)
- validate_else (pfile, dtable[i].name);
- /* fall through */
- case T_ELIF:
- if (pfile->if_stack == stack)
- return 1;
- else
- {
- pfile->if_stack->type = i;
- return 0;
- }
-
- case T_ENDIF:
- if (pfile->if_stack != stack)
- validate_else (pfile, dtable[i].name);
-
- if (pfile->if_stack == stack)
- return 1;
-
- temp = pfile->if_stack;
- pfile->if_stack = temp->next;
- free (temp);
- return 0;
-
- default:
- return 0;
- }
+ if (dtable[i].length == len
+ && !strncmp (dtable[i].name, pfile->token_buffer + ident, len))
+ goto real_directive;
}
+ return 0;
+
+ real_directive:
- /* Don't let erroneous code go by. */
- if (!CPP_OPTIONS (pfile)->lang_asm && CPP_PEDANTIC (pfile))
- cpp_pedwarn (pfile, "invalid preprocessor directive name");
+ /* If it's not a directive of interest to us, return now. */
+ if (dtable[i].origin != COND)
return 0;
+
+ /* First, deal with -traditional and -Wtraditional.
+ All COND directives are from K+R. */
+
+ if (! hash_at_bol)
+ {
+ if (CPP_TRADITIONAL (pfile))
+ {
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "ignoring #%s because of its indented #",
+ dtable[i].name);
+ return 0;
+ }
+ if (CPP_WTRADITIONAL (pfile))
+ cpp_warning (pfile, "traditional C ignores %s with the # indented",
+ dtable[i].name);
+ }
+
+ switch (i)
+ {
+ default:
+ cpp_ice (pfile, "non COND directive in switch in c_d_w_s");
+ return 0;
+
+ case T_IF:
+ case T_IFDEF:
+ case T_IFNDEF:
+ temp = (IF_STACK *) xcalloc (1, sizeof (IF_STACK));
+ temp->lineno = CPP_BUFFER (pfile)->lineno;
+ temp->next = pfile->if_stack;
+ temp->type = i;
+ pfile->if_stack = temp;
+ return 0;
+
+ case T_ELSE:
+ if (pfile->if_stack != stack)
+ validate_else (pfile, dtable[i].name);
+ /* fall through */
+ case T_ELIF:
+ if (pfile->if_stack == stack)
+ return i;
+
+ pfile->if_stack->type = i;
+ return 0;
+
+ case T_ENDIF:
+ if (pfile->if_stack != stack)
+ validate_else (pfile, dtable[i].name);
+
+ if (pfile->if_stack == stack)
+ return i;
+
+ temp = pfile->if_stack;
+ pfile->if_stack = temp->next;
+ free (temp);
+ return 0;
+ }
}
-/* skip to #endif, #else, or #elif. adjust line numbers, etc.
- * leaves input ptr at the sharp sign found.
- */
-static void
+/* Skip to #endif, #else, or #elif. Consumes the directive that
+ causes it to stop, but not its argument. Returns the number of
+ that directive, which must be passed back up to
+ _cpp_handle_directive, which will execute it. */
+static int
skip_if_group (pfile)
cpp_reader *pfile;
{
- int c;
+ enum cpp_token token;
IF_STACK *save_if_stack = pfile->if_stack; /* don't pop past here */
- const U_CHAR *beg_of_line;
long old_written;
+ int ret = 0;
+
+ /* We are no longer at the start of the file. */
+ pfile->only_seen_white = 0;
old_written = CPP_WRITTEN (pfile);
-
+ pfile->no_macro_expand++;
+ CPP_OPTION (pfile, no_line_commands)++;
for (;;)
{
- beg_of_line = CPP_BUFFER (pfile)->cur;
+ /* We are at the end of a line. Only cpp_get_token knows how to
+ advance the line number correctly. */
+ token = cpp_get_token (pfile);
+ if (token == CPP_POP)
+ break; /* Caller will issue error. */
+
+ else if (token != CPP_VSPACE)
+ cpp_ice (pfile, "cpp_get_token returned %d in skip_if_group", token);
+ CPP_SET_WRITTEN (pfile, old_written);
- if (! CPP_TRADITIONAL (pfile))
- _cpp_skip_hspace (pfile);
- c = GETC();
- if (c == '\n')
- {
- CPP_BUMP_LINE (pfile);
- continue;
- }
- else if (c == '#')
+ token = _cpp_get_directive_token (pfile);
+
+ if (token == CPP_DIRECTIVE)
{
- if (consider_directive_while_skipping (pfile, save_if_stack))
+ ret = consider_directive_while_skipping (pfile, save_if_stack);
+ if (ret)
break;
}
- else if (c == EOF)
- return; /* Caller will issue error. */
- FORWARD(-1);
- _cpp_skip_rest_of_line (pfile);
-
- c = GETC();
- if (c == EOF)
- return; /* Caller will issue error. */
- else
- CPP_BUMP_LINE (pfile);
- }
-
- /* Back up to the beginning of this line. Caller will process the
- directive. */
- CPP_BUFFER (pfile)->cur = beg_of_line;
- pfile->only_seen_white = 1;
+ if (token != CPP_VSPACE)
+ _cpp_skip_rest_of_line (pfile);
+ }
+ CPP_SET_WRITTEN (pfile, old_written);
+ pfile->no_macro_expand--;
+ CPP_OPTION (pfile, no_line_commands)--;
+ return ret;
}
/*
@@ -1484,12 +1572,9 @@ do_else (pfile)
}
if (pfile->if_stack->if_succeeded)
- skip_if_group (pfile);
- else
- {
- ++pfile->if_stack->if_succeeded; /* continue processing input */
- _cpp_output_line_command (pfile, same_file);
- }
+ return skip_if_group (pfile);
+
+ ++pfile->if_stack->if_succeeded; /* continue processing input */
return 0;
}
@@ -1511,33 +1596,8 @@ do_endif (pfile)
IF_STACK *temp = pfile->if_stack;
pfile->if_stack = temp->next;
if (temp->control_macro != 0)
- {
- /* This #endif matched a #ifndef at the start of the file.
- See if it is at the end of the file. */
- int c;
-
- CPP_SET_MARK (pfile);
-
- for (;;)
- {
- _cpp_skip_hspace (pfile);
- c = GETC ();
- if (c != '\n')
- break;
- }
- CPP_GOTO_MARK (pfile);
-
- if (c == EOF)
- {
- /* This #endif ends a #ifndef
- that contains all of the file (aside from whitespace).
- Arrange not to include the file again
- if the macro that was tested is defined. */
- CPP_BUFFER (pfile)->ihash->control_macro = temp->control_macro;
- }
- }
+ pfile->potential_control_macro = temp->control_macro;
free (temp);
- _cpp_output_line_command (pfile, same_file);
}
return 0;
}
@@ -1551,13 +1611,17 @@ validate_else (pfile, directive)
cpp_reader *pfile;
const char *directive;
{
+ long old_written;
if (! CPP_PEDANTIC (pfile))
return;
- _cpp_skip_hspace (pfile);
- if (PEEKC () != '\n')
+ old_written = CPP_WRITTEN (pfile);
+ pfile->no_macro_expand++;
+ if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
cpp_pedwarn (pfile,
"text following `#%s' violates ANSI standard", directive);
+ CPP_SET_WRITTEN (pfile, old_written);
+ pfile->no_macro_expand--;
}
void
@@ -1581,6 +1645,13 @@ _cpp_handle_eof (pfile)
}
pfile->if_stack = ifs;
+ if (pfile->potential_control_macro)
+ {
+ CPP_BUFFER (pfile)->ihash->control_macro
+ = pfile->potential_control_macro;
+ pfile->potential_control_macro = 0;
+ }
+
if (CPP_BUFFER (pfile)->nominal_fname && next_buf != NULL)
{
/* We're about to return from an #include file.
@@ -1600,47 +1671,46 @@ static int
do_assert (pfile)
cpp_reader *pfile;
{
+ long old_written;
U_CHAR *sym;
- int ret, c;
+ int ret;
HASHNODE *base, *this;
HASHNODE **bslot, **tslot;
size_t blen, tlen;
unsigned long bhash, thash;
- if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing)
- cpp_pedwarn (pfile, "ANSI C does not allow `#assert'");
-
- _cpp_skip_hspace (pfile);
- sym = CPP_PWRITTEN (pfile); /* remember where it starts */
+ old_written = CPP_WRITTEN (pfile); /* remember where it starts */
ret = _cpp_parse_assertion (pfile);
if (ret == 0)
goto error;
else if (ret == 1)
{
- cpp_error (pfile, "missing token-sequence in `#assert'");
+ cpp_error (pfile, "missing token-sequence in #assert");
goto error;
}
+ tlen = CPP_WRITTEN (pfile) - old_written;
- _cpp_skip_hspace (pfile);
- c = PEEKC();
- if (c != EOF && c != '\n')
+ if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
{
- cpp_error (pfile, "junk at end of `#assert'");
+ cpp_error (pfile, "junk at end of #assert");
goto error;
}
- tlen = strlen (sym);
+ sym = pfile->token_buffer + old_written;
blen = (U_CHAR *) strchr (sym, '(') - sym;
tslot = _cpp_lookup_slot (pfile, sym, tlen, 1, &thash);
if (*tslot)
{
- cpp_warning (pfile, "`%s' re-asserted", sym);
+ cpp_warning (pfile, "%s re-asserted", sym);
goto error;
}
bslot = _cpp_lookup_slot (pfile, sym, blen, 1, &bhash);
if (! *bslot)
- *bslot = base = _cpp_make_hashnode (sym, blen, T_ASSERT, bhash);
+ {
+ *bslot = base = _cpp_make_hashnode (sym, blen, T_ASSERT, bhash);
+ base->value.aschain = 0;
+ }
else
{
base = *bslot;
@@ -1654,13 +1724,10 @@ do_assert (pfile)
*tslot = this = _cpp_make_hashnode (sym, tlen, T_ASSERT, thash);
this->value.aschain = base->value.aschain;
base->value.aschain = this;
-
- pfile->limit = sym; /* Pop */
- return 0;
error:
_cpp_skip_rest_of_line (pfile);
- pfile->limit = sym; /* Pop */
+ CPP_SET_WRITTEN (pfile, old_written);
return 0;
}
@@ -1668,27 +1735,26 @@ static int
do_unassert (pfile)
cpp_reader *pfile;
{
- int c, ret;
+ int ret;
+ long old_written;
U_CHAR *sym;
long baselen, thislen;
HASHNODE *base, *this, *next;
-
- if (CPP_PEDANTIC (pfile) && CPP_OPTIONS (pfile)->done_initializing)
- cpp_pedwarn (pfile, "ANSI C does not allow `#unassert'");
- _cpp_skip_hspace (pfile);
-
- sym = CPP_PWRITTEN (pfile); /* remember where it starts */
+ old_written = CPP_WRITTEN (pfile);
ret = _cpp_parse_assertion (pfile);
if (ret == 0)
goto error;
-
- _cpp_skip_hspace (pfile);
- c = PEEKC ();
- if (c != EOF && c != '\n')
- cpp_error (pfile, "junk at end of `#unassert'");
+ thislen = CPP_WRITTEN (pfile) - old_written;
+
+ if (_cpp_get_directive_token (pfile) != CPP_VSPACE)
+ {
+ cpp_error (pfile, "junk at end of #unassert");
+ goto error;
+ }
+ sym = pfile->token_buffer + old_written;
+ CPP_SET_WRITTEN (pfile, old_written);
- thislen = strlen (sym);
if (ret == 1)
{
base = _cpp_lookup (pfile, sym, thislen);
@@ -1723,12 +1789,11 @@ do_unassert (pfile)
/* Last answer for this predicate deleted. */
htab_remove_elt (pfile->hashtab, base);
}
-
- pfile->limit = sym; /* Pop */
return 0;
+
error:
_cpp_skip_rest_of_line (pfile);
- pfile->limit = sym; /* Pop */
+ CPP_SET_WRITTEN (pfile, old_written);
return 0;
}
diff --git a/gcc/cpplib.h b/gcc/cpplib.h
index 19f958f3229..8133d69af40 100644
--- a/gcc/cpplib.h
+++ b/gcc/cpplib.h
@@ -67,8 +67,8 @@ struct cpp_buffer
const unsigned char *cur; /* current position */
const unsigned char *rlimit; /* end of valid data */
const unsigned char *buf; /* entire buffer */
- const unsigned char *alimit; /* end of allocated buffer */
const unsigned char *line_base; /* start of current line */
+ const unsigned char *mark; /* Saved position for lengthy backtrack. */
struct cpp_buffer *prev;
@@ -84,10 +84,11 @@ struct cpp_buffer
struct ihash *ihash;
long lineno; /* Line number at CPP_LINE_BASE. */
- long colno; /* Column number at CPP_LINE_BASE. */
- long mark; /* Saved position for lengthy backtrack. */
parse_cleanup_t cleanup;
- void *data;
+
+ /* If the buffer is the expansion of a macro, this points to the
+ macro's hash table entry. */
+ struct hashnode *macro;
/* Value of if_stack at start of this file.
Used to prohibit unmatched #endif (etc) in an include file. */
@@ -128,306 +129,294 @@ struct htab;
efficiency, and partly to limit runaway recursion. */
#define CPP_STACK_MAX 200
-/* A cpp_reader encapsulates the "state" of a pre-processor run.
- Applying cpp_get_token repeatedly yields a stream of pre-processor
- tokens. Usually, there is only one cpp_reader object active. */
+/* Values for opts.dump_macros.
+ dump_only means inhibit output of the preprocessed text
+ and instead output the definitions of all user-defined
+ macros in a form suitable for use as input to cccp.
+ dump_names means pass #define and the macro name through to output.
+ dump_definitions means pass the whole definition (plus #define) through
+*/
+enum { dump_none = 0, dump_only, dump_names, dump_definitions };
-struct cpp_reader
+/* This structure is nested inside struct cpp_reader, and
+ carries all the options visible to the command line. */
+struct cpp_options
{
- cpp_buffer *buffer;
- cpp_options *opts;
-
- /* A buffer used for both for cpp_get_token's output, and also internally. */
- unsigned char *token_buffer;
- /* Allocated size of token_buffer. CPP_RESERVE allocates space. */
- unsigned int token_buffer_size;
- /* End of the written part of token_buffer. */
- unsigned char *limit;
-
- /* Error counter for exit code */
- int errors;
-
- /* Line where a newline was first seen in a string constant. */
- int multiline_string_line;
-
- /* Current depth in #include directives that use <...>. */
- int system_include_depth;
-
- /* Current depth of buffer stack. */
- int buffer_stack_depth;
-
- /* Hash table of macros and assertions. See cpphash.c */
- struct htab *hashtab;
-
- /* Hash table of other included files. See cppfiles.c */
- struct htab *all_include_files;
-
- /* Chain of `actual directory' file_name_list entries,
- for "" inclusion. */
- struct file_name_list *actual_dirs;
-
- /* Current maximum length of directory names in the search path
- for include files. (Altered as we get more of them.) */
- unsigned int max_include_len;
-
- struct if_stack *if_stack;
-
- /* Nonzero means we have printed (while error reporting) a list of
- containing files that matches the current status. */
- char input_stack_listing_current;
-
- /* If non-zero, macros are not expanded. */
- char no_macro_expand;
-
- /* If non-zero, directives cause a hard error. Used when parsing
- macro arguments. */
- char no_directives;
-
- /* Print column number in error messages. */
- char show_column;
-
- /* We're printed a warning recommending against using #import. */
- char import_warning;
-
- /* If true, character between '<' and '>' are a single (string) token. */
- char parsing_include_directive;
-
- /* If true, # introduces an assertion (see do_assert) */
- char parsing_if_directive;
-
- /* If true, # and ## are the STRINGIZE and TOKPASTE operators */
- char parsing_define_directive;
-
- /* True if escape sequences (as described for has_escapes in
- parse_buffer) should be emitted. */
- char output_escapes;
-
- /* 0: Have seen non-white-space on this line.
- 1: Only seen white space so far on this line.
- 2: Only seen white space so far in this file. */
- char only_seen_white;
-
- long lineno;
-
- struct tm *timebuf;
-
- /* Buffer of -M output. */
- struct deps *deps;
-
- /* A buffer and a table, used only by read_and_prescan (in cppfiles.c)
- which are allocated once per cpp_reader object to keep them off the
- stack and avoid setup costs. */
- unsigned char *input_buffer;
- unsigned char *input_speccase;
- size_t input_buffer_len;
-};
-
-#define CPP_FATAL_LIMIT 1000
-/* True if we have seen a "fatal" error. */
-#define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT)
-
-/* Macros for manipulating the token_buffer. */
+ /* Name of input and output files. */
+ const char *in_fname;
+ const char *out_fname;
-/* Number of characters currently in PFILE's output buffer. */
-#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
-#define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
-#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
-#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
+ /* Pending options - -D, -U, -A, -I, -ixxx. */
+ struct cpp_pending *pending;
-#define CPP_OPTIONS(PFILE) ((PFILE)->opts)
-#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
+ /* File name which deps are being written to. This is 0 if deps are
+ being written to stdout. */
+ const char *deps_file;
-/* Pointed to by cpp_reader.opts. */
-struct cpp_options
-{
- const char *in_fname;
+ /* Target-name to write with the dependency information. */
+ char *deps_target;
- /* Name of output file, for error messages. */
- const char *out_fname;
+ /* Search paths for include files. */
+ struct file_name_list *quote_include; /* First dir to search for "file" */
+ struct file_name_list *bracket_include;/* First dir to search for <file> */
+ /* Map between header names and file names, used only on DOS where
+ file names are limited in length. */
struct file_name_map_list *map_list;
+ /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
+ in the standard include file directories. */
+ const char *include_prefix;
+ unsigned int include_prefix_len;
+
/* Non-0 means -v, so print the full set of include dirs. */
- char verbose;
+ unsigned char verbose;
/* Nonzero means use extra default include directories for C++. */
-
- char cplusplus;
+ unsigned char cplusplus;
/* Nonzero means handle cplusplus style comments */
-
- char cplusplus_comments;
+ unsigned char cplusplus_comments;
/* Nonzero means handle #import, for objective C. */
-
- char objc;
+ unsigned char objc;
/* Nonzero means this is an assembly file, so ignore unrecognized
directives and the "# 33" form of #line, both of which are
probably comments. Also, permit unbalanced ' strings (again,
likely to be in comments). */
-
- char lang_asm;
+ unsigned char lang_asm;
/* Nonzero means this is Fortran, and we don't know where the
comments are, so permit unbalanced ' strings. Unlike lang_asm,
this does not ignore unrecognized directives. */
+ unsigned char lang_fortran;
- char lang_fortran;
-
- /* Nonzero means handle CHILL comment syntax
- and output CHILL string delimiter for __DATE___ etc. */
-
- char chill;
+ /* Nonzero means handle CHILL comment syntax and output CHILL string
+ delimiters for __DATE__ etc. */
+ unsigned char chill;
/* Nonzero means don't copy comments into the output file. */
-
- char discard_comments;
+ unsigned char discard_comments;
/* Nonzero means process the ANSI trigraph sequences. */
+ unsigned char trigraphs;
- char trigraphs;
+ /* Nonzero means print the names of included files rather than the
+ preprocessed output. 1 means just the #include "...", 2 means
+ #include <...> as well. */
+ unsigned char print_deps;
- /* Nonzero means print the names of included files rather than
- the preprocessed output. 1 means just the #include "...",
- 2 means #include <...> as well. */
-
- char print_deps;
-
- /* Nonzero if missing .h files in -M output are assumed to be generated
- files and not errors. */
-
- char print_deps_missing_files;
+ /* Nonzero if missing .h files in -M output are assumed to be
+ generated files and not errors. */
+ unsigned char print_deps_missing_files;
/* If true, fopen (deps_file, "a") else fopen (deps_file, "w"). */
- char print_deps_append;
+ unsigned char print_deps_append;
/* Nonzero means print names of header files (-H). */
+ unsigned char print_include_names;
- char print_include_names;
-
- /* Nonzero means try to make failure to fit ANSI C an error. */
-
- char pedantic_errors;
+ /* Nonzero means cpp_pedwarn causes a hard error. */
+ unsigned char pedantic_errors;
/* Nonzero means don't print warning messages. */
+ unsigned char inhibit_warnings;
- char inhibit_warnings;
-
- /* Nonzero means don't print error messages. Has no option to select it,
- but can be set by a user of cpplib (e.g. fix-header). */
-
- char inhibit_errors;
+ /* Nonzero means don't print error messages. Has no option to
+ select it, but can be set by a user of cpplib (e.g. fix-header). */
+ unsigned char inhibit_errors;
/* Nonzero means warn if slash-star appears in a comment. */
-
- char warn_comments;
+ unsigned char warn_comments;
/* Nonzero means warn if there are any trigraphs. */
-
- char warn_trigraphs;
+ unsigned char warn_trigraphs;
/* Nonzero means warn if #import is used. */
-
- char warn_import;
+ unsigned char warn_import;
/* Nonzero means warn if a macro argument is (or would be)
- stringified with -traditional. */
-
- char warn_stringify;
+ stringified with -traditional, and warn about directives
+ with the # indented from the beginning of the line. */
+ unsigned char warn_traditional;
/* Nonzero means turn warnings into errors. */
+ unsigned char warnings_are_errors;
- char warnings_are_errors;
-
- /* Nonzero causes output not to be done,
- but directives such as #define that have side effects
- are still obeyed. */
-
- char no_output;
+ /* Nonzero causes output not to be done, but directives such as
+ #define that have side effects are still obeyed. */
+ unsigned char no_output;
/* Nonzero means we should look for header.gcc files that remap file
names. */
- char remap;
+ unsigned char remap;
/* Nonzero means don't output line number information. */
- char no_line_commands;
+ unsigned char no_line_commands;
- /* Nonzero means -I- has been seen,
- so don't look for #include "foo" the source-file directory. */
- char ignore_srcdir;
+ /* Nonzero means -I- has been seen, so don't look for #include "foo"
+ the source-file directory. */
+ unsigned char ignore_srcdir;
- /* Zero means dollar signs are punctuation.
- This used to be needed for conformance to the C Standard,
- before the C Standard was corrected. */
- char dollars_in_ident;
+ /* Zero means dollar signs are punctuation. */
+ unsigned char dollars_in_ident;
/* Nonzero means try to imitate old fashioned non-ANSI preprocessor. */
- char traditional;
+ unsigned char traditional;
/* Nonzero means warn if undefined identifiers are evaluated in an #if. */
- char warn_undef;
+ unsigned char warn_undef;
/* Nonzero for the 1989 C Standard, including corrigenda and amendments. */
- char c89;
+ unsigned char c89;
/* Nonzero for the 1999 C Standard, including corrigenda and amendments. */
- char c99;
+ unsigned char c99;
/* Nonzero means give all the error messages the ANSI standard requires. */
- char pedantic;
+ unsigned char pedantic;
/* Nonzero means we're looking at already preprocessed code, so don't
bother trying to do macro expansion and whatnot. */
- char preprocessed;
+ unsigned char preprocessed;
- char done_initializing;
+ /* Nonzero disables all the standard directories for headers. */
+ unsigned char no_standard_includes;
- /* Search paths for include files. */
- struct file_name_list *quote_include; /* First dir to search for "file" */
- struct file_name_list *bracket_include;/* First dir to search for <file> */
+ /* Nonzero disables the C++-specific standard directories for headers. */
+ unsigned char no_standard_cplusplus_includes;
- /* Directory prefix that should replace `/usr/lib/gcc-lib/TARGET/VERSION'
- in the standard include file directories. */
- const char *include_prefix;
- int include_prefix_len;
+ /* Nonzero means dump macros in some fashion - see above. */
+ unsigned char dump_macros;
- char no_standard_includes;
- char no_standard_cplusplus_includes;
+ /* Nonzero means pass all #define and #undef directives which we
+ actually process through to the output stream. This feature is
+ used primarily to allow cc1 to record the #defines and #undefs
+ for the sake of debuggers which understand about preprocessor
+ macros, but it may also be useful with -E to figure out how
+ symbols are defined, and where they are defined. */
+ unsigned char debug_output;
-/* dump_only means inhibit output of the preprocessed text
- and instead output the definitions of all user-defined
- macros in a form suitable for use as input to cccp.
- dump_names means pass #define and the macro name through to output.
- dump_definitions means pass the whole definition (plus #define) through
-*/
+ /* Nonzero means pass #include lines through to the output. */
+ unsigned char dump_includes;
- enum {dump_none = 0, dump_only, dump_names, dump_definitions}
- dump_macros;
+ /* Print column number in error messages. */
+ unsigned char show_column;
+};
-/* Nonzero means pass all #define and #undef directives which we actually
- process through to the output stream. This feature is used primarily
- to allow cc1 to record the #defines and #undefs for the sake of
- debuggers which understand about preprocessor macros, but it may
- also be useful with -E to figure out how symbols are defined, and
- where they are defined. */
- int debug_output;
- /* Nonzero means pass #include lines through to the output,
- even if they are ifdefed out. */
- int dump_includes;
+/* A cpp_reader encapsulates the "state" of a pre-processor run.
+ Applying cpp_get_token repeatedly yields a stream of pre-processor
+ tokens. Usually, there is only one cpp_reader object active. */
- /* Pending options - -D, -U, -A, -I, -ixxx. */
- struct cpp_pending *pending;
+struct cpp_reader
+{
+ cpp_buffer *buffer;
- /* File name which deps are being written to.
- This is 0 if deps are being written to stdout. */
- const char *deps_file;
+ /* A buffer used for both for cpp_get_token's output, and also internally. */
+ unsigned char *token_buffer;
+ /* Allocated size of token_buffer. CPP_RESERVE allocates space. */
+ unsigned int token_buffer_size;
+ /* End of the written part of token_buffer. */
+ unsigned char *limit;
- /* Target-name to write with the dependency information. */
- char *deps_target;
+ /* Error counter for exit code */
+ int errors;
+
+ /* Line where a newline was first seen in a string constant. */
+ int multiline_string_line;
+
+ /* Current depth in #include directives that use <...>. */
+ int system_include_depth;
+
+ /* Current depth of buffer stack. */
+ int buffer_stack_depth;
+
+ /* Hash table of macros and assertions. See cpphash.c */
+ struct htab *hashtab;
+
+ /* Hash table of other included files. See cppfiles.c */
+ struct htab *all_include_files;
+
+ /* Chain of `actual directory' file_name_list entries,
+ for "" inclusion. */
+ struct file_name_list *actual_dirs;
+
+ /* Current maximum length of directory names in the search path
+ for include files. (Altered as we get more of them.) */
+ unsigned int max_include_len;
+
+ struct if_stack *if_stack;
+ const unsigned char *potential_control_macro;
+
+ long lineno;
+
+ struct tm *timebuf;
+
+ /* Buffer of -M output. */
+ struct deps *deps;
+
+ /* A buffer used only by read_and_prescan (in cppfiles.c), which is
+ allocated once per cpp_reader object to keep it off the stack. */
+ unsigned char *input_buffer;
+ size_t input_buffer_len;
+
+ /* User visible options. */
+ struct cpp_options opts;
+
+ /* Nonzero means we have printed (while error reporting) a list of
+ containing files that matches the current status. */
+ unsigned char input_stack_listing_current;
+
+ /* If non-zero, macros are not expanded. */
+ unsigned char no_macro_expand;
+
+ /* If non-zero, directives cause a hard error. Used when parsing
+ macro arguments. */
+ unsigned char no_directives;
+
+ /* We're printed a warning recommending against using #import. */
+ unsigned char import_warning;
+
+ /* If true, characters between '<' and '>' are a single (string) token. */
+ unsigned char parsing_include_directive;
+
+ /* If true, # introduces an assertion (see do_assert) */
+ unsigned char parsing_if_directive;
+
+ /* If true, # and ## are the STRINGIZE and TOKPASTE operators */
+ unsigned char parsing_define_directive;
+
+ /* True if escape sequences (as described for has_escapes in
+ parse_buffer) should be emitted. */
+ unsigned char output_escapes;
+
+ /* 0: Have seen non-white-space on this line.
+ 1: Only seen white space so far on this line.
+ 2: Only seen white space so far in this file. */
+ unsigned char only_seen_white;
+
+ /* True after cpp_start_read completes. Used to inhibit some
+ warnings while parsing the command line. */
+ unsigned char done_initializing;
};
+#define CPP_FATAL_LIMIT 1000
+/* True if we have seen a "fatal" error. */
+#define CPP_FATAL_ERRORS(READER) ((READER)->errors >= CPP_FATAL_LIMIT)
+
+/* Macros for manipulating the token_buffer. */
+
+/* Number of characters currently in PFILE's output buffer. */
+#define CPP_WRITTEN(PFILE) ((size_t)((PFILE)->limit - (PFILE)->token_buffer))
+#define CPP_PWRITTEN(PFILE) ((PFILE)->limit)
+#define CPP_ADJUST_WRITTEN(PFILE,DELTA) ((PFILE)->limit += (DELTA))
+#define CPP_SET_WRITTEN(PFILE,N) ((PFILE)->limit = (PFILE)->token_buffer + (N))
+
+#define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)
+#define CPP_BUFFER(PFILE) ((PFILE)->buffer)
+
/* Name under which this program was invoked. */
extern const char *progname;
@@ -436,7 +425,6 @@ extern enum cpp_token cpp_get_token PARAMS ((cpp_reader *));
extern enum cpp_token cpp_get_non_space_token PARAMS ((cpp_reader *));
extern void cpp_reader_init PARAMS ((cpp_reader *));
-extern void cpp_options_init PARAMS ((cpp_options *));
extern int cpp_start_read PARAMS ((cpp_reader *, const char *));
extern void cpp_finish PARAMS ((cpp_reader *));
extern void cpp_cleanup PARAMS ((cpp_reader *PFILE));
diff --git a/gcc/cppmain.c b/gcc/cppmain.c
index b2f1ddba17e..43d4c7bf52c 100644
--- a/gcc/cppmain.c
+++ b/gcc/cppmain.c
@@ -28,7 +28,6 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
const char *progname;
cpp_reader parse_in;
-cpp_options options;
extern int main PARAMS ((int, char **));
@@ -38,9 +37,11 @@ main (argc, argv)
char **argv;
{
char *p;
+ cpp_reader *pfile = &parse_in;
int argi = 1; /* Next argument to handle. */
- struct cpp_options *opts = &options;
enum cpp_token kind;
+ FILE *out;
+ const char *out_fname;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && p[-1] != '/') --p;
@@ -54,47 +55,49 @@ main (argc, argv)
(void) bindtextdomain (PACKAGE, localedir);
(void) textdomain (PACKAGE);
- cpp_reader_init (&parse_in);
- parse_in.opts = opts;
-
- cpp_options_init (opts);
+ cpp_reader_init (pfile);
- argi += cpp_handle_options (&parse_in, argc - argi , argv + argi);
- if (argi < argc && ! CPP_FATAL_ERRORS (&parse_in))
- cpp_fatal (&parse_in, "Invalid option `%s'", argv[argi]);
- if (CPP_FATAL_ERRORS (&parse_in))
+ argi += cpp_handle_options (pfile, argc - argi , argv + argi);
+ if (argi < argc && ! CPP_FATAL_ERRORS (pfile))
+ cpp_fatal (pfile, "Invalid option %s", argv[argi]);
+ if (CPP_FATAL_ERRORS (pfile))
return (FATAL_EXIT_CODE);
-
- parse_in.show_column = 1;
- if (! cpp_start_read (&parse_in, opts->in_fname))
+ if (! cpp_start_read (pfile, CPP_OPTION (pfile, in_fname)))
return (FATAL_EXIT_CODE);
/* Now that we know the input file is valid, open the output. */
-
- if (!opts->out_fname || !strcmp (opts->out_fname, ""))
- opts->out_fname = "stdout";
- else if (! freopen (opts->out_fname, "w", stdout))
+ out_fname = CPP_OPTION (pfile, out_fname);
+ if (*out_fname == '\0')
+ {
+ out_fname = "stdout";
+ out = stdout;
+ }
+ else
{
- cpp_notice_from_errno (&parse_in, opts->out_fname);
- return (FATAL_EXIT_CODE);
+ out = fopen (out_fname, "w");
+ if (!out)
+ {
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
+ return (FATAL_EXIT_CODE);
+ }
}
- if (! opts->no_output)
+ if (! CPP_OPTION (pfile, no_output))
{
do
{
- kind = cpp_get_token (&parse_in);
- if (CPP_WRITTEN (&parse_in) >= BUFSIZ || kind == CPP_EOF)
+ kind = cpp_get_token (pfile);
+ if (CPP_WRITTEN (pfile) >= BUFSIZ || kind == CPP_EOF)
{
- size_t rem, count = CPP_WRITTEN (&parse_in);
+ size_t rem, count = CPP_WRITTEN (pfile);
- rem = fwrite (parse_in.token_buffer, 1, count, stdout);
+ rem = fwrite (parse_in.token_buffer, 1, count, out);
if (rem < count)
/* Write error. */
- cpp_notice_from_errno (&parse_in, opts->out_fname);
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
- CPP_SET_WRITTEN (&parse_in, 0);
+ CPP_SET_WRITTEN (pfile, 0);
}
}
while (kind != CPP_EOF);
@@ -103,19 +106,22 @@ main (argc, argv)
{
do
{
- cpp_scan_buffer (&parse_in);
- kind = cpp_get_token (&parse_in);
+ cpp_scan_buffer (pfile);
+ kind = cpp_get_token (pfile);
}
while (kind != CPP_EOF);
- CPP_SET_WRITTEN (&parse_in, 0);
+ CPP_SET_WRITTEN (pfile, 0);
}
- cpp_finish (&parse_in);
- if (fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout)
- < CPP_WRITTEN (&parse_in))
- cpp_notice_from_errno (&parse_in, opts->out_fname);
+ cpp_finish (pfile);
+ if (fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (pfile), out)
+ < CPP_WRITTEN (pfile))
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
+
+ if (ferror (out) || fclose (out))
+ cpp_notice_from_errno (pfile, CPP_OPTION (pfile, out_fname));
- cpp_cleanup (&parse_in);
+ cpp_cleanup (pfile);
if (parse_in.errors)
return (FATAL_EXIT_CODE);
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index 1619e65d55c..c4a437a28ef 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -52,6 +52,7 @@ Boston, MA 02111-1307, USA. */
compiled for the target, and hence definitions concerning only the host
do not apply. */
+#include "auto-host.h"
#include "tm.h"
#include "tsystem.h"
@@ -132,7 +133,17 @@ typedef void (*func_ptr) (void);
#ifdef OBJECT_FORMAT_ELF
/* Declare the __dso_handle variable. It should have a unique value
- in every shared-object; in a main program its value is zero. */
+ in every shared-object; in a main program its value is zero. The
+ object should in any case be protected. This means the instance
+ in one DSO or the main program is not used in another object. The
+ dynamic linker takes care of this. */
+
+/* XXX Ideally the following should be implemented using
+ __attribute__ ((__visibility__ ("hidden")))
+ but the __attribute__ support is not yet there. */
+#ifdef HAVE_GAS_HIDDEN
+asm (".hidden\t__dso_handle");
+#endif
#ifdef CRTSTUFFS_O
void *__dso_handle = &__dso_handle;
diff --git a/gcc/cse.c b/gcc/cse.c
index 8c2e9fc580a..aa26539fc69 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -246,7 +246,7 @@ struct qty_table_elem
rtx const_insn;
rtx comparison_const;
int comparison_qty;
- int first_reg, last_reg;
+ unsigned int first_reg, last_reg;
enum machine_mode mode;
enum rtx_code comparison_code;
};
@@ -302,7 +302,7 @@ struct cse_reg_info
struct cse_reg_info *next;
/* Search key */
- int regno;
+ unsigned int regno;
/* The quantity number of the register's current contents. */
int reg_qty;
@@ -336,7 +336,7 @@ static struct cse_reg_info *reg_hash[REGHASH_SIZE];
/* The last lookup we did into the cse_reg_info_tree. This allows us
to cache repeated lookups. */
-static int cached_regno;
+static unsigned int cached_regno;
static struct cse_reg_info *cached_cse_reg_info;
/* A HARD_REG_SET containing all the hard registers for which there is
@@ -408,6 +408,9 @@ static int hash_arg_in_memory;
each recording one expression's information.
That expression is in the `exp' field.
+ The canon_exp field contains a canonical (from the point of view of
+ alias analysis) version of the `exp' field.
+
Those elements with the same hash code are chained in both directions
through the `next_same_hash' and `prev_same_hash' fields.
@@ -447,6 +450,7 @@ static int hash_arg_in_memory;
struct table_elt
{
rtx exp;
+ rtx canon_exp;
struct table_elt *next_same_hash;
struct table_elt *prev_same_hash;
struct table_elt *next_same_value;
@@ -531,7 +535,7 @@ struct table_elt
/* Determine if the quantity number for register X represents a valid index
into the qty_table. */
-#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (N))
+#define REGNO_QTY_VALID_P(N) (REG_QTY (N) != (int) (N))
#ifdef ADDRESS_COST
/* The ADDRESS_COST macro does not deal with ADDRESSOF nodes. But,
@@ -653,9 +657,9 @@ struct cse_basic_block_data
static int notreg_cost PARAMS ((rtx));
static void new_basic_block PARAMS ((void));
-static void make_new_qty PARAMS ((int, enum machine_mode));
-static void make_regs_eqv PARAMS ((int, int));
-static void delete_reg_equiv PARAMS ((int));
+static void make_new_qty PARAMS ((unsigned int, enum machine_mode));
+static void make_regs_eqv PARAMS ((unsigned int, unsigned int));
+static void delete_reg_equiv PARAMS ((unsigned int));
static int mention_regs PARAMS ((rtx));
static int insert_regs PARAMS ((rtx, struct table_elt *, int));
static void remove_from_table PARAMS ((struct table_elt *, unsigned));
@@ -668,8 +672,9 @@ static void merge_equiv_classes PARAMS ((struct table_elt *,
struct table_elt *));
static void invalidate PARAMS ((rtx, enum machine_mode));
static int cse_rtx_varies_p PARAMS ((rtx));
-static void remove_invalid_refs PARAMS ((int));
-static void remove_invalid_subreg_refs PARAMS ((int, int, enum machine_mode));
+static void remove_invalid_refs PARAMS ((unsigned int));
+static void remove_invalid_subreg_refs PARAMS ((unsigned int, unsigned int,
+ enum machine_mode));
static void rehash_using_reg PARAMS ((rtx));
static void invalidate_memory PARAMS ((void));
static void invalidate_for_call PARAMS ((void));
@@ -699,7 +704,7 @@ static void cse_set_around_loop PARAMS ((rtx, rtx, rtx));
static rtx cse_basic_block PARAMS ((rtx, rtx, struct branch_path *, int));
static void count_reg_usage PARAMS ((rtx, int *, rtx, int));
extern void dump_class PARAMS ((struct table_elt*));
-static struct cse_reg_info* get_cse_reg_info PARAMS ((int));
+static struct cse_reg_info * get_cse_reg_info PARAMS ((unsigned int));
static void flush_hash_table PARAMS ((void));
@@ -845,7 +850,7 @@ rtx_cost (x, outer_code)
static struct cse_reg_info *
get_cse_reg_info (regno)
- int regno;
+ unsigned int regno;
{
struct cse_reg_info **hash_head = &reg_hash[REGHASH_FN (regno)];
struct cse_reg_info *p;
@@ -949,8 +954,8 @@ new_basic_block ()
static void
make_new_qty (reg, mode)
- register int reg;
- register enum machine_mode mode;
+ unsigned int reg;
+ enum machine_mode mode;
{
register int q;
register struct qty_table_elem *ent;
@@ -976,11 +981,11 @@ make_new_qty (reg, mode)
static void
make_regs_eqv (new, old)
- register int new, old;
+ unsigned int new, old;
{
- register int lastr, firstr;
- register int q = REG_QTY (old);
- register struct qty_table_elem *ent;
+ unsigned int lastr, firstr;
+ int q = REG_QTY (old);
+ struct qty_table_elem *ent;
ent = &qty_table[q];
@@ -1040,14 +1045,14 @@ make_regs_eqv (new, old)
static void
delete_reg_equiv (reg)
- register int reg;
+ unsigned int reg;
{
register struct qty_table_elem *ent;
register int q = REG_QTY (reg);
register int p, n;
/* If invalid, do nothing. */
- if (q == reg)
+ if (q == (int) reg)
return;
ent = &qty_table[q];
@@ -1094,11 +1099,11 @@ mention_regs (x)
code = GET_CODE (x);
if (code == REG)
{
- register int regno = REGNO (x);
- register int endregno
+ unsigned int regno = REGNO (x);
+ unsigned int endregno
= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (regno, GET_MODE (x)));
- int i;
+ unsigned int i;
for (i = regno; i < endregno; i++)
{
@@ -1117,7 +1122,7 @@ mention_regs (x)
if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
{
- int i = REGNO (SUBREG_REG (x));
+ unsigned int i = REGNO (SUBREG_REG (x));
if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i))
{
@@ -1193,8 +1198,8 @@ insert_regs (x, classp, modified)
{
if (GET_CODE (x) == REG)
{
- register int regno = REGNO (x);
- register int qty_valid;
+ unsigned int regno = REGNO (x);
+ int qty_valid;
/* If REGNO is in the equivalence table already but is of the
wrong mode for that equivalence, don't do anything here. */
@@ -1237,7 +1242,7 @@ insert_regs (x, classp, modified)
else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
&& ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
{
- int regno = REGNO (SUBREG_REG (x));
+ unsigned int regno = REGNO (SUBREG_REG (x));
insert_regs (SUBREG_REG (x), NULL_PTR, 0);
/* Mention_regs checks if REG_TICK is exactly one larger than
@@ -1324,6 +1329,7 @@ remove_from_table (elt, hash)
if (elt->related_value != 0 && elt->related_value != elt)
{
register struct table_elt *p = elt->related_value;
+
while (p->related_value != elt)
p = p->related_value;
p->related_value = elt->related_value;
@@ -1374,7 +1380,8 @@ lookup_for_remove (x, hash, mode)
if (GET_CODE (x) == REG)
{
- int regno = REGNO (x);
+ unsigned int regno = REGNO (x);
+
/* Don't check the machine mode when comparing registers;
invalidating (REG:SI 0) also invalidates (REG:DF 0). */
for (p = table[hash]; p; p = p->next_same_hash)
@@ -1400,8 +1407,9 @@ lookup_as_function (x, code)
rtx x;
enum rtx_code code;
{
- register struct table_elt *p = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK,
- GET_MODE (x));
+ register struct table_elt *p
+ = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, GET_MODE (x));
+
/* If we are looking for a CONST_INT, the mode doesn't really matter, as
long as we are narrowing. So if we looked in vain for a mode narrower
than word_mode before, look for word_mode now. */
@@ -1417,12 +1425,10 @@ lookup_as_function (x, code)
return 0;
for (p = p->first_same_value; p; p = p->next_same_value)
- {
- if (GET_CODE (p->exp) == code
- /* Make sure this is a valid entry in the table. */
- && exp_equiv_p (p->exp, p->exp, 1, 0))
- return p->exp;
- }
+ if (GET_CODE (p->exp) == code
+ /* Make sure this is a valid entry in the table. */
+ && exp_equiv_p (p->exp, p->exp, 1, 0))
+ return p->exp;
return 0;
}
@@ -1470,12 +1476,12 @@ insert (x, classp, hash, mode)
/* If X is a hard register, show it is being put in the table. */
if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
{
- int regno = REGNO (x);
- int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- int i;
+ unsigned int regno = REGNO (x);
+ unsigned int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ unsigned int i;
for (i = regno; i < endregno; i++)
- SET_HARD_REG_BIT (hard_regs_in_table, i);
+ SET_HARD_REG_BIT (hard_regs_in_table, i);
}
/* If X is a label, show we recorded it. */
@@ -1488,9 +1494,7 @@ insert (x, classp, hash, mode)
elt = free_element_chain;
if (elt)
- {
- free_element_chain = elt->next_same_hash;
- }
+ free_element_chain = elt->next_same_hash;
else
{
n_elements_made++;
@@ -1498,6 +1502,7 @@ insert (x, classp, hash, mode)
}
elt->exp = x;
+ elt->canon_exp = NULL_RTX;
elt->cost = COST (x);
elt->next_same_value = 0;
elt->prev_same_value = 0;
@@ -1538,12 +1543,15 @@ insert (x, classp, hash, mode)
/* Insert not at head of the class. */
/* Put it after the last element cheaper than X. */
register struct table_elt *p, *next;
+
for (p = classp; (next = p->next_same_value) && CHEAPER (next, elt);
p = next);
+
/* Put it after P and before NEXT. */
elt->next_same_value = next;
if (next)
next->prev_same_value = elt;
+
elt->prev_same_value = p;
p->next_same_value = elt;
elt->first_same_value = classp;
@@ -1591,7 +1599,8 @@ insert (x, classp, hash, mode)
int x_q = REG_QTY (REGNO (x));
struct qty_table_elem *x_ent = &qty_table[x_q];
- x_ent->const_rtx = gen_lowpart_if_possible (GET_MODE (x), p->exp);
+ x_ent->const_rtx
+ = gen_lowpart_if_possible (GET_MODE (x), p->exp);
x_ent->const_insn = this_insn;
break;
}
@@ -1661,7 +1670,7 @@ merge_equiv_classes (class1, class2)
for (elt = class2; elt; elt = next)
{
- unsigned hash;
+ unsigned int hash;
rtx exp = elt->exp;
enum machine_mode mode = elt->mode;
@@ -1740,8 +1749,8 @@ invalidate (x, full_mode)
through the qty number mechanism. Just change the qty number of
the register, mark it as invalid for expressions that refer to it,
and remove it itself. */
- register int regno = REGNO (x);
- register unsigned hash = HASH (x, GET_MODE (x));
+ unsigned int regno = REGNO (x);
+ unsigned int hash = HASH (x, GET_MODE (x));
/* Remove REGNO from any quantity list it might be on and indicate
that its value might have changed. If it is a pseudo, remove its
@@ -1768,18 +1777,19 @@ invalidate (x, full_mode)
{
HOST_WIDE_INT in_table
= TEST_HARD_REG_BIT (hard_regs_in_table, regno);
- int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- int tregno, tendregno;
+ unsigned int endregno
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+ unsigned int tregno, tendregno, rn;
register struct table_elt *p, *next;
CLEAR_HARD_REG_BIT (hard_regs_in_table, regno);
- for (i = regno + 1; i < endregno; i++)
+ for (rn = regno + 1; rn < endregno; rn++)
{
- in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, i);
- CLEAR_HARD_REG_BIT (hard_regs_in_table, i);
- delete_reg_equiv (i);
- REG_TICK (i)++;
+ in_table |= TEST_HARD_REG_BIT (hard_regs_in_table, rn);
+ CLEAR_HARD_REG_BIT (hard_regs_in_table, rn);
+ delete_reg_equiv (rn);
+ REG_TICK (rn)++;
}
if (in_table)
@@ -1818,6 +1828,10 @@ invalidate (x, full_mode)
return;
case MEM:
+ /* Calculate the canonical version of X here so that
+ true_dependence doesn't generate new RTL for X on each call. */
+ x = canon_rtx (x);
+
/* Remove all hash table elements that refer to overlapping pieces of
memory. */
if (full_mode == VOIDmode)
@@ -1830,11 +1844,23 @@ invalidate (x, full_mode)
for (p = table[i]; p; p = next)
{
next = p->next_same_hash;
- if (p->in_memory
- && (GET_CODE (p->exp) != MEM
- || true_dependence (x, full_mode, p->exp,
- cse_rtx_varies_p)))
- remove_from_table (p, i);
+ if (p->in_memory)
+ {
+ if (GET_CODE (p->exp) != MEM)
+ remove_from_table (p, i);
+ else
+ {
+ /* Just canonicalize the expression once;
+ otherwise each time we call invalidate
+ true_dependence will canonicalize the
+ expression again. */
+ if (!p->canon_exp)
+ p->canon_exp = canon_rtx (p->exp);
+ if (true_dependence (x, full_mode, p->canon_exp,
+ cse_rtx_varies_p))
+ remove_from_table (p, i);
+ }
+ }
}
}
return;
@@ -1851,10 +1877,10 @@ invalidate (x, full_mode)
static void
remove_invalid_refs (regno)
- int regno;
+ unsigned int regno;
{
- register int i;
- register struct table_elt *p, *next;
+ unsigned int i;
+ struct table_elt *p, *next;
for (i = 0; i < HASH_SIZE; i++)
for (p = table[i]; p; p = next)
@@ -1869,13 +1895,13 @@ remove_invalid_refs (regno)
/* Likewise for a subreg with subreg_reg WORD and mode MODE. */
static void
remove_invalid_subreg_refs (regno, word, mode)
- int regno;
- int word;
+ unsigned int regno;
+ unsigned int word;
enum machine_mode mode;
{
- register int i;
- register struct table_elt *p, *next;
- int end = word + (GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD;
+ unsigned int i;
+ struct table_elt *p, *next;
+ unsigned int end = word + (GET_MODE_SIZE (mode) - 1) / UNITS_PER_WORD;
for (i = 0; i < HASH_SIZE; i++)
for (p = table[i]; p; p = next)
@@ -1956,8 +1982,8 @@ rehash_using_reg (x)
static void
invalidate_for_call ()
{
- int regno, endregno;
- int i;
+ unsigned int regno, endregno;
+ unsigned int i;
unsigned hash;
struct table_elt *p, *next;
int in_table = 0;
@@ -2111,7 +2137,7 @@ canon_hash (x, mode)
{
case REG:
{
- register int regno = REGNO (x);
+ unsigned int regno = REGNO (x);
/* On some machines, we can't record any non-fixed hard register,
because extending its life will cause reload problems. We
@@ -2136,6 +2162,7 @@ canon_hash (x, mode)
do_not_record = 1;
return 0;
}
+
hash += ((unsigned) REG << 7) + (unsigned) REG_QTY (regno);
return hash;
}
@@ -2361,10 +2388,8 @@ exp_equiv_p (x, y, validate, equal_values)
{
case PC:
case CC0:
- return x == y;
-
case CONST_INT:
- return INTVAL (x) == INTVAL (y);
+ return x == y;
case LABEL_REF:
return XEXP (x, 0) == XEXP (y, 0);
@@ -2374,11 +2399,11 @@ exp_equiv_p (x, y, validate, equal_values)
case REG:
{
- int regno = REGNO (y);
- int endregno
+ unsigned int regno = REGNO (y);
+ unsigned int endregno
= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (regno, GET_MODE (y)));
- int i;
+ unsigned int i;
/* If the quantities are not the same, the expressions are not
equivalent. If there are and we are not to validate, they
@@ -5703,11 +5728,11 @@ cse_insn (insn, libcall_insn)
This code is similar to the REG case in mention_regs,
but it knows that reg_tick has been incremented, and
it leaves reg_in_table as -1 . */
- register int regno = REGNO (x);
- register int endregno
+ unsigned int regno = REGNO (x);
+ unsigned int endregno
= regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (regno, GET_MODE (x)));
- int i;
+ unsigned int i;
for (i = regno; i < endregno; i++)
{
@@ -6892,7 +6917,7 @@ cse_basic_block (from, to, next_branch, around_loop)
/* If we have processed 1,000 insns, flush the hash table to
avoid extreme quadratic behavior. We must not include NOTEs
- in the count since there may be more or them when generating
+ in the count since there may be more of them when generating
debugging information. If we clear the table at different
times, code generated with -g -O might be different than code
generated with -O but not -g.
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index eb51d2b43ee..7af36a1b441 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -307,7 +307,7 @@ static int current_sym_nchars;
#define CONTIN \
do {if (current_sym_nchars > DBX_CONTIN_LENGTH) dbxout_continue ();} while (0)
#else
-#define CONTIN
+#define CONTIN do { } while (0)
#endif
#if defined(ASM_OUTPUT_SECTION_NAME)
@@ -2370,8 +2370,7 @@ dbxout_parms (parms)
If we use DECL_RTL, then we must use the declared type of
the variable, not the type that it arrived in. */
- if (REGNO (DECL_RTL (parms)) >= 0
- && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
+ if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
{
best_rtl = DECL_RTL (parms);
parm_type = TREE_TYPE (parms);
@@ -2430,8 +2429,7 @@ dbxout_parms (parms)
/* DECL_RTL looks like (MEM (REG...). Get the register number.
If it is an unallocated pseudo-reg, then use the register where
it was passed instead. */
- if (REGNO (XEXP (DECL_RTL (parms), 0)) >= 0
- && REGNO (XEXP (DECL_RTL (parms), 0)) < FIRST_PSEUDO_REGISTER)
+ if (REGNO (XEXP (DECL_RTL (parms), 0)) < FIRST_PSEUDO_REGISTER)
current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
else
current_sym_value = REGNO (DECL_INCOMING_RTL (parms));
@@ -2558,7 +2556,6 @@ dbxout_reg_parms (parms)
/* Report parms that live in registers during the function
but were passed in memory. */
if (GET_CODE (DECL_RTL (parms)) == REG
- && REGNO (DECL_RTL (parms)) >= 0
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
dbxout_symbol_location (parms, TREE_TYPE (parms),
0, DECL_RTL (parms));
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6510bc9b28a..c493d54f572 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -218,7 +218,7 @@ static void reg_save PARAMS ((char *, unsigned, unsigned,
static void initial_return_save PARAMS ((rtx));
static void output_cfi PARAMS ((dw_cfi_ref, dw_fde_ref));
static void output_call_frame_info PARAMS ((int));
-static unsigned reg_number PARAMS ((rtx));
+static unsigned int reg_number PARAMS ((rtx));
static void dwarf2out_stack_adjust PARAMS ((rtx));
static void dwarf2out_frame_debug_expr PARAMS ((rtx, char *));
@@ -553,7 +553,7 @@ stripattributes (s)
/* Return the register number described by a given RTL node. */
-static unsigned
+static unsigned int
reg_number (rtl)
register rtx rtl;
{
@@ -1314,7 +1314,7 @@ dwarf2out_frame_debug_expr (expr, label)
/* Without an offset. */
case REG:
- if (cfa_store_reg != (unsigned) REGNO (XEXP (dest, 0)))
+ if (cfa_store_reg != REGNO (XEXP (dest, 0)))
abort();
offset = -cfa_store_offset;
break;
@@ -2670,9 +2670,9 @@ static inline int
is_pseudo_reg (rtl)
register rtx rtl;
{
- return (((GET_CODE (rtl) == REG) && (REGNO (rtl) >= FIRST_PSEUDO_REGISTER))
- || ((GET_CODE (rtl) == SUBREG)
- && (REGNO (XEXP (rtl, 0)) >= FIRST_PSEUDO_REGISTER)));
+ return ((GET_CODE (rtl) == REG && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
+ || (GET_CODE (rtl) == SUBREG
+ && REGNO (XEXP (rtl, 0)) >= FIRST_PSEUDO_REGISTER));
}
/* Return a reference to a type, with its const and volatile qualifiers
@@ -7905,8 +7905,14 @@ gen_enumeration_type_die (type, context_die)
IDENTIFIER_POINTER (TREE_PURPOSE (link)));
if (host_integerp (TREE_VALUE (link), 0))
- add_AT_unsigned (enum_die, DW_AT_const_value,
- tree_low_cst (TREE_VALUE (link), 0));
+ {
+ if (tree_int_cst_sgn (TREE_VALUE (link)) < 0)
+ add_AT_int (enum_die, DW_AT_const_value,
+ tree_low_cst (TREE_VALUE (link), 0));
+ else
+ add_AT_unsigned (enum_die, DW_AT_const_value,
+ tree_low_cst (TREE_VALUE (link), 0));
+ }
}
}
else
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index e238cfa43ac..feead7697dc 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -46,6 +46,7 @@ Boston, MA 02111-1307, USA. */
#include "expr.h"
#include "regs.h"
#include "hard-reg-set.h"
+#include "hashtab.h"
#include "insn-config.h"
#include "recog.h"
#include "real.h"
@@ -137,6 +138,11 @@ rtx return_address_pointer_rtx; /* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */
rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];
+/* A hash table storing CONST_INTs whose absolute value is greater
+ than MAX_SAVED_CONST_INT. */
+
+static htab_t const_int_htab;
+
/* start_sequence and gen_sequence can make a lot of rtx expressions which are
shortly thrown away. We use two mechanisms to prevent this waste:
@@ -172,16 +178,67 @@ static rtx make_call_insn_raw PARAMS ((rtx));
static rtx find_line_note PARAMS ((rtx));
static void mark_sequence_stack PARAMS ((struct sequence_stack *));
static void unshare_all_rtl_1 PARAMS ((rtx));
+static hashval_t const_int_htab_hash PARAMS ((const void *));
+static int const_int_htab_eq PARAMS ((const void *,
+ const void *));
+static int rtx_htab_mark_1 PARAMS ((void **, void *));
+static void rtx_htab_mark PARAMS ((void *));
+
+/* Returns a hash code for X (which is a really a CONST_INT). */
+
+static hashval_t
+const_int_htab_hash (x)
+ const void *x;
+{
+ return (hashval_t) INTVAL ((const struct rtx_def *) x);
+}
+
+/* Returns non-zero if the value represented by X (which is really a
+ CONST_INT) is the same as that given by Y (which is really a
+ HOST_WIDE_INT *). */
+
+static int
+const_int_htab_eq (x, y)
+ const void *x;
+ const void *y;
+{
+ return (INTVAL ((const struct rtx_def *) x) == *((const HOST_WIDE_INT *) y));
+}
+
+/* Mark the hash-table element X (which is really a pointer to an
+ rtx). */
+
+static int
+rtx_htab_mark_1 (x, data)
+ void **x;
+ void *data ATTRIBUTE_UNUSED;
+{
+ ggc_mark_rtx (*x);
+ return 1;
+}
+
+/* Mark all the elements of HTAB (which is really an htab_t full of
+ rtxs). */
+
+static void
+rtx_htab_mark (htab)
+ void *htab;
+{
+ htab_traverse (*((htab_t *) htab), rtx_htab_mark_1, NULL);
+}
+
/* There are some RTL codes that require special attention; the generation
functions do the raw handling. If you add to this list, modify
special_rtx in gengenrtl.c as well. */
rtx
gen_rtx_CONST_INT (mode, arg)
- enum machine_mode mode;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
HOST_WIDE_INT arg;
{
+ void **slot;
+
if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
return const_int_rtx[arg + MAX_SAVED_CONST_INT];
@@ -190,7 +247,24 @@ gen_rtx_CONST_INT (mode, arg)
return const_true_rtx;
#endif
- return gen_rtx_raw_CONST_INT (mode, arg);
+ /* Look up the CONST_INT in the hash table. */
+ slot = htab_find_slot_with_hash (const_int_htab,
+ &arg,
+ (hashval_t) arg,
+ /*insert=*/1);
+ if (!*slot)
+ {
+ if (!ggc_p)
+ {
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
+ }
+ *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);
+ if (!ggc_p)
+ pop_obstacks ();
+ }
+
+ return (rtx) *slot;
}
/* CONST_DOUBLEs needs special handling because its length is known
@@ -924,7 +998,8 @@ subreg_realpart_p (x)
if (GET_CODE (x) != SUBREG)
abort ();
- return SUBREG_WORD (x) * UNITS_PER_WORD < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x)));
+ return ((unsigned int) SUBREG_WORD (x) * UNITS_PER_WORD
+ < GET_MODE_UNIT_SIZE (GET_MODE (SUBREG_REG (x))));
}
/* Assuming that X is an rtx (e.g., MEM, REG or SUBREG) for a value,
@@ -1104,7 +1179,7 @@ subreg_lowpart_p (x)
rtx
operand_subword (op, i, validate_address, mode)
rtx op;
- int i;
+ unsigned int i;
int validate_address;
enum machine_mode mode;
{
@@ -1181,7 +1256,9 @@ operand_subword (op, i, validate_address, mode)
return gen_rtx_SUBREG (word_mode, SUBREG_REG (op), i + SUBREG_WORD (op));
else if (GET_CODE (op) == CONCAT)
{
- int partwords = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
+ unsigned int partwords
+ = GET_MODE_UNIT_SIZE (GET_MODE (op)) / UNITS_PER_WORD;
+
if (i < partwords)
return operand_subword (XEXP (op, 0), i, validate_address, mode);
return operand_subword (XEXP (op, 1), i - partwords,
@@ -1428,7 +1505,7 @@ operand_subword (op, i, validate_address, mode)
rtx
operand_subword_force (op, i, mode)
rtx op;
- int i;
+ unsigned int i;
enum machine_mode mode;
{
rtx result = operand_subword (op, i, 1, mode);
@@ -1624,9 +1701,7 @@ unshare_all_rtl (fndecl, insn)
/* Make sure that virtual parameters are not shared. */
for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
- {
- copy_rtx_if_shared (DECL_RTL (decl));
- }
+ copy_rtx_if_shared (DECL_RTL (decl));
/* Unshare just about everything else. */
unshare_all_rtl_1 (insn);
@@ -3836,21 +3911,16 @@ init_emit ()
REGNO_POINTER_FLAG (VIRTUAL_CFA_REGNUM) = 1;
#ifdef STACK_BOUNDARY
- REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM)
- = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY / BITS_PER_UNIT;
-
- REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM)
- = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM)
- = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM)
- = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM)
- = STACK_BOUNDARY / BITS_PER_UNIT;
- REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = UNITS_PER_WORD;
+ REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;
+
+ REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;
+ REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
#endif
#ifdef INIT_EXPANDERS
@@ -4085,6 +4155,14 @@ init_emit_once (line_numbers)
ggc_add_rtx_root (&static_chain_rtx, 1);
ggc_add_rtx_root (&static_chain_incoming_rtx, 1);
ggc_add_rtx_root (&return_address_pointer_rtx, 1);
+
+ /* Initialize the CONST_INT hash table. */
+ const_int_htab = htab_create (37,
+ const_int_htab_hash,
+ const_int_htab_eq,
+ NULL);
+ ggc_add_root (&const_int_htab, 1, sizeof (const_int_htab),
+ rtx_htab_mark);
}
/* Query and clear/ restore no_line_numbers. This is used by the
diff --git a/gcc/enquire.c b/gcc/enquire.c
index bb5ea0be604..8b4bdda3d52 100644
--- a/gcc/enquire.c
+++ b/gcc/enquire.c
@@ -716,7 +716,7 @@ int main(argc, argv) int argc; char *argv[]; {
printf ("#ifndef _FLOAT_H___\n");
printf ("#define _FLOAT_H___\n");
if (SYS_FLOAT_H_WRAP)
- printf ("#include_next <float.h>\n");
+ printf (" #include_next <float.h>\n");
}
#ifdef ID
printf("%sProduced on %s by enquire version %s, CWI, Amsterdam%s\n",
diff --git a/gcc/except.c b/gcc/except.c
index 7cf64cccd02..67bbc40c272 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2162,6 +2162,24 @@ add_eh_table_entry (n)
}
}
eh_table[eh_table_size++] = n;
+
+ if (flag_new_exceptions)
+ {
+ /* We will output the exception table late in the compilation. That
+ references type_info objects which should have already been output
+ by that time. We explicitly mark those objects as being
+ referenced now so we know to emit them. */
+ struct handler_info *handler = get_first_handler (n);
+
+ for (; handler; handler = handler->next)
+ if (handler->type_info && handler->type_info != CATCH_ALL_TYPE)
+ {
+ tree tinfo = (tree)handler->type_info;
+
+ tinfo = TREE_OPERAND (tinfo, 0);
+ TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (tinfo)) = 1;
+ }
+ }
#endif
}
@@ -2924,7 +2942,7 @@ eh_regs (pcontext, psp, pra, outgoing)
int outgoing ATTRIBUTE_UNUSED;
{
rtx rcontext, rsp, rra;
- int i;
+ unsigned int i;
#ifdef FUNCTION_OUTGOING_VALUE
if (outgoing)
diff --git a/gcc/explow.c b/gcc/explow.c
index b87764b6180..0f067caf215 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -583,11 +583,11 @@ memory_address (mode, x)
if (oldx == x)
return x;
else if (GET_CODE (x) == REG)
- mark_reg_pointer (x, 1);
+ mark_reg_pointer (x, BITS_PER_UNIT);
else if (GET_CODE (x) == PLUS
&& GET_CODE (XEXP (x, 0)) == REG
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
- mark_reg_pointer (XEXP (x, 0), 1);
+ mark_reg_pointer (XEXP (x, 0), BITS_PER_UNIT);
/* OLDX may have been the address on a temporary. Update the address
to indicate that X is now used. */
@@ -852,6 +852,11 @@ adjust_stack (adjust)
if (adjust == const0_rtx)
return;
+ /* We expect all variable sized adjustments to be multiple of
+ PREFERRED_STACK_BOUNDARY. */
+ if (GET_CODE (adjust) == CONST_INT)
+ stack_pointer_delta -= INTVAL (adjust);
+
temp = expand_binop (Pmode,
#ifdef STACK_GROWS_DOWNWARD
add_optab,
@@ -878,6 +883,11 @@ anti_adjust_stack (adjust)
if (adjust == const0_rtx)
return;
+ /* We expect all variable sized adjustments to be multiple of
+ PREFERRED_STACK_BOUNDARY. */
+ if (GET_CODE (adjust) == CONST_INT)
+ stack_pointer_delta += INTVAL (adjust);
+
temp = expand_binop (Pmode,
#ifdef STACK_GROWS_DOWNWARD
sub_optab,
@@ -1295,6 +1305,13 @@ allocate_dynamic_stack_space (size, target, known_align)
do_pending_stack_adjust ();
+ /* We ought to be called always on the toplevel and stack ought to be aligned
+ propertly. */
+#ifdef PREFERRED_STACK_BOUNDARY
+ if (stack_pointer_delta % (PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT))
+ abort ();
+#endif
+
/* If needed, check that we have the required amount of stack. Take into
account what has already been checked. */
if (flag_stack_check && ! STACK_CHECK_BUILTIN)
@@ -1305,7 +1322,7 @@ allocate_dynamic_stack_space (size, target, known_align)
|| REGNO (target) < FIRST_PSEUDO_REGISTER)
target = gen_reg_rtx (Pmode);
- mark_reg_pointer (target, known_align / BITS_PER_UNIT);
+ mark_reg_pointer (target, known_align);
/* Perform the required allocation from the stack. Some systems do
this differently than simply incrementing/decrementing from the
@@ -1584,17 +1601,20 @@ hard_function_value (valtype, func, outgoing)
int outgoing ATTRIBUTE_UNUSED;
{
rtx val;
+
#ifdef FUNCTION_OUTGOING_VALUE
if (outgoing)
val = FUNCTION_OUTGOING_VALUE (valtype, func);
else
#endif
val = FUNCTION_VALUE (valtype, func);
+
if (GET_CODE (val) == REG
&& GET_MODE (val) == BLKmode)
{
- int bytes = int_size_in_bytes (valtype);
+ unsigned HOST_WIDE_INT bytes = int_size_in_bytes (valtype);
enum machine_mode tmpmode;
+
for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
tmpmode != VOIDmode;
tmpmode = GET_MODE_WIDER_MODE (tmpmode))
diff --git a/gcc/expmed.c b/gcc/expmed.c
index a7f542bd9a9..4194f2b182e 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -35,18 +35,24 @@ Boston, MA 02111-1307, USA. */
#include "real.h"
#include "recog.h"
-static void store_fixed_bit_field PARAMS ((rtx, int, int, int, rtx,
- unsigned int));
-static void store_split_bit_field PARAMS ((rtx, int, int, rtx,
+static void store_fixed_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, rtx,
unsigned int));
-static rtx extract_fixed_bit_field PARAMS ((enum machine_mode, rtx, int,
- int, int, rtx, int,
+static void store_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, rtx,
unsigned int));
+static rtx extract_fixed_bit_field PARAMS ((enum machine_mode, rtx,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ rtx, int, unsigned int));
static rtx mask_rtx PARAMS ((enum machine_mode, int,
int, int));
static rtx lshift_value PARAMS ((enum machine_mode, rtx,
int, int));
-static rtx extract_split_bit_field PARAMS ((rtx, int, int, int,
+static rtx extract_split_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int,
unsigned int));
static void do_cmp_and_jump PARAMS ((rtx, rtx, enum rtx_code,
enum machine_mode, rtx));
@@ -211,7 +217,7 @@ negate_rtx (mode, x)
into a bit-field within structure STR_RTX
containing BITSIZE bits starting at bit BITNUM.
FIELDMODE is the machine-mode of the FIELD_DECL node for this field.
- ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
+ ALIGN is the alignment that STR_RTX is known to have.
TOTAL_SIZE is the size of the structure in bytes, or -1 if varying. */
/* ??? Note that there are two different ideas here for how
@@ -225,19 +231,20 @@ negate_rtx (mode, x)
rtx
store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
rtx str_rtx;
- register int bitsize;
- int bitnum;
+ unsigned HOST_WIDE_INT bitsize;
+ unsigned HOST_WIDE_INT bitnum;
enum machine_mode fieldmode;
rtx value;
unsigned int align;
- int total_size;
+ HOST_WIDE_INT total_size;
{
- int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
- register int offset = bitnum / unit;
- register int bitpos = bitnum % unit;
+ unsigned int unit
+ = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
+ unsigned HOST_WIDE_INT offset = bitnum / unit;
+ unsigned HOST_WIDE_INT bitpos = bitnum % unit;
register rtx op0 = str_rtx;
#ifdef HAVE_insv
- int insv_bitsize;
+ unsigned HOST_WIDE_INT insv_bitsize;
enum machine_mode op_mode;
op_mode = insn_data[(int) CODE_FOR_insv].operand[3].mode;
@@ -302,7 +309,7 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
&& (GET_CODE (op0) != MEM
|| ! SLOW_UNALIGNED_ACCESS (fieldmode, align)
|| (offset * BITS_PER_UNIT % bitsize == 0
- && align % GET_MODE_SIZE (fieldmode) == 0))
+ && align % GET_MODE_BITSIZE (fieldmode) == 0))
&& (BYTES_BIG_ENDIAN ? bitpos + bitsize == unit : bitpos == 0)
&& bitsize == GET_MODE_BITSIZE (fieldmode))
{
@@ -384,10 +391,9 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
be less than full.
However, only do that if the value is not BLKmode. */
- int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
-
- int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
- int i;
+ unsigned int backwards = WORDS_BIG_ENDIAN && fieldmode != BLKmode;
+ unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
+ unsigned int i;
/* This is the mode we must force value to, so that there will be enough
subwords to extract. Note that fieldmode will often (always?) be
@@ -400,10 +406,13 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
{
/* If I is 0, use the low-order word in both field and target;
if I is 1, use the next to lowest word; and so on. */
- int wordnum = (backwards ? nwords - i - 1 : i);
- int bit_offset = (backwards
- ? MAX (bitsize - (i + 1) * BITS_PER_WORD, 0)
- : i * BITS_PER_WORD);
+ unsigned int wordnum = (backwards ? nwords - i - 1 : i);
+ unsigned int bit_offset = (backwards
+ ? MAX ((int) bitsize - ((int) i + 1)
+ * BITS_PER_WORD,
+ 0)
+ : (int) i * BITS_PER_WORD);
+
store_bit_field (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD),
bitnum + bit_offset, word_mode,
@@ -506,14 +515,14 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
if (GET_MODE (op0) == BLKmode
|| GET_MODE_SIZE (GET_MODE (op0)) > GET_MODE_SIZE (maxmode))
bestmode
- = get_best_mode (bitsize, bitnum, align * BITS_PER_UNIT, maxmode,
+ = get_best_mode (bitsize, bitnum, align, maxmode,
MEM_VOLATILE_P (op0));
else
bestmode = GET_MODE (op0);
if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align)
- && GET_MODE_SIZE (bestmode) > (int) align))
+ && GET_MODE_BITSIZE (bestmode) > align))
goto insv_loses;
/* Adjust address to point to the containing unit of that mode. */
@@ -524,7 +533,8 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
op0 = change_address (op0, bestmode,
plus_constant (XEXP (op0, 0), offset));
- /* Fetch that unit, store the bitfield in it, then store the unit. */
+ /* Fetch that unit, store the bitfield in it, then store
+ the unit. */
tempreg = copy_to_reg (op0);
store_bit_field (tempreg, bitsize, bitpos, fieldmode, value,
align, total_size);
@@ -619,25 +629,25 @@ store_bit_field (str_rtx, bitsize, bitnum, fieldmode, value, align, total_size)
(If OP0 is a register, it may be a full word or a narrower mode,
but BITPOS still counts within a full word,
which is significant on bigendian machines.)
- STRUCT_ALIGN is the alignment the structure is known to have (in bytes).
+ STRUCT_ALIGN is the alignment the structure is known to have.
Note that protect_from_queue has already been done on OP0 and VALUE. */
static void
store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
register rtx op0;
- register int offset, bitsize, bitpos;
+ unsigned HOST_WIDE_INT offset, bitsize, bitpos;
register rtx value;
unsigned int struct_align;
{
register enum machine_mode mode;
- int total_bits = BITS_PER_WORD;
+ unsigned int total_bits = BITS_PER_WORD;
rtx subtarget, temp;
int all_zero = 0;
int all_one = 0;
if (! SLOW_UNALIGNED_ACCESS (word_mode, struct_align))
- struct_align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
+ struct_align = BIGGEST_ALIGNMENT;
/* There is a case not handled here:
a structure with a known alignment of just a halfword
@@ -665,7 +675,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
a word, we won't be doing the extraction the normal way. */
mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
- struct_align * BITS_PER_UNIT, word_mode,
+ struct_align, word_mode,
GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
if (mode == VOIDmode)
@@ -789,7 +799,7 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
BITSIZE is the field width; BITPOS the position of its first bit
(within the word).
VALUE is the value to store.
- ALIGN is the known alignment of OP0, measured in bytes.
+ ALIGN is the known alignment of OP0.
This is also the size of the memory objects to be used.
This does not yet handle fields wider than BITS_PER_WORD. */
@@ -797,19 +807,19 @@ store_fixed_bit_field (op0, offset, bitsize, bitpos, value, struct_align)
static void
store_split_bit_field (op0, bitsize, bitpos, value, align)
rtx op0;
- int bitsize, bitpos;
+ unsigned HOST_WIDE_INT bitsize, bitpos;
rtx value;
unsigned int align;
{
- int unit;
- int bitsdone = 0;
+ unsigned int unit;
+ unsigned int bitsdone = 0;
/* Make sure UNIT isn't larger than BITS_PER_WORD, we can only handle that
much at a time. */
if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
unit = BITS_PER_WORD;
else
- unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
+ unit = MIN (align, BITS_PER_WORD);
/* If VALUE is a constant other than a CONST_INT, get it into a register in
WORD_MODE. If we can do this using gen_lowpart_common, do so. Note
@@ -831,10 +841,10 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
while (bitsdone < bitsize)
{
- int thissize;
+ unsigned HOST_WIDE_INT thissize;
rtx part, word;
- int thispos;
- int offset;
+ unsigned HOST_WIDE_INT thispos;
+ unsigned HOST_WIDE_INT offset;
offset = (bitpos + bitsdone) / unit;
thispos = (bitpos + bitsdone) % unit;
@@ -876,8 +886,7 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
GET_MODE (value) == VOIDmode
? UNITS_PER_WORD
: (GET_MODE (value) == BLKmode
- ? 1
- : GET_MODE_ALIGNMENT (GET_MODE (value)) / BITS_PER_UNIT));
+ ? 1 : GET_MODE_ALIGNMENT (GET_MODE (value))));
}
else
{
@@ -893,8 +902,7 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
GET_MODE (value) == VOIDmode
? UNITS_PER_WORD
: (GET_MODE (value) == BLKmode
- ? 1
- : GET_MODE_ALIGNMENT (GET_MODE (value)) / BITS_PER_UNIT));
+ ? 1 : GET_MODE_ALIGNMENT (GET_MODE (value))));
}
/* If OP0 is a register, then handle OFFSET here.
@@ -938,7 +946,7 @@ store_split_bit_field (op0, bitsize, bitpos, value, align)
TMODE is the mode the caller would like the value to have;
but the value may be returned with type MODE instead.
- ALIGN is the alignment that STR_RTX is known to have, measured in bytes.
+ ALIGN is the alignment that STR_RTX is known to have.
TOTAL_SIZE is the size in bytes of the containing structure,
or -1 if varying.
@@ -951,27 +959,28 @@ rtx
extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
target, mode, tmode, align, total_size)
rtx str_rtx;
- register int bitsize;
- int bitnum;
+ unsigned HOST_WIDE_INT bitsize;
+ unsigned HOST_WIDE_INT bitnum;
int unsignedp;
rtx target;
enum machine_mode mode, tmode;
unsigned int align;
- int total_size;
+ HOST_WIDE_INT total_size;
{
- int unit = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
- register int offset = bitnum / unit;
- register int bitpos = bitnum % unit;
+ unsigned int unit
+ = (GET_CODE (str_rtx) == MEM) ? BITS_PER_UNIT : BITS_PER_WORD;
+ unsigned HOST_WIDE_INT offset = bitnum / unit;
+ unsigned HOST_WIDE_INT bitpos = bitnum % unit;
register rtx op0 = str_rtx;
rtx spec_target = target;
rtx spec_target_subreg = 0;
enum machine_mode int_mode;
#ifdef HAVE_extv
- int extv_bitsize;
+ unsigned HOST_WIDE_INT extv_bitsize;
enum machine_mode extv_mode;
#endif
#ifdef HAVE_extzv
- int extzv_bitsize;
+ unsigned HOST_WIDE_INT extzv_bitsize;
enum machine_mode extzv_mode;
#endif
@@ -1058,7 +1067,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
|| (GET_CODE (op0) == MEM
&& (! SLOW_UNALIGNED_ACCESS (mode, align)
|| (offset * BITS_PER_UNIT % bitsize == 0
- && align * BITS_PER_UNIT % bitsize == 0))))
+ && align % bitsize == 0))))
&& ((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
&& bitpos % BITS_PER_WORD == 0)
|| (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != BLKmode
@@ -1107,8 +1116,8 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
This is because the most significant word is the one which may
be less than full. */
- int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
- int i;
+ unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
+ unsigned int i;
if (target == 0 || GET_CODE (target) != REG)
target = gen_reg_rtx (mode);
@@ -1121,20 +1130,21 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
/* If I is 0, use the low-order word in both field and target;
if I is 1, use the next to lowest word; and so on. */
/* Word number in TARGET to use. */
- int wordnum = (WORDS_BIG_ENDIAN
- ? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
- : i);
+ unsigned int wordnum
+ = (WORDS_BIG_ENDIAN
+ ? GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD - i - 1
+ : i);
/* Offset from start of field in OP0. */
- int bit_offset = (WORDS_BIG_ENDIAN
- ? MAX (0, bitsize - (i + 1) * BITS_PER_WORD)
- : i * BITS_PER_WORD);
+ unsigned int bit_offset = (WORDS_BIG_ENDIAN
+ ? MAX (0, ((int) bitsize - ((int) i + 1)
+ * (int) BITS_PER_WORD))
+ : (int) i * BITS_PER_WORD);
rtx target_part = operand_subword (target, wordnum, 1, VOIDmode);
rtx result_part
= extract_bit_field (op0, MIN (BITS_PER_WORD,
bitsize - i * BITS_PER_WORD),
- bitnum + bit_offset,
- 1, target_part, mode, word_mode,
- align, total_size);
+ bitnum + bit_offset, 1, target_part, mode,
+ word_mode, align, total_size);
if (target_part == 0)
abort ();
@@ -1149,7 +1159,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
need to be zero'd out. */
if (GET_MODE_SIZE (GET_MODE (target)) > nwords * UNITS_PER_WORD)
{
- int i,total_words;
+ unsigned int i, total_words;
total_words = GET_MODE_SIZE (GET_MODE (target)) / UNITS_PER_WORD;
for (i = nwords; i < total_words; i++)
@@ -1215,7 +1225,7 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
&& ! ((GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
&& (bitsize + bitpos > extzv_bitsize)))
{
- int xbitpos = bitpos, xoffset = offset;
+ unsigned HOST_WIDE_INT xbitpos = bitpos, xoffset = offset;
rtx bitsize_rtx, bitpos_rtx;
rtx last = get_last_insn ();
rtx xop0 = op0;
@@ -1250,15 +1260,14 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (GET_MODE (xop0) == BLKmode
|| (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (maxmode)))
- bestmode = get_best_mode (bitsize, bitnum,
- align * BITS_PER_UNIT, maxmode,
+ bestmode = get_best_mode (bitsize, bitnum, align, maxmode,
MEM_VOLATILE_P (xop0));
else
bestmode = GET_MODE (xop0);
if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align)
- && GET_MODE_SIZE (bestmode) > (int) align))
+ && GET_MODE_BITSIZE (bestmode) > align))
goto extzv_loses;
/* Compute offset as multiple of this unit,
@@ -1388,15 +1397,14 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
if (GET_MODE (xop0) == BLKmode
|| (GET_MODE_SIZE (GET_MODE (op0))
> GET_MODE_SIZE (maxmode)))
- bestmode = get_best_mode (bitsize, bitnum,
- align * BITS_PER_UNIT, maxmode,
+ bestmode = get_best_mode (bitsize, bitnum, align, maxmode,
MEM_VOLATILE_P (xop0));
else
bestmode = GET_MODE (xop0);
if (bestmode == VOIDmode
|| (SLOW_UNALIGNED_ACCESS (bestmode, align)
- && GET_MODE_SIZE (bestmode) > (int) align))
+ && GET_MODE_BITSIZE (bestmode) > align))
goto extv_loses;
/* Compute offset as multiple of this unit,
@@ -1526,18 +1534,18 @@ extract_bit_field (str_rtx, bitsize, bitnum, unsignedp,
and return TARGET, but this is not guaranteed.
If TARGET is not used, create a pseudo-reg of mode TMODE for the value.
- ALIGN is the alignment that STR_RTX is known to have, measured in bytes. */
+ ALIGN is the alignment that STR_RTX is known to have. */
static rtx
extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
target, unsignedp, align)
enum machine_mode tmode;
register rtx op0, target;
- register int offset, bitsize, bitpos;
+ unsigned HOST_WIDE_INT offset, bitsize, bitpos;
int unsignedp;
unsigned int align;
{
- int total_bits = BITS_PER_WORD;
+ unsigned int total_bits = BITS_PER_WORD;
enum machine_mode mode;
if (GET_CODE (op0) == SUBREG || GET_CODE (op0) == REG)
@@ -1553,8 +1561,8 @@ extract_fixed_bit_field (tmode, op0, offset, bitsize, bitpos,
includes the entire field. If such a mode would be larger than
a word, we won't be doing the extraction the normal way. */
- mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT,
- align * BITS_PER_UNIT, word_mode,
+ mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, align,
+ word_mode,
GET_CODE (op0) == MEM && MEM_VOLATILE_P (op0));
if (mode == VOIDmode)
@@ -1747,17 +1755,18 @@ lshift_value (mode, value, bitpos, bitsize)
BITSIZE is the field width; BITPOS, position of its first bit, in the word.
UNSIGNEDP is 1 if should zero-extend the contents; else sign-extend.
- ALIGN is the known alignment of OP0, measured in bytes.
- This is also the size of the memory objects to be used. */
+ ALIGN is the known alignment of OP0. This is also the size of the
+ memory objects to be used. */
static rtx
extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
rtx op0;
- int bitsize, bitpos, unsignedp;
+ unsigned HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
unsigned int align;
{
- int unit;
- int bitsdone = 0;
+ unsigned int unit;
+ unsigned int bitsdone = 0;
rtx result = NULL_RTX;
int first = 1;
@@ -1766,14 +1775,14 @@ extract_split_bit_field (op0, bitsize, bitpos, unsignedp, align)
if (GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG)
unit = BITS_PER_WORD;
else
- unit = MIN (align * BITS_PER_UNIT, BITS_PER_WORD);
+ unit = MIN (align, BITS_PER_WORD);
while (bitsdone < bitsize)
{
- int thissize;
+ unsigned HOST_WIDE_INT thissize;
rtx part, word;
- int thispos;
- int offset;
+ unsigned HOST_WIDE_INT thispos;
+ unsigned HOST_WIDE_INT offset;
offset = (bitpos + bitsdone) / unit;
thispos = (bitpos + bitsdone) % unit;
diff --git a/gcc/expr.c b/gcc/expr.c
index 09d4063dcd2..0302d959459 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -45,6 +45,19 @@ Boston, MA 02111-1307, USA. */
#include "intl.h"
#include "tm_p.h"
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
+/* Supply a default definition for PUSH_ARGS. */
+#ifndef PUSH_ARGS
+#ifdef PUSH_ROUNDING
+#define PUSH_ARGS !ACCUMULATE_OUTGOING_ARGS
+#else
+#define PUSH_ARGS 0
+#endif
+#endif
+
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -143,12 +156,15 @@ static void clear_by_pieces_1 PARAMS ((rtx (*) (rtx, ...),
struct clear_by_pieces *));
static int is_zeros_p PARAMS ((tree));
static int mostly_zeros_p PARAMS ((tree));
-static void store_constructor_field PARAMS ((rtx, int, int, enum machine_mode,
+static void store_constructor_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ HOST_WIDE_INT, enum machine_mode,
tree, tree, unsigned int, int));
-static void store_constructor PARAMS ((tree, rtx, unsigned int, int, int));
-static rtx store_field PARAMS ((rtx, int, int, enum machine_mode,
+static void store_constructor PARAMS ((tree, rtx, unsigned int, int,
+ HOST_WIDE_INT));
+static rtx store_field PARAMS ((rtx, HOST_WIDE_INT,
+ HOST_WIDE_INT, enum machine_mode,
tree, enum machine_mode, int,
- unsigned int, int, int));
+ unsigned int, HOST_WIDE_INT, int));
static enum memory_use_mode
get_memory_usage_from_modifier PARAMS ((enum expand_modifier));
static tree save_noncopied_parts PARAMS ((tree, tree));
@@ -162,7 +178,8 @@ static rtx expand_increment PARAMS ((tree, int, int));
static void preexpand_calls PARAMS ((tree));
static void do_jump_by_parts_greater PARAMS ((tree, int, rtx, rtx));
static void do_jump_by_parts_equality PARAMS ((tree, rtx, rtx));
-static void do_compare_and_jump PARAMS ((tree, enum rtx_code, enum rtx_code, rtx, rtx));
+static void do_compare_and_jump PARAMS ((tree, enum rtx_code, enum rtx_code,
+ rtx, rtx));
static rtx do_store_flag PARAMS ((tree, rtx, enum machine_mode, int));
/* Record for each mode whether we can move a register directly to or
@@ -187,8 +204,8 @@ static char direct_store[NUM_MACHINE_MODES];
/* This macro is used to determine whether move_by_pieces should be called
to perform a structure copy. */
#ifndef MOVE_BY_PIECES_P
-#define MOVE_BY_PIECES_P(SIZE, ALIGN) (move_by_pieces_ninsns \
- (SIZE, ALIGN) < MOVE_RATIO)
+#define MOVE_BY_PIECES_P(SIZE, ALIGN) \
+ (move_by_pieces_ninsns (SIZE, ALIGN) < MOVE_RATIO)
#endif
/* This array records the insn_code of insns to perform block moves. */
@@ -289,7 +306,7 @@ init_expr ()
pending_chain = 0;
pending_stack_adjust = 0;
- arg_space_so_far = 0;
+ stack_pointer_delta = 0;
inhibit_defer_pop = 0;
saveregs_value = 0;
apply_args_value = 0;
@@ -1348,7 +1365,7 @@ convert_modes (mode, oldmode, x, unsignedp)
/* MOVE_MAX_PIECES is the number of bytes at a time which we can
move efficiently, as opposed to MOVE_MAX which is the maximum
- number of bhytes we can move with a single instruction. */
+ number of bytes we can move with a single instruction. */
#ifndef MOVE_MAX_PIECES
#define MOVE_MAX_PIECES MOVE_MAX
@@ -1358,7 +1375,7 @@ convert_modes (mode, oldmode, x, unsignedp)
from block FROM to block TO. (These are MEM rtx's with BLKmode).
The caller must pass FROM and TO
through protect_from_queue before calling.
- ALIGN (in bytes) is maximum alignment we can assume. */
+ ALIGN is maximum alignment we can assume. */
void
move_by_pieces (to, from, len, align)
@@ -1368,7 +1385,7 @@ move_by_pieces (to, from, len, align)
{
struct move_by_pieces data;
rtx to_addr = XEXP (to, 0), from_addr = XEXP (from, 0);
- int max_size = MOVE_MAX_PIECES + 1;
+ unsigned int max_size = MOVE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
enum insn_code icode;
@@ -1440,8 +1457,8 @@ move_by_pieces (to, from, len, align)
}
if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- align = MOVE_MAX;
+ || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
+ align = MOVE_MAX * BITS_PER_UNIT;
/* First move what we can in the largest integer mode, then go to
successively smaller modes. */
@@ -1457,9 +1474,7 @@ move_by_pieces (to, from, len, align)
break;
icode = mov_optab->handlers[(int) mode].insn_code;
- if (icode != CODE_FOR_nothing
- && align >= MIN (BIGGEST_ALIGNMENT / BITS_PER_UNIT,
- (unsigned int) GET_MODE_SIZE (mode)))
+ if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
move_by_pieces_1 (GEN_FCN (icode), mode, &data);
max_size = GET_MODE_SIZE (mode);
@@ -1479,11 +1494,11 @@ move_by_pieces_ninsns (l, align)
unsigned int align;
{
register int n_insns = 0;
- int max_size = MOVE_MAX + 1;
+ unsigned int max_size = MOVE_MAX + 1;
if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- align = MOVE_MAX;
+ || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
+ align = MOVE_MAX * BITS_PER_UNIT;
while (max_size > 1)
{
@@ -1499,8 +1514,7 @@ move_by_pieces_ninsns (l, align)
break;
icode = mov_optab->handlers[(int) mode].insn_code;
- if (icode != CODE_FOR_nothing
- && align >= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT)
+ if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
n_insns += l / GET_MODE_SIZE (mode), l %= GET_MODE_SIZE (mode);
max_size = GET_MODE_SIZE (mode);
@@ -1567,8 +1581,7 @@ move_by_pieces_1 (genfun, mode, data)
Both X and Y must be MEM rtx's (perhaps inside VOLATILE)
with mode BLKmode.
SIZE is an rtx that says how long they are.
- ALIGN is the maximum alignment we can assume they have,
- measured in bytes.
+ ALIGN is the maximum alignment we can assume they have.
Return the address of the new block, if memcpy is called and returns it,
0 otherwise. */
@@ -1610,7 +1623,7 @@ emit_block_move (x, y, size, align)
including more than one in the machine description unless
the more limited one has some advantage. */
- rtx opalign = GEN_INT (align);
+ rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
@@ -1920,8 +1933,8 @@ emit_group_load (dst, orig_src, ssize, align)
for (i = start; i < XVECLEN (dst, 0); i++)
{
enum machine_mode mode = GET_MODE (XEXP (XVECEXP (dst, 0, i), 0));
- int bytepos = INTVAL (XEXP (XVECEXP (dst, 0, i), 1));
- int bytelen = GET_MODE_SIZE (mode);
+ HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (dst, 0, i), 1));
+ unsigned int bytelen = GET_MODE_SIZE (mode);
int shift = 0;
/* Handle trailing fragments that run over the size of the struct. */
@@ -1935,7 +1948,7 @@ emit_group_load (dst, orig_src, ssize, align)
/* Optimize the access just a bit. */
if (GET_CODE (src) == MEM
- && align * BITS_PER_UNIT >= GET_MODE_ALIGNMENT (mode)
+ && align >= GET_MODE_ALIGNMENT (mode)
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
{
@@ -1957,18 +1970,15 @@ emit_group_load (dst, orig_src, ssize, align)
abort ();
}
else
- {
- tmps[i] = extract_bit_field (src, bytelen*BITS_PER_UNIT,
- bytepos*BITS_PER_UNIT, 1, NULL_RTX,
- mode, mode, align, ssize);
- }
+ tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
+ bytepos * BITS_PER_UNIT, 1, NULL_RTX,
+ mode, mode, align, ssize);
if (BYTES_BIG_ENDIAN && shift)
- {
- expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
- tmps[i], 0, OPTAB_WIDEN);
- }
+ expand_binop (mode, ashl_optab, tmps[i], GEN_INT (shift),
+ tmps[i], 0, OPTAB_WIDEN);
}
+
emit_queue();
/* Copy the extracted pieces into the proper (probable) hard regs. */
@@ -2050,9 +2060,9 @@ emit_group_store (orig_dst, src, ssize, align)
/* Process the pieces. */
for (i = start; i < XVECLEN (src, 0); i++)
{
- int bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
+ HOST_WIDE_INT bytepos = INTVAL (XEXP (XVECEXP (src, 0, i), 1));
enum machine_mode mode = GET_MODE (tmps[i]);
- int bytelen = GET_MODE_SIZE (mode);
+ unsigned int bytelen = GET_MODE_SIZE (mode);
/* Handle trailing fragments that run over the size of the struct. */
if (ssize >= 0 && bytepos + bytelen > ssize)
@@ -2068,7 +2078,7 @@ emit_group_store (orig_dst, src, ssize, align)
/* Optimize the access just a bit. */
if (GET_CODE (dst) == MEM
- && align * BITS_PER_UNIT >= GET_MODE_ALIGNMENT (mode)
+ && align >= GET_MODE_ALIGNMENT (mode)
&& bytepos * BITS_PER_UNIT % GET_MODE_ALIGNMENT (mode) == 0
&& bytelen == GET_MODE_SIZE (mode))
emit_move_insn (change_address (dst, mode,
@@ -2097,74 +2107,69 @@ emit_group_store (orig_dst, src, ssize, align)
in registers regardless of the structure's alignment. */
rtx
-copy_blkmode_from_reg (tgtblk,srcreg,type)
+copy_blkmode_from_reg (tgtblk, srcreg, type)
rtx tgtblk;
rtx srcreg;
tree type;
{
- int bytes = int_size_in_bytes (type);
- rtx src = NULL, dst = NULL;
- int bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
- int bitpos, xbitpos, big_endian_correction = 0;
-
- if (tgtblk == 0)
- {
- tgtblk = assign_stack_temp (BLKmode, bytes, 0);
- MEM_SET_IN_STRUCT_P (tgtblk, AGGREGATE_TYPE_P (type));
- preserve_temp_slots (tgtblk);
- }
+ unsigned HOST_WIDE_INT bytes = int_size_in_bytes (type);
+ rtx src = NULL, dst = NULL;
+ unsigned HOST_WIDE_INT bitsize = MIN (TYPE_ALIGN (type), BITS_PER_WORD);
+ unsigned HOST_WIDE_INT bitpos, xbitpos, big_endian_correction = 0;
+
+ if (tgtblk == 0)
+ {
+ tgtblk = assign_stack_temp (BLKmode, bytes, 0);
+ MEM_SET_IN_STRUCT_P (tgtblk, AGGREGATE_TYPE_P (type));
+ preserve_temp_slots (tgtblk);
+ }
- /* This code assumes srcreg is at least a full word. If it isn't,
- copy it into a new pseudo which is a full word. */
- if (GET_MODE (srcreg) != BLKmode
- && GET_MODE_SIZE (GET_MODE (srcreg)) < UNITS_PER_WORD)
- srcreg = convert_to_mode (word_mode, srcreg,
- TREE_UNSIGNED (type));
-
- /* Structures whose size is not a multiple of a word are aligned
- to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
- machine, this means we must skip the empty high order bytes when
- calculating the bit offset. */
- if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
- big_endian_correction = (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 (srcreg,
- 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 (tgtblk, bitpos / BITS_PER_WORD, 1, BLKmode);
+ /* This code assumes srcreg is at least a full word. If it isn't,
+ copy it into a new pseudo which is a full word. */
+ if (GET_MODE (srcreg) != BLKmode
+ && GET_MODE_SIZE (GET_MODE (srcreg)) < UNITS_PER_WORD)
+ srcreg = convert_to_mode (word_mode, srcreg, TREE_UNSIGNED (type));
+
+ /* Structures whose size is not a multiple of a word are aligned
+ to the least significant byte (to the right). On a BYTES_BIG_ENDIAN
+ machine, this means we must skip the empty high order bytes when
+ calculating the bit offset. */
+ if (BYTES_BIG_ENDIAN && bytes % UNITS_PER_WORD)
+ big_endian_correction
+ = (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 (srcreg, 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 (tgtblk, 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);
- }
- return tgtblk;
+ /* 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_WORD),
+ bitsize, BITS_PER_WORD);
+ }
+
+ return tgtblk;
}
@@ -2225,10 +2230,9 @@ use_group_regs (call_fusage, regs)
}
}
-/* Generate several move instructions to clear LEN bytes of block TO.
- (A MEM rtx with BLKmode). The caller must pass TO through
- protect_from_queue before calling. ALIGN (in bytes) is maximum alignment
- we can assume. */
+/* Generate several move instructions to clear LEN bytes of block TO. (A MEM
+ rtx with BLKmode). The caller must pass TO through protect_from_queue
+ before calling. ALIGN is maximum alignment we can assume. */
static void
clear_by_pieces (to, len, align)
@@ -2238,7 +2242,7 @@ clear_by_pieces (to, len, align)
{
struct clear_by_pieces data;
rtx to_addr = XEXP (to, 0);
- int max_size = MOVE_MAX_PIECES + 1;
+ unsigned int max_size = MOVE_MAX_PIECES + 1;
enum machine_mode mode = VOIDmode, tmode;
enum insn_code icode;
@@ -2286,8 +2290,8 @@ clear_by_pieces (to, len, align)
}
if (! SLOW_UNALIGNED_ACCESS (word_mode, align)
- || align > MOVE_MAX || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT)
- align = MOVE_MAX;
+ || align > MOVE_MAX * BITS_PER_UNIT || align >= BIGGEST_ALIGNMENT)
+ align = MOVE_MAX * BITS_PER_UNIT;
/* First move what we can in the largest integer mode, then go to
successively smaller modes. */
@@ -2303,8 +2307,7 @@ clear_by_pieces (to, len, align)
break;
icode = mov_optab->handlers[(int) mode].insn_code;
- if (icode != CODE_FOR_nothing
- && align >= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT)
+ if (icode != CODE_FOR_nothing && align >= GET_MODE_ALIGNMENT (mode))
clear_by_pieces_1 (GEN_FCN (icode), mode, &data);
max_size = GET_MODE_SIZE (mode);
@@ -2352,9 +2355,8 @@ clear_by_pieces_1 (genfun, mode, data)
}
}
-/* Write zeros through the storage of OBJECT.
- If OBJECT has BLKmode, SIZE is its length in bytes and ALIGN is
- the maximum alignment we can is has, measured in bytes.
+/* Write zeros through the storage of OBJECT. If OBJECT has BLKmode, SIZE is
+ its length in bytes and ALIGN is the maximum alignment we can is has.
If we call a function that returns the length of the block, return it. */
@@ -2378,14 +2380,13 @@ clear_storage (object, size, align)
if (GET_CODE (size) == CONST_INT
&& MOVE_BY_PIECES_P (INTVAL (size), align))
clear_by_pieces (object, INTVAL (size), align);
-
else
{
/* Try the most limited insn first, because there's no point
including more than one in the machine description unless
the more limited one has some advantage. */
- rtx opalign = GEN_INT (align);
+ rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
@@ -2587,7 +2588,7 @@ emit_move_insn_1 (x, y)
enum machine_mode mode = GET_MODE (x);
enum machine_mode submode;
enum mode_class class = GET_MODE_CLASS (mode);
- int i;
+ unsigned int i;
if (mode >= MAX_MACHINE_MODE)
abort ();
@@ -2816,27 +2817,36 @@ push_block (size, extra, below)
anti_adjust_stack (temp);
}
-#if defined (STACK_GROWS_DOWNWARD) \
- || (defined (ARGS_GROW_DOWNWARD) \
- && !defined (ACCUMULATE_OUTGOING_ARGS))
-
- /* Return the lowest stack address when STACK or ARGS grow downward and
- we are not aaccumulating outgoing arguments (the c4x port uses such
- conventions). */
- temp = virtual_outgoing_args_rtx;
- if (extra != 0 && below)
- temp = plus_constant (temp, extra);
+#ifndef STACK_GROWS_DOWNWARD
+#ifdef ARGS_GROW_DOWNWARD
+ if (!ACCUMULATE_OUTGOING_ARGS)
#else
- if (GET_CODE (size) == CONST_INT)
- temp = plus_constant (virtual_outgoing_args_rtx,
- - INTVAL (size) - (below ? 0 : extra));
- else if (extra != 0 && !below)
- temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
- negate_rtx (Pmode, plus_constant (size, extra)));
- else
- temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
- negate_rtx (Pmode, size));
+ if (0)
#endif
+#else
+ if (1)
+#endif
+ {
+
+ /* Return the lowest stack address when STACK or ARGS grow downward and
+ we are not aaccumulating outgoing arguments (the c4x port uses such
+ conventions). */
+ temp = virtual_outgoing_args_rtx;
+ if (extra != 0 && below)
+ temp = plus_constant (temp, extra);
+ }
+ else
+ {
+ if (GET_CODE (size) == CONST_INT)
+ temp = plus_constant (virtual_outgoing_args_rtx,
+ - INTVAL (size) - (below ? 0 : extra));
+ else if (extra != 0 && !below)
+ temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
+ negate_rtx (Pmode, plus_constant (size, extra)));
+ else
+ temp = gen_rtx_PLUS (Pmode, virtual_outgoing_args_rtx,
+ negate_rtx (Pmode, size));
+ }
return memory_address (GET_CLASS_NARROWEST_MODE (MODE_INT), temp);
}
@@ -2873,7 +2883,7 @@ get_push_address (size)
SIZE is an rtx for the size of data to be copied (in bytes),
needed only if X is BLKmode.
- ALIGN (in bytes) is maximum alignment we can assume.
+ ALIGN is maximum alignment we can assume.
If PARTIAL and REG are both nonzero, then copy that many of the first
words of X into registers starting with REG, and push the rest of X.
@@ -2967,6 +2977,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
and if there is no difficulty with push insns that skip bytes
on the stack for alignment purposes. */
if (args_addr == 0
+ && PUSH_ARGS
&& GET_CODE (size) == CONST_INT
&& skip == 0
&& (MOVE_BY_PIECES_P ((unsigned) INTVAL (size) - used, align))
@@ -2974,7 +2985,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
forces many pushes of a small amount of data,
and such small pushes do rounding that causes trouble. */
&& ((! SLOW_UNALIGNED_ACCESS (word_mode, align))
- || align >= BIGGEST_ALIGNMENT / BITS_PER_UNIT
+ || align >= BIGGEST_ALIGNMENT
|| PUSH_ROUNDING (align) == align)
&& PUSH_ROUNDING (INTVAL (size)) == INTVAL (size))
{
@@ -2985,6 +2996,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
&& where_pad != none && where_pad != stack_direction)
anti_adjust_stack (GEN_INT (extra));
+ stack_pointer_delta += INTVAL (size) - used;
move_by_pieces (gen_rtx_MEM (BLKmode, gen_push_operand ()), xinner,
INTVAL (size) - used, align);
@@ -3075,7 +3087,7 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
}
else
{
- rtx opalign = GEN_INT (align);
+ rtx opalign = GEN_INT (align / BITS_PER_UNIT);
enum machine_mode mode;
rtx target = gen_rtx_MEM (BLKmode, temp);
@@ -3119,15 +3131,16 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
}
}
-#ifndef ACCUMULATE_OUTGOING_ARGS
- /* If the source is referenced relative to the stack pointer,
- copy it to another register to stabilize it. We do not need
- to do this if we know that we won't be changing sp. */
+ if (!ACCUMULATE_OUTGOING_ARGS)
+ {
+ /* If the source is referenced relative to the stack pointer,
+ copy it to another register to stabilize it. We do not need
+ to do this if we know that we won't be changing sp. */
- if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
- || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
- temp = copy_to_reg (temp);
-#endif
+ if (reg_mentioned_p (virtual_stack_dynamic_rtx, temp)
+ || reg_mentioned_p (virtual_outgoing_args_rtx, temp))
+ temp = copy_to_reg (temp);
+ }
/* Make inhibit_defer_pop nonzero around the library call
to force it to pop the bcopy-arguments right away. */
@@ -3223,8 +3236,11 @@ emit_push_insn (x, mode, type, size, align, partial, reg, extra,
anti_adjust_stack (GEN_INT (extra));
#ifdef PUSH_ROUNDING
- if (args_addr == 0)
- addr = gen_push_operand ();
+ if (args_addr == 0 && PUSH_ARGS)
+ {
+ addr = gen_push_operand ();
+ stack_pointer_delta += PUSH_ROUNDING (GET_MODE_SIZE (mode));
+ }
else
#endif
{
@@ -3323,8 +3339,7 @@ expand_assignment (to, from, want_value, suggest_reg)
|| TREE_CODE (to) == ARRAY_REF)
{
enum machine_mode mode1;
- int bitsize;
- int bitpos;
+ HOST_WIDE_INT bitsize, bitpos;
tree offset;
int unsignedp;
int volatilep = 0;
@@ -3366,7 +3381,7 @@ expand_assignment (to, from, want_value, suggest_reg)
&& bitsize
&& (bitpos % bitsize) == 0
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
- && (alignment * BITS_PER_UNIT) == GET_MODE_ALIGNMENT (mode1))
+ && alignment == GET_MODE_ALIGNMENT (mode1))
{
rtx temp = change_address (to_rtx, mode1,
plus_constant (XEXP (to_rtx, 0),
@@ -3444,27 +3459,48 @@ expand_assignment (to, from, want_value, suggest_reg)
TYPE_MODE (integer_type_node));
}
- result = store_field (to_rtx, bitsize, bitpos, mode1, from,
- (want_value
- /* Spurious cast makes HPUX compiler happy. */
- ? (enum machine_mode) TYPE_MODE (TREE_TYPE (to))
- : VOIDmode),
- unsignedp,
- /* Required alignment of containing datum. */
- alignment,
- int_size_in_bytes (TREE_TYPE (tem)),
- get_alias_set (to));
- preserve_temp_slots (result);
- free_temp_slots ();
- pop_temp_slots ();
+ /* If this is a varying-length object, we must get the address of
+ the source and do an explicit block move. */
+ if (bitsize < 0)
+ {
+ unsigned int from_align;
+ rtx from_rtx = expand_expr_unaligned (from, &from_align);
+ rtx inner_to_rtx
+ = change_address (to_rtx, VOIDmode,
+ plus_constant (XEXP (to_rtx, 0),
+ bitpos / BITS_PER_UNIT));
- /* If the value is meaningful, convert RESULT to the proper mode.
- Otherwise, return nothing. */
- return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
- TYPE_MODE (TREE_TYPE (from)),
- result,
- TREE_UNSIGNED (TREE_TYPE (to)))
- : NULL_RTX);
+ emit_block_move (inner_to_rtx, from_rtx, expr_size (from),
+ MIN (alignment, from_align));
+ free_temp_slots ();
+ pop_temp_slots ();
+ return to_rtx;
+ }
+ else
+ {
+ result = store_field (to_rtx, bitsize, bitpos, mode1, from,
+ (want_value
+ /* Spurious cast for HPUX compiler. */
+ ? ((enum machine_mode)
+ TYPE_MODE (TREE_TYPE (to)))
+ : VOIDmode),
+ unsignedp,
+ alignment,
+ int_size_in_bytes (TREE_TYPE (tem)),
+ get_alias_set (to));
+
+ preserve_temp_slots (result);
+ free_temp_slots ();
+ pop_temp_slots ();
+
+ /* If the value is meaningful, convert RESULT to the proper mode.
+ Otherwise, return nothing. */
+ return (want_value ? convert_modes (TYPE_MODE (TREE_TYPE (to)),
+ TYPE_MODE (TREE_TYPE (from)),
+ result,
+ TREE_UNSIGNED (TREE_TYPE (to)))
+ : NULL_RTX);
+ }
}
/* If the rhs is a function call and its value is not an aggregate,
@@ -3493,10 +3529,10 @@ expand_assignment (to, from, want_value, suggest_reg)
The Irix 6 ABI has examples of this. */
if (GET_CODE (to_rtx) == PARALLEL)
emit_group_load (to_rtx, value, int_size_in_bytes (TREE_TYPE (from)),
- TYPE_ALIGN (TREE_TYPE (from)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (from)));
else if (GET_MODE (to_rtx) == BLKmode)
emit_block_move (to_rtx, value, expr_size (from),
- TYPE_ALIGN (TREE_TYPE (from)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (from)));
else
{
#ifdef POINTERS_EXTEND_UNSIGNED
@@ -3533,7 +3569,7 @@ expand_assignment (to, from, want_value, suggest_reg)
if (GET_CODE (to_rtx) == PARALLEL)
emit_group_load (to_rtx, temp, int_size_in_bytes (TREE_TYPE (from)),
- TYPE_ALIGN (TREE_TYPE (from)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (from)));
else
emit_move_insn (to_rtx, temp);
@@ -3859,8 +3895,7 @@ store_expr (exp, target, want_value)
size = expr_size (exp);
if (GET_CODE (size) == CONST_INT
&& INTVAL (size) < TREE_STRING_LENGTH (exp))
- emit_block_move (target, temp, size,
- TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
+ emit_block_move (target, temp, size, TYPE_ALIGN (TREE_TYPE (exp)));
else
{
/* Compute the size of the data to copy from the string. */
@@ -3874,7 +3909,7 @@ store_expr (exp, target, want_value)
/* Copy that much. */
emit_block_move (target, temp, copy_size_rtx,
- TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (exp)));
/* Figure out how much is left in TARGET that we have to clear.
Do all calculations in ptr_mode. */
@@ -3938,10 +3973,10 @@ store_expr (exp, target, want_value)
The Irix 6 ABI has examples of this. */
else if (GET_CODE (target) == PARALLEL)
emit_group_load (target, temp, int_size_in_bytes (TREE_TYPE (exp)),
- TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (exp)));
else if (GET_MODE (temp) == BLKmode)
emit_block_move (target, temp, expr_size (exp),
- TYPE_ALIGN (TREE_TYPE (exp)) / BITS_PER_UNIT);
+ TYPE_ALIGN (TREE_TYPE (exp)));
else
emit_move_insn (target, temp);
}
@@ -4051,7 +4086,8 @@ static void
store_constructor_field (target, bitsize, bitpos,
mode, exp, type, align, cleared)
rtx target;
- int bitsize, bitpos;
+ unsigned HOST_WIDE_INT bitsize;
+ HOST_WIDE_INT bitpos;
enum machine_mode mode;
tree exp, type;
unsigned int align;
@@ -4076,14 +4112,13 @@ store_constructor_field (target, bitsize, bitpos,
store_constructor (exp, target, align, cleared, bitsize / BITS_PER_UNIT);
}
else
- store_field (target, bitsize, bitpos, mode, exp, VOIDmode, 0,
- (align + BITS_PER_UNIT - 1) / BITS_PER_UNIT,
+ store_field (target, bitsize, bitpos, mode, exp, VOIDmode, 0, align,
int_size_in_bytes (type), 0);
}
/* Store the value of constructor EXP into the rtx TARGET.
TARGET is either a REG or a MEM.
- ALIGN is the maximum known alignment for TARGET, in bits.
+ ALIGN is the maximum known alignment for TARGET.
CLEARED is true if TARGET is known to have been zero'd.
SIZE is the number of bytes of TARGET we are allowed to modify: this
may not be the same as the size of EXP if we are assigning to a field
@@ -4095,11 +4130,11 @@ store_constructor (exp, target, align, cleared, size)
rtx target;
unsigned int align;
int cleared;
- int size;
+ HOST_WIDE_INT size;
{
tree type = TREE_TYPE (exp);
#ifdef WORD_REGISTER_OPERATIONS
- rtx exp_size = expr_size (exp);
+ HOST_WIDE_INT exp_size = int_size_in_bytes (type);
#endif
/* We know our target cannot conflict, since safe_from_p has been called. */
@@ -4130,8 +4165,7 @@ store_constructor (exp, target, align, cleared, size)
/* If the constructor is empty, clear the union. */
if (! CONSTRUCTOR_ELTS (exp) && ! cleared)
- clear_storage (target, expr_size (exp),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
+ clear_storage (target, expr_size (exp), TYPE_ALIGN (type));
}
/* If we are building a static constructor into a register,
@@ -4156,8 +4190,7 @@ store_constructor (exp, target, align, cleared, size)
|| mostly_zeros_p (exp)))
{
if (! cleared)
- clear_storage (target, GEN_INT (size),
- (align + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+ clear_storage (target, GEN_INT (size), align);
cleared = 1;
}
@@ -4175,10 +4208,10 @@ store_constructor (exp, target, align, cleared, size)
tree value = TREE_VALUE (elt);
#endif
register enum machine_mode mode;
- int bitsize;
- int bitpos = 0;
+ HOST_WIDE_INT bitsize;
+ HOST_WIDE_INT bitpos = 0;
int unsignedp;
- tree pos, constant = 0, offset = 0;
+ tree offset;
rtx to_rtx = target;
/* Just ignore missing fields.
@@ -4190,8 +4223,8 @@ store_constructor (exp, target, align, cleared, size)
if (cleared && is_zeros_p (TREE_VALUE (elt)))
continue;
- if (TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
- bitsize = TREE_INT_CST_LOW (DECL_SIZE (field));
+ if (host_integerp (DECL_SIZE (field), 1))
+ bitsize = tree_low_cst (DECL_SIZE (field), 1);
else
bitsize = -1;
@@ -4200,30 +4233,24 @@ store_constructor (exp, target, align, cleared, size)
if (DECL_BIT_FIELD (field))
mode = VOIDmode;
- pos = DECL_FIELD_BITPOS (field);
- if (TREE_CODE (pos) == INTEGER_CST)
- constant = pos;
- else if (TREE_CODE (pos) == PLUS_EXPR
- && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
- constant = TREE_OPERAND (pos, 1), offset = TREE_OPERAND (pos, 0);
+ offset = DECL_FIELD_OFFSET (field);
+ if (host_integerp (offset, 0)
+ && host_integerp (bit_position (field), 0))
+ {
+ bitpos = int_bit_position (field);
+ offset = 0;
+ }
else
- offset = pos;
-
- if (constant)
- bitpos = TREE_INT_CST_LOW (constant);
-
+ bitpos = tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 0);
+
if (offset)
{
rtx offset_rtx;
if (contains_placeholder_p (offset))
- offset = build (WITH_RECORD_EXPR, bitsizetype,
+ offset = build (WITH_RECORD_EXPR, sizetype,
offset, make_tree (TREE_TYPE (exp), target));
- offset = size_binop (EXACT_DIV_EXPR, offset,
- bitsize_int (BITS_PER_UNIT));
- offset = convert (sizetype, offset);
-
offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0);
if (GET_CODE (to_rtx) != MEM)
abort ();
@@ -4242,6 +4269,7 @@ store_constructor (exp, target, align, cleared, size)
gen_rtx_PLUS (ptr_mode, XEXP (to_rtx, 0),
force_reg (ptr_mode,
offset_rtx)));
+ align = DECL_OFFSET_ALIGN (field);
}
if (TREE_READONLY (field))
@@ -4257,14 +4285,13 @@ store_constructor (exp, target, align, cleared, size)
start of a word, try to widen it to a full word.
This special case allows us to output C++ member function
initializations in a form that the optimizers can understand. */
- if (constant
- && GET_CODE (target) == REG
+ if (GET_CODE (target) == REG
&& bitsize < BITS_PER_WORD
&& bitpos % BITS_PER_WORD == 0
&& GET_MODE_CLASS (mode) == MODE_INT
&& TREE_CODE (value) == INTEGER_CST
- && GET_CODE (exp_size) == CONST_INT
- && bitpos + BITS_PER_WORD <= INTVAL (exp_size) * BITS_PER_UNIT)
+ && exp_size >= 0
+ && bitpos + BITS_PER_WORD <= exp_size * BITS_PER_UNIT)
{
tree type = TREE_TYPE (value);
if (TYPE_PRECISION (type) < BITS_PER_WORD)
@@ -4281,10 +4308,7 @@ store_constructor (exp, target, align, cleared, size)
}
#endif
store_constructor_field (to_rtx, bitsize, bitpos, mode,
- TREE_VALUE (elt), type,
- MIN (align,
- DECL_ALIGN (TREE_PURPOSE (elt))),
- cleared);
+ TREE_VALUE (elt), type, align, cleared);
}
}
else if (TREE_CODE (type) == ARRAY_TYPE)
@@ -4315,19 +4339,21 @@ store_constructor (exp, target, align, cleared, size)
{
tree index = TREE_PURPOSE (elt);
HOST_WIDE_INT this_node_count;
+
if (index != NULL_TREE && TREE_CODE (index) == RANGE_EXPR)
{
tree lo_index = TREE_OPERAND (index, 0);
tree hi_index = TREE_OPERAND (index, 1);
- if (TREE_CODE (lo_index) != INTEGER_CST
- || TREE_CODE (hi_index) != INTEGER_CST)
+ if (! host_integerp (lo_index, 1)
+ || ! host_integerp (hi_index, 1))
{
need_to_clear = 1;
break;
}
- this_node_count = (TREE_INT_CST_LOW (hi_index)
- - TREE_INT_CST_LOW (lo_index) + 1);
+
+ this_node_count = (tree_low_cst (hi_index, 1)
+ - tree_low_cst (lo_index, 1) + 1);
}
else
this_node_count = 1;
@@ -4344,8 +4370,7 @@ store_constructor (exp, target, align, cleared, size)
if (need_to_clear && size > 0)
{
if (! cleared)
- clear_storage (target, GEN_INT (size),
- (align + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+ clear_storage (target, GEN_INT (size), align);
cleared = 1;
}
else
@@ -4360,8 +4385,8 @@ store_constructor (exp, target, align, cleared, size)
elt = TREE_CHAIN (elt), i++)
{
register enum machine_mode mode;
- int bitsize;
- int bitpos;
+ HOST_WIDE_INT bitsize;
+ HOST_WIDE_INT bitpos;
int unsignedp;
tree value = TREE_VALUE (elt);
unsigned int align = TYPE_ALIGN (TREE_TYPE (value));
@@ -4374,13 +4399,9 @@ store_constructor (exp, target, align, cleared, size)
unsignedp = TREE_UNSIGNED (elttype);
mode = TYPE_MODE (elttype);
if (mode == BLKmode)
- {
- if (TREE_CODE (TYPE_SIZE (elttype)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TYPE_SIZE (elttype)) == 0)
- bitsize = TREE_INT_CST_LOW (TYPE_SIZE (elttype));
- else
- bitsize = -1;
- }
+ bitsize = (host_integerp (TYPE_SIZE (elttype), 1)
+ ? tree_low_cst (TYPE_SIZE (elttype), 1)
+ : -1);
else
bitsize = GET_MODE_BITSIZE (mode);
@@ -4394,21 +4415,21 @@ store_constructor (exp, target, align, cleared, size)
tree position;
/* If the range is constant and "small", unroll the loop. */
- if (TREE_CODE (lo_index) == INTEGER_CST
- && TREE_CODE (hi_index) == INTEGER_CST
- && (lo = TREE_INT_CST_LOW (lo_index),
- hi = TREE_INT_CST_LOW (hi_index),
+ if (host_integerp (lo_index, 0)
+ && host_integerp (hi_index, 0)
+ && (lo = tree_low_cst (lo_index, 0),
+ hi = tree_low_cst (hi_index, 0),
count = hi - lo + 1,
(GET_CODE (target) != MEM
|| count <= 2
- || (TREE_CODE (TYPE_SIZE (elttype)) == INTEGER_CST
- && TREE_INT_CST_LOW (TYPE_SIZE (elttype)) * count
- <= 40 * 8))))
+ || (host_integerp (TYPE_SIZE (elttype), 1)
+ && (tree_low_cst (TYPE_SIZE (elttype), 1) * count
+ <= 40 * 8)))))
{
lo -= minelt; hi -= minelt;
for (; lo <= hi; lo++)
{
- bitpos = lo * TREE_INT_CST_LOW (TYPE_SIZE (elttype));
+ bitpos = lo * tree_low_cst (TYPE_SIZE (elttype), 0);
store_constructor_field (target, bitsize, bitpos, mode,
value, type, align, cleared);
}
@@ -4467,8 +4488,8 @@ store_constructor (exp, target, align, cleared, size)
emit_label (loop_end);
}
}
- else if ((index != 0 && TREE_CODE (index) != INTEGER_CST)
- || TREE_CODE (TYPE_SIZE (elttype)) != INTEGER_CST)
+ else if ((index != 0 && ! host_integerp (index, 0))
+ || ! host_integerp (TYPE_SIZE (elttype), 1))
{
rtx pos_rtx, addr;
tree position;
@@ -4480,6 +4501,7 @@ store_constructor (exp, target, align, cleared, size)
index = convert (ssizetype,
fold (build (MINUS_EXPR, index,
TYPE_MIN_VALUE (domain))));
+
position = size_binop (MULT_EXPR, index,
convert (ssizetype,
TYPE_SIZE_UNIT (elttype)));
@@ -4491,20 +4513,22 @@ store_constructor (exp, target, align, cleared, size)
else
{
if (index != 0)
- bitpos = ((TREE_INT_CST_LOW (index) - minelt)
- * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
+ bitpos = ((tree_low_cst (index, 0) - minelt)
+ * tree_low_cst (TYPE_SIZE (elttype), 1));
else
- bitpos = (i * TREE_INT_CST_LOW (TYPE_SIZE (elttype)));
+ bitpos = (i * tree_low_cst (TYPE_SIZE (elttype), 1));
+
store_constructor_field (target, bitsize, bitpos, mode, value,
type, align, cleared);
}
}
}
- /* set constructor assignments */
+
+ /* Set constructor assignments */
else if (TREE_CODE (type) == SET_TYPE)
{
tree elt = CONSTRUCTOR_ELTS (exp);
- int nbytes = int_size_in_bytes (type), nbits;
+ unsigned HOST_WIDE_INT nbytes = int_size_in_bytes (type), nbits;
tree domain = TYPE_DOMAIN (type);
tree domain_min, domain_max, bitlength;
@@ -4522,8 +4546,7 @@ store_constructor (exp, target, align, cleared, size)
if (elt == NULL_TREE && size > 0)
{
if (!cleared)
- clear_storage (target, GEN_INT (size),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
+ clear_storage (target, GEN_INT (size), TYPE_ALIGN (type));
return;
}
@@ -4533,9 +4556,7 @@ store_constructor (exp, target, align, cleared, size)
size_diffop (domain_max, domain_min),
ssize_int (1));
- if (nbytes < 0 || TREE_CODE (bitlength) != INTEGER_CST)
- abort ();
- nbits = TREE_INT_CST_LOW (bitlength);
+ nbits = tree_low_cst (bitlength, 1);
/* For "small" sets, or "medium-sized" (up to 32 bytes) sets that
are "complicated" (more than one range), initialize (the
@@ -4543,13 +4564,14 @@ store_constructor (exp, target, align, cleared, size)
if (GET_MODE (target) != BLKmode || nbits <= 2 * BITS_PER_WORD
|| (nbytes <= 32 && TREE_CHAIN (elt) != NULL_TREE))
{
- int set_word_size = TYPE_ALIGN (TREE_TYPE (exp));
+ unsigned int set_word_size = TYPE_ALIGN (TREE_TYPE (exp));
enum machine_mode mode = mode_for_size (set_word_size, MODE_INT, 1);
char *bit_buffer = (char *) alloca (nbits);
HOST_WIDE_INT word = 0;
- int bit_pos = 0;
- int ibit = 0;
- int offset = 0; /* In bytes from beginning of set. */
+ unsigned int bit_pos = 0;
+ unsigned int ibit = 0;
+ unsigned int offset = 0; /* In bytes from beginning of set. */
+
elt = get_set_constructor_bits (exp, bit_buffer, nbits);
for (;;)
{
@@ -4560,6 +4582,7 @@ store_constructor (exp, target, align, cleared, size)
else
word |= 1 << bit_pos;
}
+
bit_pos++; ibit++;
if (bit_pos >= set_word_size || ibit == nbits)
{
@@ -4567,6 +4590,7 @@ store_constructor (exp, target, align, cleared, size)
{
rtx datum = GEN_INT (word);
rtx to_rtx;
+
/* The assumption here is that it is safe to use
XEXP if the set is multi-word, but not if
it's single-word. */
@@ -4581,6 +4605,7 @@ store_constructor (exp, target, align, cleared, size)
abort ();
emit_move_insn (to_rtx, datum);
}
+
if (ibit == nbits)
break;
word = 0;
@@ -4590,19 +4615,16 @@ store_constructor (exp, target, align, cleared, size)
}
}
else if (!cleared)
- {
- /* Don't bother clearing storage if the set is all ones. */
- if (TREE_CHAIN (elt) != NULL_TREE
- || (TREE_PURPOSE (elt) == NULL_TREE
- ? nbits != 1
- : (TREE_CODE (TREE_VALUE (elt)) != INTEGER_CST
- || TREE_CODE (TREE_PURPOSE (elt)) != INTEGER_CST
- || ((HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_VALUE (elt))
- - (HOST_WIDE_INT) TREE_INT_CST_LOW (TREE_PURPOSE (elt)) + 1
- != nbits))))
- clear_storage (target, expr_size (exp),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
- }
+ /* Don't bother clearing storage if the set is all ones. */
+ if (TREE_CHAIN (elt) != NULL_TREE
+ || (TREE_PURPOSE (elt) == NULL_TREE
+ ? nbits != 1
+ : ( ! host_integerp (TREE_VALUE (elt), 0)
+ || ! host_integerp (TREE_PURPOSE (elt), 0)
+ || (tree_low_cst (TREE_VALUE (elt), 0)
+ - tree_low_cst (TREE_PURPOSE (elt), 0) + 1
+ != (HOST_WIDE_INT) nbits))))
+ clear_storage (target, expr_size (exp), TYPE_ALIGN (type));
for (; elt != NULL_TREE; elt = TREE_CHAIN (elt))
{
@@ -4613,10 +4635,10 @@ store_constructor (exp, target, align, cleared, size)
#ifdef TARGET_MEM_FUNCTIONS
HOST_WIDE_INT startb, endb;
#endif
- rtx bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
+ rtx bitlength_rtx, startbit_rtx, endbit_rtx, targetx;
bitlength_rtx = expand_expr (bitlength,
- NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
+ NULL_RTX, MEM, EXPAND_CONST_ADDRESS);
/* handle non-range tuple element like [ expr ] */
if (startbit == NULL_TREE)
@@ -4624,6 +4646,7 @@ store_constructor (exp, target, align, cleared, size)
startbit = save_expr (endbit);
endbit = startbit;
}
+
startbit = convert (sizetype, startbit);
endbit = convert (sizetype, endbit);
if (! integer_zerop (domain_min))
@@ -4643,6 +4666,7 @@ store_constructor (exp, target, align, cleared, size)
0);
emit_move_insn (targetx, target);
}
+
else if (GET_CODE (target) == MEM)
targetx = target;
else
@@ -4668,13 +4692,12 @@ store_constructor (exp, target, align, cleared, size)
}
else
#endif
- {
- emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__setbits"),
- 0, VOIDmode, 4, XEXP (targetx, 0), Pmode,
- bitlength_rtx, TYPE_MODE (sizetype),
- startbit_rtx, TYPE_MODE (sizetype),
- endbit_rtx, TYPE_MODE (sizetype));
- }
+ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__setbits"),
+ 0, VOIDmode, 4, XEXP (targetx, 0), Pmode,
+ bitlength_rtx, TYPE_MODE (sizetype),
+ startbit_rtx, TYPE_MODE (sizetype),
+ endbit_rtx, TYPE_MODE (sizetype));
+
if (REG_P (target))
emit_move_insn (target, targetx);
}
@@ -4696,7 +4719,7 @@ store_constructor (exp, target, align, cleared, size)
has mode VALUE_MODE if that is convenient to do.
In this case, UNSIGNEDP must be nonzero if the value is an unsigned type.
- ALIGN is the alignment that TARGET is known to have, measured in bytes.
+ ALIGN is the alignment that TARGET is known to have.
TOTAL_SIZE is the size in bytes of the structure, or -1 if varying.
ALIAS_SET is the alias set for the destination. This value will
@@ -4707,13 +4730,14 @@ static rtx
store_field (target, bitsize, bitpos, mode, exp, value_mode,
unsignedp, align, total_size, alias_set)
rtx target;
- int bitsize, bitpos;
+ HOST_WIDE_INT bitsize;
+ HOST_WIDE_INT bitpos;
enum machine_mode mode;
tree exp;
enum machine_mode value_mode;
int unsignedp;
unsigned int align;
- int total_size;
+ HOST_WIDE_INT total_size;
int alias_set;
{
HOST_WIDE_INT width_mask = 0;
@@ -4781,10 +4805,10 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
/* If the field isn't aligned enough to store as an ordinary memref,
store it as a bit field. */
|| (mode != BLKmode && SLOW_UNALIGNED_ACCESS (mode, align)
- && (align * BITS_PER_UNIT < GET_MODE_ALIGNMENT (mode)
+ && (align < GET_MODE_ALIGNMENT (mode)
|| bitpos % GET_MODE_ALIGNMENT (mode)))
|| (mode == BLKmode && SLOW_UNALIGNED_ACCESS (mode, align)
- && (TYPE_ALIGN (TREE_TYPE (exp)) > align * BITS_PER_UNIT
+ && (TYPE_ALIGN (TREE_TYPE (exp)) > align
|| bitpos % TYPE_ALIGN (TREE_TYPE (exp)) != 0))
/* If the RHS and field are a constant size and the size of the
RHS isn't the same size as the bitfield, we must use bitfield
@@ -4818,7 +4842,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
boundary. If so, we simply do a block copy. */
if (GET_MODE (target) == BLKmode && GET_MODE (temp) == BLKmode)
{
- unsigned int exp_align = expr_align (exp) / BITS_PER_UNIT;
+ unsigned int exp_align = expr_align (exp);
if (GET_CODE (target) != MEM || GET_CODE (temp) != MEM
|| bitpos % BITS_PER_UNIT != 0)
@@ -4832,7 +4856,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
align = MIN (exp_align, align);
/* Find an alignment that is consistent with the bit position. */
- while ((bitpos % (align * BITS_PER_UNIT)) != 0)
+ while ((bitpos % align) != 0)
align >>= 1;
emit_block_move (target, temp,
@@ -4910,7 +4934,7 @@ store_field (target, bitsize, bitpos, mode, exp, value_mode,
giving the variable offset (in units) in *POFFSET.
This offset is in addition to the bit position.
If the position is not variable, we store 0 in *POFFSET.
- We set *PALIGNMENT to the alignment in bytes of the address that will be
+ We set *PALIGNMENT to the alignment of the address that will be
computed. This is the alignment of the thing we return if *POFFSET
is zero, but can be more less strictly aligned if *POFFSET is nonzero.
@@ -4929,25 +4953,29 @@ tree
get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
punsignedp, pvolatilep, palignment)
tree exp;
- int *pbitsize;
- int *pbitpos;
+ HOST_WIDE_INT *pbitsize;
+ HOST_WIDE_INT *pbitpos;
tree *poffset;
enum machine_mode *pmode;
int *punsignedp;
int *pvolatilep;
unsigned int *palignment;
{
- tree orig_exp = exp;
tree size_tree = 0;
enum machine_mode mode = VOIDmode;
tree offset = size_zero_node;
+ tree bit_offset = bitsize_zero_node;
unsigned int alignment = BIGGEST_ALIGNMENT;
+ tree tem;
+ /* First get the mode, signedness, and size. We do this from just the
+ outermost expression. */
if (TREE_CODE (exp) == COMPONENT_REF)
{
size_tree = DECL_SIZE (TREE_OPERAND (exp, 1));
if (! DECL_BIT_FIELD (TREE_OPERAND (exp, 1)))
mode = DECL_MODE (TREE_OPERAND (exp, 1));
+
*punsignedp = TREE_UNSIGNED (TREE_OPERAND (exp, 1));
}
else if (TREE_CODE (exp) == BIT_FIELD_REF)
@@ -4958,122 +4986,71 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
else
{
mode = TYPE_MODE (TREE_TYPE (exp));
+ *punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
+
if (mode == BLKmode)
size_tree = TYPE_SIZE (TREE_TYPE (exp));
-
- *pbitsize = GET_MODE_BITSIZE (mode);
- *punsignedp = TREE_UNSIGNED (TREE_TYPE (exp));
+ else
+ *pbitsize = GET_MODE_BITSIZE (mode);
}
- if (size_tree)
+ if (size_tree != 0)
{
- if (TREE_CODE (size_tree) != INTEGER_CST)
+ if (! host_integerp (size_tree, 1))
mode = BLKmode, *pbitsize = -1;
else
- *pbitsize = TREE_INT_CST_LOW (size_tree);
+ *pbitsize = tree_low_cst (size_tree, 1);
}
/* Compute cumulative bit-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
-
- *pbitpos = 0;
-
while (1)
{
- if (TREE_CODE (exp) == COMPONENT_REF || TREE_CODE (exp) == BIT_FIELD_REF)
+ if (TREE_CODE (exp) == BIT_FIELD_REF)
+ bit_offset = size_binop (PLUS_EXPR, bit_offset, TREE_OPERAND (exp, 2));
+ else if (TREE_CODE (exp) == COMPONENT_REF)
{
- tree pos = (TREE_CODE (exp) == COMPONENT_REF
- ? DECL_FIELD_BITPOS (TREE_OPERAND (exp, 1))
- : TREE_OPERAND (exp, 2));
- tree constant = bitsize_int (0), var = pos;
+ tree field = TREE_OPERAND (exp, 1);
+ tree this_offset = DECL_FIELD_OFFSET (field);
/* If this field hasn't been filled in yet, don't go
past it. This should only happen when folding expressions
made during type construction. */
- if (pos == 0)
+ if (this_offset == 0)
break;
+ else if (! TREE_CONSTANT (this_offset)
+ && contains_placeholder_p (this_offset))
+ this_offset = build (WITH_RECORD_EXPR, sizetype, this_offset, exp);
- /* Assume here that the offset is a multiple of a unit.
- If not, there should be an explicitly added constant. */
- if (TREE_CODE (pos) == PLUS_EXPR
- && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST)
- constant = TREE_OPERAND (pos, 1), var = TREE_OPERAND (pos, 0);
- else if (TREE_CODE (pos) == INTEGER_CST)
- constant = pos, var = bitsize_int (0);
+ offset = size_binop (PLUS_EXPR, offset, DECL_FIELD_OFFSET (field));
+ bit_offset = size_binop (PLUS_EXPR, bit_offset,
+ DECL_FIELD_BIT_OFFSET (field));
- *pbitpos += TREE_INT_CST_LOW (constant);
- offset
- = size_binop (PLUS_EXPR, offset,
- convert (sizetype,
- size_binop (EXACT_DIV_EXPR, var,
- bitsize_int (BITS_PER_UNIT))));
+ if (! host_integerp (offset, 0))
+ alignment = MIN (alignment, DECL_OFFSET_ALIGN (field));
}
-
else if (TREE_CODE (exp) == ARRAY_REF)
{
- /* This code is based on the code in case ARRAY_REF in expand_expr
- below. We assume here that the size of an array element is
- always an integral multiple of BITS_PER_UNIT. */
-
tree index = TREE_OPERAND (exp, 1);
tree domain = TYPE_DOMAIN (TREE_TYPE (TREE_OPERAND (exp, 0)));
- tree low_bound
- = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node;
- tree index_type = TREE_TYPE (index);
- tree xindex;
-
- if (TYPE_PRECISION (index_type) != TYPE_PRECISION (sizetype))
- {
- index = convert (type_for_size (TYPE_PRECISION (sizetype), 0),
- index);
- index_type = TREE_TYPE (index);
- }
+ tree low_bound = (domain ? TYPE_MIN_VALUE (domain) : 0);
- /* Optimize the special-case of a zero lower bound.
-
- We convert the low_bound to sizetype to avoid some problems
- with constant folding. (E.g. suppose the lower bound is 1,
- and its mode is QI. Without the conversion, (ARRAY
- +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
- +INDEX), which becomes (ARRAY+255+INDEX). Oops!)
-
- But sizetype isn't quite right either (especially if
- the lowbound is negative). FIXME */
-
- if (! integer_zerop (low_bound))
- index = fold (build (MINUS_EXPR, index_type, index,
- convert (sizetype, low_bound)));
-
- if (TREE_CODE (index) == INTEGER_CST)
- {
- index = convert (sbitsizetype, index);
- index_type = TREE_TYPE (index);
- }
+ /* We assume all arrays have sizes that are a multiple of a byte.
+ First subtract the lower bound, if any, in the type of the
+ index, then convert to sizetype and multiply by the size of the
+ array element. */
+ if (low_bound != 0 && ! integer_zerop (low_bound))
+ index = fold (build (MINUS_EXPR, TREE_TYPE (index),
+ index, low_bound));
- xindex = fold (build (MULT_EXPR, sbitsizetype, index,
- convert (sbitsizetype,
- TYPE_SIZE (TREE_TYPE (exp)))));
+ if (! TREE_CONSTANT (index)
+ && contains_placeholder_p (index))
+ index = build (WITH_RECORD_EXPR, TREE_TYPE (index), index, exp);
- if (TREE_CODE (xindex) == INTEGER_CST
- && TREE_INT_CST_HIGH (xindex) == 0)
- *pbitpos += TREE_INT_CST_LOW (xindex);
- else
- {
- /* Either the bit offset calculated above is not constant, or
- it overflowed. In either case, redo the multiplication
- against the size in units. This is especially important
- in the non-constant case to avoid a division at runtime. */
- xindex
- = fold (build (MULT_EXPR, ssizetype, index,
- convert (ssizetype,
- TYPE_SIZE_UNIT (TREE_TYPE (exp)))));
-
- if (contains_placeholder_p (xindex))
- xindex = build (WITH_RECORD_EXPR, ssizetype, xindex, exp);
-
- offset
- = size_binop (PLUS_EXPR, offset, convert (sizetype, xindex));
- }
+ offset = size_binop (PLUS_EXPR, offset,
+ size_binop (MULT_EXPR,
+ convert (sizetype, index),
+ TYPE_SIZE_UNIT (TREE_TYPE (exp))));
}
else if (TREE_CODE (exp) != NON_LVALUE_EXPR
&& ! ((TREE_CODE (exp) == NOP_EXPR
@@ -5088,7 +5065,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
/* If the offset is non-constant already, then we can't assume any
alignment more than the alignment here. */
- if (! integer_zerop (offset))
+ if (! TREE_CONSTANT (offset))
alignment = MIN (alignment, TYPE_ALIGN (TREE_TYPE (exp)));
exp = TREE_OPERAND (exp, 0);
@@ -5099,19 +5076,24 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode,
else if (TREE_TYPE (exp) != 0)
alignment = MIN (alignment, TYPE_ALIGN (TREE_TYPE (exp)));
- if (integer_zerop (offset))
- offset = 0;
-
- if (offset != 0 && contains_placeholder_p (offset))
- offset = build (WITH_RECORD_EXPR, sizetype, offset, orig_exp);
+ /* If OFFSET is constant, see if we can return the whole thing as a
+ constant bit position. Otherwise, split it up. */
+ if (host_integerp (offset, 0)
+ && 0 != (tem = size_binop (MULT_EXPR, convert (bitsizetype, offset),
+ bitsize_unit_node))
+ && 0 != (tem = size_binop (PLUS_EXPR, tem, bit_offset))
+ && host_integerp (tem, 0))
+ *pbitpos = tree_low_cst (tem, 0), *poffset = 0;
+ else
+ *pbitpos = tree_low_cst (bit_offset, 0), *poffset = offset;
*pmode = mode;
- *poffset = offset;
- *palignment = alignment / BITS_PER_UNIT;
+ *palignment = alignment;
return exp;
}
/* Subroutine of expand_exp: compute memory_usage from modifier. */
+
static enum memory_use_mode
get_memory_usage_from_modifier (modifier)
enum expand_modifier modifier;
@@ -5990,8 +5972,7 @@ expand_expr (exp, target, tmode, modifier)
if (temp != 0)
{
if (GET_CODE (temp) == MEM && GET_CODE (XEXP (temp, 0)) == REG)
- mark_reg_pointer (XEXP (temp, 0),
- DECL_ALIGN (exp) / BITS_PER_UNIT);
+ mark_reg_pointer (XEXP (temp, 0), DECL_ALIGN (exp));
return temp;
}
@@ -6343,15 +6324,15 @@ expand_expr (exp, target, tmode, modifier)
&& ((mode == BLKmode
&& ! (target != 0 && safe_from_p (target, exp, 1)))
|| TREE_ADDRESSABLE (exp)
- || (TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TYPE_SIZE_UNIT (type)) == 0
+ || (host_integerp (TYPE_SIZE_UNIT (type), 1)
&& (! MOVE_BY_PIECES_P
- (TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)),
- TYPE_ALIGN (type) / BITS_PER_UNIT))
+ (tree_low_cst (TYPE_SIZE_UNIT (type), 1),
+ TYPE_ALIGN (type)))
&& ! mostly_zeros_p (exp))))
|| (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
{
rtx constructor = output_constant_def (exp);
+
if (modifier != EXPAND_CONST_ADDRESS
&& modifier != EXPAND_INITIALIZER
&& modifier != EXPAND_SUM
@@ -6615,8 +6596,7 @@ expand_expr (exp, target, tmode, modifier)
{
enum machine_mode mode1;
- int bitsize;
- int bitpos;
+ HOST_WIDE_INT bitsize, bitpos;
tree offset;
int volatilep = 0;
unsigned int alignment;
@@ -6694,7 +6674,7 @@ expand_expr (exp, target, tmode, modifier)
&& bitsize != 0
&& (bitpos % bitsize) == 0
&& (bitsize % GET_MODE_ALIGNMENT (mode1)) == 0
- && (alignment * BITS_PER_UNIT) == GET_MODE_ALIGNMENT (mode1))
+ && alignment == GET_MODE_ALIGNMENT (mode1))
{
rtx temp = change_address (op0, mode1,
plus_constant (XEXP (op0, 0),
@@ -6768,7 +6748,7 @@ expand_expr (exp, target, tmode, modifier)
|| (mode1 != BLKmode
&& SLOW_UNALIGNED_ACCESS (mode1, alignment)
&& ((TYPE_ALIGN (TREE_TYPE (tem))
- < (unsigned int) GET_MODE_ALIGNMENT (mode))
+ < GET_MODE_ALIGNMENT (mode))
|| (bitpos % GET_MODE_ALIGNMENT (mode) != 0)))
/* If the type and the field are a constant size and the
size of the type isn't the same size as the bitfield,
@@ -6782,7 +6762,7 @@ expand_expr (exp, target, tmode, modifier)
&& modifier != EXPAND_INITIALIZER
&& mode == BLKmode
&& SLOW_UNALIGNED_ACCESS (mode, alignment)
- && (TYPE_ALIGN (type) > alignment * BITS_PER_UNIT
+ && (TYPE_ALIGN (type) > alignment
|| bitpos % TYPE_ALIGN (type) != 0)))
{
enum machine_mode ext_mode = mode;
@@ -6811,7 +6791,7 @@ expand_expr (exp, target, tmode, modifier)
emit_block_move (target, op0,
GEN_INT ((bitsize + BITS_PER_UNIT - 1)
/ BITS_PER_UNIT),
- 1);
+ BITS_PER_UNIT);
return target;
}
@@ -8296,7 +8276,7 @@ expand_expr (exp, target, tmode, modifier)
if (GET_CODE (op0) == REG
&& ! REG_USERVAR_P (op0))
- mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)) / BITS_PER_UNIT);
+ mark_reg_pointer (op0, TYPE_ALIGN (TREE_TYPE (type)));
/* If we might have had a temp slot, add an equivalent address
for it. */
@@ -8616,8 +8596,7 @@ expand_expr_unaligned (exp, palign)
{
enum machine_mode mode1;
- int bitsize;
- int bitpos;
+ HOST_WIDE_INT bitsize, bitpos;
tree offset;
int volatilep = 0;
unsigned int alignment;
@@ -8719,7 +8698,7 @@ expand_expr_unaligned (exp, palign)
if (mode1 == VOIDmode
|| GET_CODE (op0) == REG || GET_CODE (op0) == SUBREG
|| (SLOW_UNALIGNED_ACCESS (mode1, alignment)
- && (TYPE_ALIGN (type) > alignment * BITS_PER_UNIT
+ && (TYPE_ALIGN (type) > alignment
|| bitpos % TYPE_ALIGN (type) != 0)))
{
enum machine_mode ext_mode = mode_for_size (bitsize, MODE_INT, 1);
@@ -9146,7 +9125,10 @@ clear_pending_stack_adjust ()
&& EXIT_IGNORE_STACK
&& ! (DECL_INLINE (current_function_decl) && ! flag_no_inline)
&& ! flag_inline_functions)
- pending_stack_adjust = 0;
+ {
+ stack_pointer_delta -= pending_stack_adjust,
+ pending_stack_adjust = 0;
+ }
#endif
}
@@ -9350,7 +9332,8 @@ do_jump (exp, if_false_label, if_true_label)
case BIT_FIELD_REF:
case ARRAY_REF:
{
- int bitsize, bitpos, unsignedp;
+ HOST_WIDE_INT bitsize, bitpos;
+ int unsignedp;
enum machine_mode mode;
tree type;
tree offset;
@@ -9359,9 +9342,8 @@ do_jump (exp, if_false_label, if_true_label)
/* Get description of this reference. We don't actually care
about the underlying object here. */
- get_inner_reference (exp, &bitsize, &bitpos, &offset,
- &mode, &unsignedp, &volatilep,
- &alignment);
+ get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode,
+ &unsignedp, &volatilep, &alignment);
type = type_for_size (bitsize, unsignedp);
if (! SLOW_BYTE_ACCESS
@@ -10046,7 +10028,7 @@ do_compare_and_jump (exp, signed_code, unsigned_code, if_false_label,
do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode,
((mode == BLKmode)
? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX),
- MIN (align0, align1) / BITS_PER_UNIT,
+ MIN (align0, align1),
if_false_label, if_true_label);
}
diff --git a/gcc/expr.h b/gcc/expr.h
index dfb7e4c9325..a349d9a32c8 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -793,12 +793,13 @@ extern void emit_0_to_1_insn PARAMS ((rtx));
/* Emit one rtl insn to compare two rtx's. */
extern void emit_cmp_insn PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, int));
+ enum machine_mode, int, unsigned int));
/* Emit a pair of rtl insns to compare two rtx's and to jump
to a label if the comparison is true. */
extern void emit_cmp_and_jump_insns PARAMS ((rtx, rtx, enum rtx_code, rtx,
- enum machine_mode, int, int, rtx));
+ enum machine_mode, int,
+ unsigned int, rtx));
/* The various uses that a comparison can have; used by can_compare_p:
jumps, conditional moves, store flag operations. */
@@ -1108,7 +1109,8 @@ extern rtx label_rtx PARAMS ((tree));
#endif
/* Indicate how an input argument register was promoted. */
-extern rtx promoted_input_arg PARAMS ((int, enum machine_mode *, int *));
+extern rtx promoted_input_arg PARAMS ((unsigned int, enum machine_mode *,
+ int *));
/* Return an rtx like arg but sans any constant terms.
Returns the original rtx if it has no constant terms.
@@ -1206,11 +1208,14 @@ extern rtx hard_libcall_value PARAMS ((enum machine_mode));
of STACK_BOUNDARY / BITS_PER_UNIT. */
extern rtx round_push PARAMS ((rtx));
-extern rtx store_bit_field PARAMS ((rtx, int, int, enum machine_mode, rtx,
- unsigned int, int));
-extern rtx extract_bit_field PARAMS ((rtx, int, int, int, rtx,
+extern rtx store_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT,
+ enum machine_mode, rtx,
+ unsigned int, HOST_WIDE_INT));
+extern rtx extract_bit_field PARAMS ((rtx, unsigned HOST_WIDE_INT,
+ unsigned HOST_WIDE_INT, int, rtx,
enum machine_mode, enum machine_mode,
- unsigned int, int));
+ unsigned int, HOST_WIDE_INT));
extern rtx expand_mult PARAMS ((enum machine_mode, rtx, rtx, rtx, int));
extern rtx expand_mult_add PARAMS ((rtx, rtx, rtx, rtx,enum machine_mode, int));
extern rtx expand_mult_highpart_adjust PARAMS ((enum machine_mode, rtx, rtx, rtx, rtx, int));
@@ -1240,5 +1245,5 @@ extern void do_jump_by_parts_greater_rtx PARAMS ((enum machine_mode,
#ifdef TREE_CODE /* Don't lose if tree.h not included. */
extern void mark_seen_cases PARAMS ((tree, unsigned char *,
- long, int));
+ HOST_WIDE_INT, int));
#endif
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog
index 827142beefb..84eb54aad64 100644
--- a/gcc/f/ChangeLog
+++ b/gcc/f/ChangeLog
@@ -1,3 +1,21 @@
+Wed Apr 5 17:46:39 2000 Mark Mitchell <mark@codesourcery.com>
+
+ * Makefile.in (GGC_H): Add varray.h.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * lang-specs.h: Pass -fno-show-column to the preprocessor.
+
+2000-03-28 Franz Sirl <Franz.Sirl-kernel@lauterbach.com>
+
+ * com.c (ffecom_decl_field): Use DECL_ALIGN for a FIELD_DECL.
+ (ffecom_init_0): Likewise.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * com.c (ffecom_tree_canonize_ptr_): Use bitsize_zero_node.
+ (ffecom_tree_canonize_ref_): Likewise.
+
Mon Mar 20 15:49:40 2000 Jim Wilson <wilson@cygnus.com>
* f/target.h (FFETARGET_32bit_longs): New. Define for alpha, sparc64,
diff --git a/gcc/f/Makefile.in b/gcc/f/Makefile.in
index f95a155ce60..1f93e551c21 100644
--- a/gcc/f/Makefile.in
+++ b/gcc/f/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for GNU F77 compiler.
-# Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
#This file is part of GNU Fortran.
@@ -225,7 +225,7 @@ ASSERT_H = $(srcdir)/assert.j $(srcdir)/../assert.h
CONFIG_H = $(srcdir)/config.j ../config.h
CONVERT_H = $(srcdir)/convert.j $(srcdir)/../convert.h
FLAGS_H = $(srcdir)/flags.j $(srcdir)/../flags.h
-GGC_H = $(srcdir)/ggc.j $(srcdir)/../ggc.h
+GGC_H = $(srcdir)/ggc.j $(srcdir)/../ggc.h $(srcdir)/../varray.h
GLIMITS_H = $(srcdir)/glimits.j $(srcdir)/../glimits.h
HCONFIG_H = $(srcdir)/hconfig.j ../hconfig.h
INPUT_H = $(srcdir)/input.j $(srcdir)/../input.h
diff --git a/gcc/f/com.c b/gcc/f/com.c
index 2f9763e7187..5fd24823012 100644
--- a/gcc/f/com.c
+++ b/gcc/f/com.c
@@ -9097,7 +9097,7 @@ ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
case PARM_DECL:
*decl = t;
- *offset = bitsize_int (0);
+ *offset = bitsize_zero_node;
break;
case ADDR_EXPR:
@@ -9105,7 +9105,7 @@ ffecom_tree_canonize_ptr_ (tree *decl, tree *offset,
{
/* A reference to COMMON. */
*decl = TREE_OPERAND (t, 0);
- *offset = bitsize_int (0);
+ *offset = bitsize_zero_node;
break;
}
/* Fall through. */
@@ -9226,7 +9226,7 @@ ffecom_tree_canonize_ref_ (tree *decl, tree *offset,
case VAR_DECL:
case PARM_DECL:
*decl = t;
- *offset = bitsize_int (0);
+ *offset = bitsize_zero_node;
*size = TYPE_SIZE (TREE_TYPE (t));
return;
@@ -11000,7 +11000,7 @@ ffecom_decl_field (tree context, tree prevfield,
field = build_decl (FIELD_DECL, get_identifier (name), type);
DECL_CONTEXT (field) = context;
- DECL_FRAME_SIZE (field) = 0;
+ DECL_ALIGN (field) = 0;
if (prevfield != NULL_TREE)
TREE_CHAIN (prevfield) = field;
@@ -12056,7 +12056,7 @@ ffecom_init_0 ()
ffecom_tree_type[i][j]);
DECL_CONTEXT (ffecom_multi_fields_[i][j])
= ffecom_multi_type_node_;
- DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0;
+ DECL_ALIGN (ffecom_multi_fields_[i][j]) = 0;
TREE_CHAIN (ffecom_multi_fields_[i][j]) = field;
field = ffecom_multi_fields_[i][j];
}
diff --git a/gcc/f/lang-specs.h b/gcc/f/lang-specs.h
index 4ee06574ff8..ed715cb5ad6 100644
--- a/gcc/f/lang-specs.h
+++ b/gcc/f/lang-specs.h
@@ -43,6 +43,7 @@ the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
%{!undef:%P} -D_LANGUAGE_FORTRAN %{trigraphs} \
%c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} -traditional\
%{ffast-math:-D__FAST_MATH__}\
+ %{fshow-column} %{fno-show-column}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:f771 %{!pipe:%g.i} %1 %(f771) \
diff --git a/gcc/f/version.c b/gcc/f/version.c
index f039d6a6a0d..eeb67facef3 100644
--- a/gcc/f/version.c
+++ b/gcc/f/version.c
@@ -1 +1 @@
-const char *ffe_version_string = "0.5.25 20000325 (experimental)";
+const char *ffe_version_string = "0.5.25 20000408 (experimental)";
diff --git a/gcc/final.c b/gcc/final.c
index 5693d460ef8..ade9da92964 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -80,6 +80,10 @@ Boston, MA 02111-1307, USA. */
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h"
#endif
@@ -1970,8 +1974,7 @@ final (first, file, optimize, prescan)
max_line = NOTE_LINE_NUMBER (insn);
}
- line_note_exists = (char *) oballoc (max_line + 1);
- bzero (line_note_exists, max_line + 1);
+ line_note_exists = (char *) xcalloc (max_line + 1, sizeof (char));
for (insn = first; insn; insn = NEXT_INSN (insn))
{
@@ -2016,6 +2019,8 @@ final (first, file, optimize, prescan)
add_bb (file);
free_insn_eh_region ();
+ free (line_note_exists);
+ line_note_exists = NULL;
}
const char *
@@ -2279,10 +2284,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
break;
case BARRIER:
-#if defined (DWARF2_UNWIND_INFO) && !defined (ACCUMULATE_OUTGOING_ARGS)
+#if defined (DWARF2_UNWIND_INFO)
/* If we push arguments, we need to check all insns for stack
adjustments. */
- if (dwarf2out_do_frame ())
+ if (!ACCUMULATE_OUTGOING_ARGS && dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#endif
break;
@@ -2885,9 +2890,10 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
debug_insn = insn;
-#if defined (DWARF2_UNWIND_INFO) && !defined (ACCUMULATE_OUTGOING_ARGS)
+#if defined (DWARF2_UNWIND_INFO)
/* If we push arguments, we want to know where the calls are. */
- if (GET_CODE (insn) == CALL_INSN && dwarf2out_do_frame ())
+ if (!ACCUMULATE_OUTGOING_ARGS && GET_CODE (insn) == CALL_INSN
+ && dwarf2out_do_frame ())
dwarf2out_frame_debug (insn);
#endif
@@ -2934,19 +2940,22 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
output_asm_insn (template, recog_data.operand);
#if defined (DWARF2_UNWIND_INFO)
-#if !defined (ACCUMULATE_OUTGOING_ARGS)
/* If we push arguments, we need to check all insns for stack
adjustments. */
- if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn);
-#else
+ if (!ACCUMULATE_OUTGOING_ARGS)
+ {
+ if (GET_CODE (insn) == INSN && dwarf2out_do_frame ())
+ dwarf2out_frame_debug (insn);
+ }
+ else
+ {
#if defined (HAVE_prologue)
- /* If this insn is part of the prologue, emit DWARF v2
- call frame info. */
- if (RTX_FRAME_RELATED_P (insn) && dwarf2out_do_frame ())
- dwarf2out_frame_debug (insn);
-#endif
+ /* If this insn is part of the prologue, emit DWARF v2
+ call frame info. */
+ if (RTX_FRAME_RELATED_P (insn) && dwarf2out_do_frame ())
+ dwarf2out_frame_debug (insn);
#endif
+ }
#endif
#if 0
diff --git a/gcc/fix-header.c b/gcc/fix-header.c
index c4d7e728ae1..f6dae3a8ffa 100644
--- a/gcc/fix-header.c
+++ b/gcc/fix-header.c
@@ -617,7 +617,6 @@ read_scan_file (in_fname, argc, argv)
char **argv;
{
cpp_reader scan_in;
- cpp_options scan_options;
struct fn_decl *fn;
int i;
register struct symbol_list *cur_symbols;
@@ -625,13 +624,11 @@ read_scan_file (in_fname, argc, argv)
obstack_init (&scan_file_obstack);
cpp_reader_init (&scan_in);
- scan_in.opts = &scan_options;
- cpp_options_init (&scan_options);
/* We are going to be scanning a header file out of its proper context,
so ignore warnings and errors. */
- scan_options.inhibit_warnings = 1;
- scan_options.inhibit_errors = 1;
- scan_options.no_line_commands = 1;
+ CPP_OPTION (&scan_in, inhibit_warnings) = 1;
+ CPP_OPTION (&scan_in, inhibit_errors) = 1;
+ CPP_OPTION (&scan_in, no_line_commands) = 1;
i = cpp_handle_options (&scan_in, argc, argv);
if (i < argc && ! CPP_FATAL_ERRORS (&scan_in))
cpp_fatal (&scan_in, "Invalid option `%s'", argv[i]);
diff --git a/gcc/fixinc/fixinc.irix b/gcc/fixinc/fixinc.irix
index 403c5441e83..3eab1a6619e 100755
--- a/gcc/fixinc/fixinc.irix
+++ b/gcc/fixinc/fixinc.irix
@@ -90,7 +90,7 @@ if [ -r $INPUT/$file ]; then
#ifdef __cplusplus
# define exception __math_exception
#endif
-#include_next <math.h>
+ #include_next <math.h>
#ifdef __cplusplus
# undef exception
#endif
@@ -123,7 +123,7 @@ if [ -r $INPUT/$file ]; then
#ifdef __cplusplus
# define bool __curses_bool_t
#endif
-#include_next <curses.h>
+ #include_next <curses.h>
#ifdef __cplusplus
# undef bool
#endif
diff --git a/gcc/fixinc/fixinc.sco b/gcc/fixinc/fixinc.sco
index a026a776683..77d96e34f41 100755
--- a/gcc/fixinc/fixinc.sco
+++ b/gcc/fixinc/fixinc.sco
@@ -394,7 +394,7 @@ do
#ifdef __cplusplus
# define bool __curses_bool_t
#endif
-#include_next <$file>
+ #include_next <$file>
#ifdef __cplusplus
# undef bool
#endif
diff --git a/gcc/fixinc/fixinc.wrap b/gcc/fixinc/fixinc.wrap
index 0c27536ce18..46318967c70 100755
--- a/gcc/fixinc/fixinc.wrap
+++ b/gcc/fixinc/fixinc.wrap
@@ -57,7 +57,7 @@ if [ -r $INPUT/$file ]; then
#ifdef __cplusplus
# define exception __math_exception
#endif
-#include_next <math.h>
+ #include_next <math.h>
#ifdef __cplusplus
# undef exception
#endif
@@ -86,7 +86,7 @@ if [ -r $INPUT/$file ]; then
#ifdef __cplusplus
# define queue __stream_queue
#endif
-#include_next <sys/stream.h>
+ #include_next <sys/stream.h>
#ifdef __cplusplus
# undef queue
#endif
@@ -116,7 +116,7 @@ if [ -r $INPUT/$file ]; then
#ifdef __cplusplus
# define bool __curses_bool_t
#endif
-#include_next <curses.h>
+ #include_next <curses.h>
#ifdef __cplusplus
# undef bool
#endif
diff --git a/gcc/fixinc/fixincl.x b/gcc/fixinc/fixincl.x
index f120a2391b6..1196ebb18c0 100644
--- a/gcc/fixinc/fixincl.x
+++ b/gcc/fixinc/fixincl.x
@@ -352,7 +352,7 @@ const char* apzAab_Fd_Zero_Asm_Posix_Types_HPatch[] = {
for older versions of the Linux kernel. */\n\
#ifndef _POSIX_TYPES_H_WRAPPER\n\
#include <features.h>\n\
-#include_next <asm/posix_types.h>\n\
+ #include_next <asm/posix_types.h>\n\
\n\
#if defined(__FD_ZERO) && !defined(__GLIBC__)\n\
#undef __FD_ZERO\n\
@@ -399,7 +399,7 @@ const char* apzAab_Fd_Zero_Gnu_Types_HPatch[] = {
"/* This file fixes a bug in the __FD_ZERO macro present in glibc 1.x. */\n\
#ifndef _TYPES_H_WRAPPER\n\
#include <features.h>\n\
-#include_next <gnu/types.h>\n\
+ #include_next <gnu/types.h>\n\
\n\
#if defined(__FD_ZERO) && !defined(__GLIBC__)\n\
#undef __FD_ZERO\n\
@@ -446,7 +446,7 @@ const char* apzAab_Fd_Zero_Selectbits_HPatch[] = {
"/* This file fixes a bug in the __FD_ZERO macro present in glibc 2.0.x. */\n\
#ifndef _SELECTBITS_H_WRAPPER\n\
#include <features.h>\n\
-#include_next <selectbits.h>\n\
+ #include_next <selectbits.h>\n\
\n\
#if defined(__FD_ZERO) && defined(__GLIBC__) \\\n\
\t&& defined(__GLIBC_MINOR__) && __GLIBC__ == 2 \\\n\
diff --git a/gcc/fixinc/inclhack.def b/gcc/fixinc/inclhack.def
index e431d1fa562..a49771b94ff 100644
--- a/gcc/fixinc/inclhack.def
+++ b/gcc/fixinc/inclhack.def
@@ -180,7 +180,7 @@ fix = {
for older versions of the Linux kernel. */
\#ifndef _POSIX_TYPES_H_WRAPPER
\#include <features.h>
-\#include_next <asm/posix_types.h>
+ \#include_next <asm/posix_types.h>
\#if defined(__FD_ZERO) && !defined(__GLIBC__)
\#undef __FD_ZERO
@@ -219,7 +219,7 @@ fix = {
'/* This file fixes a bug in the __FD_ZERO macro present in glibc 1.x. */
\#ifndef _TYPES_H_WRAPPER
\#include <features.h>
-\#include_next <gnu/types.h>
+ \#include_next <gnu/types.h>
\#if defined(__FD_ZERO) && !defined(__GLIBC__)
\#undef __FD_ZERO
@@ -258,7 +258,7 @@ fix = {
'/* This file fixes a bug in the __FD_ZERO macro present in glibc 2.0.x. */
\#ifndef _SELECTBITS_H_WRAPPER
\#include <features.h>
-\#include_next <selectbits.h>
+ \#include_next <selectbits.h>
\#if defined(__FD_ZERO) && defined(__GLIBC__) \\
&& defined(__GLIBC_MINOR__) && __GLIBC__ == 2 \\
diff --git a/gcc/fixinc/inclhack.sh b/gcc/fixinc/inclhack.sh
index 67a99745331..74fc8533980 100755
--- a/gcc/fixinc/inclhack.sh
+++ b/gcc/fixinc/inclhack.sh
@@ -563,7 +563,7 @@ _EOF_
for older versions of the Linux kernel. */
#ifndef _POSIX_TYPES_H_WRAPPER
#include <features.h>
-#include_next <asm/posix_types.h>
+ #include_next <asm/posix_types.h>
#if defined(__FD_ZERO) && !defined(__GLIBC__)
#undef __FD_ZERO
@@ -600,7 +600,7 @@ _EOF_
/* This file fixes a bug in the __FD_ZERO macro present in glibc 1.x. */
#ifndef _TYPES_H_WRAPPER
#include <features.h>
-#include_next <gnu/types.h>
+ #include_next <gnu/types.h>
#if defined(__FD_ZERO) && !defined(__GLIBC__)
#undef __FD_ZERO
@@ -636,7 +636,7 @@ _EOF_
/* This file fixes a bug in the __FD_ZERO macro present in glibc 2.0.x. */
#ifndef _SELECTBITS_H_WRAPPER
#include <features.h>
-#include_next <selectbits.h>
+ #include_next <selectbits.h>
#if defined(__FD_ZERO) && defined(__GLIBC__) \
&& defined(__GLIBC_MINOR__) && __GLIBC__ == 2 \
diff --git a/gcc/fixinc/mkfixinc.sh b/gcc/fixinc/mkfixinc.sh
index ae0dbbd074c..7d36a27a3d9 100755
--- a/gcc/fixinc/mkfixinc.sh
+++ b/gcc/fixinc/mkfixinc.sh
@@ -10,7 +10,7 @@ fi
target=../fixinc.sh
echo constructing ${target} for $machine
-fixincludes="${target}"
+fixincludes="${machine}"
case $machine in
i[34567]86-*-linux-gnu*)
diff --git a/gcc/fixinc/server.c b/gcc/fixinc/server.c
index 676df8cd0f6..5d737ac70ac 100644
--- a/gcc/fixinc/server.c
+++ b/gcc/fixinc/server.c
@@ -235,6 +235,28 @@ server_setup ()
p_cur_dir = getcwd ((char *) NULL, MAXPATHLEN + 1);
}
+/*
+ * find_shell
+ *
+ * Locate a shell suitable for use. For various reasons
+ * (like the use of "trap" in server_setup(), it must be a
+ * Bourne-like shell.
+ *
+ * Most of the time, /bin/sh is preferred, but sometimes
+ * it's quite broken (like on Ultrix). autoconf lets you
+ * override with $CONFIG_SHELL, so we do the same.
+ */
+
+static char *
+find_shell ()
+{
+ char * shell = getenv ("CONFIG_SHELL");
+ if (shell)
+ return shell;
+
+ return "/bin/sh";
+}
+
/*
* run_shell
@@ -266,6 +288,8 @@ run_shell (pz_cmd)
THEN try to start it. */
if (server_id == NULLPROCESS)
{
+ def_args[0] = find_shell ();
+
server_id = proc2_fopen (&server_pair, def_args);
if (server_id > 0)
server_setup ();
diff --git a/gcc/flags.h b/gcc/flags.h
index 1d7e782a361..81f5bda4c8b 100644
--- a/gcc/flags.h
+++ b/gcc/flags.h
@@ -299,6 +299,10 @@ extern int flag_volatile_static;
extern int flag_fast_math;
+/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
+
+extern int flag_optimize_sibling_calls;
+
/* Nonzero means the front end generally wants `errno' maintained by math
operations, like built-in SQRT, unless overridden by flag_fast_math. */
diff --git a/gcc/flow.c b/gcc/flow.c
index 69de658890c..ea386232ea7 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -225,12 +225,6 @@ varray_type reg_n_info;
unsigned int reg_n_max;
-/* Element N is the next insn that uses (hard or pseudo) register number N
- within the current basic block; or zero, if there is no such insn.
- This is valid only during the final backward scan in propagate_block. */
-
-static rtx *reg_next_use;
-
/* Size of a regset for the current function,
in (1) bytes and (2) elements. */
@@ -248,20 +242,6 @@ regset regs_live_at_setjmp;
are another pair, etc. */
rtx regs_may_share;
-/* Depth within loops of basic block being scanned for lifetime analysis,
- plus one. This is the weight attached to references to registers. */
-
-static int loop_depth;
-
-/* During propagate_block, this is non-zero if the value of CC0 is live. */
-
-static int cc0_live;
-
-/* During propagate_block, this contains a list of all the MEMs we are
- tracking for dead store elimination. */
-
-static rtx mem_set_list;
-
/* Set of registers that may be eliminable. These are handled specially
in updating regs_ever_live. */
@@ -277,6 +257,35 @@ varray_type basic_block_for_insn;
static rtx label_value_list;
+/* For use in communicating between propagate_block and its subroutines.
+ Holds all information needed to compute life and def-use information. */
+
+struct propagate_block_info
+{
+ /* The basic block we're considering. */
+ basic_block bb;
+
+ /* Bit N is set if register N is conditionally or unconditionally live. */
+ regset reg_live;
+
+ /* Element N is the next insn that uses (hard or pseudo) register N
+ within the current basic block; or zero, if there is no such insn. */
+ rtx *reg_next_use;
+
+ /* Contains a list of all the MEMs we are tracking for dead store
+ elimination. */
+ rtx mem_set_list;
+
+ /* If non-null, record the set of registers set in the basic block. */
+ regset local_set;
+
+ /* Non-zero if the value of CC0 is live. */
+ int cc0_live;
+
+ /* Flags controling the set of information propagate_block collects. */
+ int flags;
+};
+
/* Forward declarations */
static int count_basic_blocks PARAMS ((rtx));
static rtx find_basic_blocks_1 PARAMS ((rtx));
@@ -302,10 +311,8 @@ static int merge_blocks_move_predecessor_nojumps PARAMS ((basic_block,
basic_block));
static int merge_blocks_move_successor_nojumps PARAMS ((basic_block,
basic_block));
-static void merge_blocks_nomove PARAMS ((basic_block, basic_block));
static int merge_blocks PARAMS ((edge,basic_block,basic_block));
static void try_merge_blocks PARAMS ((void));
-static void tidy_fallthru_edge PARAMS ((edge,basic_block,basic_block));
static void tidy_fallthru_edges PARAMS ((void));
static int verify_wide_reg_1 PARAMS ((rtx *, void *));
static void verify_wide_reg PARAMS ((int, rtx, rtx));
@@ -317,29 +324,43 @@ static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *));
static void notice_stack_pointer_modification PARAMS ((rtx));
static void mark_reg PARAMS ((rtx, void *));
static void mark_regs_live_at_end PARAMS ((regset));
+static int set_phi_alternative_reg PARAMS ((rtx, int, int, void *));
static void calculate_global_regs_live PARAMS ((sbitmap, sbitmap, int));
+static void propagate_block_delete_insn PARAMS ((basic_block, rtx));
+static rtx propagate_block_delete_libcall PARAMS ((basic_block, rtx, rtx));
static void propagate_block PARAMS ((basic_block, regset,
regset, int));
-static int insn_dead_p PARAMS ((rtx, regset, int, rtx));
-static int libcall_dead_p PARAMS ((rtx, regset, rtx, rtx));
-static void mark_set_regs PARAMS ((regset, regset, rtx,
- rtx, regset, int));
-static void mark_set_1 PARAMS ((regset, regset, rtx,
- rtx, regset, int));
+static int insn_dead_p PARAMS ((struct propagate_block_info *,
+ rtx, int, rtx));
+static int libcall_dead_p PARAMS ((struct propagate_block_info *,
+ rtx, rtx, rtx));
+static void mark_set_regs PARAMS ((struct propagate_block_info *,
+ regset, rtx, rtx));
+static void mark_set_1 PARAMS ((struct propagate_block_info *,
+ regset, rtx, rtx, rtx));
+static int mark_set_reg PARAMS ((struct propagate_block_info *,
+ regset, rtx, rtx,
+ int *, int *));
#ifdef AUTO_INC_DEC
-static void find_auto_inc PARAMS ((regset, rtx, rtx));
-static int try_pre_increment_1 PARAMS ((rtx));
+static void find_auto_inc PARAMS ((struct propagate_block_info *,
+ rtx, rtx));
+static int try_pre_increment_1 PARAMS ((struct propagate_block_info *,
+ rtx));
static int try_pre_increment PARAMS ((rtx, rtx, HOST_WIDE_INT));
#endif
-static void mark_used_regs PARAMS ((regset, regset, rtx, int, rtx));
+static void mark_used_reg PARAMS ((struct propagate_block_info *,
+ regset, rtx, rtx, rtx));
+static void mark_used_regs PARAMS ((struct propagate_block_info *,
+ regset, rtx, rtx, rtx));
void dump_flow_info PARAMS ((FILE *));
void debug_flow_info PARAMS ((void));
static void dump_edge_info PARAMS ((FILE *, edge, int));
-static void count_reg_sets_1 PARAMS ((rtx));
-static void count_reg_sets PARAMS ((rtx));
-static void count_reg_references PARAMS ((rtx));
-static void invalidate_mems_from_autoinc PARAMS ((rtx));
+static void count_reg_sets_1 PARAMS ((rtx, int));
+static void count_reg_sets PARAMS ((rtx, int));
+static void count_reg_references PARAMS ((rtx, int));
+static void invalidate_mems_from_autoinc PARAMS ((struct propagate_block_info *,
+ rtx));
static void remove_fake_successors PARAMS ((basic_block));
static void flow_nodes_print PARAMS ((const char *, const sbitmap, FILE *));
static void flow_exits_print PARAMS ((const char *, const edge *, int, FILE *));
@@ -353,13 +374,6 @@ static void flow_loop_tree_node_add PARAMS ((struct loop *, struct loop *));
static void flow_loops_tree_build PARAMS ((struct loops *));
static int flow_loop_level_compute PARAMS ((struct loop *, int));
static int flow_loops_level_compute PARAMS ((struct loops *));
-
-/* This function is always defined so it can be called from the
- debugger, and it is declared extern so we don't get warnings about
- it being unused. */
-void verify_flow_info PARAMS ((void));
-int flow_loop_outside_edge_p PARAMS ((const struct loop *, edge));
-void clear_log_links PARAMS ((rtx));
/* Find basic blocks of the current function.
F is the first insn of the function and NREGS the number of register
@@ -2038,6 +2052,109 @@ can_delete_label_p (label)
return 1;
}
+/* Blocks A and B are to be merged into a single block A. The insns
+ are already contiguous, hence `nomove'. */
+
+void
+merge_blocks_nomove (a, b)
+ basic_block a, b;
+{
+ edge e;
+ rtx b_head, b_end, a_end;
+ rtx del_first = NULL_RTX, del_last = NULL_RTX;
+ int b_empty = 0;
+
+ /* If there was a CODE_LABEL beginning B, delete it. */
+ b_head = b->head;
+ b_end = b->end;
+ if (GET_CODE (b_head) == CODE_LABEL)
+ {
+ /* Detect basic blocks with nothing but a label. This can happen
+ in particular at the end of a function. */
+ if (b_head == b_end)
+ b_empty = 1;
+ del_first = del_last = b_head;
+ b_head = NEXT_INSN (b_head);
+ }
+
+ /* Delete the basic block note. */
+ if (GET_CODE (b_head) == NOTE
+ && NOTE_LINE_NUMBER (b_head) == NOTE_INSN_BASIC_BLOCK)
+ {
+ if (b_head == b_end)
+ b_empty = 1;
+ if (! del_last)
+ del_first = b_head;
+ del_last = b_head;
+ b_head = NEXT_INSN (b_head);
+ }
+
+ /* If there was a jump out of A, delete it. */
+ a_end = a->end;
+ if (GET_CODE (a_end) == JUMP_INSN)
+ {
+ rtx prev;
+
+ prev = prev_nonnote_insn (a_end);
+ if (!prev)
+ prev = a->head;
+
+ del_first = a_end;
+
+#ifdef HAVE_cc0
+ /* If this was a conditional jump, we need to also delete
+ the insn that set cc0. */
+ if (prev && sets_cc0_p (prev))
+ {
+ rtx tmp = prev;
+ prev = prev_nonnote_insn (prev);
+ if (!prev)
+ prev = a->head;
+ del_first = tmp;
+ }
+#endif
+
+ a_end = prev;
+ }
+
+ /* Delete everything marked above as well as crap that might be
+ hanging out between the two blocks. */
+ flow_delete_insn_chain (del_first, del_last);
+
+ /* Normally there should only be one successor of A and that is B, but
+ partway though the merge of blocks for conditional_execution we'll
+ be merging a TEST block with THEN and ELSE successors. Free the
+ whole lot of them and hope the caller knows what they're doing. */
+ while (a->succ)
+ remove_edge (a->succ);
+
+ /* Adjust the edges out of B for the new owner. */
+ for (e = b->succ; e ; e = e->succ_next)
+ e->src = a;
+ a->succ = b->succ;
+
+ /* B hasn't quite yet ceased to exist. Attempt to prevent mishap. */
+ b->pred = b->succ = NULL;
+
+ /* Reassociate the insns of B with A. */
+ if (!b_empty)
+ {
+ if (basic_block_for_insn)
+ {
+ BLOCK_FOR_INSN (b_head) = a;
+ while (b_head != b_end)
+ {
+ b_head = NEXT_INSN (b_head);
+ BLOCK_FOR_INSN (b_head) = a;
+ }
+ }
+ a_end = b_end;
+ }
+ a->end = a_end;
+
+ expunge_block (b);
+}
+
/* Blocks A and B are to be merged into a single block. A has no incoming
fallthru edge, so it can be moved before B without adding or modifying
any jumps (aside from the jump from A to B). */
@@ -2151,95 +2268,6 @@ merge_blocks_move_successor_nojumps (a, b)
return 1;
}
-/* Blocks A and B are to be merged into a single block. The insns
- are already contiguous, hence `nomove'. */
-
-static void
-merge_blocks_nomove (a, b)
- basic_block a, b;
-{
- edge e;
- rtx b_head, b_end, a_end;
- int b_empty = 0;
-
- /* If there was a CODE_LABEL beginning B, delete it. */
- b_head = b->head;
- b_end = b->end;
- if (GET_CODE (b_head) == CODE_LABEL)
- {
- /* Detect basic blocks with nothing but a label. This can happen
- in particular at the end of a function. */
- if (b_head == b_end)
- b_empty = 1;
- b_head = flow_delete_insn (b_head);
- }
-
- /* Delete the basic block note. */
- if (GET_CODE (b_head) == NOTE
- && NOTE_LINE_NUMBER (b_head) == NOTE_INSN_BASIC_BLOCK)
- {
- if (b_head == b_end)
- b_empty = 1;
- b_head = flow_delete_insn (b_head);
- }
-
- /* If there was a jump out of A, delete it. */
- a_end = a->end;
- if (GET_CODE (a_end) == JUMP_INSN)
- {
- rtx prev;
-
- prev = prev_nonnote_insn (a_end);
- if (!prev)
- prev = a->head;
-
-#ifdef HAVE_cc0
- /* If this was a conditional jump, we need to also delete
- the insn that set cc0. */
-
- if (prev && sets_cc0_p (prev))
- {
- rtx tmp = prev;
- prev = prev_nonnote_insn (prev);
- if (!prev)
- prev = a->head;
- flow_delete_insn (tmp);
- }
-#endif
-
- /* Note that a->head != a->end, since we should have at least a
- bb note plus the jump, so prev != insn. */
- flow_delete_insn (a_end);
- a_end = prev;
- }
-
- /* By definition, there should only be one successor of A, and that is
- B. Free that edge struct. */
- n_edges--;
- free (a->succ);
-
- /* Adjust the edges out of B for the new owner. */
- for (e = b->succ; e ; e = e->succ_next)
- e->src = a;
- a->succ = b->succ;
-
- /* Reassociate the insns of B with A. */
- if (!b_empty)
- {
- BLOCK_FOR_INSN (b_head) = a;
- while (b_head != b_end)
- {
- b_head = NEXT_INSN (b_head);
- BLOCK_FOR_INSN (b_head) = a;
- }
- a_end = b_head;
- }
- a->end = a_end;
-
- /* Compact the basic block array. */
- expunge_block (b);
-}
-
/* Attempt to merge basic blocks that are potentially non-adjacent.
Return true iff the attempt succeeded. */
@@ -2372,7 +2400,7 @@ try_merge_blocks ()
/* The given edge should potentially be a fallthru edge. If that is in
fact true, delete the jump and barriers that are in the way. */
-static void
+void
tidy_fallthru_edge (e, b, c)
edge e;
basic_block b, c;
@@ -2493,6 +2521,15 @@ life_analysis (f, nregs, file, remove_dead_code)
#endif
int flags;
sbitmap all_blocks;
+
+ /* Dead code elimination changes basic block structure and therefore
+ breaks the SSA phi representation. Particularly, a phi node
+ can have an alternative value for each incoming block, referenced
+ by the block number. Removing dead code can bump entire blocks
+ and therefore cause blocks to be renumbered, invalidating the
+ numbering of phi alternatives. */
+ if (remove_dead_code && in_ssa_form)
+ abort ();
/* Record which registers will be eliminated. We use this in
mark_used_regs. */
@@ -2543,7 +2580,6 @@ life_analysis (f, nregs, file, remove_dead_code)
data from lifetime analysis. */
allocate_reg_life_data ();
allocate_bb_life_data ();
- reg_next_use = (rtx *) xcalloc (nregs, sizeof (rtx));
all_blocks = sbitmap_alloc (n_basic_blocks);
sbitmap_ones (all_blocks);
@@ -2560,8 +2596,6 @@ life_analysis (f, nregs, file, remove_dead_code)
/* Clean up. */
sbitmap_free (all_blocks);
- free (reg_next_use);
- reg_next_use = NULL;
end_alias_analysis ();
if (file)
@@ -2579,7 +2613,7 @@ verify_wide_reg_1 (px, pregno)
void *pregno;
{
rtx x = *px;
- int regno = *(int *) pregno;
+ unsigned int regno = *(int *) pregno;
if (GET_CODE (x) == REG && REGNO (x) == regno)
{
@@ -2660,9 +2694,8 @@ verify_local_live_at_start (new_live_at_start, bb)
BLOCK_FOR_INSN is assumed to be correct.
- PROP_FLAGS should not contain PROP_LOG_LINKS unless the caller sets
- up reg_next_use. Including PROP_REG_INFO does not properly refresh
- regs_ever_live unless the caller resets it to zero. */
+ Including PROP_REG_INFO does not properly refresh regs_ever_live
+ unless the caller resets it to zero. */
void
update_life_info (blocks, extent, prop_flags)
@@ -2967,6 +3000,22 @@ mark_regs_live_at_end (set)
diddle_return_value (mark_reg, set);
}
+/* Callback function for for_each_successor_phi. DATA is a regset.
+ Sets the SRC_REGNO, the regno of the phi alternative for phi node
+ INSN, in the regset. */
+
+static int
+set_phi_alternative_reg (insn, dest_regno, src_regno, data)
+ rtx insn ATTRIBUTE_UNUSED;
+ int dest_regno ATTRIBUTE_UNUSED;
+ int src_regno;
+ void *data;
+{
+ regset live = (regset) data;
+ SET_REGNO_REG_SET (live, src_regno);
+ return 0;
+}
+
/* Propagate global life info around the graph of basic blocks. Begin
considering blocks with their corresponding bit set in BLOCKS_IN.
BLOCKS_OUT is set for every block that was changed. */
@@ -3027,6 +3076,13 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
IOR_REG_SET (new_live_at_end, sb->global_live_at_start);
}
+ /* Regs used in phi nodes are not included in
+ global_live_at_start, since they are live only along a
+ particular edge. Set those regs that are live because of a
+ phi node alternative corresponding to this particular block. */
+ for_each_successor_phi (bb->index, &set_phi_alternative_reg,
+ new_live_at_end);
+
if (bb == ENTRY_BLOCK_PTR)
{
COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
@@ -3179,49 +3235,100 @@ allocate_reg_life_data ()
}
}
-/* Compute the registers live at the beginning of a basic block
- from those live at the end.
+/* Delete dead instructions for propagate_block. */
- When called, OLD contains those live at the end.
- On return, it contains those live at the beginning.
- FIRST and LAST are the first and last insns of the basic block.
+static void
+propagate_block_delete_insn (bb, insn)
+ basic_block bb;
+ rtx insn;
+{
+ rtx inote = find_reg_note (insn, REG_LABEL, NULL_RTX);
- FINAL is nonzero if we are doing the final pass which is not
- for computing the life info (since that has already been done)
- but for acting on it. On this pass, we delete dead stores,
- set up the logical links and dead-variables lists of instructions,
- and merge instructions for autoincrement and autodecrement addresses.
+ /* If the insn referred to a label, and that label was attached to
+ an ADDR_VEC, it's safe to delete the ADDR_VEC. In fact, it's
+ pretty much mandatory to delete it, because the ADDR_VEC may be
+ referencing labels that no longer exist. */
- SIGNIFICANT is nonzero only the first time for each basic block.
- If it is nonzero, it points to a regset in which we store
- a 1 for each register that is set within the block.
+ if (inote)
+ {
+ rtx label = XEXP (inote, 0);
+ rtx next;
- BNUM is the number of the basic block. */
+ if (LABEL_NUSES (label) == 1
+ && (next = next_nonnote_insn (label)) != NULL
+ && GET_CODE (next) == JUMP_INSN
+ && (GET_CODE (PATTERN (next)) == ADDR_VEC
+ || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
+ {
+ rtx pat = PATTERN (next);
+ int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
+ int len = XVECLEN (pat, diff_vec_p);
+ int i;
-static void
-propagate_block (bb, old, significant, flags)
+ for (i = 0; i < len; i++)
+ LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
+
+ flow_delete_insn (next);
+ }
+ }
+
+ if (bb->end == insn)
+ bb->end = PREV_INSN (insn);
+ flow_delete_insn (insn);
+}
+
+/* Delete dead libcalls for propagate_block. Return the insn
+ before the libcall. */
+
+static rtx
+propagate_block_delete_libcall (bb, insn, note)
basic_block bb;
- regset old;
- regset significant;
- int flags;
+ rtx insn, note;
{
- register rtx insn;
- rtx prev;
- regset live;
- regset_head live_head;
- regset dead;
- regset_head dead_head;
+ rtx first = XEXP (note, 0);
+ rtx before = PREV_INSN (first);
- /* Find the loop depth for this block. Ignore loop level changes in the
- middle of the basic block -- for register allocation purposes, the
- important uses will be in the blocks wholely contained within the loop
- not in the loop pre-header or post-trailer. */
- loop_depth = bb->loop_depth;
+ if (insn == bb->end)
+ bb->end = before;
+
+ flow_delete_insn_chain (first, insn);
+ return before;
+}
- dead = INITIALIZE_REG_SET (live_head);
- live = INITIALIZE_REG_SET (dead_head);
+/* Compute the registers live at the beginning of a basic block BB from
+ those live at the end.
- cc0_live = 0;
+ When called, REG_LIVE contains those live at the end. On return, it
+ contains those live at the beginning.
+
+ LOCAL_SET, if non-null, will be set with all registers killed by
+ this basic block. */
+
+static void
+propagate_block (bb, live, local_set, flags)
+ basic_block bb;
+ regset live;
+ regset local_set;
+ int flags;
+{
+ struct propagate_block_info pbi;
+ rtx insn, prev;
+ regset_head tmp_head;
+ regset tmp;
+
+ pbi.bb = bb;
+ pbi.reg_live = live;
+ pbi.mem_set_list = NULL_RTX;
+ pbi.local_set = local_set;
+ pbi.cc0_live = 0;
+ pbi.flags = flags;
+
+ if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+ pbi.reg_next_use = (rtx *) xcalloc (max_reg_num (), sizeof (rtx));
+ else
+ pbi.reg_next_use = NULL;
+
+ tmp = INITIALIZE_REG_SET (tmp_head);
if (flags & PROP_REG_INFO)
{
@@ -3229,7 +3336,7 @@ propagate_block (bb, old, significant, flags)
/* Process the regs live at the end of the block.
Mark them as not local to any one basic block. */
- EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+ EXECUTE_IF_SET_IN_REG_SET (live, 0, i,
{
REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
});
@@ -3248,7 +3355,7 @@ propagate_block (bb, old, significant, flags)
if ((flags & PROP_REG_INFO)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
- IOR_REG_SET (regs_live_at_setjmp, old);
+ IOR_REG_SET (regs_live_at_setjmp, pbi.reg_live);
}
/* Update the life-status of regs for this insn.
@@ -3267,10 +3374,10 @@ propagate_block (bb, old, significant, flags)
if (flags & PROP_SCAN_DEAD_CODE)
{
- insn_is_dead = insn_dead_p (PATTERN (insn), old, 0,
+ insn_is_dead = insn_dead_p (&pbi, PATTERN (insn), 0,
REG_NOTES (insn));
libcall_is_dead = (insn_is_dead && note != 0
- && libcall_dead_p (PATTERN (insn), old,
+ && libcall_dead_p (&pbi, PATTERN (insn),
note, insn));
}
@@ -3293,84 +3400,25 @@ propagate_block (bb, old, significant, flags)
}
/* If an instruction consists of just dead store(s) on final pass,
- "delete" it by turning it into a NOTE of type NOTE_INSN_DELETED.
- We could really delete it with delete_insn, but that
- can cause trouble for first or last insn in a basic block. */
+ delete it. */
if ((flags & PROP_KILL_DEAD_CODE) && insn_is_dead)
{
- rtx inote;
- /* If the insn referred to a label, note that the label is
- now less used. */
- for (inote = REG_NOTES (insn); inote; inote = XEXP (inote, 1))
+ if (libcall_is_dead)
{
- if (REG_NOTE_KIND (inote) == REG_LABEL)
- {
- rtx label = XEXP (inote, 0);
- rtx next;
- LABEL_NUSES (label)--;
-
- /* If this label was attached to an ADDR_VEC, it's
- safe to delete the ADDR_VEC. In fact, it's pretty
- much mandatory to delete it, because the ADDR_VEC may
- be referencing labels that no longer exist. */
- if (LABEL_NUSES (label) == 0
- && (next = next_nonnote_insn (label)) != NULL
- && GET_CODE (next) == JUMP_INSN
- && (GET_CODE (PATTERN (next)) == ADDR_VEC
- || GET_CODE (PATTERN (next)) == ADDR_DIFF_VEC))
- {
- rtx pat = PATTERN (next);
- int diff_vec_p = GET_CODE (pat) == ADDR_DIFF_VEC;
- int len = XVECLEN (pat, diff_vec_p);
- int i;
- for (i = 0; i < len; i++)
- LABEL_NUSES (XEXP (XVECEXP (pat, diff_vec_p, i), 0))--;
- PUT_CODE (next, NOTE);
- NOTE_LINE_NUMBER (next) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (next) = 0;
-
- if ((next = next_nonnote_insn (label)) != NULL
- && GET_CODE (next) == BARRIER)
- {
- PUT_CODE (next, NOTE);
- NOTE_LINE_NUMBER (next) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (next) = 0;
- }
- }
- }
+ prev = propagate_block_delete_libcall (bb, insn, note);
+ insn = NEXT_INSN (prev);
}
-
- PUT_CODE (insn, NOTE);
- NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (insn) = 0;
+ else
+ propagate_block_delete_insn (bb, insn);
/* CC0 is now known to be dead. Either this insn used it,
in which case it doesn't anymore, or clobbered it,
so the next insn can't use it. */
- cc0_live = 0;
+ pbi.cc0_live = 0;
- /* If this insn is copying the return value from a library call,
- delete the entire library call. */
- if (libcall_is_dead)
- {
- rtx first = XEXP (note, 0);
- rtx p = insn;
- while (INSN_DELETED_P (first))
- first = NEXT_INSN (first);
- while (p != first)
- {
- p = PREV_INSN (p);
- PUT_CODE (p, NOTE);
- NOTE_LINE_NUMBER (p) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (p) = 0;
- }
- }
goto flushed;
}
- CLEAR_REG_SET (dead);
- CLEAR_REG_SET (live);
-
/* See if this is an increment or decrement that can be
merged into a following memory address. */
#ifdef AUTO_INC_DEC
@@ -3390,20 +3438,22 @@ propagate_block (bb, old, significant, flags)
If one is found, change the memory ref to a PRE_INC
or PRE_DEC, cancel this insn, and return 1.
Return 0 if nothing has been done. */
- && try_pre_increment_1 (insn))
+ && try_pre_increment_1 (&pbi, insn))
goto flushed;
}
#endif /* AUTO_INC_DEC */
+ CLEAR_REG_SET (tmp);
+
/* If this is not the final pass, and this insn is copying the
value of a library call and it's dead, don't scan the
insns that perform the library call, so that the call's
arguments are not marked live. */
if (libcall_is_dead)
{
- /* Mark the dest reg as `significant'. */
- mark_set_regs (old, dead, PATTERN (insn), NULL_RTX,
- significant, flags);
+ /* Record the death of the dest reg. */
+ mark_set_regs (&pbi, tmp, PATTERN (insn), insn);
+ AND_COMPL_REG_SET (pbi.reg_live, tmp);
insn = XEXP (note, 0);
prev = PREV_INSN (insn);
@@ -3426,29 +3476,67 @@ propagate_block (bb, old, significant, flags)
if (GET_CODE (insn) == CALL_INSN
&& (flags & PROP_REG_INFO))
- EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
- {
- REG_N_CALLS_CROSSED (i)++;
- });
+ EXECUTE_IF_SET_IN_REG_SET (pbi.reg_live, 0, i,
+ { REG_N_CALLS_CROSSED (i)++; });
+
+ /* Record sets. Do this even for dead instructions,
+ since they would have killed the values if they hadn't
+ been deleted. */
+ mark_set_regs (&pbi, tmp, PATTERN (insn), insn);
+
+ /* Each call clobbers all call-clobbered regs that are not
+ global or fixed. Note that the function-value reg is a
+ call-clobbered reg, and mark_set_regs has already had
+ a chance to handle it. */
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ register int i;
+ rtx cond;
- /* LIVE gets the regs used in INSN;
- DEAD gets those set by it. Dead insns don't make anything
- live. */
+ cond = NULL_RTX;
+ if (GET_CODE (PATTERN (insn)) == COND_EXEC)
+ cond = COND_EXEC_TEST (PATTERN (insn));
- mark_set_regs (old, dead, PATTERN (insn),
- insn, significant, flags);
+ /* Non-constant calls clobber memory. */
+ if (! CONST_CALL_P (insn))
+ free_EXPR_LIST_list (&pbi.mem_set_list);
+
+ /* There may be extra registers to be clobbered. */
+ for (note = CALL_INSN_FUNCTION_USAGE (insn);
+ note;
+ note = XEXP (note, 1))
+ if (GET_CODE (XEXP (note, 0)) == CLOBBER)
+ mark_set_1 (&pbi, tmp, XEXP (XEXP (note, 0), 0),
+ cond, insn);
+
+ /* Calls change all call-used and global registers. */
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (call_used_regs[i] && ! global_regs[i]
+ && ! fixed_regs[i])
+ {
+ int dummy;
+ mark_set_reg (&pbi, tmp,
+ gen_rtx_REG (reg_raw_mode[i], i),
+ cond, &dummy, &dummy);
+ }
+ }
+
+ /* Update live for the registers killed. */
+ AND_COMPL_REG_SET (pbi.reg_live, tmp);
+ CLEAR_REG_SET (tmp);
/* If an insn doesn't use CC0, it becomes dead since we
assume that every insn clobbers it. So show it dead here;
mark_used_regs will set it live if it is referenced. */
- cc0_live = 0;
+ pbi.cc0_live = 0;
+ /* Record uses. */
if (! insn_is_dead)
- mark_used_regs (old, live, PATTERN (insn), flags, insn);
+ mark_used_regs (&pbi, tmp, PATTERN (insn), NULL_RTX, insn);
- /* Sometimes we may have inserted something before INSN (such as
- a move) when we make an auto-inc. So ensure we will scan
- those insns. */
+ /* Sometimes we may have inserted something before INSN
+ (such as a move) when we make an auto-inc. So ensure
+ we will scan those insns. */
#ifdef AUTO_INC_DEC
prev = PREV_INSN (insn);
#endif
@@ -3456,65 +3544,53 @@ propagate_block (bb, old, significant, flags)
if (! insn_is_dead && GET_CODE (insn) == CALL_INSN)
{
register int i;
+ rtx note, cond;
- rtx note;
+ cond = NULL_RTX;
+ if (GET_CODE (PATTERN (insn)) == COND_EXEC)
+ cond = COND_EXEC_TEST (PATTERN (insn));
for (note = CALL_INSN_FUNCTION_USAGE (insn);
note;
note = XEXP (note, 1))
if (GET_CODE (XEXP (note, 0)) == USE)
- mark_used_regs (old, live, XEXP (XEXP (note, 0), 0),
- flags, insn);
-
- /* Each call clobbers all call-clobbered regs that are not
- global or fixed. Note that the function-value reg is a
- call-clobbered reg, and mark_set_regs has already had
- a chance to handle it. */
-
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i] && ! global_regs[i]
- && ! fixed_regs[i])
- {
- SET_REGNO_REG_SET (dead, i);
- if (significant)
- SET_REGNO_REG_SET (significant, i);
- }
+ mark_used_regs (&pbi, tmp, XEXP (XEXP (note, 0), 0),
+ cond, insn);
/* The stack ptr is used (honorarily) by a CALL insn. */
- SET_REGNO_REG_SET (live, STACK_POINTER_REGNUM);
+ SET_REGNO_REG_SET (tmp, STACK_POINTER_REGNUM);
/* Calls may also reference any of the global registers,
so they are made live. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (global_regs[i])
- mark_used_regs (old, live,
- gen_rtx_REG (reg_raw_mode[i], i),
- flags, insn);
-
- /* Calls also clobber memory. */
- free_EXPR_LIST_list (&mem_set_list);
+ mark_used_reg (&pbi, tmp,
+ gen_rtx_REG (reg_raw_mode[i], i),
+ cond, insn);
}
- /* Update OLD for the registers used or set. */
- AND_COMPL_REG_SET (old, dead);
- IOR_REG_SET (old, live);
-
+ /* Update live for the registers used. */
+ IOR_REG_SET (pbi.reg_live, tmp);
}
/* On final pass, update counts of how many insns in which
each reg is live. */
if (flags & PROP_REG_INFO)
- EXECUTE_IF_SET_IN_REG_SET (old, 0, i, { REG_LIVE_LENGTH (i)++; });
+ EXECUTE_IF_SET_IN_REG_SET (pbi.reg_live, 0, i,
+ { REG_LIVE_LENGTH (i)++; });
}
flushed:
if (insn == bb->head)
break;
}
- FREE_REG_SET (dead);
- FREE_REG_SET (live);
- free_EXPR_LIST_list (&mem_set_list);
+ FREE_REG_SET (tmp);
+ free_EXPR_LIST_list (&pbi.mem_set_list);
+
+ if (pbi.reg_next_use)
+ free (pbi.reg_next_use);
}
+
/* Return 1 if X (the body of an insn, or part of it) is just dead stores
(SET expressions whose destinations are registers dead after the insn).
@@ -3526,9 +3602,9 @@ propagate_block (bb, old, significant, flags)
pertaining to the insn. */
static int
-insn_dead_p (x, needed, call_ok, notes)
+insn_dead_p (pbi, x, call_ok, notes)
+ struct propagate_block_info *pbi;
rtx x;
- regset needed;
int call_ok;
rtx notes ATTRIBUTE_UNUSED;
{
@@ -3547,7 +3623,7 @@ insn_dead_p (x, needed, call_ok, notes)
/* Don't delete insns to set global regs. */
if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
- || REGNO_REG_SET_P (needed, regno))
+ || REGNO_REG_SET_P (pbi->reg_live, regno))
return 0;
}
}
@@ -3563,7 +3639,7 @@ insn_dead_p (x, needed, call_ok, notes)
#ifdef HAVE_cc0
if (GET_CODE (r) == CC0)
- return ! cc0_live;
+ return ! pbi->cc0_live;
#endif
/* A SET that is a subroutine call cannot be dead. */
@@ -3588,7 +3664,7 @@ insn_dead_p (x, needed, call_ok, notes)
and see if one is an identical match to this memory location.
If so, this memory write is dead (remember, we're walking
backwards from the end of the block to the start. */
- temp = mem_set_list;
+ temp = pbi->mem_set_list;
while (temp)
{
if (rtx_equal_p (XEXP (temp, 0), r))
@@ -3608,7 +3684,7 @@ insn_dead_p (x, needed, call_ok, notes)
int regno = REGNO (r);
/* Obvious. */
- if (REGNO_REG_SET_P (needed, regno))
+ if (REGNO_REG_SET_P (pbi->reg_live, regno))
return 0;
/* If this is a hard register, verify that subsequent
@@ -3618,7 +3694,7 @@ insn_dead_p (x, needed, call_ok, notes)
int n = HARD_REGNO_NREGS (regno, GET_MODE (r));
while (--n > 0)
- if (REGNO_REG_SET_P (needed, regno+n))
+ if (REGNO_REG_SET_P (pbi->reg_live, regno+n))
return 0;
}
@@ -3665,7 +3741,7 @@ insn_dead_p (x, needed, call_ok, notes)
for (i--; i >= 0; i--)
if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
&& GET_CODE (XVECEXP (x, 0, i)) != USE
- && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok, NULL_RTX))
+ && ! insn_dead_p (pbi, XVECEXP (x, 0, i), call_ok, NULL_RTX))
return 0;
return 1;
@@ -3675,7 +3751,7 @@ insn_dead_p (x, needed, call_ok, notes)
is not necessarily true for hard registers. */
else if (code == CLOBBER && GET_CODE (XEXP (x, 0)) == REG
&& REGNO (XEXP (x, 0)) >= FIRST_PSEUDO_REGISTER
- && ! REGNO_REG_SET_P (needed, REGNO (XEXP (x, 0))))
+ && ! REGNO_REG_SET_P (pbi->reg_live, REGNO (XEXP (x, 0))))
return 1;
/* We do not check other CLOBBER or USE here. An insn consisting of just
@@ -3698,9 +3774,9 @@ insn_dead_p (x, needed, call_ok, notes)
NOTE is the REG_RETVAL note of the insn. INSN is the insn itself. */
static int
-libcall_dead_p (x, needed, note, insn)
+libcall_dead_p (pbi, x, note, insn)
+ struct propagate_block_info *pbi;
rtx x;
- regset needed;
rtx note;
rtx insn;
{
@@ -3743,7 +3819,7 @@ libcall_dead_p (x, needed, note, insn)
call_pat = XVECEXP (call_pat, 0, i);
}
- return insn_dead_p (call_pat, needed, 1, REG_NOTES (call));
+ return insn_dead_p (pbi, call_pat, 1, REG_NOTES (call));
}
}
return 1;
@@ -3788,7 +3864,8 @@ regno_clobbered_at_setjmp (regno)
Find any entries on the mem_set_list that need to be invalidated due
to an address change. */
static void
-invalidate_mems_from_autoinc (insn)
+invalidate_mems_from_autoinc (pbi, insn)
+ struct propagate_block_info *pbi;
rtx insn;
{
rtx note = REG_NOTES (insn);
@@ -3796,7 +3873,7 @@ invalidate_mems_from_autoinc (insn)
{
if (REG_NOTE_KIND (note) == REG_INC)
{
- rtx temp = mem_set_list;
+ rtx temp = pbi->mem_set_list;
rtx prev = NULL_RTX;
rtx next;
@@ -3809,7 +3886,7 @@ invalidate_mems_from_autoinc (insn)
if (prev)
XEXP (prev, 1) = next;
else
- mem_set_list = next;
+ pbi->mem_set_list = next;
free_EXPR_LIST_node (temp);
}
else
@@ -3828,44 +3905,71 @@ invalidate_mems_from_autoinc (insn)
FLAGS is the set of operations to perform. */
static void
-mark_set_regs (needed, dead, x, insn, significant, flags)
- regset needed;
- regset dead;
- rtx x;
- rtx insn;
- regset significant;
- int flags;
+mark_set_regs (pbi, new_dead, x, insn)
+ struct propagate_block_info *pbi;
+ regset new_dead;
+ rtx x, insn;
{
- register RTX_CODE code = GET_CODE (x);
+ rtx cond = NULL_RTX;
- if (code == SET || code == CLOBBER)
- mark_set_1 (needed, dead, x, insn, significant, flags);
- else if (code == PARALLEL)
+ retry:
+ switch (GET_CODE (x))
{
- register int i;
- for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
- {
- code = GET_CODE (XVECEXP (x, 0, i));
- if (code == SET || code == CLOBBER)
- mark_set_1 (needed, dead, XVECEXP (x, 0, i), insn,
- significant, flags);
- }
+ case SET:
+ case CLOBBER:
+ mark_set_1 (pbi, new_dead, SET_DEST (x), cond, insn);
+ return;
+
+ case COND_EXEC:
+ cond = COND_EXEC_TEST (x);
+ x = COND_EXEC_CODE (x);
+ goto retry;
+
+ case PARALLEL:
+ {
+ register int i;
+ for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ {
+ rtx sub = XVECEXP (x, 0, i);
+ switch (GET_CODE (sub))
+ {
+ case COND_EXEC:
+ if (cond != NULL_RTX)
+ abort ();
+
+ cond = COND_EXEC_TEST (sub);
+ sub = COND_EXEC_CODE (sub);
+ if (GET_CODE (sub) != SET && GET_CODE (sub) != CLOBBER)
+ break;
+ /* FALLTHRU */
+
+ case SET:
+ case CLOBBER:
+ mark_set_1 (pbi, new_dead, SET_DEST (sub), cond, insn);
+ break;
+
+ default:
+ break;
+ }
+ }
+ break;
+ }
+
+ default:
+ break;
}
}
/* Process a single SET rtx, X. */
static void
-mark_set_1 (needed, dead, x, insn, significant, flags)
- regset needed;
- regset dead;
- rtx x;
- rtx insn;
- regset significant;
- int flags;
+mark_set_1 (pbi, new_dead, reg, cond, insn)
+ struct propagate_block_info *pbi;
+ regset new_dead;
+ rtx reg, cond, insn;
{
register int regno = -1;
- register rtx reg = SET_DEST (x);
+ int flags = pbi->flags;
/* Some targets place small structures in registers for
return values of functions. We have to detect this
@@ -3876,8 +3980,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
- mark_set_1 (needed, dead, XVECEXP (reg, 0, i), insn,
- significant, flags);
+ mark_set_1 (pbi, new_dead, XVECEXP (reg, 0, i), cond, insn);
return;
}
@@ -3902,10 +4005,9 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
If this set is a REG, then it kills any MEMs which use the reg. */
if (flags & PROP_SCAN_DEAD_CODE)
{
- if (GET_CODE (reg) == MEM
- || GET_CODE (reg) == REG)
+ if (GET_CODE (reg) == MEM || GET_CODE (reg) == REG)
{
- rtx temp = mem_set_list;
+ rtx temp = pbi->mem_set_list;
rtx prev = NULL_RTX;
rtx next;
@@ -3921,7 +4023,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
if (prev)
XEXP (prev, 1) = next;
else
- mem_set_list = next;
+ pbi->mem_set_list = next;
free_EXPR_LIST_node (temp);
}
else
@@ -3934,7 +4036,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
address modes. Then we may need to kill some entries on the
memory set list. */
if (insn && GET_CODE (reg) == MEM)
- invalidate_mems_from_autoinc (insn);
+ invalidate_mems_from_autoinc (pbi, insn);
if (GET_CODE (reg) == MEM && ! side_effects_p (reg)
/* We do not know the size of a BLKmode store, so we do not track
@@ -3944,7 +4046,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
everything that invalidates it. To be safe, don't eliminate any
stores though SP; none of them should be redundant anyway. */
&& ! reg_mentioned_p (stack_pointer_rtx, reg))
- mem_set_list = alloc_EXPR_LIST (0, reg, mem_set_list);
+ pbi->mem_set_list = alloc_EXPR_LIST (0, reg, pbi->mem_set_list);
}
if (GET_CODE (reg) == REG
@@ -3958,54 +4060,25 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
&& ! (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
#endif
- && ! (regno < FIRST_PSEUDO_REGISTER && global_regs[regno]))
- /* && regno != STACK_POINTER_REGNUM) -- let's try without this. */
+ )
{
- int some_needed = REGNO_REG_SET_P (needed, regno);
- int some_not_needed = ! some_needed;
+ int some_was_live, some_was_dead;
- /* Mark it as a significant register for this basic block. */
- if (significant)
- SET_REGNO_REG_SET (significant, regno);
-
- /* Mark it as dead before this insn. */
- SET_REGNO_REG_SET (dead, regno);
-
- /* A hard reg in a wide mode may really be multiple registers.
- If so, mark all of them just like the first. */
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int n;
-
- /* Nothing below is needed for the stack pointer; get out asap.
- Eg, log links aren't needed, since combine won't use them. */
- if (regno == STACK_POINTER_REGNUM)
- return;
-
- n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
- while (--n > 0)
- {
- int regno_n = regno + n;
- int needed_regno = REGNO_REG_SET_P (needed, regno_n);
- if (significant)
- SET_REGNO_REG_SET (significant, regno_n);
-
- SET_REGNO_REG_SET (dead, regno_n);
- some_needed |= needed_regno;
- some_not_needed |= ! needed_regno;
- }
- }
+ /* Perform the pbi datastructure update. */
+ if (! mark_set_reg (pbi, new_dead, reg, cond,
+ &some_was_live, &some_was_dead))
+ return;
/* Additional data to record if this is the final pass. */
if (flags & (PROP_LOG_LINKS | PROP_REG_INFO
| PROP_DEATH_NOTES | PROP_AUTOINC))
{
register rtx y;
- register int blocknum = BLOCK_NUM (insn);
+ register int blocknum = pbi->bb->index;
y = NULL_RTX;
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- y = reg_next_use[regno];
+ y = pbi->reg_next_use[regno];
/* If this is a hard reg, record this function uses the reg. */
@@ -4019,7 +4092,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
{
/* The next use is no longer "next", since a store
intervenes. */
- reg_next_use[i] = 0;
+ pbi->reg_next_use[i] = 0;
}
if (flags & PROP_REG_INFO)
@@ -4034,7 +4107,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
/* The next use is no longer "next", since a store
intervenes. */
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- reg_next_use[regno] = 0;
+ pbi->reg_next_use[regno] = 0;
/* Keep track of which basic blocks each reg appears in. */
@@ -4048,7 +4121,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
/* Count (weighted) references, stores, etc. This counts a
register twice if it is modified, but that is correct. */
REG_N_SETS (regno)++;
- REG_N_REFS (regno) += loop_depth + 1;
+ REG_N_REFS (regno) += pbi->bb->loop_depth + 1;
/* The insns where a reg is live are normally counted
elsewhere, but we want the count to include the insn
@@ -4058,7 +4131,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
}
}
- if (! some_not_needed)
+ if (! some_was_dead)
{
if (flags & PROP_LOG_LINKS)
{
@@ -4077,7 +4150,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
LOG_LINKS (y) = alloc_INSN_LIST (insn, LOG_LINKS (y));
}
}
- else if (! some_needed)
+ else if (! some_was_live)
{
if (flags & PROP_REG_INFO)
REG_N_DEATHS (REGNO (reg))++;
@@ -4107,7 +4180,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
for (i = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1;
i >= 0; i--)
- if (!REGNO_REG_SET_P (needed, regno + i))
+ if (! REGNO_REG_SET_P (pbi->reg_live, regno + i))
REG_NOTES (insn)
= (alloc_EXPR_LIST
(REG_UNUSED,
@@ -4120,7 +4193,7 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
else if (GET_CODE (reg) == REG)
{
if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- reg_next_use[regno] = 0;
+ pbi->reg_next_use[regno] = 0;
}
/* If this is the last pass and this is a SCRATCH, show it will be dying
@@ -4132,6 +4205,64 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
= alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
}
}
+
+/* Update data structures for a (possibly conditional) store into REG.
+ Return true if REG is now unconditionally dead. */
+
+static int
+mark_set_reg (pbi, new_dead, reg, cond, p_some_was_live, p_some_was_dead)
+ struct propagate_block_info *pbi;
+ regset new_dead;
+ rtx reg;
+ rtx cond ATTRIBUTE_UNUSED;
+ int *p_some_was_live, *p_some_was_dead;
+{
+ int regno = REGNO (reg);
+ int some_was_live = REGNO_REG_SET_P (pbi->reg_live, regno);
+ int some_was_dead = ! some_was_live;
+
+ /* Mark it as a significant register for this basic block. */
+ if (pbi->local_set)
+ SET_REGNO_REG_SET (pbi->local_set, regno);
+
+ /* A hard reg in a wide mode may really be multiple registers.
+ If so, mark all of them just like the first. */
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ while (--n > 0)
+ {
+ int regno_n = regno + n;
+ int needed_regno = REGNO_REG_SET_P (pbi->reg_live, regno_n);
+ if (pbi->local_set)
+ SET_REGNO_REG_SET (pbi->local_set, regno_n);
+
+ some_was_live |= needed_regno;
+ some_was_dead |= ! needed_regno;
+ }
+ }
+
+ *p_some_was_live = some_was_live;
+ *p_some_was_dead = some_was_dead;
+
+ /* The stack pointer is never dead. Well, not strictly true, but it's
+ very difficult to tell from here. Hopefully combine_stack_adjustments
+ will fix up the most egregious errors. */
+ if (regno == STACK_POINTER_REGNUM)
+ return 0;
+
+ /* Mark it as dead before this insn. */
+ SET_REGNO_REG_SET (new_dead, regno);
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ while (--n > 0)
+ SET_REGNO_REG_SET (new_dead, regno + n);
+ }
+
+ /* Unconditionally dead. */
+ return 1;
+}
#ifdef AUTO_INC_DEC
@@ -4139,8 +4270,8 @@ mark_set_1 (needed, dead, x, insn, significant, flags)
reference. */
static void
-find_auto_inc (needed, x, insn)
- regset needed;
+find_auto_inc (pbi, x, insn)
+ struct propagate_block_info *pbi;
rtx x;
rtx insn;
{
@@ -4163,7 +4294,7 @@ find_auto_inc (needed, x, insn)
int regno = REGNO (addr);
/* Is the next use an increment that might make auto-increment? */
- if ((incr = reg_next_use[regno]) != 0
+ if ((incr = pbi->reg_next_use[regno]) != 0
&& (set = single_set (incr)) != 0
&& GET_CODE (set) == SET
&& BLOCK_NUM (incr) == BLOCK_NUM (insn)
@@ -4252,18 +4383,18 @@ find_auto_inc (needed, x, insn)
if (GET_CODE (PREV_INSN (insn)) == INSN
&& GET_CODE (PATTERN (PREV_INSN (insn))) == SET
&& SET_SRC (PATTERN (PREV_INSN (insn))) == addr)
- reg_next_use[regno] = PREV_INSN (insn);
+ pbi->reg_next_use[regno] = PREV_INSN (insn);
else
- reg_next_use[regno] = 0;
+ pbi->reg_next_use[regno] = 0;
addr = q;
regno = REGNO (q);
- /* REGNO is now used in INCR which is below INSN, but
- it previously wasn't live here. If we don't mark
- it as needed, we'll put a REG_DEAD note for it
- on this insn, which is incorrect. */
- SET_REGNO_REG_SET (needed, regno);
+ /* REGNO is now used in INCR which is below INSN, but it
+ previously wasn't live here. If we don't mark it as
+ live, we'll put a REG_DEAD note for it on this insn,
+ which is incorrect. */
+ SET_REGNO_REG_SET (pbi->reg_live, regno);
/* If there are any calls between INSN and INCR, show
that REGNO now crosses them. */
@@ -4301,7 +4432,7 @@ find_auto_inc (needed, x, insn)
/* Count an extra reference to the reg. When a reg is
incremented, spilling it is worse, so we want to make
that less likely. */
- REG_N_REFS (regno) += loop_depth + 1;
+ REG_N_REFS (regno) += pbi->bb->loop_depth + 1;
/* Count the increment as a setting of the register,
even though it isn't a SET in rtl. */
@@ -4312,26 +4443,143 @@ find_auto_inc (needed, x, insn)
}
#endif /* AUTO_INC_DEC */
-/* Scan expression X and store a 1-bit in LIVE for each reg it uses.
- This is done assuming the registers needed from X
- are those that have 1-bits in NEEDED.
+static void
+mark_used_reg (pbi, new_live, reg, cond, insn)
+ struct propagate_block_info *pbi;
+ regset new_live;
+ rtx reg;
+ rtx cond ATTRIBUTE_UNUSED;
+ rtx insn;
+{
+ int regno = REGNO (reg);
+ int some_was_live = REGNO_REG_SET_P (pbi->reg_live, regno);
+ int some_was_dead = ! some_was_live;
- FLAGS is the set of enabled operations.
+ SET_REGNO_REG_SET (new_live, regno);
+
+ /* A hard reg in a wide mode may really be multiple registers.
+ If so, mark all of them just like the first. */
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ while (--n > 0)
+ {
+ int regno_n = regno + n;
+ int needed_regno = REGNO_REG_SET_P (pbi->reg_live, regno_n);
- INSN is the containing instruction. If INSN is dead, this function is not
- called. */
+ SET_REGNO_REG_SET (new_live, regno_n);
+ some_was_live |= needed_regno;
+ some_was_dead |= ! needed_regno;
+ }
+ }
+
+ if (pbi->flags & (PROP_LOG_LINKS | PROP_AUTOINC))
+ {
+ /* Record where each reg is used, so when the reg is set we know
+ the next insn that uses it. */
+ pbi->reg_next_use[regno] = insn;
+ }
+
+ if (pbi->flags & PROP_REG_INFO)
+ {
+ if (regno < FIRST_PSEUDO_REGISTER)
+ {
+ /* If this is a register we are going to try to eliminate,
+ don't mark it live here. If we are successful in
+ eliminating it, it need not be live unless it is used for
+ pseudos, in which case it will have been set live when it
+ was allocated to the pseudos. If the register will not
+ be eliminated, reload will set it live at that point.
+
+ Otherwise, record that this function uses this register. */
+
+ if (! TEST_HARD_REG_BIT (elim_reg_set, regno))
+ {
+ int n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ if (n == 0)
+ n = 1;
+ do
+ regs_ever_live[regno + --n] = 1;
+ while (n > 0);
+ }
+ }
+ else
+ {
+ /* Keep track of which basic block each reg appears in. */
+
+ register int blocknum = pbi->bb->index;
+ if (REG_BASIC_BLOCK (regno) == REG_BLOCK_UNKNOWN)
+ REG_BASIC_BLOCK (regno) = blocknum;
+ else if (REG_BASIC_BLOCK (regno) != blocknum)
+ REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
+
+ /* Count (weighted) number of uses of each reg. */
+ REG_N_REFS (regno) += pbi->bb->loop_depth + 1;
+ }
+ }
+
+ /* Record and count the insns in which a reg dies. If it is used in
+ this insn and was dead below the insn then it dies in this insn.
+ If it was set in this insn, we do not make a REG_DEAD note;
+ likewise if we already made such a note. */
+
+ if ((pbi->flags & PROP_DEATH_NOTES)
+ && some_was_dead
+ && ! dead_or_set_p (insn, reg))
+ {
+ int n;
+
+ /* Check for the case where the register dying partially
+ overlaps the register set by this insn. */
+ if (regno < FIRST_PSEUDO_REGISTER
+ && HARD_REGNO_NREGS (regno, GET_MODE (reg)) > 1)
+ {
+ n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
+ while (--n >= 0)
+ some_was_live |= dead_or_set_regno_p (insn, regno + n);
+ }
+
+ /* If none of the words in X is needed, make a REG_DEAD note.
+ Otherwise, we must make partial REG_DEAD notes. */
+ if (! some_was_live)
+ {
+ REG_NOTES (insn)
+ = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));
+ REG_N_DEATHS (regno)++;
+ }
+ else
+ {
+ /* Don't make a REG_DEAD note for a part of a register
+ that is set in the insn. */
+
+ n = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1;
+ for (; n >= regno; n--)
+ if (!REGNO_REG_SET_P (pbi->reg_live, n)
+ && ! dead_or_set_regno_p (insn, n))
+ REG_NOTES (insn)
+ = alloc_EXPR_LIST (REG_DEAD,
+ gen_rtx_REG (reg_raw_mode[n], n),
+ REG_NOTES (insn));
+ }
+ }
+}
+
+/* Scan expression X and store a 1-bit in NEW_LIVE for each reg it uses.
+ This is done assuming the registers needed from X are those that
+ have 1-bits in PBI->REG_LIVE.
+
+ INSN is the containing instruction. If INSN is dead, this function
+ is not called. */
static void
-mark_used_regs (needed, live, x, flags, insn)
- regset needed;
- regset live;
- rtx x;
- int flags;
- rtx insn;
+mark_used_regs (pbi, new_live, x, cond, insn)
+ struct propagate_block_info *pbi;
+ regset new_live;
+ rtx x, cond, insn;
{
register RTX_CODE code;
register int regno;
- int i;
+ int flags = pbi->flags;
retry:
code = GET_CODE (x);
@@ -4349,7 +4597,7 @@ mark_used_regs (needed, live, x, flags, insn)
#ifdef HAVE_cc0
case CC0:
- cc0_live = 1;
+ pbi->cc0_live = 1;
return;
#endif
@@ -4357,7 +4605,7 @@ mark_used_regs (needed, live, x, flags, insn)
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (GET_CODE (XEXP (x, 0)) == MEM)
- mark_used_regs (needed, live, XEXP (XEXP (x, 0), 0), flags, insn);
+ mark_used_regs (pbi, new_live, XEXP (XEXP (x, 0), 0), cond, insn);
return;
case MEM:
@@ -4372,7 +4620,7 @@ mark_used_regs (needed, live, x, flags, insn)
; /* needn't clear the memory set list */
else
{
- rtx temp = mem_set_list;
+ rtx temp = pbi->mem_set_list;
rtx prev = NULL_RTX;
rtx next;
@@ -4385,7 +4633,7 @@ mark_used_regs (needed, live, x, flags, insn)
if (prev)
XEXP (prev, 1) = next;
else
- mem_set_list = next;
+ pbi->mem_set_list = next;
free_EXPR_LIST_node (temp);
}
else
@@ -4398,12 +4646,12 @@ mark_used_regs (needed, live, x, flags, insn)
address modes. Then we may need to kill some entries on the
memory set list. */
if (insn)
- invalidate_mems_from_autoinc (insn);
+ invalidate_mems_from_autoinc (pbi, insn);
}
#ifdef AUTO_INC_DEC
if (flags & PROP_AUTOINC)
- find_auto_inc (needed, x, insn);
+ find_auto_inc (pbi, x, insn);
#endif
break;
@@ -4416,170 +4664,13 @@ mark_used_regs (needed, live, x, flags, insn)
/* While we're here, optimize this case. */
x = SUBREG_REG (x);
-
- /* In case the SUBREG is not of a register, don't optimize */
if (GET_CODE (x) != REG)
- {
- mark_used_regs (needed, live, x, flags, insn);
- return;
- }
-
- /* ... fall through ... */
+ goto retry;
+ /* FALLTHRU */
case REG:
- /* See a register other than being set
- => mark it as needed. */
-
- regno = REGNO (x);
- {
- int some_needed = REGNO_REG_SET_P (needed, regno);
- int some_not_needed = ! some_needed;
-
- SET_REGNO_REG_SET (live, regno);
-
- /* A hard reg in a wide mode may really be multiple registers.
- If so, mark all of them just like the first. */
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- int n;
-
- /* For stack ptr or fixed arg pointer,
- nothing below can be necessary, so waste no more time. */
- if (regno == STACK_POINTER_REGNUM
-#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
- || (regno == HARD_FRAME_POINTER_REGNUM
- && (! reload_completed || frame_pointer_needed))
-#endif
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
-#endif
- || (regno == FRAME_POINTER_REGNUM
- && (! reload_completed || frame_pointer_needed)))
- {
- /* If this is a register we are going to try to eliminate,
- don't mark it live here. If we are successful in
- eliminating it, it need not be live unless it is used for
- pseudos, in which case it will have been set live when
- it was allocated to the pseudos. If the register will not
- be eliminated, reload will set it live at that point. */
-
- if ((flags & PROP_REG_INFO)
- && ! TEST_HARD_REG_BIT (elim_reg_set, regno))
- regs_ever_live[regno] = 1;
- return;
- }
- /* No death notes for global register variables;
- their values are live after this function exits. */
- if (global_regs[regno])
- {
- if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- reg_next_use[regno] = insn;
- return;
- }
-
- n = HARD_REGNO_NREGS (regno, GET_MODE (x));
- while (--n > 0)
- {
- int regno_n = regno + n;
- int needed_regno = REGNO_REG_SET_P (needed, regno_n);
-
- SET_REGNO_REG_SET (live, regno_n);
- some_needed |= needed_regno;
- some_not_needed |= ! needed_regno;
- }
- }
-
- if (flags & (PROP_LOG_LINKS | PROP_AUTOINC))
- {
- /* Record where each reg is used, so when the reg
- is set we know the next insn that uses it. */
-
- reg_next_use[regno] = insn;
- }
- if (flags & PROP_REG_INFO)
- {
- if (regno < FIRST_PSEUDO_REGISTER)
- {
- /* If a hard reg is being used,
- record that this function does use it. */
-
- i = HARD_REGNO_NREGS (regno, GET_MODE (x));
- if (i == 0)
- i = 1;
- do
- regs_ever_live[regno + --i] = 1;
- while (i > 0);
- }
- else
- {
- /* Keep track of which basic block each reg appears in. */
-
- register int blocknum = BLOCK_NUM (insn);
-
- if (REG_BASIC_BLOCK (regno) == REG_BLOCK_UNKNOWN)
- REG_BASIC_BLOCK (regno) = blocknum;
- else if (REG_BASIC_BLOCK (regno) != blocknum)
- REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
-
- /* Count (weighted) number of uses of each reg. */
-
- REG_N_REFS (regno) += loop_depth + 1;
- }
- }
-
- /* Record and count the insns in which a reg dies.
- If it is used in this insn and was dead below the insn
- then it dies in this insn. If it was set in this insn,
- we do not make a REG_DEAD note; likewise if we already
- made such a note. */
-
- if (flags & PROP_DEATH_NOTES)
- {
- if (some_not_needed
- && ! dead_or_set_p (insn, x)
-#if 0
- && (regno >= FIRST_PSEUDO_REGISTER || ! fixed_regs[regno])
-#endif
- )
- {
- /* Check for the case where the register dying partially
- overlaps the register set by this insn. */
- if (regno < FIRST_PSEUDO_REGISTER
- && HARD_REGNO_NREGS (regno, GET_MODE (x)) > 1)
- {
- int n = HARD_REGNO_NREGS (regno, GET_MODE (x));
- while (--n >= 0)
- some_needed |= dead_or_set_regno_p (insn, regno + n);
- }
-
- /* If none of the words in X is needed, make a REG_DEAD
- note. Otherwise, we must make partial REG_DEAD notes. */
- if (! some_needed)
- {
- REG_NOTES (insn)
- = alloc_EXPR_LIST (REG_DEAD, x, REG_NOTES (insn));
- REG_N_DEATHS (regno)++;
- }
- else
- {
- int i;
-
- /* Don't make a REG_DEAD note for a part of a register
- that is set in the insn. */
-
- for (i = HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1;
- i >= 0; i--)
- if (!REGNO_REG_SET_P (needed, regno + i)
- && ! dead_or_set_regno_p (insn, regno + i))
- REG_NOTES (insn)
- = (alloc_EXPR_LIST
- (REG_DEAD, gen_rtx_REG (reg_raw_mode[regno + i],
- regno + i),
- REG_NOTES (insn)));
- }
- }
- }
- }
+ /* See a register other than being set => mark it as needed. */
+ mark_used_reg (pbi, new_live, x, cond, insn);
return;
case SET:
@@ -4593,10 +4684,10 @@ mark_used_regs (needed, live, x, flags, insn)
{
#ifdef AUTO_INC_DEC
if (flags & PROP_AUTOINC)
- find_auto_inc (needed, testreg, insn);
+ find_auto_inc (pbi, testreg, insn);
#endif
- mark_used_regs (needed, live, XEXP (testreg, 0), flags, insn);
- mark_used_regs (needed, live, SET_SRC (x), flags, insn);
+ mark_used_regs (pbi, new_live, XEXP (testreg, 0), cond, insn);
+ mark_used_regs (pbi, new_live, SET_SRC (x), cond, insn);
return;
}
@@ -4631,14 +4722,15 @@ mark_used_regs (needed, live, x, flags, insn)
testreg = XEXP (testreg, 0);
}
- /* If this is a store into a register,
- recursively scan the value being stored. */
+ /* If this is a store into a register, recursively scan the
+ value being stored. */
if ((GET_CODE (testreg) == PARALLEL
&& GET_MODE (testreg) == BLKmode)
|| (GET_CODE (testreg) == REG
- && (regno = REGNO (testreg), ! (regno == FRAME_POINTER_REGNUM
- && (! reload_completed || frame_pointer_needed)))
+ && (regno = REGNO (testreg),
+ ! (regno == FRAME_POINTER_REGNUM
+ && (! reload_completed || frame_pointer_needed)))
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
&& ! (regno == HARD_FRAME_POINTER_REGNUM
&& (! reload_completed || frame_pointer_needed))
@@ -4650,9 +4742,9 @@ mark_used_regs (needed, live, x, flags, insn)
/* We used to exclude global_regs here, but that seems wrong.
Storing in them is like storing in mem. */
{
- mark_used_regs (needed, live, SET_SRC (x), flags, insn);
+ mark_used_regs (pbi, new_live, SET_SRC (x), cond, insn);
if (mark_dest)
- mark_used_regs (needed, live, SET_DEST (x), flags, insn);
+ mark_used_regs (pbi, new_live, SET_DEST (x), cond, insn);
return;
}
}
@@ -4678,7 +4770,7 @@ mark_used_regs (needed, live, x, flags, insn)
So for now, just clear the memory set list and mark any regs
we can find in ASM_OPERANDS as used. */
if (code != ASM_OPERANDS || MEM_VOLATILE_P (x))
- free_EXPR_LIST_list (&mem_set_list);
+ free_EXPR_LIST_list (&pbi->mem_set_list);
/* For all ASM_OPERANDS, we must traverse the vector of input operands.
We can not just fall through here since then we would be confused
@@ -4689,12 +4781,29 @@ mark_used_regs (needed, live, x, flags, insn)
int j;
for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
- mark_used_regs (needed, live, ASM_OPERANDS_INPUT (x, j),
- flags, insn);
+ mark_used_regs (pbi, new_live, ASM_OPERANDS_INPUT (x, j),
+ cond, insn);
}
break;
}
+ case COND_EXEC:
+ if (cond != NULL_RTX)
+ abort ();
+
+ mark_used_regs (pbi, new_live, COND_EXEC_TEST (x), NULL_RTX, insn);
+
+ cond = COND_EXEC_TEST (x);
+ x = COND_EXEC_CODE (x);
+ goto retry;
+
+ case PHI:
+ /* We _do_not_ want to scan operands of phi nodes. Operands of
+ a phi function are evaluated only when control reaches this
+ block along a particular edge. Therefore, regs that appear
+ as arguments to phi should not be added to the global live at
+ start. */
+ return;
default:
break;
@@ -4716,13 +4825,13 @@ mark_used_regs (needed, live, x, flags, insn)
x = XEXP (x, 0);
goto retry;
}
- mark_used_regs (needed, live, XEXP (x, i), flags, insn);
+ mark_used_regs (pbi, new_live, XEXP (x, i), cond, insn);
}
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
- mark_used_regs (needed, live, XVECEXP (x, i, j), flags, insn);
+ mark_used_regs (pbi, new_live, XVECEXP (x, i, j), cond, insn);
}
}
}
@@ -4731,7 +4840,8 @@ mark_used_regs (needed, live, x, flags, insn)
#ifdef AUTO_INC_DEC
static int
-try_pre_increment_1 (insn)
+try_pre_increment_1 (pbi, insn)
+ struct propagate_block_info *pbi;
rtx insn;
{
/* Find the next use of this reg. If in same basic block,
@@ -4740,7 +4850,7 @@ try_pre_increment_1 (insn)
HOST_WIDE_INT amount = ((GET_CODE (SET_SRC (x)) == PLUS ? 1 : -1)
* INTVAL (XEXP (SET_SRC (x), 1)));
int regno = REGNO (SET_DEST (x));
- rtx y = reg_next_use[regno];
+ rtx y = pbi->reg_next_use[regno];
if (y != 0
&& BLOCK_NUM (y) == BLOCK_NUM (insn)
/* Don't do this if the reg dies, or gets set in y; a standard addressing
@@ -4760,7 +4870,7 @@ try_pre_increment_1 (insn)
less likely. */
if (regno >= FIRST_PSEUDO_REGISTER)
{
- REG_N_REFS (regno) += loop_depth + 1;
+ REG_N_REFS (regno) += pbi->bb->loop_depth + 1;
REG_N_SETS (regno)++;
}
return 1;
@@ -5081,7 +5191,7 @@ dump_bb (bb, outf)
edge e;
fprintf (outf, ";; Basic block %d, loop depth %d",
- bb->index, bb->loop_depth - 1);
+ bb->index, bb->loop_depth);
if (bb->eh_beg != -1 || bb->eh_end != -1)
fprintf (outf, ", eh regions %d/%d", bb->eh_beg, bb->eh_end);
putc ('\n', outf);
@@ -5190,7 +5300,12 @@ print_rtl_with_bb (outf, rtx_first)
did_output = print_rtl_single (outf, tmp_rtx);
if ((bb = end[INSN_UID (tmp_rtx)]) != NULL)
- fprintf (outf, ";; End of basic block %d\n", bb->index);
+ {
+ fprintf (outf, ";; End of basic block %d, registers live:\n",
+ bb->index);
+ dump_regset (bb->global_live_at_end, outf);
+ putc ('\n', outf);
+ }
if (did_output)
putc ('\n', outf);
@@ -5219,13 +5334,14 @@ compute_flow_dominators (dominators, post_dominators)
int bb;
sbitmap *temp_bitmap;
edge e;
- basic_block *worklist, *tos;
+ basic_block *worklist, *workend, *qin, *qout;
+ int qlen;
/* Allocate a worklist array/queue. Entries are only added to the
list if they were not already on the list. So the size is
bounded by the number of basic blocks. */
- tos = worklist = (basic_block *) xmalloc (sizeof (basic_block)
- * n_basic_blocks);
+ worklist = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
+ workend = &worklist[n_basic_blocks];
temp_bitmap = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
sbitmap_vector_zero (temp_bitmap, n_basic_blocks);
@@ -5234,11 +5350,14 @@ compute_flow_dominators (dominators, post_dominators)
{
/* The optimistic setting of dominators requires us to put every
block on the work list initially. */
+ qin = qout = worklist;
for (bb = 0; bb < n_basic_blocks; bb++)
{
- *tos++ = BASIC_BLOCK (bb);
+ *qin++ = BASIC_BLOCK (bb);
BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
}
+ qlen = n_basic_blocks;
+ qin = worklist;
/* We want a maximal solution, so initially assume everything dominates
everything else. */
@@ -5249,10 +5368,14 @@ compute_flow_dominators (dominators, post_dominators)
e->dest->aux = ENTRY_BLOCK_PTR;
/* Iterate until the worklist is empty. */
- while (tos != worklist)
+ while (qlen)
{
/* Take the first entry off the worklist. */
- basic_block b = *--tos;
+ basic_block b = *qout++;
+ if (qout >= workend)
+ qout = worklist;
+ qlen--;
+
bb = b->index;
/* Compute the intersection of the dominators of all the
@@ -5292,7 +5415,11 @@ compute_flow_dominators (dominators, post_dominators)
{
if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR)
{
- *tos++ = e->dest;
+ *qin++ = e->dest;
+ if (qin >= workend)
+ qin = worklist;
+ qlen++;
+
e->dest->aux = e;
}
}
@@ -5304,11 +5431,14 @@ compute_flow_dominators (dominators, post_dominators)
{
/* The optimistic setting of dominators requires us to put every
block on the work list initially. */
+ qin = qout = worklist;
for (bb = 0; bb < n_basic_blocks; bb++)
{
- *tos++ = BASIC_BLOCK (bb);
+ *qin++ = BASIC_BLOCK (bb);
BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
}
+ qlen = n_basic_blocks;
+ qin = worklist;
/* We want a maximal solution, so initially assume everything post
dominates everything else. */
@@ -5319,10 +5449,14 @@ compute_flow_dominators (dominators, post_dominators)
e->src->aux = EXIT_BLOCK_PTR;
/* Iterate until the worklist is empty. */
- while (tos != worklist)
+ while (qlen)
{
/* Take the first entry off the worklist. */
- basic_block b = *--tos;
+ basic_block b = *qout++;
+ if (qout >= workend)
+ qout = worklist;
+ qlen--;
+
bb = b->index;
/* Compute the intersection of the post dominators of all the
@@ -5365,13 +5499,19 @@ compute_flow_dominators (dominators, post_dominators)
{
if (!e->src->aux && e->src != ENTRY_BLOCK_PTR)
{
- *tos++ = e->src;
+ *qin++ = e->src;
+ if (qin >= workend)
+ qin = worklist;
+ qlen++;
+
e->src->aux = e;
}
}
}
}
}
+
+ free (worklist);
free (temp_bitmap);
}
@@ -5418,8 +5558,9 @@ compute_immediate_dominators (idom, dominators)
/* Count for a single SET rtx, X. */
static void
-count_reg_sets_1 (x)
+count_reg_sets_1 (x, loop_depth)
rtx x;
+ int loop_depth;
{
register int regno;
register rtx reg = SET_DEST (x);
@@ -5435,7 +5576,7 @@ count_reg_sets_1 (x)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
- count_reg_sets_1 (XVECEXP (reg, 0, i));
+ count_reg_sets_1 (XVECEXP (reg, 0, i), loop_depth);
return;
}
@@ -5456,13 +5597,14 @@ count_reg_sets_1 (x)
REG_N_REFS by the current loop depth for each SET or CLOBBER found. */
static void
-count_reg_sets (x)
+count_reg_sets (x, loop_depth)
rtx x;
+ int loop_depth;
{
register RTX_CODE code = GET_CODE (x);
if (code == SET || code == CLOBBER)
- count_reg_sets_1 (x);
+ count_reg_sets_1 (x, loop_depth);
else if (code == PARALLEL)
{
register int i;
@@ -5470,7 +5612,7 @@ count_reg_sets (x)
{
code = GET_CODE (XVECEXP (x, 0, i));
if (code == SET || code == CLOBBER)
- count_reg_sets_1 (XVECEXP (x, 0, i));
+ count_reg_sets_1 (XVECEXP (x, 0, i), loop_depth);
}
}
}
@@ -5479,8 +5621,9 @@ count_reg_sets (x)
found in X. */
static void
-count_reg_references (x)
+count_reg_references (x, loop_depth)
rtx x;
+ int loop_depth;
{
register RTX_CODE code;
@@ -5508,7 +5651,7 @@ count_reg_references (x)
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (GET_CODE (XEXP (x, 0)) == MEM)
- count_reg_references (XEXP (XEXP (x, 0), 0));
+ count_reg_references (XEXP (XEXP (x, 0), 0), loop_depth);
return;
case SUBREG:
@@ -5518,7 +5661,7 @@ count_reg_references (x)
/* In case the SUBREG is not of a register, don't optimize */
if (GET_CODE (x) != REG)
{
- count_reg_references (x);
+ count_reg_references (x, loop_depth);
return;
}
@@ -5538,8 +5681,8 @@ count_reg_references (x)
show the address as being used. */
if (GET_CODE (testreg) == MEM)
{
- count_reg_references (XEXP (testreg, 0));
- count_reg_references (SET_SRC (x));
+ count_reg_references (XEXP (testreg, 0), loop_depth);
+ count_reg_references (SET_SRC (x), loop_depth);
return;
}
@@ -5574,9 +5717,9 @@ count_reg_references (x)
&& GET_MODE (testreg) == BLKmode)
|| GET_CODE (testreg) == REG)
{
- count_reg_references (SET_SRC (x));
+ count_reg_references (SET_SRC (x), loop_depth);
if (mark_dest)
- count_reg_references (SET_DEST (x));
+ count_reg_references (SET_DEST (x), loop_depth);
return;
}
}
@@ -5602,13 +5745,13 @@ count_reg_references (x)
x = XEXP (x, 0);
goto retry;
}
- count_reg_references (XEXP (x, i));
+ count_reg_references (XEXP (x, i), loop_depth);
}
else if (fmt[i] == 'E')
{
register int j;
for (j = 0; j < XVECLEN (x, i); j++)
- count_reg_references (XVECEXP (x, i, j));
+ count_reg_references (XVECEXP (x, i, j), loop_depth);
}
}
}
@@ -5641,6 +5784,7 @@ recompute_reg_usage (f, loop_step)
rtx insn;
int i, max_reg;
int index;
+ int loop_depth;
/* Clear out the old data. */
max_reg = max_reg_num ();
@@ -5665,21 +5809,22 @@ recompute_reg_usage (f, loop_step)
/* This call will increment REG_N_SETS for each SET or CLOBBER
of a register in INSN. It will also increment REG_N_REFS
by the loop depth for each set of a register in INSN. */
- count_reg_sets (PATTERN (insn));
+ count_reg_sets (PATTERN (insn), loop_depth);
/* count_reg_sets does not detect autoincrement address modes, so
detect them here by looking at the notes attached to INSN. */
for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
{
if (REG_NOTE_KIND (links) == REG_INC)
- /* Count (weighted) references, stores, etc. This counts a
- register twice if it is modified, but that is correct. */
+ /* Count (weighted) references, stores, etc. This
+ counts a register twice if it is modified, but
+ that is correct. */
REG_N_SETS (REGNO (XEXP (links, 0)))++;
}
- /* This call will increment REG_N_REFS by the current loop depth for
- each reference to a register in INSN. */
- count_reg_references (PATTERN (insn));
+ /* This call will increment REG_N_REFS by the current loop depth
+ for each reference to a register in INSN. */
+ count_reg_references (PATTERN (insn), loop_depth);
/* count_reg_references will not include counts for arguments to
function calls, so detect them here by examining the
@@ -5692,7 +5837,8 @@ recompute_reg_usage (f, loop_step)
note;
note = XEXP (note, 1))
if (GET_CODE (XEXP (note, 0)) == USE)
- count_reg_references (XEXP (XEXP (note, 0), 0));
+ count_reg_references (XEXP (XEXP (note, 0), 0),
+ loop_depth);
}
}
if (insn == bb->end)
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0f38f7f1339..19b2f703201 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -80,7 +80,8 @@ static tree distribute_bit_expr PARAMS ((enum tree_code, tree, tree, tree));
static tree make_bit_field_ref PARAMS ((tree, tree, int, int, int));
static tree optimize_bit_field_compare PARAMS ((enum tree_code, tree,
tree, tree));
-static tree decode_field_reference PARAMS ((tree, int *, int *,
+static tree decode_field_reference PARAMS ((tree, HOST_WIDE_INT *,
+ HOST_WIDE_INT *,
enum machine_mode *, int *,
int *, tree *, tree *));
static int all_ones_mask_p PARAMS ((tree, int));
@@ -1491,18 +1492,15 @@ int_const_binop (code, arg1, arg2, notrunc, forsize)
/* It's unclear from the C standard whether shifts can overflow.
The following code ignores overflow; perhaps a C standard
interpretation ruling is needed. */
- lshift_double (int1l, int1h, int2l,
- TYPE_PRECISION (TREE_TYPE (arg1)),
- &low, &hi,
- !uns);
+ lshift_double (int1l, int1h, int2l, TYPE_PRECISION (TREE_TYPE (arg1)),
+ &low, &hi, !uns);
no_overflow = 1;
break;
case RROTATE_EXPR:
int2l = - int2l;
case LROTATE_EXPR:
- lrotate_double (int1l, int1h, int2l,
- TYPE_PRECISION (TREE_TYPE (arg1)),
+ lrotate_double (int1l, int1h, int2l, TYPE_PRECISION (TREE_TYPE (arg1)),
&low, &hi);
break;
@@ -1599,7 +1597,7 @@ int_const_binop (code, arg1, arg2, notrunc, forsize)
abort ();
}
- if (forsize && hi == 0 && low < 1000)
+ if (forsize && hi == 0 && low < 10000)
return size_int_type_wide (low, TREE_TYPE (arg1));
else
{
@@ -1850,7 +1848,7 @@ size_int_type_wide (number, type)
tree type;
{
/* Type-size nodes already made for small sizes. */
- static tree size_table[2 * HOST_BITS_PER_WIDE_INT + 1];
+ static tree size_table[2048 + 1];
static int init_p = 0;
tree t;
@@ -1864,8 +1862,7 @@ size_int_type_wide (number, type)
/* If this is a positive number that fits in the table we use to hold
cached entries, see if it is already in the table and put it there
if not. */
- if (number >= 0
- && number < (int) (sizeof size_table / sizeof size_table[0]) / 2)
+ if (number >= 0 && number < (int) (sizeof size_table / sizeof size_table[0]))
{
if (size_table[number] != 0)
for (t = size_table[number]; t != 0; t = TREE_CHAIN (t))
@@ -2021,7 +2018,7 @@ fold_convert (t, arg1)
/* If we are trying to make a sizetype for a small integer, use
size_int to pick up cached types to reduce duplicate nodes. */
if (TREE_CODE (type) == INTEGER_CST && TYPE_IS_SIZETYPE (type)
- && compare_tree_int (arg1, 1000) < 0)
+ && compare_tree_int (arg1, 10000) < 0)
return size_int_type_wide (TREE_INT_CST_LOW (arg1), type);
/* Given an integer constant, make new constant with new type,
@@ -2432,7 +2429,7 @@ operand_equal_for_comparison_p (arg0, arg1, other)
{
int unsignedp1, unsignedpo;
tree primarg0, primarg1, primother;
- unsigned correct_width;
+ unsigned int correct_width;
if (operand_equal_p (arg0, arg1, 0))
return 1;
@@ -2909,14 +2906,14 @@ optimize_bit_field_compare (code, compare_type, lhs, rhs)
tree compare_type;
tree lhs, rhs;
{
- int lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
+ HOST_WIDE_INT lbitpos, lbitsize, rbitpos, rbitsize, nbitpos, nbitsize;
tree type = TREE_TYPE (lhs);
tree signed_type, unsigned_type;
int const_p = TREE_CODE (rhs) == INTEGER_CST;
enum machine_mode lmode, rmode, nmode;
int lunsignedp, runsignedp;
int lvolatilep = 0, rvolatilep = 0;
- int alignment;
+ unsigned int alignment;
tree linner, rinner = NULL_TREE;
tree mask;
tree offset;
@@ -3085,7 +3082,7 @@ static tree
decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
pvolatilep, pmask, pand_mask)
tree exp;
- int *pbitsize, *pbitpos;
+ HOST_WIDE_INT *pbitsize, *pbitpos;
enum machine_mode *pmode;
int *punsignedp, *pvolatilep;
tree *pmask;
@@ -3094,8 +3091,8 @@ decode_field_reference (exp, pbitsize, pbitpos, pmode, punsignedp,
tree and_mask = 0;
tree mask, inner, offset;
tree unsigned_type;
- int precision;
- int alignment;
+ unsigned int precision;
+ unsigned int alignment;
/* All the optimizations using this function assume integer fields.
There are problems with FP fields since the type_for_size call
@@ -3151,7 +3148,7 @@ all_ones_mask_p (mask, size)
int size;
{
tree type = TREE_TYPE (mask);
- int precision = TYPE_PRECISION (type);
+ unsigned int precision = TYPE_PRECISION (type);
tree tmask;
tmask = build_int_2 (~0, ~0);
@@ -3893,10 +3890,10 @@ fold_truthop (code, truth_type, lhs, rhs)
enum tree_code lcode, rcode;
tree ll_arg, lr_arg, rl_arg, rr_arg;
tree ll_inner, lr_inner, rl_inner, rr_inner;
- int ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
- int rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
- int xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
- int lnbitsize, lnbitpos, rnbitsize, rnbitpos;
+ HOST_WIDE_INT ll_bitsize, ll_bitpos, lr_bitsize, lr_bitpos;
+ HOST_WIDE_INT rl_bitsize, rl_bitpos, rr_bitsize, rr_bitpos;
+ HOST_WIDE_INT xll_bitpos, xlr_bitpos, xrl_bitpos, xrr_bitpos;
+ HOST_WIDE_INT lnbitsize, lnbitpos, rnbitsize, rnbitpos;
int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
enum machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
enum machine_mode lnmode, rnmode;
@@ -4737,10 +4734,8 @@ fold (expr)
STRIP_SIGN_NOPS (op);
}
else
- {
- /* Strip any conversions that don't change the mode. */
- STRIP_NOPS (op);
- }
+ /* Strip any conversions that don't change the mode. */
+ STRIP_NOPS (op);
if (TREE_CODE (op) == COMPLEX_CST)
subop = TREE_REALPART (op);
@@ -5042,17 +5037,17 @@ fold (expr)
int inside_int = INTEGRAL_TYPE_P (inside_type);
int inside_ptr = POINTER_TYPE_P (inside_type);
int inside_float = FLOAT_TYPE_P (inside_type);
- int inside_prec = TYPE_PRECISION (inside_type);
+ unsigned int inside_prec = TYPE_PRECISION (inside_type);
int inside_unsignedp = TREE_UNSIGNED (inside_type);
int inter_int = INTEGRAL_TYPE_P (inter_type);
int inter_ptr = POINTER_TYPE_P (inter_type);
int inter_float = FLOAT_TYPE_P (inter_type);
- int inter_prec = TYPE_PRECISION (inter_type);
+ unsigned int inter_prec = TYPE_PRECISION (inter_type);
int inter_unsignedp = TREE_UNSIGNED (inter_type);
int final_int = INTEGRAL_TYPE_P (final_type);
int final_ptr = POINTER_TYPE_P (final_type);
int final_float = FLOAT_TYPE_P (final_type);
- int final_prec = TYPE_PRECISION (final_type);
+ unsigned int final_prec = TYPE_PRECISION (final_type);
int final_unsignedp = TREE_UNSIGNED (final_type);
/* In addition to the cases of two conversions in a row
@@ -5229,7 +5224,7 @@ fold (expr)
case CONJ_EXPR:
if (TREE_CODE (TREE_TYPE (arg0)) != COMPLEX_TYPE)
- return arg0;
+ return convert (type, arg0);
else if (TREE_CODE (arg0) == COMPLEX_EXPR)
return build (COMPLEX_EXPR, type,
TREE_OPERAND (arg0, 0),
@@ -5690,7 +5685,9 @@ fold (expr)
if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == NOP_EXPR
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg1, 0))))
{
- int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
+ unsigned int prec
+ = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)));
+
if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
&& (~TREE_INT_CST_LOW (arg0)
& (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
@@ -5699,7 +5696,9 @@ fold (expr)
if (TREE_CODE (arg1) == INTEGER_CST && TREE_CODE (arg0) == NOP_EXPR
&& TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (arg0, 0))))
{
- int prec = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
+ unsigned int prec
+ = TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg0, 0)));
+
if (prec < BITS_PER_WORD && prec < HOST_BITS_PER_WIDE_INT
&& (~TREE_INT_CST_LOW (arg1)
& (((HOST_WIDE_INT) 1 << prec) - 1)) == 0)
@@ -5880,7 +5879,7 @@ fold (expr)
case MIN_EXPR:
if (operand_equal_p (arg0, arg1, 0))
- return arg0;
+ return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
&& operand_equal_p (arg1, TYPE_MIN_VALUE (type), 1))
return omit_one_operand (type, arg1, arg0);
@@ -5888,7 +5887,7 @@ fold (expr)
case MAX_EXPR:
if (operand_equal_p (arg0, arg1, 0))
- return arg0;
+ return omit_one_operand (type, arg0, arg1);
if (INTEGRAL_TYPE_P (type)
&& TYPE_MAX_VALUE (type)
&& operand_equal_p (arg1, TYPE_MAX_VALUE (type), 1))
@@ -5912,13 +5911,13 @@ fold (expr)
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant zero, return it. */
if (integer_zerop (arg0))
- return arg0;
+ return convert (type, arg0);
case TRUTH_AND_EXPR:
/* If either arg is constant true, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If second arg is constant zero, result is zero, but first arg
must be evaluated. */
if (integer_zerop (arg1))
@@ -5998,13 +5997,13 @@ fold (expr)
("true" is a fixed value perhaps depending on the language.) */
/* If first arg is constant true, return it. */
if (TREE_CODE (arg0) == INTEGER_CST && ! integer_zerop (arg0))
- return arg0;
+ return convert (type, arg0);
case TRUTH_OR_EXPR:
/* If either arg is constant zero, drop it. */
if (TREE_CODE (arg0) == INTEGER_CST && integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (TREE_CODE (arg1) == INTEGER_CST && integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If second arg is constant true, result is true, but we must
evaluate first arg. */
if (TREE_CODE (arg1) == INTEGER_CST && ! integer_zerop (arg1))
@@ -6018,14 +6017,14 @@ fold (expr)
case TRUTH_XOR_EXPR:
/* If either arg is constant zero, drop it. */
if (integer_zerop (arg0))
- return non_lvalue (arg1);
+ return non_lvalue (convert (type, arg1));
if (integer_zerop (arg1))
- return non_lvalue (arg0);
+ return non_lvalue (convert (type, arg0));
/* If either arg is constant true, this is a logical inversion. */
if (integer_onep (arg0))
- return non_lvalue (invert_truthvalue (arg1));
+ return non_lvalue (convert (type, invert_truthvalue (arg1)));
if (integer_onep (arg1))
- return non_lvalue (invert_truthvalue (arg0));
+ return non_lvalue (convert (type, invert_truthvalue (arg0)));
return t;
case EQ_EXPR:
@@ -6108,7 +6107,7 @@ fold (expr)
(TREE_OPERAND
(TREE_OPERAND (varop, 0), 1)));
tree mask, unsigned_type;
- int precision;
+ unsigned int precision;
tree folded_compare;
/* First check whether the comparison would come out
@@ -6165,7 +6164,7 @@ fold (expr)
(TREE_OPERAND
(TREE_OPERAND (varop, 0), 1)));
tree mask, unsigned_type;
- int precision;
+ unsigned int precision;
tree folded_compare;
if (constopnum == 0)
@@ -7021,8 +7020,8 @@ fold (expr)
return t;
/* Don't let (0, 0) be null pointer constant. */
if (integer_zerop (arg1))
- return build1 (NOP_EXPR, TREE_TYPE (arg1), arg1);
- return arg1;
+ return build1 (NOP_EXPR, type, arg1);
+ return convert (type, arg1);
case COMPLEX_EXPR:
if (wins)
diff --git a/gcc/function.c b/gcc/function.c
index 60535922c4b..b17f360cd77 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -61,6 +61,10 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "tm_p.h"
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
#ifndef TRAMPOLINE_ALIGNMENT
#define TRAMPOLINE_ALIGNMENT FUNCTION_BOUNDARY
#endif
@@ -247,7 +251,8 @@ static rtx assign_stack_temp_for_type PARAMS ((enum machine_mode,
static struct temp_slot *find_temp_slot_from_address PARAMS ((rtx));
static void put_reg_into_stack PARAMS ((struct function *, rtx, tree,
enum machine_mode, enum machine_mode,
- int, int, int, struct hash_table *));
+ int, unsigned int, int,
+ struct hash_table *));
static void fixup_var_refs PARAMS ((rtx, enum machine_mode, int,
struct hash_table *));
static struct fixup_replacement
@@ -262,7 +267,7 @@ static rtx fixup_stack_1 PARAMS ((rtx, rtx));
static void optimize_bit_field PARAMS ((rtx, rtx, rtx *));
static void instantiate_decls PARAMS ((tree, int));
static void instantiate_decls_1 PARAMS ((tree, int));
-static void instantiate_decl PARAMS ((rtx, int, int));
+static void instantiate_decl PARAMS ((rtx, HOST_WIDE_INT, int));
static int instantiate_virtual_regs_1 PARAMS ((rtx *, rtx, int));
static void delete_handlers PARAMS ((void));
static void pad_to_arg_alignment PARAMS ((struct args_size *, int,
@@ -440,6 +445,9 @@ void
free_after_compilation (f)
struct function *f;
{
+ struct temp_slot *ts;
+ struct temp_slot *next;
+
free_eh_status (f);
free_expr_status (f);
free_emit_status (f);
@@ -451,6 +459,13 @@ free_after_compilation (f)
if (f->x_parm_reg_stack_loc)
free (f->x_parm_reg_stack_loc);
+ for (ts = f->x_temp_slots; ts; ts = next)
+ {
+ next = ts->next;
+ free (ts);
+ }
+ f->x_temp_slots = NULL;
+
f->arg_offset_rtx = NULL;
f->return_rtx = NULL;
f->internal_arg_pointer = NULL;
@@ -471,7 +486,6 @@ free_after_compilation (f)
f->x_parm_birth_insn = NULL;
f->x_last_parm_insn = NULL;
f->x_parm_reg_stack_loc = NULL;
- f->x_temp_slots = NULL;
f->fixup_var_refs_queue = NULL;
f->original_arg_vector = NULL;
f->original_decl_initial = NULL;
@@ -709,7 +723,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
if (best_p->size - rounded_size >= alignment)
{
- p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
+ p = (struct temp_slot *) xmalloc (sizeof (struct temp_slot));
p->in_use = p->addr_taken = 0;
p->size = best_p->size - rounded_size;
p->base_offset = best_p->base_offset + rounded_size;
@@ -739,7 +753,7 @@ assign_stack_temp_for_type (mode, size, keep, type)
{
HOST_WIDE_INT frame_offset_old = frame_offset;
- p = (struct temp_slot *) oballoc (sizeof (struct temp_slot));
+ p = (struct temp_slot *) xmalloc (sizeof (struct temp_slot));
/* We are passing an explicit alignment request to assign_stack_local.
One side effect of that is assign_stack_local will not round SIZE
@@ -930,7 +944,10 @@ combine_temp_slots ()
}
/* Either delete Q or advance past it. */
if (delete_q)
- prev_q->next = q->next;
+ {
+ prev_q->next = q->next;
+ free (q);
+ }
else
prev_q = q;
}
@@ -1451,19 +1468,20 @@ put_reg_into_stack (function, reg, type, promoted_mode, decl_mode, volatile_p,
tree type;
enum machine_mode promoted_mode, decl_mode;
int volatile_p;
- int original_regno;
+ unsigned int original_regno;
int used_p;
struct hash_table *ht;
{
struct function *func = function ? function : cfun;
rtx new = 0;
- int regno = original_regno;
+ unsigned int regno = original_regno;
if (regno == 0)
regno = REGNO (reg);
if (regno < func->x_max_parm_reg)
new = func->x_parm_reg_stack_loc[regno];
+
if (new == 0)
new = assign_stack_local_1 (decl_mode, GET_MODE_SIZE (decl_mode), 0, func);
@@ -2736,7 +2754,6 @@ static int cfa_offset;
#ifndef STACK_DYNAMIC_OFFSET
-#ifdef ACCUMULATE_OUTGOING_ARGS
/* The bottom of the stack points to the actual arguments. If
REG_PARM_STACK_SPACE is defined, this includes the space for the register
parameters. However, if OUTGOING_REG_PARM_STACK space is not defined,
@@ -2747,16 +2764,14 @@ static int cfa_offset;
#if defined(REG_PARM_STACK_SPACE) && ! defined(OUTGOING_REG_PARM_STACK_SPACE)
#define STACK_DYNAMIC_OFFSET(FNDECL) \
-(current_function_outgoing_args_size \
- + REG_PARM_STACK_SPACE (FNDECL) + (STACK_POINTER_OFFSET))
+((ACCUMULATE_OUTGOING_ARGS \
+ ? (current_function_outgoing_args_size + REG_PARM_STACK_SPACE (FNDECL)) : 0)\
+ + (STACK_POINTER_OFFSET)) \
#else
#define STACK_DYNAMIC_OFFSET(FNDECL) \
-(current_function_outgoing_args_size + (STACK_POINTER_OFFSET))
-#endif
-
-#else
-#define STACK_DYNAMIC_OFFSET(FNDECL) STACK_POINTER_OFFSET
+((ACCUMULATE_OUTGOING_ARGS ? current_function_outgoing_args_size : 0) \
+ + (STACK_POINTER_OFFSET))
#endif
#endif
@@ -2801,7 +2816,6 @@ gen_mem_addressof (reg, decl)
/* If DECL has an RTL that is an ADDRESSOF rtx, put it into the stack. */
-#if 0
void
flush_addressof (decl)
tree decl;
@@ -2813,7 +2827,6 @@ flush_addressof (decl)
&& GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == REG)
put_addressof_into_stack (XEXP (DECL_RTL (decl), 0), 0);
}
-#endif
/* Force the register pointed to by R, an ADDRESSOF rtx, into the stack. */
@@ -3026,7 +3039,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
start_sequence ();
store_bit_field (sub, size_x, 0, GET_MODE (x),
val, GET_MODE_SIZE (GET_MODE (sub)),
- GET_MODE_SIZE (GET_MODE (sub)));
+ GET_MODE_ALIGNMENT (GET_MODE (sub)));
/* Make sure to unshare any shared rtl that store_bit_field
might have created. */
@@ -3273,7 +3286,7 @@ purge_addressof (insns)
/* When we actually purge ADDRESSOFs, we turn REGs into MEMs. That
requires a fixup pass over the instruction stream to correct
INSNs that depended on the REG being a REG, and not a MEM. But,
- these fixup passes are slow. Furthermore, more MEMs are not
+ these fixup passes are slow. Furthermore, most MEMs are not
mentioned in very many instructions. So, we speed up the process
by pre-calculating which REGs occur in which INSNs; that allows
us to perform the fixup passes much more quickly. */
@@ -3328,7 +3341,7 @@ instantiate_virtual_regs (fndecl, insns)
rtx insns;
{
rtx insn;
- int i;
+ unsigned int i;
/* Compute the offsets to use for this function. */
in_arg_offset = FIRST_PARM_OFFSET (fndecl);
@@ -3446,7 +3459,7 @@ instantiate_decls_1 (let, valid_only)
static void
instantiate_decl (x, size, valid_only)
rtx x;
- int size;
+ HOST_WIDE_INT size;
int valid_only;
{
enum machine_mode mode;
@@ -3476,21 +3489,23 @@ instantiate_decl (x, size, valid_only)
instantiate_virtual_regs_1 (&addr, NULL_RTX, 0);
- if (valid_only)
+ if (valid_only && size >= 0)
{
+ unsigned HOST_WIDE_INT decl_size = size;
+
/* Now verify that the resulting address is valid for every integer or
floating-point mode up to and including SIZE bytes long. We do this
since the object might be accessed in any mode and frame addresses
are shared. */
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
- mode != VOIDmode && GET_MODE_SIZE (mode) <= size;
+ mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
mode = GET_MODE_WIDER_MODE (mode))
if (! memory_address_p (mode, addr))
return;
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
- mode != VOIDmode && GET_MODE_SIZE (mode) <= size;
+ mode != VOIDmode && GET_MODE_SIZE (mode) <= decl_size;
mode = GET_MODE_WIDER_MODE (mode))
if (! memory_address_p (mode, addr))
return;
@@ -4336,8 +4351,8 @@ assign_parms (fndecl)
if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm,
int_size_in_bytes (TREE_TYPE (parm)),
- (TYPE_ALIGN (TREE_TYPE (parm))
- / BITS_PER_UNIT));
+ TYPE_ALIGN (TREE_TYPE (parm)));
+
else
move_block_from_reg (REGNO (entry_parm),
validize_mem (stack_parm), nregs,
@@ -4495,8 +4510,7 @@ assign_parms (fndecl)
if (GET_CODE (entry_parm) == PARALLEL)
emit_group_store (validize_mem (stack_parm), entry_parm,
int_size_in_bytes (TREE_TYPE (parm)),
- (TYPE_ALIGN (TREE_TYPE (parm))
- / BITS_PER_UNIT));
+ TYPE_ALIGN (TREE_TYPE (parm)));
else
move_block_from_reg (REGNO (entry_parm),
validize_mem (stack_parm),
@@ -4523,7 +4537,7 @@ assign_parms (fndecl)
may need to do it in a wider mode. */
register rtx parmreg;
- int regno, regnoi = 0, regnor = 0;
+ unsigned int regno, regnoi = 0, regnor = 0;
unsignedp = TREE_UNSIGNED (TREE_TYPE (parm));
@@ -4761,8 +4775,8 @@ assign_parms (fndecl)
/* For pointer data type, suggest pointer register. */
if (POINTER_TYPE_P (TREE_TYPE (parm)))
mark_reg_pointer (parmreg,
- (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm)))
- / BITS_PER_UNIT));
+ TYPE_ALIGN (TREE_TYPE (TREE_TYPE (parm))));
+
}
else
{
@@ -4917,7 +4931,7 @@ assign_parms (fndecl)
rtx
promoted_input_arg (regno, pmode, punsignedp)
- int regno;
+ unsigned int regno;
enum machine_mode *pmode;
int *punsignedp;
{
@@ -6439,7 +6453,7 @@ expand_function_end (filename, line, end_bindings)
blktramp = change_address (initial_trampoline, BLKmode, tramp);
emit_block_move (blktramp, initial_trampoline,
GEN_INT (TRAMPOLINE_SIZE),
- TRAMPOLINE_ALIGNMENT / BITS_PER_UNIT);
+ TRAMPOLINE_ALIGNMENT);
#endif
INITIALIZE_TRAMPOLINE (tramp, XEXP (DECL_RTL (function), 0), context);
seq = get_insns ();
diff --git a/gcc/function.h b/gcc/function.h
index 5c7aa414d30..08d438ab67e 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -108,7 +108,7 @@ struct emit_status
/* Indexed by pseudo register number, if nonzero gives the known alignment
for that pseudo (if regno_pointer_flag is set).
Allocated in parallel with regno_pointer_flag. */
- char *regno_pointer_align;
+ unsigned char *regno_pointer_align;
/* Indexed by pseudo register number, gives the rtx for that pseudo.
Allocated in parallel with regno_pointer_flag. */
@@ -130,10 +130,6 @@ struct expr_status
These are the arguments to function calls that have already returned. */
int x_pending_stack_adjust;
- /* Number of units that we should eventually pop off the stack.
- These are the arguments to function calls that have not happened yet. */
- int x_arg_space_so_far;
-
/* Under some ABIs, it is the caller's responsibility to pop arguments
pushed for function calls. A naive implementation would simply pop
the arguments immediately after each call. However, if several
@@ -151,6 +147,12 @@ struct expr_status
NO_DEFER_POP and OK_DEFER_POP. */
int x_inhibit_defer_pop;
+ /* If PREFERRED_STACK_BOUNDARY and PUSH_ROUNDING are defined, the stack
+ boundary can be momentairly unaligned while pushing the arguments.
+ Record the delta since last aligned boundary here in order to get
+ stack alignment in the nested function calls working right. */
+ int x_stack_pointer_delta;
+
/* Nonzero means __builtin_saveregs has already been done in this function.
The value is the pseudoreg containing the value __builtin_saveregs
returned. */
@@ -167,12 +169,12 @@ struct expr_status
};
#define pending_stack_adjust (cfun->expr->x_pending_stack_adjust)
-#define arg_space_so_far (cfun->expr->x_arg_space_so_far)
#define inhibit_defer_pop (cfun->expr->x_inhibit_defer_pop)
#define saveregs_value (cfun->expr->x_saveregs_value)
#define apply_args_value (cfun->expr->x_apply_args_value)
#define forced_labels (cfun->expr->x_forced_labels)
#define pending_chain (cfun->expr->x_pending_chain)
+#define stack_pointer_delta (cfun->expr->x_stack_pointer_delta)
/* This structure can save all the important global and static variables
describing the status of the current function. */
@@ -399,7 +401,7 @@ struct function
/* 1 + last pseudo register number possibly used for loading a copy
of a parameter of this function. */
- int x_max_parm_reg;
+ unsigned int x_max_parm_reg;
/* Vector indexed by REGNO, containing location on stack in which
to put the parm which is nominally in pseudo register REGNO,
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 14499cff0b1..a5e6bbe4e5f 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -366,6 +366,10 @@ or with constant text in a single argument.
specified to CC. Note that the tail part of the -S option
(i.e. the part matched by the `*') will be substituted for each
occurrence of %* within X.
+ %{<S} remove all occurences of S from the command line.
+ Note - this option is position dependent. % commands in the
+ spec string before this option will see S, % commands in the
+ spec string after this option will not.
%{S:X} substitutes X, but only if the -S switch was given to CC.
%{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
%{|S:X} like %{S:X}, but if no S switch, substitute `-'.
@@ -627,6 +631,7 @@ static struct compiler default_compilers[] =
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
%{fleading-underscore} %{fno-leading-underscore}\
+ %{fshow-column} %{fno-show-column}\
%{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:cc1 %i %1 \
@@ -663,6 +668,7 @@ static struct compiler default_compilers[] =
%{fshort-wchar:-D__WCHAR_TYPE__=short\\ unsigned\\ int}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fshow-column} %{fno-show-column}\
%{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
@@ -691,6 +697,7 @@ static struct compiler default_compilers[] =
%{fshort-wchar:-D__WCHAR_TYPE__=short\\ unsigned\\ int}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fshow-column} %{fno-show-column}\
%{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %W{o*}}\
@@ -709,6 +716,7 @@ static struct compiler default_compilers[] =
%{fshort-wchar:-D__WCHAR_TYPE__=short\\ unsigned\\ int}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fshow-column} %{fno-show-column}\
%{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %W{o*}"}},
@@ -739,6 +747,7 @@ static struct compiler default_compilers[] =
%{fshort-wchar:-D__WCHAR_TYPE__=short\\ unsigned\\ int}\
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
+ %{fshow-column} %{fno-show-column}\
%{fleading-underscore} %{fno-leading-underscore}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.s}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
@@ -2639,11 +2648,19 @@ execute ()
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
- The `live_cond' field is 1 if the switch is true in a conditional spec,
- -1 if false (overridden by a later switch), and is initialized to zero.
+ The `live_cond' field is:
+ 0 when initialized
+ 1 if the switch is true in a conditional spec,
+ -1 if false (overridden by a later switch)
+ -2 if this switch should be ignored (used in %{<S})
The `validated' field is nonzero if any spec has looked at this switch;
if it remains zero at the end of the run, it must be meaningless. */
+#define SWITCH_OK 0
+#define SWITCH_FALSE -1
+#define SWITCH_IGNORE -2
+#define SWITCH_LIVE 1
+
struct switchstr
{
const char *part1;
@@ -3465,7 +3482,7 @@ process_command (argc, argv)
cc1 spec string. */
switches[n_switches].part1 = "--help";
switches[n_switches].args = 0;
- switches[n_switches].live_cond = 0;
+ switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
n_switches++;
@@ -3480,7 +3497,7 @@ process_command (argc, argv)
-e0 or -e1 down into the linker. */
switches[n_switches].part1 = &argv[i][0];
switches[n_switches].args = 0;
- switches[n_switches].live_cond = 0;
+ switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
n_switches++;
}
@@ -3589,7 +3606,7 @@ process_command (argc, argv)
else
switches[n_switches].args = 0;
- switches[n_switches].live_cond = 0;
+ switches[n_switches].live_cond = SWITCH_OK;
switches[n_switches].validated = 0;
/* This is always valid, since gcc.c itself understands it. */
if (!strcmp (p, "save-temps"))
@@ -4601,16 +4618,31 @@ handle_braces (p)
int negate;
int suffix;
int include_blanks = 1;
+ int elide_switch = 0;
if (*p == '^')
- /* A '^' after the open-brace means to not give blanks before args. */
- include_blanks = 0, ++p;
+ {
+ /* A '^' after the open-brace means to not give blanks before args. */
+ include_blanks = 0;
+ ++p;
+ }
if (*p == '|')
- /* A `|' after the open-brace means,
- if the test fails, output a single minus sign rather than nothing.
- This is used in %{|!pipe:...}. */
- pipe_p = 1, ++p;
+ {
+ /* A `|' after the open-brace means,
+ if the test fails, output a single minus sign rather than nothing.
+ This is used in %{|!pipe:...}. */
+ pipe_p = 1;
+ ++p;
+ }
+
+ if (*p == '<')
+ {
+ /* A `<' after the open-brace means that the switch should be
+ removed from the command-line. */
+ elide_switch = 1;
+ ++p;
+ }
next_member:
negate = suffix = 0;
@@ -4630,6 +4662,13 @@ next_member:
++p;
}
+ if (elide_switch && (negate || pipe_p || suffix))
+ {
+ /* It doesn't make sense to mix elision with other flags. We
+ could fatal() here, but the standard seems to be to abort. */
+ abort ();
+ }
+
filter = p;
while (*p != ':' && *p != '}' && *p != '|') p++;
@@ -4744,6 +4783,7 @@ next_member:
&& check_live_switch (i, hard_match_len))
{
present = 1;
+ break;
}
}
}
@@ -4767,7 +4807,12 @@ next_member:
conditional text. */
if (present != negate)
{
- if (*p == '}')
+ if (elide_switch)
+ {
+ switches[i].live_cond = SWITCH_IGNORE;
+ switches[i].validated = 1;
+ }
+ else if (*p == '}')
{
give_switch (i, 0, include_blanks);
}
@@ -4829,7 +4874,7 @@ check_live_switch (switchnum, prefix_length)
if (switches[i].part1[0] == 'O')
{
switches[switchnum].validated = 1;
- switches[switchnum].live_cond = -1;
+ switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
break;
@@ -4843,7 +4888,7 @@ check_live_switch (switchnum, prefix_length)
&& ! strcmp (&switches[i].part1[1], &name[4]))
{
switches[switchnum].validated = 1;
- switches[switchnum].live_cond = -1;
+ switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
}
@@ -4858,7 +4903,7 @@ check_live_switch (switchnum, prefix_length)
&& !strcmp (&switches[i].part1[4], &name[1]))
{
switches[switchnum].validated = 1;
- switches[switchnum].live_cond = -1;
+ switches[switchnum].live_cond = SWITCH_FALSE;
return 0;
}
}
@@ -4866,7 +4911,7 @@ check_live_switch (switchnum, prefix_length)
}
/* Otherwise the switch is live. */
- switches[switchnum].live_cond = 1;
+ switches[switchnum].live_cond = SWITCH_LIVE;
return 1;
}
@@ -4887,6 +4932,9 @@ give_switch (switchnum, omit_first_word, include_blanks)
int omit_first_word;
int include_blanks;
{
+ if (switches[switchnum].live_cond == SWITCH_IGNORE)
+ return;
+
if (!omit_first_word)
{
do_spec_1 ("-", 0, NULL_PTR);
diff --git a/gcc/gcc.texi b/gcc/gcc.texi
index b59fc65d455..a12dd357ef4 100644
--- a/gcc/gcc.texi
+++ b/gcc/gcc.texi
@@ -2156,12 +2156,13 @@ information that makes for fixing the bug.
* Criteria: Bug Criteria. Have you really found a bug?
* Where: Bug Lists. Where to send your bug report.
* Reporting: Bug Reporting. How to report a bug effectively.
+* GNATS: gccbug. You can use a bug reporting tool.
* Patches: Sending Patches. How to send a patch for GCC.
* Known: Trouble. Known problems.
* Help: Service. Where to ask for help.
@end menu
-@node Bug Criteria
+@node Bug Criteria,Bug Lists,,Bugs
@section Have You Found a Bug?
@cindex bug criteria
@@ -2228,7 +2229,7 @@ If you are an experienced user of one of the languages GCC supports, your
suggestions for improvement of GCC are welcome in any case.
@end itemize
-@node Bug Lists
+@node Bug Lists,Bug Reporting,Bug Criteria,Bugs
@section Where to Report Bugs
@cindex bug report mailing lists
@kindex gcc-bugs@@gcc.gnu.org or bug-gcc@@gnu.org
@@ -2257,7 +2258,7 @@ Free Software Foundation
Boston, MA 02111-1307, USA
@end example
-@node Bug Reporting
+@node Bug Reporting,gccbug,Bug Lists,Bugs
@section How to Report Bugs
@cindex compiler bugs, reporting
@@ -2517,7 +2518,138 @@ unless we have an identical system---and if we do have one,
we should be able to reproduce the crash ourselves.
@end itemize
-@node Sending Patches,, Bug Reporting, Bugs
+@node gccbug,Sending Patches, Bug Reporting, Bugs
+@section The gccbug script
+@cindex gccbug script
+
+To simplify creation of bug reports, and to allow better tracking of
+reports, we use the GNATS bug tracking system. Part of that system is
+the @code{gccbug} script. This is a Unix shell script, so you need a
+shell to run it. It is normally installed in the same directory where
+@code{gcc} is installed.
+
+The gccbug script is derived from send-pr, @pxref{using
+send-pr,,Creating new Problem Reports,send-pr,Reporting Problems}. When
+invoked, it starts a text editor so you can fill out the various fields
+of the report. When the you quit the editor, the report is automatically
+send to the bug reporting address.
+
+A number of fields in this bug report form are specific to GCC, and are
+explained here.
+
+@table @code
+
+@cindex @code{Category} field
+@cindex @code{>Category:}
+@item >Category:
+The category of a GCC problem can be one of the following:
+
+@table @code
+@item c
+A problem with the C compiler proper.
+driver.
+
+@item c++
+A problem with the C++ compiler.
+driver.
+
+@item fortran
+A problem with the Fortran 77.
+
+@item java
+A problem with the Java compiler.
+
+@item objc
+A problem with the Objective C compiler.
+
+@item libstdc++
+A problem with the C++ standard library.
+
+@item libf2c
+A problem with the Fortran 77 library.
+
+@item libobjc
+A problem with the Objective C library.
+
+@item optimization
+The problem occurs only when generating optimized code.
+
+@item debug
+The problem occurs only when generating code for debugging.
+
+@item target
+The problem is specific to the target architecture.
+
+@item middle-end
+The problem is independent from target architecture and programming
+language.
+
+@item other
+It is a problem in some other part of the GCC software.
+
+@item web
+There is a problem with the GCC home page.
+
+@end table
+
+@cindex @code{Class} field
+@cindex @code{>Class:}
+@item >Class:
+The class of a problem can be one of the following:
+
+@table @code
+@cindex @emph{doc-bug} class
+@item doc-bug
+A problem with the documentation.
+
+@cindex @emph{accepts-illegal} class
+@item accepts-illegal
+GCC fails to reject erroneous code.
+
+@cindex @emph{rejects-legal} class
+@item rejects-legal
+GCC gives an error message for correct code.
+
+@cindex @emph{wrong-code} class
+@item wrong-code
+The machine code generated by gcc is incorrect.
+
+@cindex @emph{ice-on-legal-code} class
+@item ice-on-legal-code
+GCC gives an Internal Compiler Error (ICE) for correct code.
+
+@cindex @emph{ice-on-illegal-code} class
+@item ice-on-illegal-code
+GCC gives an ICE instead of reporting an error
+
+@cindex @emph{pessimizes-code} class
+@item pessimizes-code
+GCC misses an important optimization opportunity.
+
+@cindex @emph{sw-bug} class
+@item sw-bug
+A general product problem. (@samp{sw} stands for ``software''.)
+
+@cindex @emph{change-request} class
+@item change-request
+A request for a change in behavior, etc.
+
+@cindex @emph{support} class
+@item support
+A support problem or question.
+
+@cindex @emph{duplicate} class
+@item duplicate (@var{pr-number})
+Duplicate PR. @var{pr-number} should be the number of the original PR.
+
+@noindent
+The default is @samp{sw-bug}.
+@sp 1
+@end table
+
+@end table
+
+@node Sending Patches,, gccbug, Bugs
@section Sending Patches for GCC
If you would like to write bug fixes or improvements for the GNU C
diff --git a/gcc/gccbug.in b/gcc/gccbug.in
index 04f968a5812..18aba83bb33 100755
--- a/gcc/gccbug.in
+++ b/gcc/gccbug.in
@@ -177,7 +177,7 @@ while [ $# -gt 0 ]; do
done
# spam does not need to be listed here
-CATEGORIES="c++ c debug fortran gc host java libf2c libgcc libobjc libstdc++ middle-end objc optimization other profiling target web"
+CATEGORIES="c++ c debug fortran java libf2c libobjc libstdc++ middle-end objc optimization other target web"
case "$FORMAT" in
lisp) echo "$CATEGORIES" | \
@@ -205,8 +205,7 @@ if [ -z "$SEVERITY_C" ]; then
SEVERITY_C='<[ non-critical | serious | critical ] (one line)>'
fi
PRIORITY_C='<[ low | medium | high ] (one line)>'
-CATEGORY_C='<choose from the list of categories above (one line)>'
-CLASS_C='<[ doc-bug | accepts-illegal | rejects-legal | wrong-code | ice-on-legal-code| ice-on-illegal-code | pessimizes-code | sw-bug | change-request | support ] (one line)>'
+CATEGORY_C='<choose from the top of this file (one line)>'
RELEASE_C='<release number or tag (one line)>'
ENVIRONMENT_C='<machine, os, target, libraries (multiple lines)>'
DESCRIPTION_C='<precise description of the problem (multiple lines)>'
@@ -256,8 +255,8 @@ SEND-PR: -*- send-pr -*-
SEND-PR: Lines starting with `SEND-PR' will be removed automatically, as
SEND-PR: will all comments (text enclosed in `<' and `>').
SEND-PR:
-SEND-PR: Please consult the send-pr man page `send-pr(1)' or the Texinfo
-SEND-PR: manual if you are not sure how to fill out a problem report.
+SEND-PR: Please consult the GCC manual manual if you are not sure how to
+SEND-PR: fill out a problem report.
SEND-PR: Note that the Synopsis field is mandatory. The Subject (for
SEND-PR: the mail) will be made the same as Synopsis unless explicitly
SEND-PR: changed.
@@ -294,9 +293,26 @@ X-GNATS-Notify:
>Confidential: $CONFIDENTIAL_C
>Synopsis: $SYNOPSIS_C
>Severity: $SEVERITY_C
+SEND-PR: critical GCC is completely not operational; no work-around known.
+SEND-PR: serious GCC is not working properly; a work-around is possible.
+SEND-PR: non-critical Report indicates minor problem.
>Priority: $PRIORITY_C
+SEND-PR: high A solution is necessary as soon as possible.
+SEND-PR: medium The problem should be solved in the next release.
+SEND-PR: low The problem should be solve in a future release.
>Category: $CATEGORY_C
->Class: $CLASS_C
+>Class: <[ doc-bug | accepts-illegal | rejects-legal | wrong-code | ice-on-legal-code| ice-on-illegal-code | pessimizes-code | sw-bug | change-request | support ] (one line)>
+SEND-PR: doc-bug The doumentation is incorrect.
+SEND-PR: accepts-illegal GCC fails to reject erroneous code.
+SEND-PR: rejects-legal GCC gives an error message for correct code.
+SEND-PR: wrong-code The machine code generated by gcc is incorrect.
+SEND-PR: ice-on-legal-code GCC gives an Internal Compiler Error (ICE)
+SEND-PR: for correct code
+SEND-PR: ice-on-illegal-code GCC gives an ICE instead of reporting an error
+SEND-PR: pessimizes-code GCC misses an important optimization opportunity
+SEND-PR: sw-bug Software bug of some other class than above
+SEND-PR: change-request A feature in GCC is missing.
+SEND-PR: support I need help with gcc.
>Release: ${DEFAULT_RELEASE-$RELEASE_C}
>Environment:
`[ -n "$SYSTEM" ] && echo System: $SYSTEM`
@@ -410,7 +426,7 @@ while [ -z "$REQUEST_ID" ]; do
PATTERN=">Class:"
CLASS=`eval sed -n -e "\"$SED_CMD\"" $TEMP`
case "$CLASS" in
- ""|sw-bug|doc-bug|change-request|support) CNT=`expr $CNT + 1` ;;
+ ""|doc-bug|accepts-illegal|rejects-legal|wrong-code|ice-on-legal-code|ice-on-illegal-code|pessimizes-code|sw-bug|change-request|support) CNT=`expr $CNT + 1` ;;
*) echo "$COMMAND: \`$CLASS' is not a valid value for \`Class'."
esac
#
diff --git a/gcc/gcse.c b/gcc/gcse.c
index d3e00b83c20..996cde95e72 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -399,7 +399,7 @@ static rtx *cuid_insn;
/* Maximum register number in function prior to doing gcse + 1.
Registers created during this pass have regno >= max_gcse_regno.
This is named with "gcse" to not collide with global of same name. */
-static int max_gcse_regno;
+static unsigned int max_gcse_regno;
/* Maximum number of cse-able expressions found. */
static int n_exprs;
@@ -519,9 +519,9 @@ struct null_pointer_info
/* The basic block being processed. */
int current_block;
/* The first register to be handled in this pass. */
- int min_reg;
+ unsigned int min_reg;
/* One greater than the last register to be handled in this pass. */
- int max_reg;
+ unsigned int max_reg;
sbitmap *nonnull_local;
sbitmap *nonnull_killed;
};
@@ -566,8 +566,8 @@ static void compute_expr_hash_table PARAMS ((void));
static void dump_hash_table PARAMS ((FILE *, const char *, struct expr **,
int, int));
static struct expr *lookup_expr PARAMS ((rtx));
-static struct expr *lookup_set PARAMS ((int, rtx));
-static struct expr *next_set PARAMS ((int, struct expr *));
+static struct expr *lookup_set PARAMS ((unsigned int, rtx));
+static struct expr *next_set PARAMS ((unsigned int, struct expr *));
static void reset_opr_set_tables PARAMS ((void));
static int oprs_not_set_p PARAMS ((rtx, rtx));
static void mark_call PARAMS ((rtx));
@@ -628,7 +628,8 @@ static int handle_avail_expr PARAMS ((rtx, struct expr *));
static int classic_gcse PARAMS ((void));
static int one_classic_gcse_pass PARAMS ((int));
static void invalidate_nonnull_info PARAMS ((rtx, rtx, void *));
-static void delete_null_pointer_checks_1 PARAMS ((int *, sbitmap *, sbitmap *,
+static void delete_null_pointer_checks_1 PARAMS ((unsigned int *, sbitmap *,
+ sbitmap *,
struct null_pointer_info *));
static rtx process_insert_insn PARAMS ((struct expr *));
static int pre_edge_insert PARAMS ((struct edge_list *, struct expr **));
@@ -668,18 +669,13 @@ gcse_main (f, file)
/* Identify the basic block information for this function, including
successors and predecessors. */
max_gcse_regno = max_reg_num ();
- find_basic_blocks (f, max_gcse_regno, file);
- cleanup_cfg (f);
if (file)
dump_flow_info (file);
/* Return if there's nothing to do. */
if (n_basic_blocks <= 1)
- {
- free_basic_block_vars (0);
- return 0;
- }
+ return 0;
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
@@ -690,10 +686,7 @@ gcse_main (f, file)
a couple switch statements. So we require a relatively large number
of basic blocks and the ratio of edges to blocks to be high. */
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
- {
- free_basic_block_vars (0);
- return 0;
- }
+ return 0;
/* See what modes support reg/reg copy operations. */
if (! can_copy_init_p)
@@ -806,7 +799,6 @@ gcse_main (f, file)
obstack_free (&gcse_obstack, NULL_PTR);
free_reg_set_mem ();
- free_basic_block_vars (0);
return run_jump_opt_after_gcse;
}
@@ -2124,9 +2116,9 @@ compute_hash_table (set_p)
for (bb = 0; bb < n_basic_blocks; bb++)
{
rtx insn;
- int regno;
+ unsigned int regno;
int in_libcall_block;
- int i;
+ unsigned int i;
/* First pass over the instructions records information used to
determine when registers and memory are first and last set.
@@ -2135,6 +2127,7 @@ compute_hash_table (set_p)
for (i = 0; i < max_gcse_regno; i++)
reg_first_set[i] = reg_last_set[i] = NEVER_SET;
+
mem_first_set = NEVER_SET;
mem_last_set = NEVER_SET;
@@ -2321,7 +2314,7 @@ lookup_expr (pat)
static struct expr *
lookup_set (regno, pat)
- int regno;
+ unsigned int regno;
rtx pat;
{
unsigned int hash = hash_set (regno, set_hash_table_size);
@@ -2347,7 +2340,7 @@ lookup_set (regno, pat)
static struct expr *
next_set (regno, expr)
- int regno;
+ unsigned int regno;
struct expr *expr;
{
do
@@ -3074,7 +3067,7 @@ handle_avail_expr (insn, expr)
{
/* This is the case when the available expression that reaches
here has already been handled as an available expression. */
- int regnum_for_replacing
+ unsigned int regnum_for_replacing
= REGNO (SET_SRC (PATTERN (insn_computes_expr)));
/* If the register was created by GCSE we can't use `reg_set_table',
@@ -3093,7 +3086,7 @@ handle_avail_expr (insn, expr)
if (!found_setting)
{
- int regnum_for_replacing
+ unsigned int regnum_for_replacing
= REGNO (SET_DEST (PATTERN (insn_computes_expr)));
/* This shouldn't happen. */
@@ -3836,7 +3829,7 @@ cprop_insn (insn, alter_jumps)
for (reg_used = &reg_use_table[0]; reg_use_count > 0;
reg_used++, reg_use_count--)
{
- int regno = REGNO (reg_used->reg_rtx);
+ unsigned int regno = REGNO (reg_used->reg_rtx);
rtx pat, src;
struct expr *set;
@@ -4868,10 +4861,8 @@ invalidate_nonnull_info (x, setter, data)
rtx setter ATTRIBUTE_UNUSED;
void *data;
{
- int offset, regno;
- struct null_pointer_info* npi = (struct null_pointer_info *) data;
-
- offset = 0;
+ unsigned int regno;
+ struct null_pointer_info *npi = (struct null_pointer_info *) data;
while (GET_CODE (x) == SUBREG)
x = SUBREG_REG (x);
@@ -4894,7 +4885,7 @@ invalidate_nonnull_info (x, setter, data)
static void
delete_null_pointer_checks_1 (block_reg, nonnull_avin, nonnull_avout, npi)
- int *block_reg;
+ unsigned int *block_reg;
sbitmap *nonnull_avin;
sbitmap *nonnull_avout;
struct null_pointer_info *npi;
@@ -5063,24 +5054,16 @@ delete_null_pointer_checks (f)
rtx f;
{
sbitmap *nonnull_avin, *nonnull_avout;
- int *block_reg;
+ unsigned int *block_reg;
int bb;
int reg;
int regs_per_pass;
int max_reg;
struct null_pointer_info npi;
- /* First break the program into basic blocks. */
- find_basic_blocks (f, max_reg_num (), NULL);
- cleanup_cfg (f);
-
/* If we have only a single block, then there's nothing to do. */
if (n_basic_blocks <= 1)
- {
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
- return;
- }
+ return;
/* Trying to perform global optimizations on flow graphs which have
a high connectivity will take a long time and is unlikely to be
@@ -5091,11 +5074,7 @@ delete_null_pointer_checks (f)
a couple switch statements. So we require a relatively large number
of basic blocks and the ratio of edges to blocks to be high. */
if (n_basic_blocks > 1000 && n_edges / n_basic_blocks >= 20)
- {
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
- return;
- }
+ return;
/* We need four bitmaps, each with a bit for each register in each
basic block. */
@@ -5152,9 +5131,6 @@ delete_null_pointer_checks (f)
nonnull_avout, &npi);
}
- /* Free storage allocated by find_basic_blocks. */
- free_basic_block_vars (0);
-
/* Free the table of registers compared at the end of every block. */
free (block_reg);
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index a656f1fc995..46da58773a5 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -622,7 +622,7 @@ attr_rtx VPARAMS ((enum rtx_code code, ...))
else if (GET_RTX_LENGTH (code) == 1
&& GET_RTX_FORMAT (code)[0] == 's')
{
- char * arg0 = va_arg (p, char *);
+ char *arg0 = va_arg (p, char *);
if (code == SYMBOL_REF)
arg0 = attr_string (arg0, strlen (arg0));
diff --git a/gcc/genconfig.c b/gcc/genconfig.c
index 8c8ee9d6520..65c8701ab22 100644
--- a/gcc/genconfig.c
+++ b/gcc/genconfig.c
@@ -39,7 +39,7 @@ static int max_dup_operands; /* Largest number of match_dup in any insn. */
static int max_clobbers_per_insn;
static int have_cc0_flag;
static int have_cmove_flag;
-static int have_cond_arith_flag;
+static int have_cond_exec_flag;
static int have_lo_sum_flag;
static int have_peephole_flag;
static int have_peephole2_flag;
@@ -131,21 +131,17 @@ walk_insn_part (part, recog_p, non_pc_set_src)
two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise,
we have some specific IF_THEN_ELSE construct (like the doz
instruction on the RS/6000) that can't be used in the general
- context we want it for. If the first operand is an arithmetic
- operation and the second is a MATCH_OPERNAND, show we have
- conditional arithmetic. */
+ context we want it for. */
if (recog_p && non_pc_set_src
&& GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
&& GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
have_cmove_flag = 1;
- else if (recog_p && non_pc_set_src
- && (GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == '1'
- || GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == '2'
- || GET_RTX_CLASS (GET_CODE (XEXP (part, 1))) == 'c')
- && GET_CODE (XEXP (XEXP (part, 1), 0)) == MATCH_OPERAND
- && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
- have_cond_arith_flag = 1;
+ break;
+
+ case COND_EXEC:
+ if (recog_p)
+ have_cond_exec_flag = 1;
break;
case REG: case CONST_INT: case SYMBOL_REF:
@@ -341,8 +337,9 @@ from the machine description file `md'. */\n\n");
/* This is conditionally defined, in case the user writes code which emits
more splits than we can readily see (and knows s/he does it). */
- printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n",
- max_insns_per_split);
+ printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
+ printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
+ printf ("#endif\n");
if (have_cc0_flag)
printf ("#define HAVE_cc0\n");
@@ -350,11 +347,8 @@ from the machine description file `md'. */\n\n");
if (have_cmove_flag)
printf ("#define HAVE_conditional_move\n");
-#if 0
- /* Disabled. See the discussion in jump.c. */
- if (have_cond_arith_flag)
- printf ("#define HAVE_conditional_arithmetic\n");
-#endif
+ if (have_cond_exec_flag)
+ printf ("#define HAVE_conditional_execution\n");
if (have_lo_sum_flag)
printf ("#define HAVE_lo_sum\n");
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 9ad2ba2998c..c86b62a7342 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -1607,9 +1607,9 @@ change_state (oldpos, newpos, afterward, indent)
if (newpos[new_has_insn] >= 'A' && newpos[new_has_insn] <= 'Z')
break;
- /* Make sure to reset the _last_insn pointer when popping back up. */
+ /* Make sure to reset the last_insn pointer when popping back up. */
if (old_has_insn >= 0 && new_has_insn < 0)
- printf ("%s_last_insn = insn;\n", indent);
+ printf ("%slast_insn = insn;\n", indent);
/* Go down to desired level. */
while (depth < ndepth)
@@ -1620,7 +1620,7 @@ change_state (oldpos, newpos, afterward, indent)
/* We can only fail if we're moving down the tree. */
if (old_has_insn >= 0 && oldpos[old_has_insn] >= newpos[depth])
{
- printf ("%s_last_insn = recog_next_insn (insn, %d);\n",
+ printf ("%slast_insn = recog_next_insn (insn, %d);\n",
indent, newpos[depth] - 'A');
}
else
@@ -1632,9 +1632,9 @@ change_state (oldpos, newpos, afterward, indent)
printf ("%s goto L%d;\n", indent, afterward->number);
else
printf ("%s goto ret0;\n", indent);
- printf ("%s_last_insn = tem;\n", indent);
+ printf ("%slast_insn = tem;\n", indent);
}
- printf ("%sx%d = PATTERN (_last_insn);\n", indent, depth + 1);
+ printf ("%sx%d = PATTERN (last_insn);\n", indent, depth + 1);
}
else if (newpos[depth] >= 'a' && newpos[depth] <= 'z')
printf ("%sx%d = XVECEXP (x%d, 0, %d);\n",
@@ -2210,7 +2210,7 @@ peephole2%s (x0, insn, _plast_insn)\n\
printf (" register rtx x%d ATTRIBUTE_UNUSED;\n", i);
if (type == PEEPHOLE2)
- printf (" register rtx _last_insn = insn;\n");
+ printf (" register rtx last_insn = insn;\n");
printf (" %s tem ATTRIBUTE_UNUSED;\n", IS_SPLIT (type) ? "rtx" : "int");
if (head->first)
@@ -2219,7 +2219,7 @@ peephole2%s (x0, insn, _plast_insn)\n\
printf (" goto ret0;\n");
if (type == PEEPHOLE2)
- printf (" ret1:\n *_plast_insn = _last_insn;\n return tem;\n");
+ printf (" ret1:\n *_plast_insn = last_insn;\n return tem;\n");
printf (" ret0:\n return %d;\n}\n\n", IS_SPLIT (type) ? 0 : -1);
}
@@ -2310,6 +2310,7 @@ make_insn_sequence (insn, type)
struct decision *last;
struct decision_test *test, **place;
struct decision_head head;
+ char *c_test_pos = "";
record_insn_name (next_insn_code, (type == RECOG ? XSTR (insn, 0) : NULL));
@@ -2334,6 +2335,10 @@ make_insn_sequence (insn, type)
}
}
XVECLEN (x, 0) = j;
+
+ c_test_pos = alloca (2);
+ c_test_pos[0] = 'A' + j - 1;
+ c_test_pos[1] = '\0';
}
else if (XVECLEN (insn, type == RECOG) == 1)
x = XVECEXP (insn, type == RECOG, 0);
@@ -2359,7 +2364,7 @@ make_insn_sequence (insn, type)
/* Need a new node if we have another test to add. */
if (test->type == DT_accept_op)
{
- last = new_decision ("", &last->success);
+ last = new_decision (c_test_pos, &last->success);
place = &last->tests;
}
test = new_decision_test (DT_c_test, &place);
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
index 50a610e5e3f..88488fec445 100644
--- a/gcc/ggc-common.c
+++ b/gcc/ggc-common.c
@@ -33,12 +33,16 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Statistics about the allocation. */
static ggc_statistics *ggc_stats;
+/* Trees that have been marked, but whose children still need marking. */
+varray_type ggc_pending_trees;
+
static void ggc_mark_rtx_ptr PARAMS ((void *));
static void ggc_mark_tree_ptr PARAMS ((void *));
static void ggc_mark_rtx_varray_ptr PARAMS ((void *));
static void ggc_mark_tree_varray_ptr PARAMS ((void *));
static void ggc_mark_tree_hash_table_ptr PARAMS ((void *));
static void ggc_mark_string_ptr PARAMS ((void *));
+static void ggc_mark_trees PARAMS ((void));
static boolean ggc_mark_tree_hash_table_entry PARAMS ((struct hash_entry *,
hash_table_key));
@@ -174,6 +178,8 @@ ggc_mark_roots ()
{
struct ggc_root* x;
+ VARRAY_TREE_INIT (ggc_pending_trees, 4096, "ggc_pending_trees");
+
for (x = roots; x != NULL; x = x->next)
{
char *elt = x->base;
@@ -184,6 +190,10 @@ ggc_mark_roots ()
for (i = 0; i < n; ++i, elt += s)
(*cb)(elt);
}
+
+ /* Mark all the queued up trees, and their children. */
+ ggc_mark_trees ();
+ VARRAY_FREE (ggc_pending_trees);
}
/* R had not been previously marked, but has now been marked via
@@ -297,144 +307,155 @@ ggc_mark_rtvec_children (v)
ggc_mark_rtx (RTVEC_ELT (v, i));
}
-/* T had not been previously marked, but has now been marked via
- ggc_set_mark. Now recurse and process the children. */
+/* Recursively set marks on all of the children of the
+ GCC_PENDING_TREES. */
-void
-ggc_mark_tree_children (t)
- tree t;
+static void
+ggc_mark_trees ()
{
- enum tree_code code = TREE_CODE (t);
-
- /* Collect statistics, if appropriate. */
- if (ggc_stats)
+ while (ggc_pending_trees->elements_used)
{
- ++ggc_stats->num_trees[(int) code];
- ggc_stats->size_trees[(int) code] += ggc_get_size (t);
- }
+ tree t;
+ enum tree_code code;
- /* Bits from common. */
- ggc_mark_tree (TREE_TYPE (t));
- ggc_mark_tree (TREE_CHAIN (t));
+ t = VARRAY_TOP_TREE (ggc_pending_trees);
+ VARRAY_POP (ggc_pending_trees);
+ code = TREE_CODE (t);
- /* Some nodes require special handling. */
- switch (code)
- {
- case TREE_LIST:
- ggc_mark_tree (TREE_PURPOSE (t));
- ggc_mark_tree (TREE_VALUE (t));
- return;
+ /* Collect statistics, if appropriate. */
+ if (ggc_stats)
+ {
+ ++ggc_stats->num_trees[(int) code];
+ ggc_stats->size_trees[(int) code] += ggc_get_size (t);
+ }
- case TREE_VEC:
- {
- int i = TREE_VEC_LENGTH (t);
- while (--i >= 0)
- ggc_mark_tree (TREE_VEC_ELT (t, i));
- return;
- }
+ /* Bits from common. */
+ ggc_mark_tree (TREE_TYPE (t));
+ ggc_mark_tree (TREE_CHAIN (t));
- case SAVE_EXPR:
- ggc_mark_tree (TREE_OPERAND (t, 0));
- ggc_mark_tree (SAVE_EXPR_CONTEXT (t));
- ggc_mark_rtx (SAVE_EXPR_RTL (t));
- return;
-
- case RTL_EXPR:
- ggc_mark_rtx (RTL_EXPR_SEQUENCE (t));
- ggc_mark_rtx (RTL_EXPR_RTL (t));
- return;
-
- case CALL_EXPR:
- ggc_mark_tree (TREE_OPERAND (t, 0));
- ggc_mark_tree (TREE_OPERAND (t, 1));
- ggc_mark_rtx (CALL_EXPR_RTL (t));
- return;
-
- case COMPLEX_CST:
- ggc_mark_tree (TREE_REALPART (t));
- ggc_mark_tree (TREE_IMAGPART (t));
- break;
-
- case STRING_CST:
- ggc_mark_string (TREE_STRING_POINTER (t));
- break;
-
- case PARM_DECL:
- ggc_mark_rtx (DECL_INCOMING_RTL (t));
- break;
-
- case IDENTIFIER_NODE:
- ggc_mark_string (IDENTIFIER_POINTER (t));
- lang_mark_tree (t);
- return;
-
- default:
- break;
- }
+ /* Some nodes require special handling. */
+ switch (code)
+ {
+ case TREE_LIST:
+ ggc_mark_tree (TREE_PURPOSE (t));
+ ggc_mark_tree (TREE_VALUE (t));
+ continue;
+
+ case TREE_VEC:
+ {
+ int i = TREE_VEC_LENGTH (t);
+ while (--i >= 0)
+ ggc_mark_tree (TREE_VEC_ELT (t, i));
+ continue;
+ }
+
+ case SAVE_EXPR:
+ ggc_mark_tree (TREE_OPERAND (t, 0));
+ ggc_mark_tree (SAVE_EXPR_CONTEXT (t));
+ ggc_mark_rtx (SAVE_EXPR_RTL (t));
+ continue;
+
+ case RTL_EXPR:
+ ggc_mark_rtx (RTL_EXPR_SEQUENCE (t));
+ ggc_mark_rtx (RTL_EXPR_RTL (t));
+ continue;
+
+ case CALL_EXPR:
+ ggc_mark_tree (TREE_OPERAND (t, 0));
+ ggc_mark_tree (TREE_OPERAND (t, 1));
+ ggc_mark_rtx (CALL_EXPR_RTL (t));
+ continue;
+
+ case COMPLEX_CST:
+ ggc_mark_tree (TREE_REALPART (t));
+ ggc_mark_tree (TREE_IMAGPART (t));
+ break;
+
+ case STRING_CST:
+ ggc_mark_string (TREE_STRING_POINTER (t));
+ break;
+
+ case PARM_DECL:
+ ggc_mark_rtx (DECL_INCOMING_RTL (t));
+ break;
+
+ case FIELD_DECL:
+ ggc_mark_tree (DECL_FIELD_BIT_OFFSET (t));
+ break;
+
+ case IDENTIFIER_NODE:
+ ggc_mark_string (IDENTIFIER_POINTER (t));
+ lang_mark_tree (t);
+ continue;
+
+ default:
+ break;
+ }
- /* But in general we can handle them by class. */
- switch (TREE_CODE_CLASS (code))
- {
- case 'd': /* A decl node. */
- ggc_mark_string (DECL_SOURCE_FILE (t));
- ggc_mark_tree (DECL_SIZE (t));
- ggc_mark_tree (DECL_SIZE_UNIT (t));
- ggc_mark_tree (DECL_NAME (t));
- ggc_mark_tree (DECL_CONTEXT (t));
- ggc_mark_tree (DECL_ARGUMENTS (t));
- ggc_mark_tree (DECL_RESULT (t));
- ggc_mark_tree (DECL_INITIAL (t));
- ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
- ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
- ggc_mark_tree (DECL_SECTION_NAME (t));
- ggc_mark_tree (DECL_MACHINE_ATTRIBUTES (t));
- ggc_mark_rtx (DECL_RTL (t));
- ggc_mark_rtx (DECL_LIVE_RANGE_RTL (t));
- ggc_mark_tree (DECL_VINDEX (t));
- lang_mark_tree (t);
- break;
-
- case 't': /* A type node. */
- ggc_mark_tree (TYPE_SIZE (t));
- ggc_mark_tree (TYPE_SIZE_UNIT (t));
- ggc_mark_tree (TYPE_ATTRIBUTES (t));
- ggc_mark_tree (TYPE_VALUES (t));
- ggc_mark_tree (TYPE_POINTER_TO (t));
- ggc_mark_tree (TYPE_REFERENCE_TO (t));
- ggc_mark_tree (TYPE_NAME (t));
- ggc_mark_tree (TYPE_MIN_VALUE (t));
- ggc_mark_tree (TYPE_MAX_VALUE (t));
- ggc_mark_tree (TYPE_NEXT_VARIANT (t));
- ggc_mark_tree (TYPE_MAIN_VARIANT (t));
- ggc_mark_tree (TYPE_BINFO (t));
- ggc_mark_tree (TYPE_NONCOPIED_PARTS (t));
- ggc_mark_tree (TYPE_CONTEXT (t));
- lang_mark_tree (t);
- break;
-
- case 'b': /* A lexical block. */
- ggc_mark_tree (BLOCK_VARS (t));
- ggc_mark_tree (BLOCK_SUBBLOCKS (t));
- ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
- ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
- break;
-
- case 'c': /* A constant. */
- ggc_mark_rtx (TREE_CST_RTL (t));
- break;
-
- case 'r': case '<': case '1':
- case '2': case 'e': case 's': /* Expressions. */
- {
- int i = tree_code_length[TREE_CODE (t)];
- while (--i >= 0)
- ggc_mark_tree (TREE_OPERAND (t, i));
- break;
- }
+ /* But in general we can handle them by class. */
+ switch (TREE_CODE_CLASS (code))
+ {
+ case 'd': /* A decl node. */
+ ggc_mark_string (DECL_SOURCE_FILE (t));
+ ggc_mark_tree (DECL_SIZE (t));
+ ggc_mark_tree (DECL_SIZE_UNIT (t));
+ ggc_mark_tree (DECL_NAME (t));
+ ggc_mark_tree (DECL_CONTEXT (t));
+ ggc_mark_tree (DECL_ARGUMENTS (t));
+ ggc_mark_tree (DECL_RESULT_FLD (t));
+ ggc_mark_tree (DECL_INITIAL (t));
+ ggc_mark_tree (DECL_ABSTRACT_ORIGIN (t));
+ ggc_mark_tree (DECL_ASSEMBLER_NAME (t));
+ ggc_mark_tree (DECL_SECTION_NAME (t));
+ ggc_mark_tree (DECL_MACHINE_ATTRIBUTES (t));
+ ggc_mark_rtx (DECL_RTL (t));
+ ggc_mark_rtx (DECL_LIVE_RANGE_RTL (t));
+ ggc_mark_tree (DECL_VINDEX (t));
+ lang_mark_tree (t);
+ break;
+
+ case 't': /* A type node. */
+ ggc_mark_tree (TYPE_SIZE (t));
+ ggc_mark_tree (TYPE_SIZE_UNIT (t));
+ ggc_mark_tree (TYPE_ATTRIBUTES (t));
+ ggc_mark_tree (TYPE_VALUES (t));
+ ggc_mark_tree (TYPE_POINTER_TO (t));
+ ggc_mark_tree (TYPE_REFERENCE_TO (t));
+ ggc_mark_tree (TYPE_NAME (t));
+ ggc_mark_tree (TYPE_MIN_VALUE (t));
+ ggc_mark_tree (TYPE_MAX_VALUE (t));
+ ggc_mark_tree (TYPE_NEXT_VARIANT (t));
+ ggc_mark_tree (TYPE_MAIN_VARIANT (t));
+ ggc_mark_tree (TYPE_BINFO (t));
+ ggc_mark_tree (TYPE_NONCOPIED_PARTS (t));
+ ggc_mark_tree (TYPE_CONTEXT (t));
+ lang_mark_tree (t);
+ break;
+
+ case 'b': /* A lexical block. */
+ ggc_mark_tree (BLOCK_VARS (t));
+ ggc_mark_tree (BLOCK_SUBBLOCKS (t));
+ ggc_mark_tree (BLOCK_SUPERCONTEXT (t));
+ ggc_mark_tree (BLOCK_ABSTRACT_ORIGIN (t));
+ break;
+
+ case 'c': /* A constant. */
+ ggc_mark_rtx (TREE_CST_RTL (t));
+ break;
- case 'x':
- lang_mark_tree (t);
- break;
+ case 'r': case '<': case '1':
+ case '2': case 'e': case 's': /* Expressions. */
+ {
+ int i = tree_code_length[TREE_CODE (t)];
+ while (--i >= 0)
+ ggc_mark_tree (TREE_OPERAND (t, i));
+ break;
+ }
+
+ case 'x':
+ lang_mark_tree (t);
+ break;
+ }
}
}
diff --git a/gcc/ggc.h b/gcc/ggc.h
index 32f40965c6e..9ee6c3dd7a9 100644
--- a/gcc/ggc.h
+++ b/gcc/ggc.h
@@ -1,24 +1,25 @@
/* Garbage collection for the GNU compiler.
Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
- This file is part of GNU CC.
+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 free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free 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.
+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. */
+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 "gansidecl.h"
+#include "varray.h"
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
an external gc library that might be linked in. */
@@ -36,15 +37,18 @@ struct emit_status;
struct expr_status;
struct hash_table;
struct label_node;
+struct rtx_def;
struct rtvec_def;
struct stmt_status;
union tree_node;
struct varasm_status;
-struct varray_head_tag;
/* Constants for general use. */
extern char *empty_string;
+/* Trees that have been marked, but whose children still need marking. */
+extern varray_type ggc_pending_trees;
+
/* Manipulate global roots that are needed between calls to gc. */
void ggc_add_root PARAMS ((void *base, int nelt, int size, void (*)(void *)));
void ggc_add_rtx_root PARAMS ((struct rtx_def **, int nelt));
@@ -64,7 +68,6 @@ extern void ggc_mark_roots PARAMS ((void));
extern void ggc_mark_rtx_children PARAMS ((struct rtx_def *));
extern void ggc_mark_rtvec_children PARAMS ((struct rtvec_def *));
-extern void ggc_mark_tree_children PARAMS ((union tree_node *));
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
to true. Otherwise evaluate to false. */
@@ -78,11 +81,11 @@ extern void ggc_mark_tree_children PARAMS ((union tree_node *));
ggc_mark_rtx_children (r__); \
} while (0)
-#define ggc_mark_tree(EXPR) \
- do { \
- tree t__ = (EXPR); \
- if (ggc_test_and_set_mark (t__)) \
- ggc_mark_tree_children (t__); \
+#define ggc_mark_tree(EXPR) \
+ do { \
+ tree t__ = (EXPR); \
+ if (ggc_test_and_set_mark (t__)) \
+ VARRAY_PUSH_TREE (ggc_pending_trees, t__); \
} while (0)
#define ggc_mark_rtvec(EXPR) \
diff --git a/gcc/ginclude/stdarg.h b/gcc/ginclude/stdarg.h
index 3337065a06c..9f6215d31fa 100644
--- a/gcc/ginclude/stdarg.h
+++ b/gcc/ginclude/stdarg.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -51,13 +51,13 @@ typedef __builtin_va_list __gnuc_va_list;
actual type **after default promotions**.
Thus, va_arg (..., short) is not valid. */
-#define va_start(v,l) __builtin_stdarg_start(&(v),l)
+#define va_start(v,l) __builtin_stdarg_start((v),l)
#define va_end __builtin_va_end
#define va_arg __builtin_va_arg
#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L
-#define va_copy(d,s) __builtin_va_copy(&(d),(s))
+#define va_copy(d,s) __builtin_va_copy((d),(s))
#endif
-#define __va_copy(d,s) __builtin_va_copy(&(d),(s))
+#define __va_copy(d,s) __builtin_va_copy((d),(s))
/* Define va_list, if desired, from __gnuc_va_list. */
diff --git a/gcc/ginclude/varargs.h b/gcc/ginclude/varargs.h
index 210b9674743..098094cdd7b 100644
--- a/gcc/ginclude/varargs.h
+++ b/gcc/ginclude/varargs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989, 1997, 1998, 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1989, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU CC.
@@ -63,10 +63,10 @@ typedef int __builtin_va_alist_t __attribute__((__mode__(__word__)));
typedef __builtin_va_list __gnuc_va_list;
#endif
-#define va_start(v) __builtin_varargs_start(&(v))
+#define va_start(v) __builtin_varargs_start((v))
#define va_end __builtin_va_end
#define va_arg __builtin_va_arg
-#define __va_copy(d,s) __builtin_va_copy(&(d),(s))
+#define __va_copy(d,s) __builtin_va_copy((d),(s))
/* Define va_list from __gnuc_va_list. */
diff --git a/gcc/global.c b/gcc/global.c
index f672076aeb5..3c615538643 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -1585,11 +1585,11 @@ static void
set_preference (dest, src)
rtx dest, src;
{
- int src_regno, dest_regno;
+ unsigned int src_regno, dest_regno;
/* Amount to add to the hard regno for SRC, or subtract from that for DEST,
to compensate for subregs in SRC or DEST. */
int offset = 0;
- int i;
+ unsigned int i;
int copy = 1;
if (GET_RTX_FORMAT (GET_CODE (src))[0] == 'e')
@@ -1633,7 +1633,7 @@ set_preference (dest, src)
&& reg_allocno[src_regno] >= 0)
{
dest_regno -= offset;
- if (dest_regno >= 0 && dest_regno < FIRST_PSEUDO_REGISTER)
+ if (dest_regno < FIRST_PSEUDO_REGISTER)
{
if (copy)
SET_REGBIT (hard_reg_copy_preferences,
@@ -1652,7 +1652,7 @@ set_preference (dest, src)
&& reg_allocno[dest_regno] >= 0)
{
src_regno += offset;
- if (src_regno >= 0 && src_regno < FIRST_PSEUDO_REGISTER)
+ if (src_regno < FIRST_PSEUDO_REGISTER)
{
if (copy)
SET_REGBIT (hard_reg_copy_preferences,
diff --git a/gcc/gsyslimits.h b/gcc/gsyslimits.h
index a3628025e8a..cc7b3fb877a 100644
--- a/gcc/gsyslimits.h
+++ b/gcc/gsyslimits.h
@@ -4,5 +4,5 @@
instead of this text. */
#define _GCC_NEXT_LIMITS_H /* tell gcc's limits.h to recurse */
-#include_next <limits.h>
+ #include_next <limits.h>
#undef _GCC_NEXT_LIMITS_H
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index eb6f121d0b7..36a4cc80522 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -2588,6 +2588,7 @@ haifa_classify_insn (insn)
WORST_CLASS (tmp_class,
may_trap_exp (SET_SRC (XVECEXP (pat, 0, i)), 0));
break;
+ case COND_EXEC:
case TRAP_IF:
tmp_class = TRAP_RISKY;
break;
@@ -2617,6 +2618,7 @@ haifa_classify_insn (insn)
WORST_CLASS (tmp_class,
may_trap_exp (SET_SRC (pat), 0));
break;
+ case COND_EXEC:
case TRAP_IF:
tmp_class = TRAP_RISKY;
break;
@@ -3649,6 +3651,15 @@ sched_analyze_insn (deps, x, insn, loop_notes)
int maxreg = max_reg_num ();
int i;
+ if (code == COND_EXEC)
+ {
+ sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
+
+ /* ??? Should be recording conditions so we reduce the number of
+ false dependancies. */
+ x = COND_EXEC_CODE (x);
+ code = GET_CODE (x);
+ }
if (code == SET || code == CLOBBER)
sched_analyze_1 (deps, x, insn);
else if (code == PARALLEL)
@@ -3656,11 +3667,19 @@ sched_analyze_insn (deps, x, insn, loop_notes)
register int i;
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
{
- code = GET_CODE (XVECEXP (x, 0, i));
+ rtx sub = XVECEXP (x, 0, i);
+ code = GET_CODE (sub);
+
+ if (code == COND_EXEC)
+ {
+ sched_analyze_2 (deps, COND_EXEC_TEST (sub), insn);
+ sub = COND_EXEC_CODE (sub);
+ code = GET_CODE (sub);
+ }
if (code == SET || code == CLOBBER)
- sched_analyze_1 (deps, XVECEXP (x, 0, i), insn);
+ sched_analyze_1 (deps, sub, insn);
else
- sched_analyze_2 (deps, XVECEXP (x, 0, i), insn);
+ sched_analyze_2 (deps, sub, insn);
}
}
else
@@ -5313,6 +5332,11 @@ print_pattern (buf, x, verbose)
print_value (t1, XEXP (x, 0), verbose);
sprintf (buf, "use %s", t1);
break;
+ case COND_EXEC:
+ print_value (t1, COND_EXEC_CODE (x), verbose);
+ print_value (t2, COND_EXEC_TEST (x), verbose);
+ sprintf (buf, "cond_exec %s %s", t1, t2);
+ break;
case PARALLEL:
{
int i;
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index dd093db3cbe..8037edaacd5 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -1,5 +1,5 @@
/* Sets (bit vectors) of hard registers, and operations on them.
- Copyright (C) 1987, 1992, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1992, 1994, 2000 Free Software Foundation, Inc.
This file is part of GNU CC
@@ -445,7 +445,7 @@ extern HARD_REG_SET reg_class_contents[];
/* For each reg class, number of regs it contains. */
-extern int reg_class_size[N_REG_CLASSES];
+extern unsigned int reg_class_size[N_REG_CLASSES];
/* For each reg class, table listing all the containing classes. */
diff --git a/gcc/integrate.c b/gcc/integrate.c
index 2325fae9a01..38dca61528d 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -186,7 +186,8 @@ function_cannot_inline_p (fndecl)
return N_("inline functions not supported for this return value type");
/* We can't inline functions that return structures of varying size. */
- if (int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
+ if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE
+ && int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
return N_("function with varying-size return value cannot be inline");
/* Cannot inline a function with a varying size argument or one that
@@ -755,8 +756,7 @@ expand_inline_function (fndecl, parms, target, ignore, type,
if (arg_vals[i] != 0 && GET_CODE (arg_vals[i]) == REG
&& POINTER_TYPE_P (TREE_TYPE (formal)))
mark_reg_pointer (arg_vals[i],
- (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (formal)))
- / BITS_PER_UNIT));
+ TYPE_ALIGN (TREE_TYPE (TREE_TYPE (formal))));
}
/* Allocate the structures we use to remap things. */
@@ -1760,8 +1760,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
= force_reg (Pmode, force_operand (loc, NULL_RTX));
#ifdef STACK_BOUNDARY
- mark_reg_pointer (map->reg_map[regno],
- STACK_BOUNDARY / BITS_PER_UNIT);
+ mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
#endif
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
@@ -1794,8 +1793,7 @@ copy_rtx_and_substitute (orig, map, for_lhs)
= force_reg (Pmode, force_operand (loc, NULL_RTX));
#ifdef STACK_BOUNDARY
- mark_reg_pointer (map->reg_map[regno],
- STACK_BOUNDARY / BITS_PER_UNIT);
+ mark_reg_pointer (map->reg_map[regno], STACK_BOUNDARY);
#endif
SET_CONST_EQUIV_DATA (map, temp, loc, CONST_AGE_PARM);
@@ -2572,15 +2570,16 @@ mark_stores (dest, x, data)
if (regno >= 0)
{
- int last_reg = (regno >= FIRST_PSEUDO_REGISTER ? regno
- : regno + HARD_REGNO_NREGS (regno, mode) - 1);
- int i;
+ unsigned int uregno = regno;
+ unsigned int last_reg = (uregno >= FIRST_PSEUDO_REGISTER ? uregno
+ : uregno + HARD_REGNO_NREGS (uregno, mode) - 1);
+ unsigned int i;
/* Ignore virtual stack var or virtual arg register since those
are handled separately. */
- if (regno != VIRTUAL_INCOMING_ARGS_REGNUM
- && regno != VIRTUAL_STACK_VARS_REGNUM)
- for (i = regno; i <= last_reg; i++)
+ if (uregno != VIRTUAL_INCOMING_ARGS_REGNUM
+ && uregno != VIRTUAL_STACK_VARS_REGNUM)
+ for (i = uregno; i <= last_reg; i++)
if ((size_t) i < VARRAY_SIZE (global_const_equiv_varray))
VARRAY_CONST_EQUIV (global_const_equiv_varray, i).rtx = 0;
}
diff --git a/gcc/invoke.texi b/gcc/invoke.texi
index 837c48ba855..946abccd672 100644
--- a/gcc/invoke.texi
+++ b/gcc/invoke.texi
@@ -164,8 +164,8 @@ in the following sections.
-finline-functions -finline-limit=@var{n} -fkeep-inline-functions
-fmove-all-movables -fno-default-inline -fno-defer-pop
-fno-function-cse -fno-inline -fno-peephole
--fomit-frame-pointer -foptimize-register-moves -fregmove
--frerun-cse-after-loop -frerun-loop-opt -freduce-all-givs
+-fomit-frame-pointer -foptimize-register-moves -foptimize-sibling-calls
+-fregmove -frerun-cse-after-loop -frerun-loop-opt -freduce-all-givs
-fschedule-insns -fschedule-insns2 -fstrength-reduce
-fstrict-aliasing -fthread-jumps -funroll-all-loops
-funroll-loops
@@ -362,6 +362,7 @@ in the following sections.
-malign-jumps=@var{num} -malign-loops=@var{num}
-malign-functions=@var{num} -mpreferred-stack-boundary=@var{num}
-mthreads -mno-align-stringops -minline-all-stringops
+-mpush-args -maccumulate-outgoing-args
@emph{HPPA Options}
-march=@var{architecture type}
@@ -2461,6 +2462,9 @@ restore frame pointers; it also makes an extra register available
in many functions. @strong{It also makes debugging impossible on
some machines.}
+@item -foptimize-sibling-calls
+Optimize sibling and tail recursive calls.
+
@ifset INTERNALS
On some machines, such as the Vax, this flag has no effect, because
the standard calling sequence automatically handles the frame pointer
@@ -3586,6 +3590,12 @@ text, including the space. Thus two arguments would be generated.
Like %@{@code{S}*@}, but don't put a blank between a switch and its
argument. Thus %@{^o*@} would only generate one argument, not two.
+@item %@{<@code{S}@}
+Remove all occurences of @code{S} from the command line. Note - this
+command is position dependent. @samp{%} commands in the spec string
+before this option will see @code{S}, @samp{%} commands in the spec
+string after this option will not.
+
@item %@{@code{S}*:@code{X}@}
Substitutes @code{X} if one or more switches whose names start with
@code{-S} are specified to GCC. Note that the tail part of the
@@ -6015,6 +6025,21 @@ to stack space usage, such as embedded systems and operating system kernels,
may want to reduce the preferred alignment to
@samp{-mpreferred-stack-boundary=2}.
+@item -mpush-args
+@kindex -mpush-args
+Use PUSH operations to store outgoing parameters. This method is shorter
+and usually equally fast as method using SUB/MOV operations and is enabled
+by default. In some cases disabling it may improve performance because of
+improved scheduling and reduced dependencies.
+
+@item -maccumulate-outgoing-args
+@kindex -maccumulate-outgoing-args
+If enabled, the maximum amount of space required for outgoing arguments will be
+computed in the function prologue. This in faster on most modern CPUs
+because of reduced dependecies, improved scheduling and reduced stack usage
+when preferred stack boundary is not equal to 2. The drawback is a notable
+increase in code size. This switch implies -mno-push-args.
+
@item -mthreads
@kindex -mthreads
Support thread-safe exception handling on @samp{Mingw32}. Code that relies
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 09927d9c24f..8123c230f75 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,16 +1,115 @@
+2000-04-05 Tom Tromey <tromey@cygnus.com>
+
+ Fix for PR gcj/140:
+ * parse.y (check_final_assignment): Recognize assignments to the
+ `length' field of an array when generating class files.
+
+2000-04-05 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c (decl_hash): Prototype removed.
+ (decl_compare): Likewise.
+
+2000-04-05 Tom Tromey <tromey@cygnus.com>
+
+ * parse.h (THIS_MODIFIER_ONLY): Changed meaning of `v' parameter.
+ * parse.y (check_modifiers_consistency): Check for final/volatile
+ clash. Fixes PR gcj/164.
+
+2000-04-05 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * class.c: (java_hash_hash_tree_node): Renamed from `decl_hash',
+ made global.
+ (java_hash_compare_tree_node): Renamed from `decl_compare, made
+ global.
+ (add_method_1): Use `java_hash_hash_tree_node' and
+ `java_hash_compare_tree_node'.
+ * java-tree.h: (java_hash_hash_tree_node): Prototyped.
+ (java_hash_compare_tree_node): Likewise.
+ * parse.y (find_applicable_accessible_methods_list): Create,
+ delete and use a hash table to remember already searched interfaces.
+
+2000-04-03 Matt Welsh <mdw@cs.berkeley.edu>
+
+ * jcf-depend.c (add_entry): Fixed bug where list was always replaced
+ with latest entry.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * boehm.c (mark_reference_fields, set_bit): Prototype.
+ (set_bit): Un-ANSI-fy definition.
+
+ * class.c (init_test_hash_newfunc, decl_hash, decl_compare):
+ Prototype.
+
+ * decl.c (emit_init_test_initialization): Likewise.
+
+ * gjavah.c (jni_print_char): Likewise.
+
+ * parse.y (create_new_parser_context): Likewise.
+
+Thu Mar 30 15:26:56 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * expr.c (java_lang_expand_expr): Added Anthony's Thu Jan 6 2000
+ patch missing hunk. Fixed indentation.
+
+2000-03-30 Tom Tromey <tromey@cygnus.com>
+
+ * gjavah.c (D_NAN_MASK): Only define as word-reversed when
+ HOST_FLOAT_WORDS_BIG_ENDIAN and HOST_WORDS_BIG_ENDIAN disagree.
+
+2000-03-28 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse-scan.y (pop_class_context): Reset `inner_qualifier_length'
+ when negative *before* using it as an array index.
+ * ChangeLog: Fixed typo.
+
+2000-03-28 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse-scan.y (pop_class_context): Reset `inner_qualifier_length'
+ to 0 when it reaches -1.
+
+2000-03-27 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * jcf-parse.c (get_constant): Properly cast `num' during the
+ invocation of `add_double'.
+ * jcf-write.c (push_long_const): Properly cast `lo' before
+ comparing it to short bounds.
+ * parse-scan.y (interface_declaration:): Rule re-arrange so that
+ `interface_body:' is reduced after the current interface is
+ pushed.
+
+2000-03-26 Tom Tromey <tromey@cygnus.com>
+
+ * jvspec.c (jvgenmain_spec): Add `%{<...}' construct for each
+ Java-specific `-f' option.
+
+Sun Mar 26 11:37:55 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * decl.c (init_decl_processing): Only call initialize_sizetypes once.
+ Adjust order of making types.
+ Make bitsize_*_node values.
+
+Sat Mar 25 09:12:10 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
+
+ * class.c (make_field_value): Use byte_position.
+ * expr.c (JAVA_ARRAY_LENGTH_OFFSET): Use byte_position.
+ (java_array_data_offset): Likewise.
+ * java-tree.h (MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC): Add case to
+ bzero call.
+
2000-03-22 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (check_abstract_method_definitions): New local
`end_type_reached'. Make sure we also consider `end_type'.
- (java_check_abstract_method_definitions): Make sure we also
- eventually consider `java.lang.Object'.
- (maybe_use_access_method): Don't use access method if not a pure
- inner class or if the method's context is right.
- (find_applicable_accessible_methods_list): New static
+ (java_check_abstract_method_definitions): Make sure we eventually
+ consider `java.lang.Object'.
+ (maybe_use_access_method): Don't use access method if not in the
+ context of a pure inner class or if the method's context is right.
+ (find_applicable_accessible_methods_list): New static flag
`object_done'. Don't search abstract classes as interfaces. Fixed
- indentation. Fixed the `java.lang.Object' only search. Search class'
- interface(s) first, fully search enclosing contexts.
- (find_most_specific_methods_list): Pick closest candidates when
+ indentation. Fixed the `java.lang.Object' only search. Search
+ class interface(s) first, then fully search enclosing contexts.
+ (find_most_specific_methods_list): Pick the closest candidate when
they're all abstract.
Mon Mar 20 08:58:51 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
@@ -111,6 +210,17 @@ Tue Mar 14 17:15:41 2000 Alexandre Petit-Bianco <apbianco@cygnus.com>
* parse.y (register_incomplete_type): Fixed initialization of
JDEP_ENCLOSING.
+2000-02-28 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * parse-scan.y (inner_qualifier, inner_qualifier_length): New
+ static globals.
+ (push_class_context, pop_class_context): New function.
+ (class_body:): Call pop_class_context.
+ (interface_body:): Likewise.
+ (INNER_QUALIFIER): New macro.
+ (report_class_declaration): Changed output format and use
+ INNER_QUALIFIER. Call push_class_context.
+
2000-02-14 Andrew Haley <aph@cygnus.com>
* check-init.c (check_init): Add new cases for unary and binary
diff --git a/gcc/java/boehm.c b/gcc/java/boehm.c
index 504637e5fd9..98978395fa0 100644
--- a/gcc/java/boehm.c
+++ b/gcc/java/boehm.c
@@ -31,6 +31,15 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "java-tree.h"
#include "parse.h"
+static unsigned int mark_reference_fields PARAMS ((tree,
+ unsigned HOST_WIDE_INT *,
+ unsigned HOST_WIDE_INT *,
+ unsigned int,
+ int *, int *, int *));
+static void set_bit PARAMS ((unsigned HOST_WIDE_INT *,
+ unsigned HOST_WIDE_INT *,
+ unsigned int));
+
/* Compute a procedure-based object descriptor. We know that our
`kind' is 0, and `env' is likewise 0, so we have a simple
computation. From the GC sources:
@@ -42,8 +51,9 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
/* Treat two HOST_WIDE_INT's as a contiguous bitmap, with bit 0 being
the least significant. This function sets bit N in the bitmap. */
static void
-set_bit (unsigned HOST_WIDE_INT *low, unsigned HOST_WIDE_INT *high,
- unsigned int n)
+set_bit (low, high, n)
+ unsigned HOST_WIDE_INT *low, *high;
+ unsigned int n;
{
HOST_WIDE_INT *which;
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 6252d376eb0..031d4b726fe 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -48,6 +48,9 @@ static tree mangle_static_field PARAMS ((tree));
static void add_interface_do PARAMS ((tree, tree, int));
static tree maybe_layout_super_class PARAMS ((tree, tree));
static int assume_compiled PARAMS ((const char *));
+static struct hash_entry *init_test_hash_newfunc PARAMS ((struct hash_entry *,
+ struct hash_table *,
+ hash_table_key));
static rtx registerClass_libfunc;
@@ -589,22 +592,25 @@ init_test_hash_newfunc (entry, table, string)
return (struct hash_entry *) ret;
}
-static unsigned long
-decl_hash (k)
+/* Hash table helpers. Also reused in find_applicable_accessible_methods_list
+ (parse.y). The hash of a tree node is it's pointer value,
+ comparison is direct. */
+
+unsigned long
+java_hash_hash_tree_node (k)
hash_table_key k;
{
return (long) k;
}
-static boolean
-decl_compare (k1, k2)
+boolean
+java_hash_compare_tree_node (k1, k2)
hash_table_key k1;
hash_table_key k2;
{
return ((char*) k1 == (char*) k2);
}
-
tree
add_method_1 (handle_class, access_flags, name, function_type)
tree handle_class;
@@ -627,8 +633,8 @@ add_method_1 (handle_class, access_flags, name, function_type)
/* Initialize the static initializer test table. */
hash_table_init (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl),
- init_test_hash_newfunc, decl_hash,
- decl_compare);
+ init_test_hash_newfunc, java_hash_hash_tree_node,
+ java_hash_compare_tree_node);
TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);
TYPE_METHODS (handle_class) = fndecl;
@@ -1071,7 +1077,7 @@ static tree
make_field_value (fdecl)
tree fdecl;
{
- tree finit, info;
+ tree finit;
int flags;
tree type = TREE_TYPE (fdecl);
int resolved = is_compiled_class (type);
@@ -1083,33 +1089,30 @@ make_field_value (fdecl)
else
{
tree signature = build_java_signature (type);
+
type = build_utf8_ref (unmangle_classname
- (IDENTIFIER_POINTER(signature),
- IDENTIFIER_LENGTH(signature)));
+ (IDENTIFIER_POINTER (signature),
+ IDENTIFIER_LENGTH (signature)));
}
PUSH_FIELD_VALUE (finit, "type", type);
+
flags = get_access_flags_from_decl (fdecl);
if (! resolved)
flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
PUSH_FIELD_VALUE (finit, "accflags", build_int_2 (flags, 0));
PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
- if (FIELD_STATIC (fdecl))
- {
- tree cfield = TREE_CHAIN (TYPE_FIELDS (field_info_union_node));
- tree faddr = build_address_of (build_static_field_ref (fdecl));
-
- info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
- build_tree_list (cfield, faddr));
- }
- else
- info = build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
- build_tree_list (TYPE_FIELDS (field_info_union_node),
- build_int_2 ((int_bit_position (fdecl)
- / BITS_PER_UNIT),
- 0)));
- PUSH_FIELD_VALUE (finit, "info", info);
+ PUSH_FIELD_VALUE
+ (finit, "info",
+ build (CONSTRUCTOR, field_info_union_node, NULL_TREE,
+ build_tree_list
+ ((FIELD_STATIC (fdecl)
+ ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
+ : TYPE_FIELDS (field_info_union_node)),
+ (FIELD_STATIC (fdecl)
+ ? build_address_of (build_static_field_ref (fdecl))
+ : byte_position (fdecl)))));
FINISH_RECORD_CONSTRUCTOR (finit);
return finit;
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index f5cd80ef76f..915d2c9359e 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -46,6 +46,8 @@ static tree push_jvm_slot PARAMS ((int, tree));
static tree lookup_name_current_level PARAMS ((tree));
static tree push_promoted_type PARAMS ((const char *, tree));
static struct binding_level *make_binding_level PARAMS ((void));
+static boolean emit_init_test_initialization PARAMS ((struct hash_entry *,
+ hash_table_key));
/* Set to non-zero value in order to emit class initilization code
before static field references. */
@@ -457,17 +459,13 @@ init_decl_processing ()
pushlevel (0); /* make the binding_level structure for global names */
global_binding_level = current_binding_level;
+ /* The code here must be similar to build_common_tree_nodes{,_2} in
+ tree.c, especially as to the order of initializing common nodes. */
error_mark_node = make_node (ERROR_MARK);
TREE_TYPE (error_mark_node) = error_mark_node;
- initialize_sizetypes ();
/* Create sizetype first - needed for other types. */
initialize_sizetypes ();
- set_sizetype (make_unsigned_type (POINTER_SIZE));
- size_zero_node = build_int_2 (0, 0);
- TREE_TYPE (size_zero_node) = sizetype;
- size_one_node = build_int_2 (1, 0);
- TREE_TYPE (size_one_node) = sizetype;
byte_type_node = make_signed_type (8);
pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node));
@@ -491,14 +489,22 @@ init_decl_processing ()
pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"),
unsigned_long_type_node));
- integer_type_node = type_for_size (INT_TYPE_SIZE, 0);
+ set_sizetype (make_unsigned_type (POINTER_SIZE));
+ /* Define these next since types below may used them. */
+ integer_type_node = type_for_size (INT_TYPE_SIZE, 0);
integer_zero_node = build_int_2 (0, 0);
integer_one_node = build_int_2 (1, 0);
integer_two_node = build_int_2 (2, 0);
integer_four_node = build_int_2 (4, 0);
integer_negative_one_node = build_int_2 (-1, 0);
+ size_zero_node = size_int (0);
+ size_one_node = size_int (1);
+ bitsize_zero_node = bitsize_int (0);
+ bitsize_one_node = bitsize_int (1);
+ bitsize_unit_node = bitsize_int (BITS_PER_UNIT);
+
long_zero_node = build_int_2 (0, 0);
TREE_TYPE (long_zero_node) = long_type_node;
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index dc568578cc0..c5fe6690a2c 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -575,11 +575,8 @@ build_java_ret (location)
/* Array core info access macros */
-#define JAVA_ARRAY_LENGTH_OFFSET(A) \
- size_binop (CEIL_DIV_EXPR, \
- (DECL_FIELD_BITPOS \
- (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \
- bitsize_int (BITS_PER_UNIT))
+#define JAVA_ARRAY_LENGTH_OFFSET(A) \
+ byte_position (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))
tree
decode_newarray_type (atype)
@@ -690,10 +687,11 @@ java_array_data_offset (array)
{
tree array_type = TREE_TYPE (TREE_TYPE (array));
tree data_fld = TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (array_type)));
+
if (data_fld == NULL_TREE)
return size_in_bytes (array_type);
else
- return build_int_2 (int_bit_position (data_fld) / BITS_PER_UNIT, 0);
+ return byte_position (data_fld);
}
/* Implement array indexing (either as l-value or r-value).
@@ -2024,8 +2022,10 @@ java_lang_expand_expr (exp, target, tmode, modifier)
if (TREE_CONSTANT (init)
&& ilength >= 10 && JPRIMITIVE_TYPE_P (element_type))
{
- tree init_decl = build_decl (VAR_DECL, generate_name (),
- TREE_TYPE (init));
+ tree init_decl;
+ push_obstacks (&permanent_obstack, &permanent_obstack);
+ init_decl = build_decl (VAR_DECL, generate_name (),
+ TREE_TYPE (init));
pushdecl_top_level (init_decl);
TREE_STATIC (init_decl) = 1;
DECL_INITIAL (init_decl) = init;
@@ -2033,12 +2033,12 @@ java_lang_expand_expr (exp, target, tmode, modifier)
TREE_READONLY (init_decl) = 1;
TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (init_decl)) = 1;
make_decl_rtl (init_decl, NULL, 1);
+ pop_obstacks ();
init = init_decl;
}
expand_assignment (build (COMPONENT_REF, TREE_TYPE (data_fld),
- build1 (INDIRECT_REF, array_type, array_decl),
- data_fld),
- init, 0, 0);
+ build1 (INDIRECT_REF, array_type,
+ array_decl), data_fld), init, 0, 0);
return tmp;
}
case BLOCK:
diff --git a/gcc/java/gjavah.c b/gcc/java/gjavah.c
index 769eb77b3f2..4c36e879319 100644
--- a/gcc/java/gjavah.c
+++ b/gcc/java/gjavah.c
@@ -146,6 +146,7 @@ static void help PARAMS ((void)) ATTRIBUTE_NORETURN;
static void version PARAMS ((void)) ATTRIBUTE_NORETURN;
static int overloaded_jni_method_exists_p PARAMS ((const unsigned char *, int,
const char *, int));
+static void jni_print_char PARAMS ((FILE *, int));
JCF_u2 current_field_name;
JCF_u2 current_field_value;
@@ -203,7 +204,7 @@ static int decompiled = 0;
/* Some useful constants. */
#define F_NAN_MASK 0x7f800000
-#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN)
+#if (1 == HOST_FLOAT_WORDS_BIG_ENDIAN) && ! defined (HOST_WORDS_BIG_ENDIAN)
#define D_NAN_MASK 0x000000007ff00000LL
#else
#define D_NAN_MASK 0x7ff0000000000000LL
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 5aaceee2c01..e38ed81b105 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -541,9 +541,12 @@ struct lang_decl_var
if (TYPE_LANG_SPECIFIC ((T)) == NULL) \
{ \
TYPE_LANG_SPECIFIC ((T)) = \
- (struct lang_type *)xmalloc (sizeof (struct lang_type)); \
- bzero (TYPE_LANG_SPECIFIC ((T)), sizeof (struct lang_type)); \
+ (struct lang_type *) xmalloc (sizeof (struct lang_type)); \
+ \
+ bzero ((char *) TYPE_LANG_SPECIFIC ((T)), \
+ sizeof (struct lang_type)); \
}
+
#define TYPE_FINIT_STMT_LIST(T) (TYPE_LANG_SPECIFIC(T)->finit_stmt_list)
#define TYPE_CLINIT_STMT_LIST(T) (TYPE_LANG_SPECIFIC(T)->clinit_stmt_list)
#define TYPE_II_STMT_LIST(T) (TYPE_LANG_SPECIFIC(T)->ii_block)
@@ -750,6 +753,9 @@ void java_debug_context PARAMS ((void));
void safe_layout_class PARAMS ((tree));
extern tree get_boehm_type_descriptor PARAMS ((tree));
+extern unsigned long java_hash_hash_tree_node PARAMS ((hash_table_key));
+extern boolean java_hash_compare_tree_node PARAMS ((hash_table_key,
+ hash_table_key));
/* We use ARGS_SIZE_RTX to indicate that gcc/expr.h has been included
to declare `enum expand_modifier'. */
diff --git a/gcc/java/jcf-depend.c b/gcc/java/jcf-depend.c
index 3fb8c00bb15..79d060a4b04 100644
--- a/gcc/java/jcf-depend.c
+++ b/gcc/java/jcf-depend.c
@@ -94,7 +94,7 @@ add_entry (entp, name)
ent->file = xstrdup (name);
ent->next = NULL;
- if (last == *entp)
+ if (last == NULL)
{
// This is only true the first time through, when the entry list
// is empty.
diff --git a/gcc/java/jcf-parse.c b/gcc/java/jcf-parse.c
index 09991eb818e..4c3dff765bc 100644
--- a/gcc/java/jcf-parse.c
+++ b/gcc/java/jcf-parse.c
@@ -272,7 +272,7 @@ get_constant (jcf, index)
HOST_WIDE_INT lo, hi;
lshift_double (num, 0, 32, 64, &lo, &hi, 0);
num = JPOOL_INT (jcf, index+1);
- add_double (lo, hi, num, 0, &lo, &hi);
+ add_double (lo, hi, (uint32)num, 0, &lo, &hi);
value = build_int_2 (lo, hi);
TREE_TYPE (value) = long_type_node;
force_fit_type (value, 0);
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index f2df8c3e276..61ff0fdbf4d 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -845,7 +845,8 @@ push_long_const (lo, hi, state)
RESERVE(1);
OP1(OPCODE_lconst_0 + lo);
}
- else if ((hi == 0 && lo < 32768) || (hi == -1 && lo >= -32768))
+ else if ((hi == 0 && (jword)(lo & 0xFFFFFFFF) < 32768)
+ || (hi == -1 && (jword)(lo & 0xFFFFFFFF) >= -32768))
{
push_int_const (lo, state);
RESERVE (1);
diff --git a/gcc/java/jvspec.c b/gcc/java/jvspec.c
index 4f3a6822e9b..58592f86c48 100644
--- a/gcc/java/jvspec.c
+++ b/gcc/java/jvspec.c
@@ -54,7 +54,14 @@ const char jvgenmain_spec[] =
cc1 %{!pipe:%Umain.i} %1 \
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a*}\
%{g*} %{O*} \
- %{v:-version} %{pg:-p} %{p} %{f*}\
+ %{v:-version} %{pg:-p} %{p}\
+ %{<fbounds-check} %{<fno-bounds-check}\
+ %{<fassume-compiled} %{<fno-assume-compiled}\
+ %{<femit-class-file} %{<femit-class-files}\
+ %{<fuse-boehm-gc} %{<fhash-synchronization} %{<fjni}\
+ %{<fclasspath*} %{<fCLASSPATH*} %{<foutput-class-dir}\
+ %{<fuse-divide-subroutine} %{<fno-use-divide-subroutine}\
+ %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%Umain.s}} |\n\
diff --git a/gcc/java/parse-scan.c b/gcc/java/parse-scan.c
index 2416642ae98..649c18160d7 100644
--- a/gcc/java/parse-scan.c
+++ b/gcc/java/parse-scan.c
@@ -145,6 +145,10 @@ static int absorber;
static const char *current_class;
static const char *package_name;
+/* Keep track of the current inner class qualifier. */
+static char *inner_qualifier;
+static int inner_qualifier_length;
+
/* Keep track of whether things have be listed before. */
static int previous_output;
@@ -171,17 +175,19 @@ struct method_declarator {
/* Two actions for this grammar */
static void report_class_declaration PARAMS ((const char *));
static void report_main_declaration PARAMS ((struct method_declarator *));
+static void push_class_context PARAMS ((const char *));
+static void pop_class_context PARAMS ((void));
#include "lex.h"
#include "parse.h"
-#line 100 "./parse-scan.y"
+#line 106 "./parse-scan.y"
typedef union {
char *node;
struct method_declarator *declarator;
int value; /* For modifiers */
} YYSTYPE;
-#line 106 "./parse-scan.y"
+#line 112 "./parse-scan.y"
#include "lex.c"
#ifndef YYDEBUG
@@ -198,11 +204,11 @@ typedef union {
-#define YYFINAL 601
+#define YYFINAL 605
#define YYFLAG -32768
#define YYNTBASE 110
-#define YYTRANSLATE(x) ((unsigned)(x) <= 363 ? yytranslate[x] : 253)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 363 ? yytranslate[x] : 257)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -257,30 +263,30 @@ static const short yyprhs[] = { 0,
210, 214, 218, 223, 228, 232, 237, 241, 243, 247,
250, 254, 255, 258, 260, 264, 266, 269, 271, 274,
278, 280, 284, 289, 294, 300, 304, 309, 312, 316,
- 320, 325, 330, 336, 344, 351, 353, 355, 359, 364,
- 369, 375, 378, 382, 385, 389, 391, 394, 396, 398,
- 400, 402, 404, 407, 410, 414, 418, 423, 425, 429,
- 432, 436, 438, 441, 443, 445, 447, 450, 453, 457,
- 459, 461, 463, 465, 467, 469, 471, 473, 475, 477,
+ 320, 325, 330, 336, 344, 351, 353, 355, 356, 361,
+ 362, 368, 369, 375, 376, 383, 386, 390, 393, 397,
+ 399, 402, 404, 406, 408, 410, 412, 415, 418, 422,
+ 426, 431, 433, 437, 440, 444, 446, 449, 451, 453,
+ 455, 458, 461, 465, 467, 469, 471, 473, 475, 477,
479, 481, 483, 485, 487, 489, 491, 493, 495, 497,
- 499, 501, 503, 506, 509, 512, 515, 517, 519, 521,
- 523, 525, 527, 529, 535, 543, 551, 557, 560, 564,
- 568, 573, 575, 578, 581, 583, 586, 590, 593, 598,
- 601, 604, 606, 614, 622, 629, 637, 644, 647, 650,
- 651, 653, 655, 656, 658, 660, 664, 667, 671, 674,
- 678, 681, 685, 689, 695, 701, 703, 707, 711, 716,
- 718, 721, 727, 730, 732, 734, 736, 738, 742, 744,
- 746, 748, 750, 754, 758, 762, 766, 772, 777, 784,
- 790, 795, 801, 807, 814, 818, 822, 824, 828, 832,
- 836, 840, 845, 850, 855, 860, 862, 865, 869, 872,
- 876, 880, 884, 888, 893, 899, 906, 912, 919, 924,
- 929, 931, 933, 935, 937, 940, 943, 945, 947, 950,
- 953, 955, 958, 961, 963, 966, 969, 971, 977, 982,
- 987, 993, 995, 999, 1003, 1007, 1009, 1013, 1017, 1019,
- 1023, 1027, 1031, 1033, 1037, 1041, 1045, 1049, 1053, 1055,
- 1059, 1063, 1065, 1069, 1071, 1075, 1077, 1081, 1083, 1087,
- 1089, 1093, 1095, 1101, 1103, 1105, 1109, 1111, 1113, 1115,
- 1117, 1119, 1121
+ 499, 501, 503, 505, 507, 509, 511, 514, 517, 520,
+ 523, 525, 527, 529, 531, 533, 535, 537, 543, 551,
+ 559, 565, 568, 572, 576, 581, 583, 586, 589, 591,
+ 594, 598, 601, 606, 609, 612, 614, 622, 630, 637,
+ 645, 652, 655, 658, 659, 661, 663, 664, 666, 668,
+ 672, 675, 679, 682, 686, 689, 693, 697, 703, 709,
+ 711, 715, 719, 724, 726, 729, 735, 738, 740, 742,
+ 744, 746, 750, 752, 754, 756, 758, 762, 766, 770,
+ 774, 780, 785, 792, 798, 803, 809, 815, 822, 826,
+ 830, 832, 836, 840, 844, 848, 853, 858, 863, 868,
+ 870, 873, 877, 880, 884, 888, 892, 896, 901, 907,
+ 914, 920, 927, 932, 937, 939, 941, 943, 945, 948,
+ 951, 953, 955, 958, 961, 963, 966, 969, 971, 974,
+ 977, 979, 985, 990, 995, 1001, 1003, 1007, 1011, 1015,
+ 1017, 1021, 1025, 1027, 1031, 1035, 1039, 1041, 1045, 1049,
+ 1053, 1057, 1061, 1063, 1067, 1071, 1073, 1077, 1079, 1083,
+ 1085, 1089, 1091, 1095, 1097, 1101, 1103, 1109, 1111, 1113,
+ 1117, 1119, 1121, 1123, 1125, 1127, 1129
};
static const short yyrhs[] = { 123,
@@ -300,144 +306,144 @@ static const short yyrhs[] = { 123,
134, 138, 0, 0, 63, 116, 0, 0, 52, 137,
0, 117, 0, 137, 100, 117, 0, 95, 96, 0,
95, 139, 96, 0, 140, 0, 139, 140, 0, 141,
- 0, 155, 0, 157, 0, 171, 0, 142, 0, 147,
+ 0, 155, 0, 157, 0, 175, 0, 142, 0, 147,
0, 132, 0, 162, 0, 112, 143, 99, 0, 131,
112, 143, 99, 0, 144, 0, 143, 100, 144, 0,
145, 0, 145, 92, 146, 0, 122, 0, 145, 97,
- 98, 0, 251, 0, 169, 0, 148, 154, 0, 112,
+ 98, 0, 255, 0, 173, 0, 148, 154, 0, 112,
149, 152, 0, 59, 149, 152, 0, 131, 112, 149,
152, 0, 131, 59, 149, 152, 0, 122, 93, 94,
0, 122, 93, 150, 94, 0, 149, 97, 98, 0,
151, 0, 150, 100, 151, 0, 112, 145, 0, 131,
112, 145, 0, 0, 53, 153, 0, 116, 0, 153,
- 100, 116, 0, 171, 0, 171, 99, 0, 99, 0,
- 156, 171, 0, 156, 171, 99, 0, 44, 0, 158,
+ 100, 116, 0, 175, 0, 175, 99, 0, 99, 0,
+ 156, 175, 0, 156, 175, 99, 0, 44, 0, 158,
152, 159, 0, 131, 158, 152, 159, 0, 158, 152,
159, 99, 0, 131, 158, 152, 159, 99, 0, 120,
93, 94, 0, 120, 93, 150, 94, 0, 95, 96,
- 0, 95, 160, 96, 0, 95, 172, 96, 0, 95,
- 160, 172, 96, 0, 161, 93, 94, 99, 0, 161,
- 93, 220, 94, 99, 0, 119, 101, 65, 93, 220,
+ 0, 95, 160, 96, 0, 95, 176, 96, 0, 95,
+ 160, 176, 96, 0, 161, 93, 94, 99, 0, 161,
+ 93, 224, 94, 99, 0, 119, 101, 65, 93, 224,
94, 99, 0, 119, 101, 65, 93, 94, 99, 0,
- 76, 0, 65, 0, 61, 122, 164, 0, 131, 61,
- 122, 164, 0, 61, 122, 163, 164, 0, 131, 61,
- 122, 163, 164, 0, 63, 117, 0, 163, 100, 117,
- 0, 95, 96, 0, 95, 165, 96, 0, 166, 0,
- 165, 166, 0, 167, 0, 168, 0, 132, 0, 162,
- 0, 142, 0, 148, 99, 0, 95, 96, 0, 95,
- 170, 96, 0, 95, 100, 96, 0, 95, 170, 100,
- 96, 0, 146, 0, 170, 100, 146, 0, 95, 96,
- 0, 95, 172, 96, 0, 173, 0, 172, 173, 0,
- 174, 0, 176, 0, 132, 0, 175, 99, 0, 112,
- 143, 0, 131, 112, 143, 0, 178, 0, 181, 0,
- 185, 0, 186, 0, 195, 0, 199, 0, 178, 0,
- 182, 0, 187, 0, 196, 0, 200, 0, 171, 0,
- 179, 0, 183, 0, 188, 0, 198, 0, 206, 0,
- 207, 0, 208, 0, 210, 0, 209, 0, 212, 0,
- 99, 0, 122, 88, 0, 180, 176, 0, 180, 177,
- 0, 184, 99, 0, 248, 0, 232, 0, 233, 0,
- 229, 0, 230, 0, 226, 0, 218, 0, 48, 93,
- 251, 94, 176, 0, 48, 93, 251, 94, 177, 56,
- 176, 0, 48, 93, 251, 94, 177, 56, 177, 0,
- 68, 93, 251, 94, 189, 0, 95, 96, 0, 95,
- 192, 96, 0, 95, 190, 96, 0, 95, 190, 192,
- 96, 0, 191, 0, 190, 191, 0, 192, 172, 0,
- 193, 0, 192, 193, 0, 62, 252, 88, 0, 47,
- 88, 0, 66, 93, 251, 94, 0, 194, 176, 0,
- 194, 177, 0, 51, 0, 197, 176, 66, 93, 251,
- 94, 99, 0, 202, 99, 251, 99, 204, 94, 176,
- 0, 202, 99, 99, 204, 94, 176, 0, 202, 99,
- 251, 99, 204, 94, 177, 0, 202, 99, 99, 204,
- 94, 177, 0, 71, 93, 0, 201, 203, 0, 0,
- 205, 0, 175, 0, 0, 205, 0, 184, 0, 205,
- 100, 184, 0, 54, 99, 0, 54, 122, 99, 0,
- 73, 99, 0, 73, 122, 99, 0, 58, 99, 0,
- 58, 251, 99, 0, 49, 251, 99, 0, 211, 93,
- 251, 94, 171, 0, 211, 93, 251, 94, 1, 0,
- 44, 0, 70, 171, 213, 0, 70, 171, 215, 0,
- 70, 171, 213, 215, 0, 214, 0, 213, 214, 0,
- 60, 93, 151, 94, 171, 0, 64, 171, 0, 217,
- 0, 221, 0, 111, 0, 76, 0, 93, 251, 94,
- 0, 218, 0, 225, 0, 226, 0, 227, 0, 119,
- 101, 67, 0, 113, 101, 67, 0, 59, 101, 67,
- 0, 119, 101, 76, 0, 72, 116, 93, 220, 94,
- 0, 72, 116, 93, 94, 0, 72, 116, 93, 220,
- 94, 138, 0, 72, 116, 93, 94, 138, 0, 219,
- 122, 93, 94, 0, 219, 122, 93, 94, 138, 0,
- 219, 122, 93, 220, 94, 0, 219, 122, 93, 220,
- 94, 138, 0, 119, 101, 72, 0, 216, 101, 72,
- 0, 251, 0, 220, 100, 251, 0, 220, 100, 1,
- 0, 72, 113, 222, 0, 72, 115, 222, 0, 72,
- 113, 222, 224, 0, 72, 115, 222, 224, 0, 72,
- 115, 224, 169, 0, 72, 113, 224, 169, 0, 223,
- 0, 222, 223, 0, 97, 251, 98, 0, 97, 98,
- 0, 224, 97, 98, 0, 216, 101, 122, 0, 65,
- 101, 122, 0, 119, 93, 94, 0, 119, 93, 220,
- 94, 0, 216, 101, 122, 93, 94, 0, 216, 101,
- 122, 93, 220, 94, 0, 65, 101, 122, 93, 94,
- 0, 65, 101, 122, 93, 220, 94, 0, 119, 97,
- 251, 98, 0, 217, 97, 251, 98, 0, 216, 0,
- 119, 0, 229, 0, 230, 0, 228, 46, 0, 228,
- 45, 0, 232, 0, 233, 0, 3, 231, 0, 4,
- 231, 0, 234, 0, 46, 231, 0, 45, 231, 0,
- 228, 0, 89, 231, 0, 90, 231, 0, 235, 0,
- 93, 113, 224, 94, 231, 0, 93, 113, 94, 231,
- 0, 93, 251, 94, 234, 0, 93, 119, 224, 94,
- 234, 0, 231, 0, 236, 5, 231, 0, 236, 6,
- 231, 0, 236, 7, 231, 0, 236, 0, 237, 3,
- 236, 0, 237, 4, 236, 0, 237, 0, 238, 8,
- 237, 0, 238, 9, 237, 0, 238, 10, 237, 0,
- 238, 0, 239, 20, 238, 0, 239, 18, 238, 0,
- 239, 21, 238, 0, 239, 19, 238, 0, 239, 57,
- 114, 0, 239, 0, 240, 16, 239, 0, 240, 17,
- 239, 0, 240, 0, 241, 11, 240, 0, 241, 0,
- 242, 12, 241, 0, 242, 0, 243, 13, 242, 0,
- 243, 0, 244, 14, 243, 0, 244, 0, 245, 15,
- 244, 0, 245, 0, 245, 87, 251, 88, 246, 0,
- 246, 0, 248, 0, 249, 250, 247, 0, 119, 0,
- 225, 0, 227, 0, 91, 0, 92, 0, 247, 0,
- 251, 0
+ 76, 0, 65, 0, 0, 61, 122, 163, 168, 0,
+ 0, 131, 61, 122, 164, 168, 0, 0, 61, 122,
+ 167, 165, 168, 0, 0, 131, 61, 122, 167, 166,
+ 168, 0, 63, 117, 0, 167, 100, 117, 0, 95,
+ 96, 0, 95, 169, 96, 0, 170, 0, 169, 170,
+ 0, 171, 0, 172, 0, 132, 0, 162, 0, 142,
+ 0, 148, 99, 0, 95, 96, 0, 95, 174, 96,
+ 0, 95, 100, 96, 0, 95, 174, 100, 96, 0,
+ 146, 0, 174, 100, 146, 0, 95, 96, 0, 95,
+ 176, 96, 0, 177, 0, 176, 177, 0, 178, 0,
+ 180, 0, 132, 0, 179, 99, 0, 112, 143, 0,
+ 131, 112, 143, 0, 182, 0, 185, 0, 189, 0,
+ 190, 0, 199, 0, 203, 0, 182, 0, 186, 0,
+ 191, 0, 200, 0, 204, 0, 175, 0, 183, 0,
+ 187, 0, 192, 0, 202, 0, 210, 0, 211, 0,
+ 212, 0, 214, 0, 213, 0, 216, 0, 99, 0,
+ 122, 88, 0, 184, 180, 0, 184, 181, 0, 188,
+ 99, 0, 252, 0, 236, 0, 237, 0, 233, 0,
+ 234, 0, 230, 0, 222, 0, 48, 93, 255, 94,
+ 180, 0, 48, 93, 255, 94, 181, 56, 180, 0,
+ 48, 93, 255, 94, 181, 56, 181, 0, 68, 93,
+ 255, 94, 193, 0, 95, 96, 0, 95, 196, 96,
+ 0, 95, 194, 96, 0, 95, 194, 196, 96, 0,
+ 195, 0, 194, 195, 0, 196, 176, 0, 197, 0,
+ 196, 197, 0, 62, 256, 88, 0, 47, 88, 0,
+ 66, 93, 255, 94, 0, 198, 180, 0, 198, 181,
+ 0, 51, 0, 201, 180, 66, 93, 255, 94, 99,
+ 0, 206, 99, 255, 99, 208, 94, 180, 0, 206,
+ 99, 99, 208, 94, 180, 0, 206, 99, 255, 99,
+ 208, 94, 181, 0, 206, 99, 99, 208, 94, 181,
+ 0, 71, 93, 0, 205, 207, 0, 0, 209, 0,
+ 179, 0, 0, 209, 0, 188, 0, 209, 100, 188,
+ 0, 54, 99, 0, 54, 122, 99, 0, 73, 99,
+ 0, 73, 122, 99, 0, 58, 99, 0, 58, 255,
+ 99, 0, 49, 255, 99, 0, 215, 93, 255, 94,
+ 175, 0, 215, 93, 255, 94, 1, 0, 44, 0,
+ 70, 175, 217, 0, 70, 175, 219, 0, 70, 175,
+ 217, 219, 0, 218, 0, 217, 218, 0, 60, 93,
+ 151, 94, 175, 0, 64, 175, 0, 221, 0, 225,
+ 0, 111, 0, 76, 0, 93, 255, 94, 0, 222,
+ 0, 229, 0, 230, 0, 231, 0, 119, 101, 67,
+ 0, 113, 101, 67, 0, 59, 101, 67, 0, 119,
+ 101, 76, 0, 72, 116, 93, 224, 94, 0, 72,
+ 116, 93, 94, 0, 72, 116, 93, 224, 94, 138,
+ 0, 72, 116, 93, 94, 138, 0, 223, 122, 93,
+ 94, 0, 223, 122, 93, 94, 138, 0, 223, 122,
+ 93, 224, 94, 0, 223, 122, 93, 224, 94, 138,
+ 0, 119, 101, 72, 0, 220, 101, 72, 0, 255,
+ 0, 224, 100, 255, 0, 224, 100, 1, 0, 72,
+ 113, 226, 0, 72, 115, 226, 0, 72, 113, 226,
+ 228, 0, 72, 115, 226, 228, 0, 72, 115, 228,
+ 173, 0, 72, 113, 228, 173, 0, 227, 0, 226,
+ 227, 0, 97, 255, 98, 0, 97, 98, 0, 228,
+ 97, 98, 0, 220, 101, 122, 0, 65, 101, 122,
+ 0, 119, 93, 94, 0, 119, 93, 224, 94, 0,
+ 220, 101, 122, 93, 94, 0, 220, 101, 122, 93,
+ 224, 94, 0, 65, 101, 122, 93, 94, 0, 65,
+ 101, 122, 93, 224, 94, 0, 119, 97, 255, 98,
+ 0, 221, 97, 255, 98, 0, 220, 0, 119, 0,
+ 233, 0, 234, 0, 232, 46, 0, 232, 45, 0,
+ 236, 0, 237, 0, 3, 235, 0, 4, 235, 0,
+ 238, 0, 46, 235, 0, 45, 235, 0, 232, 0,
+ 89, 235, 0, 90, 235, 0, 239, 0, 93, 113,
+ 228, 94, 235, 0, 93, 113, 94, 235, 0, 93,
+ 255, 94, 238, 0, 93, 119, 228, 94, 238, 0,
+ 235, 0, 240, 5, 235, 0, 240, 6, 235, 0,
+ 240, 7, 235, 0, 240, 0, 241, 3, 240, 0,
+ 241, 4, 240, 0, 241, 0, 242, 8, 241, 0,
+ 242, 9, 241, 0, 242, 10, 241, 0, 242, 0,
+ 243, 20, 242, 0, 243, 18, 242, 0, 243, 21,
+ 242, 0, 243, 19, 242, 0, 243, 57, 114, 0,
+ 243, 0, 244, 16, 243, 0, 244, 17, 243, 0,
+ 244, 0, 245, 11, 244, 0, 245, 0, 246, 12,
+ 245, 0, 246, 0, 247, 13, 246, 0, 247, 0,
+ 248, 14, 247, 0, 248, 0, 249, 15, 248, 0,
+ 249, 0, 249, 87, 255, 88, 250, 0, 250, 0,
+ 252, 0, 253, 254, 251, 0, 119, 0, 229, 0,
+ 231, 0, 91, 0, 92, 0, 251, 0, 255, 0
};
#endif
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 175, 180, 182, 183, 184, 185, 186, 190, 192, 195,
- 201, 206, 213, 215, 218, 222, 226, 230, 232, 236,
- 243, 245, 248, 252, 259, 264, 265, 266, 267, 268,
- 269, 270, 271, 274, 276, 279, 281, 284, 289, 291,
- 294, 298, 302, 304, 305, 311, 320, 331, 338, 338,
- 341, 343, 344, 347, 348, 351, 354, 358, 360, 363,
- 365, 368, 370, 371, 372, 375, 377, 378, 379, 383,
- 386, 390, 393, 396, 398, 401, 404, 408, 410, 414,
- 418, 421, 422, 424, 431, 438, 444, 447, 449, 455,
- 471, 487, 488, 491, 494, 498, 500, 501, 505, 507,
- 510, 520, 522, 525, 527, 533, 536, 540, 542, 543,
- 544, 548, 550, 553, 555, 559, 561, 566, 569, 571,
- 573, 577, 579, 582, 584, 587, 589, 592, 594, 595,
- 596, 599, 603, 608, 610, 611, 612, 615, 617, 621,
- 623, 626, 628, 631, 633, 634, 637, 641, 644, 648,
- 650, 651, 652, 653, 654, 657, 659, 660, 661, 662,
- 665, 667, 668, 669, 670, 671, 672, 673, 674, 675,
- 676, 679, 683, 688, 692, 698, 702, 704, 705, 706,
- 707, 708, 709, 712, 716, 720, 724, 728, 730, 731,
- 732, 735, 737, 740, 745, 747, 750, 752, 755, 759,
- 763, 767, 771, 775, 777, 780, 782, 785, 789, 792,
- 793, 794, 797, 798, 801, 803, 806, 808, 811, 813,
- 816, 818, 821, 825, 827, 830, 835, 837, 838, 841,
- 843, 846, 850, 855, 857, 860, 862, 863, 864, 865,
- 866, 867, 871, 873, 875, 879, 883, 885, 889, 890,
- 894, 895, 896, 897, 900, 903, 906, 908, 909, 912,
- 914, 915, 916, 919, 920, 923, 925, 928, 932, 934,
- 937, 939, 942, 945, 947, 948, 949, 950, 953, 956,
- 959, 961, 963, 964, 967, 971, 975, 977, 978, 979,
- 980, 983, 987, 991, 993, 994, 995, 998, 1000, 1001,
- 1002, 1005, 1007, 1008, 1009, 1012, 1014, 1015, 1018, 1020,
- 1021, 1022, 1025, 1027, 1028, 1029, 1030, 1031, 1034, 1036,
- 1037, 1040, 1042, 1045, 1047, 1050, 1052, 1055, 1057, 1060,
- 1062, 1065, 1067, 1070, 1072, 1075, 1079, 1082, 1083, 1086,
- 1088, 1091, 1095
+ 181, 186, 188, 189, 190, 191, 192, 196, 198, 201,
+ 207, 212, 219, 221, 224, 228, 232, 236, 238, 242,
+ 249, 251, 254, 258, 265, 270, 271, 272, 273, 274,
+ 275, 276, 277, 280, 282, 285, 287, 290, 295, 297,
+ 300, 304, 308, 310, 311, 317, 326, 337, 344, 344,
+ 347, 349, 350, 353, 354, 357, 360, 364, 367, 371,
+ 373, 376, 378, 379, 380, 383, 385, 386, 387, 391,
+ 394, 398, 401, 404, 406, 409, 412, 416, 418, 422,
+ 426, 429, 430, 432, 439, 446, 452, 455, 457, 463,
+ 479, 495, 496, 499, 502, 506, 508, 509, 513, 515,
+ 518, 528, 530, 533, 535, 541, 544, 548, 550, 551,
+ 552, 556, 558, 561, 563, 567, 569, 574, 578, 578,
+ 581, 581, 584, 584, 587, 589, 591, 594, 597, 601,
+ 603, 606, 608, 609, 610, 613, 617, 622, 624, 625,
+ 626, 629, 631, 635, 637, 640, 642, 645, 647, 648,
+ 651, 655, 658, 662, 664, 665, 666, 667, 668, 671,
+ 673, 674, 675, 676, 679, 681, 682, 683, 684, 685,
+ 686, 687, 688, 689, 690, 693, 697, 702, 706, 712,
+ 716, 718, 719, 720, 721, 722, 723, 726, 730, 734,
+ 738, 742, 744, 745, 746, 749, 751, 754, 759, 761,
+ 764, 766, 769, 773, 777, 781, 785, 789, 791, 794,
+ 796, 799, 803, 806, 807, 808, 811, 812, 815, 817,
+ 820, 822, 825, 827, 830, 832, 835, 839, 841, 844,
+ 849, 851, 852, 855, 857, 860, 864, 869, 871, 874,
+ 876, 877, 878, 879, 880, 881, 885, 887, 889, 893,
+ 897, 899, 903, 904, 908, 909, 910, 911, 914, 917,
+ 920, 922, 923, 926, 928, 929, 930, 933, 934, 937,
+ 939, 942, 946, 948, 951, 953, 956, 959, 961, 962,
+ 963, 964, 967, 970, 973, 975, 977, 978, 981, 985,
+ 989, 991, 992, 993, 994, 997, 1001, 1005, 1007, 1008,
+ 1009, 1012, 1014, 1015, 1016, 1019, 1021, 1022, 1023, 1026,
+ 1028, 1029, 1032, 1034, 1035, 1036, 1039, 1041, 1042, 1043,
+ 1044, 1045, 1048, 1050, 1051, 1054, 1056, 1059, 1061, 1064,
+ 1066, 1069, 1071, 1074, 1076, 1079, 1081, 1084, 1086, 1089,
+ 1093, 1096, 1097, 1100, 1102, 1105, 1109
};
#endif
@@ -471,11 +477,12 @@ static const char * const yytname[] = { "$","error","$undefined.","PLUS_TK",
"method_declarator","formal_parameter_list","formal_parameter","throws","class_type_list",
"method_body","static_initializer","static","constructor_declaration","constructor_declarator",
"constructor_body","explicit_constructor_invocation","this_or_super","interface_declaration",
-"extends_interfaces","interface_body","interface_member_declarations","interface_member_declaration",
-"constant_declaration","abstract_method_declaration","array_initializer","variable_initializers",
-"block","block_statements","block_statement","local_variable_declaration_statement",
-"local_variable_declaration","statement","statement_nsi","statement_without_trailing_substatement",
-"empty_statement","label_decl","labeled_statement","labeled_statement_nsi","expression_statement",
+"@3","@4","@5","@6","extends_interfaces","interface_body","interface_member_declarations",
+"interface_member_declaration","constant_declaration","abstract_method_declaration",
+"array_initializer","variable_initializers","block","block_statements","block_statement",
+"local_variable_declaration_statement","local_variable_declaration","statement",
+"statement_nsi","statement_without_trailing_substatement","empty_statement",
+"label_decl","labeled_statement","labeled_statement_nsi","expression_statement",
"statement_expression","if_then_statement","if_then_else_statement","if_then_else_statement_nsi",
"switch_statement","switch_block","switch_block_statement_groups","switch_block_statement_group",
"switch_labels","switch_label","while_expression","while_statement","while_statement_nsi",
@@ -507,30 +514,30 @@ static const short yyr1[] = { 0,
148, 148, 148, 148, 149, 149, 149, 150, 150, 151,
151, 152, 152, 153, 153, 154, 154, 154, 155, 155,
156, 157, 157, 157, 157, 158, 158, 159, 159, 159,
- 159, 160, 160, 160, 160, 161, 161, 162, 162, 162,
- 162, 163, 163, 164, 164, 165, 165, 166, 166, 166,
- 166, 167, 168, 169, 169, 169, 169, 170, 170, 171,
- 171, 172, 172, 173, 173, 173, 174, 175, 175, 176,
- 176, 176, 176, 176, 176, 177, 177, 177, 177, 177,
- 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
- 178, 179, 180, 181, 182, 183, 184, 184, 184, 184,
- 184, 184, 184, 185, 186, 187, 188, 189, 189, 189,
- 189, 190, 190, 191, 192, 192, 193, 193, 194, 195,
- 196, 197, 198, 199, 199, 200, 200, 201, 202, 203,
- 203, 203, 204, 204, 205, 205, 206, 206, 207, 207,
- 208, 208, 209, 210, 210, 211, 212, 212, 212, 213,
- 213, 214, 215, 216, 216, 217, 217, 217, 217, 217,
- 217, 217, 217, 217, 217, 217, 218, 218, 218, 218,
- 218, 218, 218, 218, 219, 219, 220, 220, 220, 221,
- 221, 221, 221, 221, 221, 222, 222, 223, 224, 224,
- 225, 225, 226, 226, 226, 226, 226, 226, 227, 227,
- 228, 228, 228, 228, 229, 230, 231, 231, 231, 231,
- 231, 232, 233, 234, 234, 234, 234, 235, 235, 235,
- 235, 236, 236, 236, 236, 237, 237, 237, 238, 238,
- 238, 238, 239, 239, 239, 239, 239, 239, 240, 240,
- 240, 241, 241, 242, 242, 243, 243, 244, 244, 245,
- 245, 246, 246, 247, 247, 248, 249, 249, 249, 250,
- 250, 251, 252
+ 159, 160, 160, 160, 160, 161, 161, 163, 162, 164,
+ 162, 165, 162, 166, 162, 167, 167, 168, 168, 169,
+ 169, 170, 170, 170, 170, 171, 172, 173, 173, 173,
+ 173, 174, 174, 175, 175, 176, 176, 177, 177, 177,
+ 178, 179, 179, 180, 180, 180, 180, 180, 180, 181,
+ 181, 181, 181, 181, 182, 182, 182, 182, 182, 182,
+ 182, 182, 182, 182, 182, 183, 184, 185, 186, 187,
+ 188, 188, 188, 188, 188, 188, 188, 189, 190, 191,
+ 192, 193, 193, 193, 193, 194, 194, 195, 196, 196,
+ 197, 197, 198, 199, 200, 201, 202, 203, 203, 204,
+ 204, 205, 206, 207, 207, 207, 208, 208, 209, 209,
+ 210, 210, 211, 211, 212, 212, 213, 214, 214, 215,
+ 216, 216, 216, 217, 217, 218, 219, 220, 220, 221,
+ 221, 221, 221, 221, 221, 221, 221, 221, 221, 221,
+ 222, 222, 222, 222, 222, 222, 222, 222, 223, 223,
+ 224, 224, 224, 225, 225, 225, 225, 225, 225, 226,
+ 226, 227, 228, 228, 229, 229, 230, 230, 230, 230,
+ 230, 230, 231, 231, 232, 232, 232, 232, 233, 234,
+ 235, 235, 235, 235, 235, 236, 237, 238, 238, 238,
+ 238, 239, 239, 239, 239, 240, 240, 240, 240, 241,
+ 241, 241, 242, 242, 242, 242, 243, 243, 243, 243,
+ 243, 243, 244, 244, 244, 245, 245, 246, 246, 247,
+ 247, 248, 248, 249, 249, 250, 250, 251, 251, 252,
+ 253, 253, 253, 254, 254, 255, 256
};
static const short yyr2[] = { 0,
@@ -545,834 +552,858 @@ static const short yyr2[] = { 0,
3, 3, 4, 4, 3, 4, 3, 1, 3, 2,
3, 0, 2, 1, 3, 1, 2, 1, 2, 3,
1, 3, 4, 4, 5, 3, 4, 2, 3, 3,
- 4, 4, 5, 7, 6, 1, 1, 3, 4, 4,
- 5, 2, 3, 2, 3, 1, 2, 1, 1, 1,
- 1, 1, 2, 2, 3, 3, 4, 1, 3, 2,
- 3, 1, 2, 1, 1, 1, 2, 2, 3, 1,
+ 4, 4, 5, 7, 6, 1, 1, 0, 4, 0,
+ 5, 0, 5, 0, 6, 2, 3, 2, 3, 1,
+ 2, 1, 1, 1, 1, 1, 2, 2, 3, 3,
+ 4, 1, 3, 2, 3, 1, 2, 1, 1, 1,
+ 2, 2, 3, 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, 2, 2, 2, 2, 1, 1, 1, 1,
- 1, 1, 1, 5, 7, 7, 5, 2, 3, 3,
- 4, 1, 2, 2, 1, 2, 3, 2, 4, 2,
- 2, 1, 7, 7, 6, 7, 6, 2, 2, 0,
- 1, 1, 0, 1, 1, 3, 2, 3, 2, 3,
- 2, 3, 3, 5, 5, 1, 3, 3, 4, 1,
- 2, 5, 2, 1, 1, 1, 1, 3, 1, 1,
- 1, 1, 3, 3, 3, 3, 5, 4, 6, 5,
- 4, 5, 5, 6, 3, 3, 1, 3, 3, 3,
- 3, 4, 4, 4, 4, 1, 2, 3, 2, 3,
- 3, 3, 3, 4, 5, 6, 5, 6, 4, 4,
- 1, 1, 1, 1, 2, 2, 1, 1, 2, 2,
- 1, 2, 2, 1, 2, 2, 1, 5, 4, 4,
- 5, 1, 3, 3, 3, 1, 3, 3, 1, 3,
- 3, 3, 1, 3, 3, 3, 3, 3, 1, 3,
- 3, 1, 3, 1, 3, 1, 3, 1, 3, 1,
- 3, 1, 5, 1, 1, 3, 1, 1, 1, 1,
- 1, 1, 1
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 5, 7, 7,
+ 5, 2, 3, 3, 4, 1, 2, 2, 1, 2,
+ 3, 2, 4, 2, 2, 1, 7, 7, 6, 7,
+ 6, 2, 2, 0, 1, 1, 0, 1, 1, 3,
+ 2, 3, 2, 3, 2, 3, 3, 5, 5, 1,
+ 3, 3, 4, 1, 2, 5, 2, 1, 1, 1,
+ 1, 3, 1, 1, 1, 1, 3, 3, 3, 3,
+ 5, 4, 6, 5, 4, 5, 5, 6, 3, 3,
+ 1, 3, 3, 3, 3, 4, 4, 4, 4, 1,
+ 2, 3, 2, 3, 3, 3, 3, 4, 5, 6,
+ 5, 6, 4, 4, 1, 1, 1, 1, 2, 2,
+ 1, 1, 2, 2, 1, 2, 2, 1, 2, 2,
+ 1, 5, 4, 4, 5, 1, 3, 3, 3, 1,
+ 3, 3, 1, 3, 3, 3, 1, 3, 3, 3,
+ 3, 3, 1, 3, 3, 1, 3, 1, 3, 1,
+ 3, 1, 3, 1, 3, 1, 5, 1, 1, 3,
+ 1, 1, 1, 1, 1, 1, 1
};
static const short yydefact[] = { 26,
46, 0, 0, 0, 0, 45, 1, 28, 29, 27,
34, 39, 40, 36, 0, 43, 44, 25, 0, 21,
- 22, 23, 0, 52, 0, 32, 35, 37, 30, 31,
- 47, 0, 0, 41, 0, 0, 0, 0, 118, 0,
- 54, 38, 0, 33, 0, 52, 0, 24, 17, 122,
- 15, 12, 0, 10, 11, 124, 0, 8, 9, 13,
- 14, 15, 0, 130, 132, 0, 131, 0, 126, 128,
- 129, 0, 120, 16, 53, 0, 50, 0, 119, 54,
- 42, 0, 92, 76, 0, 72, 74, 92, 0, 0,
- 0, 0, 0, 133, 125, 127, 123, 56, 55, 0,
- 121, 48, 0, 0, 0, 82, 70, 0, 0, 0,
- 81, 18, 20, 19, 92, 0, 92, 0, 0, 51,
- 0, 85, 0, 0, 0, 88, 94, 93, 87, 76,
- 73, 0, 0, 0, 0, 0, 0, 0, 237, 0,
- 0, 0, 0, 6, 5, 2, 3, 4, 7, 236,
- 0, 282, 75, 79, 281, 234, 239, 0, 235, 240,
- 241, 242, 294, 283, 284, 302, 287, 288, 291, 297,
- 306, 309, 313, 319, 322, 324, 326, 328, 330, 332,
- 334, 342, 335, 0, 78, 77, 84, 71, 83, 57,
- 46, 0, 58, 21, 0, 68, 0, 60, 62, 66,
- 67, 0, 63, 0, 64, 92, 69, 65, 49, 90,
- 0, 86, 0, 0, 282, 240, 242, 289, 290, 293,
- 292, 0, 0, 0, 16, 0, 295, 296, 0, 282,
- 0, 134, 0, 138, 0, 0, 0, 0, 0, 0,
- 0, 0, 286, 285, 0, 0, 0, 0, 0, 0,
+ 22, 23, 118, 52, 0, 32, 35, 37, 30, 31,
+ 47, 0, 0, 41, 0, 0, 0, 122, 0, 54,
+ 38, 0, 33, 120, 52, 0, 24, 17, 126, 15,
+ 0, 119, 0, 0, 16, 53, 0, 50, 0, 124,
+ 54, 42, 12, 0, 10, 11, 128, 0, 8, 9,
+ 13, 14, 15, 0, 134, 136, 0, 135, 0, 130,
+ 132, 133, 127, 123, 56, 55, 0, 121, 0, 48,
+ 0, 92, 76, 0, 72, 74, 92, 0, 0, 0,
+ 0, 0, 137, 129, 131, 0, 0, 51, 125, 0,
+ 0, 0, 0, 82, 70, 0, 0, 0, 81, 18,
+ 20, 19, 92, 0, 92, 57, 46, 0, 58, 21,
+ 0, 68, 0, 60, 62, 66, 67, 0, 63, 0,
+ 64, 92, 69, 65, 49, 85, 0, 0, 0, 88,
+ 94, 93, 87, 76, 73, 0, 0, 0, 0, 0,
+ 0, 0, 241, 0, 0, 0, 0, 6, 5, 2,
+ 3, 4, 7, 240, 0, 286, 75, 79, 285, 238,
+ 243, 0, 239, 244, 245, 246, 298, 287, 288, 306,
+ 291, 292, 295, 301, 310, 313, 317, 323, 326, 328,
+ 330, 332, 334, 336, 338, 346, 339, 0, 78, 77,
+ 84, 71, 83, 46, 0, 0, 206, 0, 0, 0,
+ 0, 0, 0, 0, 0, 144, 176, 0, 8, 286,
+ 23, 0, 150, 165, 0, 146, 148, 0, 149, 154,
+ 166, 0, 155, 167, 0, 156, 157, 168, 0, 158,
+ 0, 169, 159, 214, 0, 170, 171, 172, 174, 173,
+ 0, 175, 243, 245, 0, 184, 185, 182, 183, 181,
+ 0, 92, 59, 61, 98, 80, 96, 99, 0, 90,
+ 0, 86, 0, 0, 286, 244, 246, 293, 294, 297,
+ 296, 0, 0, 0, 16, 0, 299, 300, 0, 286,
+ 0, 138, 0, 142, 0, 0, 0, 0, 0, 0,
+ 0, 0, 290, 289, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 340, 341, 0, 46, 0,
- 0, 202, 0, 0, 0, 0, 0, 0, 0, 0,
- 140, 172, 0, 8, 282, 23, 0, 146, 161, 0,
- 142, 144, 0, 145, 150, 162, 0, 151, 163, 0,
- 152, 153, 164, 0, 154, 0, 165, 155, 210, 0,
- 166, 167, 168, 170, 169, 0, 171, 239, 241, 0,
- 180, 181, 178, 179, 177, 0, 92, 59, 61, 98,
- 80, 96, 99, 0, 91, 89, 95, 245, 272, 0,
- 260, 266, 0, 261, 0, 0, 0, 0, 0, 0,
- 0, 238, 136, 135, 0, 244, 273, 0, 257, 0,
- 243, 255, 246, 256, 271, 0, 0, 303, 304, 305,
- 307, 308, 310, 311, 312, 315, 317, 314, 316, 0,
- 318, 320, 321, 323, 325, 327, 329, 331, 0, 336,
- 0, 0, 217, 0, 221, 0, 0, 0, 0, 208,
- 219, 0, 0, 148, 0, 173, 0, 141, 143, 147,
- 226, 174, 176, 200, 0, 0, 212, 215, 209, 211,
- 0, 0, 106, 0, 0, 97, 100, 0, 102, 0,
- 269, 0, 267, 262, 0, 265, 263, 264, 248, 0,
- 299, 0, 0, 300, 137, 139, 274, 0, 279, 0,
- 280, 251, 0, 0, 0, 223, 218, 222, 0, 0,
- 0, 0, 227, 230, 228, 220, 238, 149, 0, 0,
- 213, 0, 0, 107, 103, 117, 237, 108, 282, 0,
- 0, 0, 104, 277, 0, 268, 270, 250, 247, 298,
- 301, 259, 258, 275, 0, 252, 253, 333, 0, 199,
- 0, 0, 233, 231, 229, 0, 216, 0, 214, 213,
- 0, 105, 0, 109, 0, 0, 110, 278, 249, 276,
- 254, 0, 184, 0, 150, 0, 157, 158, 0, 159,
- 160, 0, 0, 187, 0, 0, 0, 0, 225, 224,
- 0, 111, 0, 0, 0, 0, 175, 201, 0, 0,
- 0, 188, 0, 192, 0, 195, 0, 0, 205, 0,
- 0, 112, 0, 0, 185, 213, 0, 198, 343, 0,
- 190, 193, 0, 189, 194, 196, 232, 203, 204, 0,
- 0, 113, 0, 0, 213, 197, 191, 115, 0, 0,
- 0, 0, 114, 0, 207, 0, 186, 206, 0, 0,
- 0
+ 0, 0, 0, 0, 0, 344, 345, 0, 0, 0,
+ 221, 0, 225, 0, 0, 0, 0, 212, 223, 0,
+ 0, 152, 0, 177, 0, 145, 147, 151, 230, 178,
+ 180, 204, 0, 0, 216, 219, 213, 215, 0, 0,
+ 106, 0, 0, 97, 100, 0, 102, 91, 89, 95,
+ 249, 276, 0, 264, 270, 0, 265, 0, 0, 0,
+ 0, 0, 0, 0, 242, 140, 139, 0, 248, 277,
+ 0, 261, 0, 247, 259, 250, 260, 275, 0, 0,
+ 307, 308, 309, 311, 312, 314, 315, 316, 319, 321,
+ 318, 320, 0, 322, 324, 325, 327, 329, 331, 333,
+ 335, 0, 340, 0, 227, 222, 226, 0, 0, 0,
+ 0, 231, 234, 232, 224, 242, 153, 0, 0, 217,
+ 0, 0, 107, 103, 117, 241, 108, 286, 0, 0,
+ 0, 104, 0, 273, 0, 271, 266, 0, 269, 267,
+ 268, 252, 0, 303, 0, 0, 304, 141, 143, 278,
+ 0, 283, 0, 284, 255, 0, 0, 0, 203, 0,
+ 0, 237, 235, 233, 0, 220, 0, 218, 217, 0,
+ 105, 0, 109, 0, 0, 110, 281, 0, 272, 274,
+ 254, 251, 302, 305, 263, 262, 279, 0, 256, 257,
+ 337, 0, 188, 0, 154, 0, 161, 162, 0, 163,
+ 164, 0, 0, 191, 0, 0, 0, 0, 229, 228,
+ 0, 111, 0, 0, 282, 253, 280, 258, 0, 0,
+ 179, 205, 0, 0, 0, 192, 0, 196, 0, 199,
+ 0, 0, 209, 0, 0, 112, 0, 0, 189, 217,
+ 0, 202, 347, 0, 194, 197, 0, 193, 198, 200,
+ 236, 207, 208, 0, 0, 113, 0, 0, 217, 201,
+ 195, 115, 0, 0, 0, 0, 114, 0, 211, 0,
+ 190, 210, 0, 0, 0
};
-static const short yydefgoto[] = { 599,
- 150, 283, 151, 59, 60, 75, 50, 61, 152, 20,
+static const short yydefgoto[] = { 603,
+ 174, 228, 175, 70, 71, 56, 49, 72, 176, 20,
21, 22, 7, 8, 9, 10, 11, 12, 13, 14,
- 287, 288, 121, 100, 41, 77, 99, 120, 197, 198,
- 199, 65, 85, 86, 87, 153, 201, 66, 83, 125,
- 126, 106, 128, 331, 203, 204, 205, 206, 429, 480,
- 481, 17, 38, 39, 68, 69, 70, 71, 154, 235,
- 289, 575, 291, 292, 293, 294, 524, 295, 296, 297,
- 298, 527, 299, 300, 301, 302, 528, 303, 534, 553,
- 554, 555, 556, 304, 305, 530, 306, 307, 308, 531,
- 309, 310, 419, 508, 509, 311, 312, 313, 314, 315,
- 316, 317, 463, 464, 465, 155, 156, 157, 158, 358,
- 159, 341, 342, 343, 160, 161, 162, 163, 164, 165,
- 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 176, 177, 178, 179, 180, 181, 182, 183, 184, 268,
- 359, 570
+ 232, 233, 110, 87, 40, 58, 86, 108, 133, 134,
+ 135, 76, 94, 95, 96, 177, 137, 77, 92, 149,
+ 150, 114, 152, 276, 139, 140, 141, 142, 377, 459,
+ 460, 17, 37, 59, 54, 89, 38, 52, 79, 80,
+ 81, 82, 178, 305, 234, 579, 236, 237, 238, 239,
+ 524, 240, 241, 242, 243, 527, 244, 245, 246, 247,
+ 528, 248, 534, 557, 558, 559, 560, 249, 250, 530,
+ 251, 252, 253, 531, 254, 255, 367, 497, 498, 256,
+ 257, 258, 259, 260, 261, 262, 442, 443, 444, 179,
+ 180, 181, 182, 401, 183, 384, 385, 386, 184, 185,
+ 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
+ 196, 197, 198, 199, 200, 201, 202, 203, 204, 205,
+ 206, 207, 208, 338, 402, 574
};
-static const short yypact[] = { 11,
--32768, -52, -52, -52, -52,-32768,-32768, 18, 154, 18,
--32768,-32768,-32768,-32768, 185,-32768,-32768,-32768, 187,-32768,
--32768,-32768, -24, -5, 332, 154,-32768,-32768, 18, 154,
--32768, -52, -52,-32768, 5, -52, 745, 162,-32768, -52,
- 76,-32768, -52, 154, -24, -5, 57,-32768,-32768,-32768,
- 41,-32768, -52,-32768,-32768,-32768, -52, 71,-32768,-32768,
- 170, 113, 518,-32768,-32768, 126,-32768, 758,-32768,-32768,
--32768, -52,-32768,-32768,-32768, -52,-32768, 162,-32768, 76,
--32768, 249, -15, 249, 321,-32768, 205, -15, 149, 255,
- 265, -52, -52,-32768,-32768,-32768,-32768,-32768, 198, 294,
--32768,-32768, 58, -52, 298,-32768,-32768, -52, 1568, 309,
--32768,-32768,-32768,-32768, -15, 359, -15, -52, 596,-32768,
- 294,-32768, -52, 199, -13,-32768,-32768, 310,-32768,-32768,
--32768, 2315, 2315, 2315, 2315, 329, 352, 88,-32768, 2315,
- 2315, 2315, 1438,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
- 354, 393,-32768,-32768, 360, 369,-32768, -52,-32768, 347,
--32768, 378, 437,-32768,-32768,-32768,-32768,-32768,-32768,-32768,
- 445, 495, 483, 380, 492, 461, 462, 467, 502, 1,
--32768,-32768,-32768, 412,-32768,-32768,-32768,-32768,-32768,-32768,
- 423, 2513,-32768, 429, 518,-32768, 683,-32768,-32768,-32768,
--32768, 128,-32768, 432,-32768, 471,-32768,-32768,-32768, 435,
- -52,-32768, 337, -52, 52,-32768,-32768,-32768,-32768,-32768,
--32768, 468, -52, 440, 440, 449,-32768,-32768, 174, 414,
- 454,-32768, 460,-32768, 235, 500, 1619, 2315, 261, -21,
- 2315, 476,-32768,-32768, 2315, 2315, 2315, 2315, 2315, 2315,
- 2315, 2315, 2315, 2315, 2315, 2315, 88, 2315, 2315, 2315,
- 2315, 2315, 2315, 2315, 2315,-32768,-32768, 2315, 480, 482,
- 2315,-32768, 60, 1684, 490, 491, 432, 494, 89, 2315,
--32768,-32768, -52, 137, 559, 488, 496,-32768,-32768, 2579,
--32768,-32768, 493,-32768,-32768,-32768, 2975,-32768,-32768, 498,
--32768,-32768,-32768, 2975,-32768, 2975,-32768,-32768, 1029, 499,
--32768,-32768,-32768,-32768,-32768, 497,-32768, 96, 196, 437,
- 485, 505,-32768,-32768,-32768, 323, 471,-32768,-32768,-32768,
--32768, 506, 507, 504, 435,-32768,-32768,-32768, 508, 1735,
- 440,-32768, 339, 440, 339, 1800, 2315, 509, 180, 1735,
- 246, 1364,-32768,-32768, 1503,-32768,-32768, 3,-32768, 512,
--32768,-32768,-32768,-32768, 520, 513, 1851,-32768,-32768,-32768,
- 445, 445, 495, 495, 495, 483, 483, 483, 483, 71,
--32768, 380, 380, 492, 461, 462, 467, 502, 501,-32768,
- 2315, 522,-32768, 523,-32768, 526, 2315, 2315, 322,-32768,
--32768, 528, 534, 535, 1916,-32768, -52,-32768,-32768,-32768,
--32768,-32768,-32768,-32768, 572, 199,-32768,-32768,-32768, 539,
- 1967, 2315,-32768, 141, 504,-32768,-32768, 2645, 543, 2032,
--32768, 545,-32768, 547, 549,-32768, 547,-32768, 294, 244,
--32768, 2315, 1364,-32768,-32768,-32768,-32768, 1323,-32768, 2083,
--32768, 294, 251, 2315, 555,-32768,-32768,-32768, 564, 565,
- 573, 432, 322,-32768,-32768,-32768,-32768, 535, 576, 1171,
- 1171, 566, 582,-32768, 571, 352, 584,-32768, 849, 2711,
- 587, 2777,-32768,-32768, 256,-32768,-32768,-32768, 294,-32768,
--32768,-32768,-32768,-32768, 260,-32768, 294,-32768, 3041,-32768,
- 588, 337,-32768,-32768,-32768, 2315,-32768, 591, 539, 1171,
- 6,-32768, 183,-32768, 2843, 2148,-32768,-32768,-32768,-32768,
--32768, 593,-32768, 631, 632, 3041,-32768,-32768, 3041,-32768,
--32768, 590, -16,-32768, 600, 601, 2975, 602,-32768,-32768,
- 604,-32768, 603, 272, 2315, 2975,-32768,-32768, 2199, 611,
- 2315,-32768, 45,-32768, 2381,-32768, 432, 609,-32768, 2975,
- 2264,-32768, 610, 616,-32768, 1171, 613,-32768,-32768, 615,
--32768,-32768, 2447,-32768, 2909,-32768,-32768,-32768,-32768, 619,
- 280,-32768, 3041, 621, 1171,-32768,-32768,-32768, 623, 670,
- 3041, 636,-32768, 3041,-32768, 3041,-32768,-32768, 725, 735,
--32768
+static const short yypact[] = { 206,
+-32768, -59, -59, -59, -59,-32768,-32768, 84, -10, 84,
+-32768,-32768,-32768,-32768, 149,-32768,-32768,-32768, 113,-32768,
+-32768,-32768, -27, 16, 155, -10,-32768,-32768, 84, -10,
+-32768, -59, -59,-32768, 6, -59, -23, -13, -59, 44,
+-32768, -59, -10, -27, 16, 28,-32768,-32768,-32768, 55,
+ 751,-32768, -59, -23,-32768,-32768, -59,-32768, -23, -13,
+ 44,-32768,-32768, -59,-32768,-32768,-32768, -59, 94,-32768,
+-32768, 127, 179, 834,-32768,-32768, 66,-32768, 822,-32768,
+-32768,-32768,-32768,-32768,-32768, 81, 134,-32768, -23,-32768,
+ 154, -35, 154, 290,-32768, 27, -35, 166, 177, 187,
+ -59, -59,-32768,-32768,-32768, -59, 485,-32768,-32768, 134,
+ 207, -59, 225,-32768,-32768, -59, 1549, 238,-32768,-32768,
+-32768,-32768, -35, 353, -35,-32768, 271, 2494,-32768, 293,
+ 834,-32768, 579,-32768,-32768,-32768,-32768, 213,-32768, 286,
+-32768, 374,-32768,-32768,-32768,-32768, -59, 68, 21,-32768,
+-32768, 336,-32768,-32768,-32768, 2296, 2296, 2296, 2296, 342,
+ 363, 294,-32768, 2296, 2296, 2296, 1419,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 366, 338,-32768,-32768, 368, 381,
+-32768, -59,-32768, 204,-32768, 419, 474,-32768,-32768,-32768,
+-32768,-32768,-32768,-32768, 443, 518, 505, 310, 508, 472,
+ 479, 481, 482, 4,-32768,-32768,-32768, 436,-32768,-32768,
+-32768,-32768,-32768, 405, 407, 2296,-32768, 102, 1600, 412,
+ 414, 286, 440, 121, 2296,-32768,-32768, -59, 224, 354,
+ 450, 568,-32768,-32768, 2560,-32768,-32768, 456,-32768,-32768,
+-32768, 2956,-32768,-32768, 458,-32768,-32768,-32768, 2956,-32768,
+ 2956,-32768,-32768, 3088, 465,-32768,-32768,-32768,-32768,-32768,
+ 475,-32768, 215, 284, 474, 496, 517,-32768,-32768,-32768,
+ 283, 374,-32768,-32768,-32768,-32768, 467, 476, 477, 480,
+ -59,-32768, 173, -59, 148,-32768,-32768,-32768,-32768,-32768,
+-32768, 511, -59, 486, 486, 493,-32768,-32768, 171, 369,
+ 494,-32768, 483,-32768, 226, 522, 1665, 2296, 9, 100,
+ 2296, 497,-32768,-32768, 2296, 2296, 2296, 2296, 2296, 2296,
+ 2296, 2296, 2296, 2296, 2296, 2296, 294, 2296, 2296, 2296,
+ 2296, 2296, 2296, 2296, 2296,-32768,-32768, 2296, 2296, 492,
+-32768, 495,-32768, 500, 2296, 2296, 287,-32768,-32768, 503,
+ 499, 504, 1716,-32768, -59,-32768,-32768,-32768,-32768,-32768,
+-32768,-32768, 530, 68,-32768,-32768,-32768, 509, 1781, 2296,
+-32768, 200, 477,-32768,-32768, 2626, 506, 480,-32768,-32768,
+-32768, 515, 1832, 486,-32768, 362, 486, 362, 1897, 2296,
+ 512, 52, 1832, 125, 3154,-32768,-32768, 1484,-32768,-32768,
+ 203,-32768, 513,-32768,-32768,-32768,-32768, 520, 519, 1948,
+-32768,-32768,-32768, 443, 443, 518, 518, 518, 505, 505,
+ 505, 505, 94,-32768, 310, 310, 508, 472, 479, 481,
+ 482, 527,-32768, 526,-32768,-32768,-32768, 528, 532, 531,
+ 286, 287,-32768,-32768,-32768,-32768, 504, 534, 3113, 3113,
+ 535, 536,-32768, 540, 363, 538,-32768, 411, 2692, 548,
+ 2758,-32768, 2013,-32768, 523,-32768, 546, 547,-32768, 546,
+-32768, 134, 245,-32768, 2296, 3154,-32768,-32768,-32768,-32768,
+ 1368,-32768, 2064,-32768, 134, 260, 2296, 3022,-32768, 552,
+ 173,-32768,-32768,-32768, 2296,-32768, 554, 509, 3113, 12,
+-32768, 352,-32768, 2824, 2129,-32768,-32768, 270,-32768,-32768,
+-32768, 134,-32768,-32768,-32768,-32768,-32768, 288,-32768, 134,
+-32768, 558,-32768, 596, 600, 3022,-32768,-32768, 3022,-32768,
+-32768, 560, 13,-32768, 566, 572, 2956, 573,-32768,-32768,
+ 569,-32768, 574, 291,-32768,-32768,-32768,-32768, 2296, 2956,
+-32768,-32768, 2180, 584, 2296,-32768, 20,-32768, 2362,-32768,
+ 286, 578,-32768, 2956, 2245,-32768, 582, 589,-32768, 3113,
+ 585,-32768,-32768, 602,-32768,-32768, 2428,-32768, 2890,-32768,
+-32768,-32768,-32768, 593, 326,-32768, 3022, 599, 3113,-32768,
+-32768,-32768, 597, 639, 3022, 604,-32768, 3022,-32768, 3022,
+-32768,-32768, 701, 702,-32768
};
static const short yypgoto[] = {-32768,
--32768, 139, -26, 479, 253, -85, 43,-32768, 59, -72,
--32768, -3,-32768, 729, 150,-32768, 20,-32768,-32768, 200,
- 15, 586,-32768,-32768, 695, 665,-32768, -113,-32768, 550,
--32768, -83, -80, 640, -105, -138,-32768, -71, 93, 426,
- -211, -82,-32768,-32768,-32768,-32768,-32768, 554, 328,-32768,
--32768, -25, 709, -18,-32768, 688,-32768,-32768, 103,-32768,
- -93, -188, -276,-32768, 450, -167, -372, -378,-32768, -151,
--32768,-32768,-32768, -306,-32768,-32768,-32768,-32768,-32768,-32768,
- 207, 208, -499, -134,-32768,-32768,-32768,-32768,-32768,-32768,
--32768, -58,-32768, -453, 458,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,-32768, 295, 300,-32768,-32768, 138,-32768, -283,
--32768, 546, 14, -208, 1037, 191, 1059, 327, 410, 434,
- -65, 487, 570, -343,-32768, 305, 308, 159, 306, 510,
- 511, 519, 517, 524,-32768, 319, 531, 669,-32768,-32768,
- 123,-32768
+-32768, -1, 209, 376, -22, -106, -20,-32768, 78, -79,
+-32768, -3,-32768, 694, 30,-32768, 126,-32768,-32768, 329,
+ 15, 831,-32768,-32768, 660, 645,-32768, -98,-32768, 577,
+-32768, -87, -92, 591, -138, -160,-32768, -65, 96, 445,
+ -278, -54,-32768,-32768,-32768,-32768,-32768, 580, 341,-32768,
+-32768, -30,-32768,-32768,-32768,-32768, 673, 79,-32768, 640,
+-32768,-32768, 35,-32768, -85, -124, -233,-32768, 469, -55,
+ -321, -425,-32768, -424,-32768,-32768,-32768, -246,-32768,-32768,
+-32768,-32768,-32768,-32768, 164, 168, -436, -418,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768, -296,-32768, -496, 478,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,-32768, 289, 295,-32768,
+-32768, 99,-32768, -363,-32768, 431, 29, -100, 973, 183,
+ 1061, 230, 365, 473, 2, 557, 616, -379,-32768, 212,
+ 196, 163, 222, 398, 399, 403, 406, 402,-32768, 251,
+ 408, 663,-32768,-32768, 862,-32768
};
-#define YYLAST 3150
+#define YYLAST 3263
static const short yytable[] = { 23,
- 24, 336, 418, 290, 234, 111, 539, 209, 444, 47,
- 58, 67, 116, 409, 15, 264, 345, 210, 127, 73,
- 349, 351, 15, 15, 15, 208, 79, 27, 45, 46,
- 550, 48, 187, 18, 189, 200, 58, 104, 36, 48,
- 15, 58, 67, 15, 15, 551, 194, 202, 27, 82,
- 364, 63, 226, 84, 1, 576, 538, 40, 15, 101,
- 19, 1, 440, 25, 18, 2, 218, 219, 220, 221,
- 37, 3, 2, 576, 227, 228, 58, 4, 3, 552,
- 212, 105, 63, 453, 4, 5, 213, 265, 82, 84,
- 18, 550, 58, 207, 51, 62, 447, 58, 51, 491,
- 192, 1, 448, 208, 130, 335, 551, 52, 332, 6,
- 333, 224, 584, 200, 97, 229, 6, 124, 98, 130,
- 525, 62, 194, 334, 194, 202, 62, 76, 337, 412,
- 51, 592, 434, 195, 51, 437, 414, 52, 415, 54,
- 571, 43, 55, 18, 237, 18, 485, 525, 238, 88,
- 525, 122, 239, 547, 242, 81, 548, 26, 393, 30,
- 190, 62, 51, 507, 418, 284, 495, 89, 58, 54,
- 58, 207, 55, 18, 18, 57, 51, 62, 44, 368,
- 369, 370, 62, 399, 115, 117, 58, 401, 286, -183,
- 215, 215, 215, 215, -183, -183, 51, 1, 215, 215,
- 230, 93, 404, 418, 525, 409, 57, 130, 28, 91,
- 590, 195, 525, 43, 3, 525, 446, 525, 595, 339,
- 4, 597, 192, 598, 94, 28, 330, 124, 31, 28,
- 380, 185, 544, 89, 474, 48, 365, 236, 409, 482,
- 213, 123, 31, 28, 425, 32, 112, 541, 52, 361,
- 285, 33, 6, 62, 362, 62, 37, 57, 363, 418,
- 58, 72, 211, 284, 231, 185, 90, 347, 18, 394,
- 348, 62, 51, 442, 236, 402, 435, 581, 418, 130,
- 54, 441, 284, 55, 18, 34, 286, 35, 49, -182,
- 535, 515, 74, 286, -182, -182, 109, 118, 409, 58,
- 286, 110, 286, 215, 215, 215, 215, 215, 215, 215,
- 215, 215, 215, 215, 215, 62, 215, 215, 215, 215,
- 215, 215, 215, 416, 49, 488, 468, 361, 49, 318,
- 354, 523, 362, 93, 355, 57, 363, 489, 496, 443,
- 124, 103, 435, 448, 497, 62, 18, 526, 285, 518,
- 448, 123, 113, 520, 433, 448, 74, 433, 412, 448,
- 360, 414, 114, 366, 529, 563, 1, 285, 503, 559,
- 49, 448, 52, 589, 526, 519, 490, 526, 565, 448,
- 1, 461, 319, 521, 62, 462, 52, 389, 119, 58,
- 225, 529, 579, 392, 529, 129, 396, 253, 254, 255,
- 256, 284, 403, 130, 54, 215, 186, 55, 18, 214,
- 215, 376, 377, 378, 379, 523, 423, 540, 54, 107,
- 108, 55, 18, 559, 286, 407, 565, 318, 579, 222,
- 42, 526, 43, 143, 318, 435, 257, -338, -338, 526,
- 532, 318, 526, 318, 526, 436, 318, 438, 529, 245,
- 246, 247, 223, 284, 236, 284, 529, 188, 108, 529,
- 240, 529, 432, 577, 123, 241, 74, 532, -339, -339,
- 532, 260, 360, 261, 62, 58, 286, 185, 286, 262,
- 319, 243, 244, -337, -337, 237, 479, 319, 284, 238,
- 250, 251, 252, 239, 319, 286, 319, 248, 249, 319,
- 215, 215, 266, 267, -337, -337, 237, 258, 259, 48,
- 350, 286, 215, 455, 239, 263, 124, -101, 320, 459,
- 460, 326, 286, 104, 532, 286, 192, 360, 284, -283,
- -283, 110, 532, 286, 338, 532, 340, 532, 285, 31,
- 285, 346, 286, 472, 473, 52, 284, 352, 284, -284,
- -284, 286, 371, 372, 407, 353, 286, 373, 374, 375,
- 62, 31, 33, 382, 383, 318, 356, 52, 367, 286,
- 493, 286, -226, 285, 391, 406, 92, 54, 32, 286,
- 55, 18, 397, 398, 33, 16, 400, 286, 454, 422,
- 286, 410, 286, 16, 16, 16, 413, 421, 428, 54,
- 430, 321, 55, 18, 426, 427, 431, 318, 318, 449,
- 451, 16, 450, 285, 16, 16, 320, 318, 319, 318,
- 456, 457, 64, 320, 458, 322, 466, 467, 536, 16,
- 320, 285, 320, 285, 108, 320, 318, 469, 470, 191,
- 123, 483, 486, 435, -15, 52, 487, 318, 499, -337,
- -337, 237, 318, 64, 53, 405, 3, 500, 501, 239,
- 319, 319, 4, 318, 510, 502, 318, 564, 506, 512,
- 319, 567, 319, 569, 318, 511, -116, 54, 323, 516,
- 55, 18, 533, 318, 537, 545, 546, -156, 549, 319,
- 192, 193, 318, 557, 558, 560, 561, 318, 568, 321,
- 319, 562, 586, 318, 196, 319, 321, 578, 582, 583,
- 318, 585, 318, 321, 591, 321, 319, 588, 321, 319,
- 318, 593, 318, 322, 600, 594, 191, 319, 318, 596,
- 322, 318, 52, 318, 601, 381, 319, 322, 29, 322,
- 80, 53, 322, 3, 102, 319, 329, 131, 327, 4,
- 319, 424, 475, 78, 320, 96, 319, 504, 417, 572,
- 573, 324, 505, 319, 54, 319, 420, 55, 18, 384,
- 344, 385, 498, 319, 0, 319, 323, 192, 328, 387,
- 386, 319, 196, 323, 319, 0, 319, 388, 1, 0,
- 323, 0, 323, 0, 52, 323, 320, 320, 390, 0,
- 0, 1, 0, 53, 0, 3, 320, 52, 320, 0,
- 0, 4, 0, 0, 0, 0, 53, 0, 3, 0,
- 0, 0, 0, 0, 4, 320, 54, 0, 0, 55,
- 18, 0, 0, 0, 0, 0, 320, 321, 0, 54,
- 56, 320, 55, 18, 0, 0, 0, 0, 0, 0,
- 0, 0, 320, 95, 0, 320, 0, 0, 0, 324,
- 325, 322, 0, 320, 0, 0, 324, 0, 0, 0,
- 0, 0, 320, 324, 0, 324, 0, 0, 324, 321,
- 321, 320, 0, 0, 0, 0, 320, 0, 0, 321,
- 0, 321, 320, 0, 0, 0, 0, 0, 0, 320,
- 0, 320, 0, 322, 322, 0, 0, 0, 321, 320,
- 0, 320, 0, 322, 323, 322, 0, 320, 0, 321,
- 320, 0, 320, 0, 321, 0, 0, 0, 0, 0,
- 0, 0, 322, 0, -15, 321, 0, 0, 321, -337,
- -337, 237, 0, 322, 0, 405, 321, 0, 322, 513,
- 0, 0, 0, 0, 0, 321, 323, 323, 325, 322,
- 0, 0, 322, 0, 321, 325, 323, 0, 323, 321,
- 322, 0, 325, 0, 325, 321, 0, 325, 0, 322,
- 0, 0, 321, 0, 321, 323, 0, 0, 322, 0,
- 0, 0, 321, 322, 321, 0, 323, 324, 0, 322,
- 321, 323, 0, 321, 0, 321, 322, 0, 322, 0,
- 0, 0, 323, 0, 0, 323, 322, 0, 322, 0,
- 0, 0, 0, 323, 322, 0, 0, 322, 0, 322,
- 0, 0, 323, 0, 0, 0, 0, 0, 0, 324,
- 324, 323, 0, 0, 0, 0, 323, 0, 0, 324,
- 0, 324, 323, 0, 0, 0, 0, 0, 0, 323,
- 0, 323, 0, 0, 0, 0, 0, 0, 324, 323,
- 0, 323, 1, 134, 135, 0, 0, 323, 52, 324,
- 323, 0, 323, 0, 324, 0, 0, 136, 0, 0,
- 0, 0, 0, 137, 0, 324, 325, 0, 324, 0,
- 138, 0, 0, 0, 139, 0, 324, 0, 0, 0,
- 54, 0, 0, 55, 18, 324, 0, 0, 0, 0,
- 0, 280, 0, 0, 324, 0, 0, 0, 0, 324,
- 144, 145, 146, 147, 0, 324, 148, 149, 325, 325,
- 0, 0, 324, 0, 324, 0, 0, 0, 325, 0,
- 325, 0, 324, 0, 324, 0, 0, 0, 0, 0,
- 324, 0, 0, 324, 0, 324, 0, 325, 216, 216,
- 216, 216, 0, 0, 0, 0, 216, 216, 325, 0,
- 0, 0, 0, 325, 0, 0, 0, 0, 0, 0,
- 217, 217, 217, 217, 325, 0, 0, 325, 217, 217,
- 0, 0, 0, 0, 0, 325, 0, 0, 0, 0,
- 0, 0, 0, 0, 325, 134, 135, 0, 0, 0,
- 52, 0, 0, 325, 0, 0, 0, 0, 325, 136,
- 0, 0, 0, 0, 325, 137, 0, 0, 0, 0,
- 0, 325, 138, 325, 0, 0, 139, 0, 0, 0,
- 0, 325, 54, 325, 0, 55, 18, 0, 0, 325,
- 0, 0, 325, 280, 325, 0, 0, 0, 0, 0,
- 0, 0, 144, 145, 146, 147, 0, 0, 148, 149,
- 0, 216, 216, 216, 216, 216, 216, 216, 216, 216,
- 216, 216, 216, 0, 216, 216, 216, 216, 216, 216,
- 216, 0, 0, 217, 217, 217, 217, 217, 217, 217,
- 217, 217, 217, 217, 217, 0, 217, 217, 217, 217,
- 217, 217, 217, 492, 0, 132, 133, 0, 0, 0,
+ 24, 357, 538, 235, 379, 151, 304, 366, 280, 124,
+ 46, 145, 539, 48, 15, 477, 55, 112, 334, 136,
+ 78, 144, 15, 15, 15, 473, 18, 130, 44, 45,
+ 48, 47, 83, 1, 48, 36, 85, 26, 47, 30,
+ 15, 138, 119, 15, 15, 136, 486, 144, 78, 68,
+ 3, 130, 277, 130, 278, 296, 4, 15, 43, 554,
+ 91, 113, 525, 526, 93, 74, 554, 138, 211, 529,
+ 213, 51, 102, 588, 555, 404, 143, 68, 39, 19,
+ 405, 555, 25, 48, 406, 126, 53, 279, 6, 55,
+ 335, 18, 596, 74, 18, 57, 514, 91, 93, 508,
+ 525, 526, 143, 525, 526, 68, 128, 529, 556, 147,
+ 529, 31, 154, 50, 282, 575, 50, 63, 117, 518,
+ 283, 131, 580, 118, 231, 148, 62, 1, 73, 102,
+ 50, 68, 84, 27, 50, 352, 347, 88, 2, 295,
+ 580, 544, 378, 154, 3, 475, 281, 131, 468, 65,
+ 4, 73, 66, 18, 27, 42, 73, 288, 289, 290,
+ 291, 525, 526, 97, 103, 297, 298, 109, 529, 525,
+ 526, 407, 525, 526, 525, 526, 529, 380, 312, 529,
+ 106, 529, 6, 50, 73, 18, 360, 18, 73, 50,
+ 98, 532, 31, 362, 388, 363, 123, 125, 392, 394,
+ 341, 585, 496, 366, 551, 230, 18, 552, 73, 32,
+ 73, 34, 535, 35, 342, 33, 1, 373, 476, 349,
+ 350, 468, 63, 99, 154, 73, 263, 357, 107, 532,
+ 355, 231, 532, 285, 285, 285, 285, 479, 231, 50,
+ 307, 285, 285, 300, 308, 231, 111, 231, 309, 1,
+ 1, 461, 366, 41, 65, 42, 63, 66, 18, 69,
+ 2, 55, 447, 120, 390, 594, 3, 391, 364, 147,
+ 357, 306, 4, 599, 121, 100, 601, 154, 602, 42,
+ 5, 147, 69, 467, 122, 148, 470, 69, 65, 382,
+ 532, 66, 18, 453, -342, -342, 480, 148, 532, 283,
+ 146, 532, 481, 532, 6, 47, 408, 128, -187, 73,
+ 264, 275, 230, -187, -187, 69, 411, 412, 413, 69,
+ 98, 397, 153, 366, 306, 398, 1, 323, 324, 325,
+ 326, 230, 63, 263, 504, 210, 229, 28, 512, 69,
+ 263, 69, 366, 63, 481, 357, 440, 263, 73, 263,
+ 441, 154, 263, 520, 28, 492, 69, 265, 28, 481,
+ 73, 50, 355, 545, 65, -101, 327, 66, 18, 481,
+ 294, 28, 231, 511, 299, 65, 371, -186, 66, 18,
+ 128, 547, -186, -186, 567, 271, 519, 481, 115, 116,
+ 481, 474, 285, 285, 285, 285, 285, 285, 285, 285,
+ 285, 285, 285, 285, 73, 285, 285, 285, 285, 285,
+ 285, 285, 466, 546, 540, 466, 541, 264, 404, 593,
+ 469, 548, 471, 405, 264, 481, 112, 406, -341, -341,
+ 307, 264, 523, 264, 308, 284, 264, 18, 309, -15,
+ 69, 73, 292, 229, -341, -341, 307, 315, 316, 317,
+ 353, 212, 116, 458, 309, 231, 167, 231, 468, -341,
+ -341, 307, 229, 293, 265, 393, 306, 285, 310, 309,
+ 360, 265, 285, 362, 263, 581, 513, 311, 265, 69,
+ 265, 563, 330, 265, 231, 419, 420, 421, 422, 147,
+ 331, 69, 266, 332, 569, 333, -15, -230, 47, 339,
+ 231, -341, -341, 307, 345, 148, 346, 353, 583, -343,
+ -343, 502, 320, 321, 322, 416, 417, 418, 313, 314,
+ 318, 319, 231, 328, 329, 231, 336, 337, 127, 414,
+ 415, 523, 348, 231, 63, 423, 230, 354, 230, 563,
+ -287, -287, 569, 64, 583, 3, 231, 263, 263, 425,
+ 426, 4, 285, 285, 358, 231, 361, 263, 264, 263,
+ 231, -288, -288, 369, 285, 374, 65, 370, 73, 66,
+ 18, 376, 69, 231, 375, 231, 118, 381, 396, 128,
+ 129, 230, 383, 231, 229, 389, 263, 395, 399, 410,
+ 435, 231, 446, 436, 231, 448, 231, 263, 437, 266,
+ 267, 445, 263, 116, 462, 265, 266, 463, 449, 464,
+ 482, 31, 483, 266, 487, 266, 484, 63, 266, 488,
+ 509, 489, 127, 491, 263, 490, 495, 263, 63, 500,
+ -116, 264, 264, 499, 33, 263, 230, 64, 501, 3,
+ 505, 264, 468, 264, 510, 4, 533, 537, 263, 65,
+ 549, 550, 66, 18, 230, -160, 230, 263, 553, 561,
+ 65, 565, 263, 66, 18, 562, 564, 229, 263, 229,
+ 264, 572, 566, 128, 273, 263, 582, 263, 265, 265,
+ 586, 264, 587, 589, 268, 263, 264, 263, 265, 590,
+ 265, 592, 595, 263, 598, 597, 263, 600, 263, 69,
+ 604, 605, 424, 29, 61, 90, 155, 267, 264, 274,
+ 272, 264, 229, 454, 267, 372, 60, 265, 105, 264,
+ 576, 267, 365, 267, 577, 387, 267, 427, 265, 428,
+ 493, 368, 264, 265, 429, 431, 494, 521, 430, 0,
+ 266, 264, 0, 269, 0, 433, 264, 0, 0, 0,
+ 0, 0, 264, 0, 0, 265, 0, 0, 265, 264,
+ 0, 264, 0, 0, 0, 0, 265, 229, 0, 264,
+ 0, 264, 0, 0, 0, 0, 0, 264, 0, 265,
+ 264, 0, 264, 0, 0, 229, 0, 229, 265, 0,
+ 270, 268, 0, 265, 1, 0, 0, 0, 268, 265,
+ 63, 0, 0, 0, 0, 268, 265, 268, 265, 64,
+ 268, 3, 0, 266, 266, 0, 265, 4, 265, 0,
+ 0, 0, 0, 266, 265, 266, 0, 265, 0, 265,
+ 16, 0, 65, 0, 0, 66, 18, 0, 16, 16,
+ 16, 0, 0, 0, 0, 0, 67, 0, 267, 0,
+ 269, 0, 266, 0, 0, 0, 16, 269, 0, 16,
+ 16, 0, 0, 266, 269, 1, 269, 0, 266, 269,
+ 0, 63, 0, 16, 0, 0, 0, 31, 0, 0,
+ 64, 75, 3, 63, 0, 0, 0, 0, 4, 0,
+ 266, 0, 101, 266, 32, 0, 0, 270, 0, 0,
+ 33, 266, 0, 65, 270, 0, 66, 18, 0, 75,
+ 0, 270, 0, 270, 266, 65, 270, 104, 66, 18,
+ 0, 267, 267, 266, 0, 0, 0, 0, 266, 0,
+ 0, 267, 268, 267, 266, 0, 0, 132, 0, 0,
+ 0, 266, 0, 266, 0, 0, 0, 0, 0, 0,
+ 0, 266, 0, 266, 0, 0, 0, 0, 0, 266,
+ 267, 0, 266, 132, 266, 0, 0, 0, 0, 0,
+ 0, 267, 0, 0, 0, 0, 267, 0, 209, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 269, 0, 0, 0, 0, 0, 0, 267, 0,
+ 0, 267, 0, 0, 0, 268, 268, 0, 0, 267,
+ 0, 0, 0, 0, 0, 268, 0, 268, 0, 0,
+ 0, 0, 267, 0, 0, 0, 0, 301, 209, 0,
+ 0, 267, 0, 0, 0, 0, 267, 0, 270, 0,
+ 0, 0, 267, 0, 268, 0, 0, 0, 0, 267,
+ 0, 267, 0, 0, 0, 268, 0, 0, 0, 267,
+ 268, 267, 0, 0, 269, 269, 0, 267, 0, 0,
+ 267, 0, 267, 0, 269, 0, 269, 340, 0, 0,
+ 344, 0, 268, 0, 0, 268, 351, 0, 0, 0,
+ 0, 0, 0, 268, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 269, 0, 0, 268, 0, 0, 0,
+ 0, 270, 270, 0, 269, 268, 0, 0, 0, 269,
+ 268, 270, 0, 270, 0, 0, 268, 0, 286, 286,
+ 286, 286, 0, 268, 0, 268, 286, 286, 0, 0,
+ 0, 269, 0, 268, 269, 268, 0, 0, 0, 0,
+ 270, 268, 269, 0, 268, 0, 268, 0, 0, 0,
+ 0, 270, 0, 0, 0, 269, 270, 0, 0, 403,
+ 0, 0, 409, 0, 269, 0, 0, 0, 0, 269,
+ 0, 0, 0, 0, 0, 269, 0, 0, 270, 0,
+ 0, 270, 269, 0, 269, 0, 432, 0, 0, 270,
+ 434, 0, 269, 0, 269, 0, 438, 439, 0, 0,
+ 269, 0, 270, 269, 403, 269, 287, 287, 287, 287,
+ 0, 270, 0, 0, 287, 287, 270, 0, 0, 0,
+ 451, 452, 270, 0, 0, 0, 0, 0, 0, 270,
+ 0, 270, 0, 0, 465, 0, 0, 0, 0, 270,
+ 0, 270, 0, 0, 403, 0, 0, 270, 0, 209,
+ 270, 0, 270, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 286, 286, 286,
+ 286, 286, 286, 286, 286, 286, 286, 286, 286, 0,
+ 286, 286, 286, 286, 286, 286, 286, 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, 134, 135, 0,
- 0, 0, 52, 0, 0, 0, 0, 0, 0, 0,
- 0, 136, 0, 216, 0, 0, 0, 137, 216, 0,
- 0, 0, 0, 0, 138, 0, 0, 0, 139, 0,
- 0, 0, 0, 0, 54, 217, 0, 55, 18, 0,
- 217, 140, 141, 52, 0, 142, 0, 0, 0, 0,
- 0, 0, 136, 0, 144, 145, 146, 147, 137, 0,
- 148, 149, 0, 0, 0, 138, 0, 0, 0, 139,
- 132, 133, 0, 0, 0, 54, 0, 0, 55, 18,
- 0, 0, 140, 141, 0, 0, 142, 0, 0, 0,
- 0, 0, 0, 0, 0, 144, 145, 146, 147, 0,
- 0, 148, 149, 0, 0, 0, 0, 0, 216, 216,
- 0, 0, 134, 135, 0, 0, 0, 52, 0, 0,
- 216, 0, 0, 0, 0, 0, 136, 0, 0, 0,
- 217, 217, 137, 0, 0, 132, 133, 0, 0, 138,
- 0, 0, 217, 139, 0, 0, 0, 0, 0, 54,
- 0, 0, 55, 18, 0, 0, 140, 141, 0, 0,
- 142, 0, 143, 232, 0, 0, 0, 233, 0, 144,
- 145, 146, 147, 0, 0, 148, 149, 134, 135, 0,
- 0, 0, 52, 0, 0, 0, 0, 0, 0, 0,
- 0, 136, 0, 0, 0, 0, 0, 137, 0, 0,
- 132, 133, 0, 0, 138, 0, 0, 0, 139, 0,
- 0, 0, 0, 0, 54, 0, 0, 55, 18, 0,
- 0, 140, 141, 0, 0, 142, 0, 143, 445, 0,
- 0, 0, 0, 0, 144, 145, 146, 147, 0, 0,
- 148, 149, 134, 135, 0, 0, 0, 52, 0, 0,
- 0, 132, 133, 0, 0, 0, 136, 0, 0, 0,
- 0, 0, 137, 0, 0, 0, 0, 0, 0, 138,
- 0, 0, 0, 139, 0, 0, 0, 0, 0, 54,
- 0, 0, 55, 18, 0, 0, 140, 141, 0, 0,
- 142, 0, 143, 134, 135, 0, 0, 0, 52, 144,
- 145, 146, 147, 0, 0, 148, 149, 136, 0, 0,
- 0, 0, 0, 137, 0, 0, 132, 133, 0, 0,
- 138, 0, 0, 0, 139, 0, 0, 0, 0, 0,
- 54, 0, 0, 55, 18, 0, 0, 140, 141, 0,
- 0, 142, 357, 0, 0, 0, 0, 0, 0, 0,
- 144, 145, 146, 147, 0, 0, 148, 149, 134, 135,
- 0, 0, 0, 52, 0, 0, 0, 132, 133, 0,
- 0, 0, 136, 0, 0, 0, 0, 0, 137, 0,
- 0, 0, 0, 0, 0, 138, 0, 0, 0, 139,
- 0, 0, 0, 0, 0, 54, 0, 0, 55, 18,
- 0, 0, 140, 141, 0, 0, 142, 0, 0, 134,
- 135, 0, 395, 0, 52, 144, 145, 146, 147, 0,
- 0, 148, 149, 136, 0, 0, 0, 0, 0, 137,
- 0, 0, 132, 133, 0, 0, 138, 0, 0, 0,
- 139, 0, 0, 0, 0, 0, 54, 0, 0, 55,
- 18, 0, 0, 140, 141, 0, 0, 142, 0, 0,
- 0, 0, 431, 0, 0, 0, 144, 145, 146, 147,
- 0, 0, 148, 149, 134, 135, 0, 0, 0, 52,
- 0, 0, 0, 132, 133, 0, 0, 0, 136, 0,
- 0, 0, 0, 0, 137, 0, 0, 0, 0, 0,
- 0, 138, 0, 0, 0, 139, 0, 0, 0, 0,
- 0, 54, 0, 0, 55, 18, 0, 0, 140, 141,
- 0, 0, 142, 439, 0, 134, 135, 0, 0, 0,
- 52, 144, 145, 146, 147, 0, 0, 148, 149, 136,
- 0, 0, 0, 0, 0, 137, 0, 0, 132, 133,
- 0, 0, 138, 0, 0, 0, 139, 0, 0, 0,
- 0, 0, 54, 0, 0, 55, 18, 0, 0, 140,
- 141, 0, 0, 142, 452, 0, 0, 0, 0, 0,
- 0, 0, 144, 145, 146, 147, 0, 0, 148, 149,
- 134, 135, 0, 0, 0, 52, 0, 0, 0, 132,
- 133, 0, 0, 0, 136, 0, 0, 0, 0, 0,
- 137, 0, 0, 0, 0, 0, 0, 138, 0, 0,
- 0, 139, 0, 0, 0, 0, 0, 54, 0, 0,
- 55, 18, 0, 0, 140, 141, 0, 0, 142, 0,
- 0, 134, 135, 114, 0, 0, 52, 144, 145, 146,
- 147, 0, 0, 148, 149, 136, 0, 0, 0, 0,
- 0, 137, 0, 0, 132, 133, 0, 0, 138, 0,
- 0, 0, 139, 0, 0, 0, 0, 0, 54, 0,
- 0, 55, 18, 0, 0, 140, 141, 0, 0, 142,
- 0, 0, 0, 0, 0, 471, 0, 0, 144, 145,
- 146, 147, 0, 0, 148, 149, 134, 135, 0, 0,
- 0, 52, 0, 0, 0, 132, 133, 0, 0, 0,
- 136, 0, 0, 0, 0, 0, 137, 0, 0, 0,
- 0, 0, 0, 138, 0, 0, 0, 139, 0, 0,
- 0, 0, 0, 54, 0, 0, 55, 18, 0, 0,
- 140, 141, 0, 0, 142, 484, 0, 134, 135, 0,
- 0, 0, 52, 144, 145, 146, 147, 0, 0, 148,
- 149, 136, 0, 0, 0, 0, 0, 137, 0, 0,
- 132, 133, 0, 0, 138, 0, 0, 0, 139, 0,
- 0, 0, 0, 0, 54, 0, 0, 55, 18, 0,
- 0, 140, 141, 0, 0, 142, 494, 0, 0, 0,
- 0, 0, 0, 0, 144, 145, 146, 147, 0, 0,
- 148, 149, 134, 135, 0, 0, 0, 52, 0, 0,
- 0, 132, 133, 0, 0, 0, 136, 0, 0, 0,
- 0, 0, 137, 0, 0, 0, 0, 0, 0, 138,
- 0, 0, 0, 139, 0, 0, 0, 0, 0, 54,
- 0, 0, 55, 18, 0, 0, 140, 141, 0, 0,
- 142, 543, 0, 134, 135, 0, 0, 0, 52, 144,
- 145, 146, 147, 0, 0, 148, 149, 136, 0, 0,
- 0, 0, 0, 137, 0, 0, 132, 133, 0, 0,
- 138, 0, 0, 0, 139, 0, 0, 0, 0, 0,
- 54, 0, 0, 55, 18, 0, 0, 140, 141, 0,
- 0, 142, 0, 0, 0, 0, 0, 566, 0, 0,
- 144, 145, 146, 147, 0, 0, 148, 149, 134, 135,
- 0, 0, 0, 52, 0, 0, 0, 132, 133, 0,
- 0, 0, 136, 0, 0, 0, 0, 0, 137, 0,
- 0, 0, 0, 0, 0, 138, 0, 0, 0, 139,
- 0, 0, 0, 0, 0, 54, 0, 0, 55, 18,
- 0, 0, 140, 141, 0, 0, 142, 580, 0, 134,
- 135, 0, 0, 0, 52, 144, 145, 146, 147, 0,
- 0, 148, 149, 136, 0, 0, 0, 0, 0, 137,
- 0, 0, 0, 0, 0, 0, 138, 0, 0, 0,
- 139, 0, 0, 0, 0, 0, 54, 0, 0, 55,
- 18, 0, 0, 140, 141, 0, 0, 142, 0, 0,
- 0, 0, 0, 0, 0, 0, 144, 145, 146, 147,
- 0, 0, 148, 149, 269, 134, 135, 550, 270, 271,
- 52, 272, 0, 0, 273, 0, 0, 0, 274, 136,
- 0, 0, 551, 0, 0, 137, 275, 4, 276, 0,
- 277, 278, 138, 279, 0, 0, 139, 0, 0, 0,
- 0, 0, 54, 0, 0, 55, 18, 0, 0, 0,
- 0, 0, 0, 280, 0, 192, 574, 0, 0, 282,
- 0, 0, 144, 145, 146, 147, 0, 0, 148, 149,
- 269, 134, 135, 550, 270, 271, 52, 272, 0, 0,
- 273, 0, 0, 0, 274, 136, 0, 0, 551, 0,
- 0, 137, 275, 4, 276, 0, 277, 278, 138, 279,
- 0, 0, 139, 0, 0, 0, 0, 0, 54, 0,
- 0, 55, 18, 0, 0, 0, 0, 0, 0, 280,
- 0, 192, 587, 0, 0, 282, 0, 0, 144, 145,
- 146, 147, 0, 0, 148, 149, 269, 134, 135, 0,
- 270, 271, 52, 272, 0, 0, 273, 0, 0, 0,
- 274, 136, 0, 0, 0, 0, 0, 137, 275, 4,
- 276, 0, 277, 278, 138, 279, 0, 0, 139, 0,
- 0, 0, 0, 0, 54, 0, 0, 55, 18, 0,
- 0, 0, 0, 0, 0, 280, 0, 192, 281, 0,
- 0, 282, 0, 0, 144, 145, 146, 147, 0, 0,
- 148, 149, 269, 134, 135, 0, 270, 271, 52, 272,
- 0, 0, 273, 0, 0, 0, 274, 136, 0, 0,
- 0, 0, 0, 137, 275, 4, 276, 0, 277, 278,
- 138, 279, 0, 0, 139, 0, 0, 0, 0, 0,
- 54, 0, 0, 55, 18, 0, 0, 0, 0, 0,
- 0, 280, 0, 192, 408, 0, 0, 282, 0, 0,
- 144, 145, 146, 147, 0, 0, 148, 149, 269, 134,
- 135, 0, 270, 271, 52, 272, 0, 0, 273, 0,
- 0, 0, 274, 136, 0, 0, 0, 0, 0, 476,
- 275, 4, 276, 0, 277, 278, 138, 279, 0, 0,
- 477, 0, 0, 0, 0, 0, 54, 0, 0, 55,
- 18, 0, 0, 0, 0, 0, 0, 280, 0, 192,
- 478, 0, 0, 282, 0, 0, 144, 145, 146, 147,
- 0, 0, 148, 149, 269, 134, 135, 0, 270, 271,
- 52, 272, 0, 0, 273, 0, 0, 0, 274, 136,
- 0, 0, 0, 0, 0, 137, 275, 4, 276, 0,
- 277, 278, 138, 279, 0, 0, 139, 0, 0, 0,
- 0, 0, 54, 0, 0, 55, 18, 0, 0, 0,
- 0, 0, 0, 280, 0, 192, 514, 0, 0, 282,
- 0, 0, 144, 145, 146, 147, 0, 0, 148, 149,
- 269, 134, 135, 0, 270, 271, 52, 272, 0, 0,
- 273, 0, 0, 0, 274, 136, 0, 0, 0, 0,
- 0, 137, 275, 4, 276, 0, 277, 278, 138, 279,
- 0, 0, 139, 0, 0, 0, 0, 0, 54, 0,
- 0, 55, 18, 0, 0, 0, 0, 0, 0, 280,
- 0, 192, 517, 0, 0, 282, 0, 0, 144, 145,
- 146, 147, 0, 0, 148, 149, 269, 134, 135, 0,
- 270, 271, 52, 272, 0, 0, 273, 0, 0, 0,
- 274, 136, 0, 0, 0, 0, 0, 137, 275, 4,
- 276, 0, 277, 278, 138, 279, 0, 0, 139, 0,
- 0, 0, 0, 0, 54, 0, 0, 55, 18, 0,
- 0, 0, 0, 0, 0, 280, 0, 192, 542, 0,
- 0, 282, 0, 0, 144, 145, 146, 147, 0, 0,
- 148, 149, 269, 134, 135, 0, 270, 271, 52, 272,
- 0, 0, 273, 0, 0, 0, 274, 136, 0, 0,
- 0, 0, 0, 137, 275, 4, 276, 0, 277, 278,
- 138, 279, 0, 0, 139, 0, 0, 0, 0, 0,
- 54, 0, 0, 55, 18, 0, 0, 0, 0, 0,
- 0, 280, 0, 192, 0, 0, 0, 282, 0, 0,
- 144, 145, 146, 147, 0, 0, 148, 149, 411, 134,
- 135, 0, 270, 271, 52, 272, 0, 0, 273, 0,
- 0, 0, 274, 136, 0, 0, 0, 0, 0, 137,
- 275, 0, 276, 0, 277, 278, 138, 279, 0, 0,
- 139, 0, 0, 0, 0, 0, 54, 0, 0, 55,
- 18, 0, 0, 0, 0, 0, 0, 280, 0, 192,
- 0, 0, 0, 282, 0, 0, 144, 145, 146, 147,
- 0, 0, 148, 149, 411, 134, 135, 0, 522, 271,
- 52, 272, 0, 0, 273, 0, 0, 0, 274, 136,
- 0, 0, 0, 0, 0, 137, 275, 0, 276, 0,
- 277, 278, 138, 279, 0, 0, 139, 0, 0, 0,
- 0, 0, 54, 0, 0, 55, 18, 0, 0, 0,
- 0, 0, 0, 280, 0, 192, 0, 0, 0, 282,
- 0, 0, 144, 145, 146, 147, 0, 0, 148, 149
+ 0, 0, 516, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 536, 0, 0, 0,
+ 0, 0, 286, 0, 0, 0, 0, 286, 515, 0,
+ 156, 157, 0, 0, 0, 287, 287, 287, 287, 287,
+ 287, 287, 287, 287, 287, 287, 287, 0, 287, 287,
+ 287, 287, 287, 287, 287, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 568, 0, 158, 159, 571, 0, 573, 63, 0, 0,
+ 0, 156, 157, 0, 0, 0, 160, 0, 0, 0,
+ 0, 0, 161, 0, 0, 0, 0, 0, 0, 162,
+ 0, 0, 0, 163, 0, 0, 0, 286, 286, 65,
+ 287, 0, 66, 18, 0, 287, 164, 165, 0, 286,
+ 166, 0, 0, 158, 159, 0, 0, 0, 63, 168,
+ 169, 170, 171, 0, 0, 172, 173, 160, 0, 0,
+ 0, 0, 0, 161, 0, 0, 156, 157, 0, 0,
+ 162, 0, 0, 0, 163, 0, 0, 0, 0, 0,
+ 65, 0, 0, 66, 18, 0, 0, 164, 165, 0,
+ 0, 166, 0, 167, 302, 0, 0, 0, 303, 0,
+ 168, 169, 170, 171, 0, 0, 172, 173, 158, 159,
+ 0, 0, 0, 63, 0, 287, 287, 0, 0, 0,
+ 0, 0, 160, 0, 0, 0, 0, 287, 161, 0,
+ 0, 156, 157, 0, 0, 162, 0, 0, 0, 163,
+ 0, 0, 0, 0, 0, 65, 0, 0, 66, 18,
+ 0, 0, 164, 165, 0, 0, 166, 0, 167, 478,
+ 0, 0, 0, 0, 0, 168, 169, 170, 171, 0,
+ 0, 172, 173, 158, 159, 0, 0, 0, 63, 0,
+ 0, 0, 156, 157, 0, 0, 0, 160, 0, 0,
+ 0, 0, 0, 161, 0, 0, 0, 0, 0, 0,
+ 162, 0, 0, 0, 163, 0, 0, 0, 0, 0,
+ 65, 0, 0, 66, 18, 0, 0, 164, 165, 0,
+ 0, 166, 0, 167, 158, 159, 0, 0, 0, 63,
+ 168, 169, 170, 171, 0, 0, 172, 173, 160, 0,
+ 0, 0, 0, 0, 161, 0, 0, 156, 157, 0,
+ 0, 162, 0, 0, 0, 163, 0, 0, 0, 0,
+ 0, 65, 0, 0, 66, 18, 0, 0, 164, 165,
+ 0, 0, 166, 0, 0, 0, 0, 0, 343, 0,
+ 0, 168, 169, 170, 171, 0, 0, 172, 173, 158,
+ 159, 0, 0, 0, 63, 0, 0, 0, 156, 157,
+ 0, 0, 0, 160, 0, 0, 0, 0, 0, 161,
+ 0, 0, 0, 0, 0, 0, 162, 0, 0, 0,
+ 163, 0, 0, 0, 0, 0, 65, 0, 0, 66,
+ 18, 0, 0, 164, 165, 0, 0, 166, 400, 0,
+ 158, 159, 0, 0, 0, 63, 168, 169, 170, 171,
+ 0, 0, 172, 173, 160, 0, 0, 0, 0, 0,
+ 161, 0, 0, 156, 157, 0, 0, 162, 0, 0,
+ 0, 163, 0, 0, 0, 0, 0, 65, 0, 0,
+ 66, 18, 0, 0, 164, 165, 0, 0, 166, 0,
+ 0, 0, 0, 122, 0, 0, 0, 168, 169, 170,
+ 171, 0, 0, 172, 173, 158, 159, 0, 0, 0,
+ 63, 0, 0, 0, 156, 157, 0, 0, 0, 160,
+ 0, 0, 0, 0, 0, 161, 0, 0, 0, 0,
+ 0, 0, 162, 0, 0, 0, 163, 0, 0, 0,
+ 0, 0, 65, 0, 0, 66, 18, 0, 0, 164,
+ 165, 0, 0, 166, 0, 0, 158, 159, 0, 450,
+ 0, 63, 168, 169, 170, 171, 0, 0, 172, 173,
+ 160, 0, 0, 0, 0, 0, 161, 0, 0, 156,
+ 157, 0, 0, 162, 0, 0, 0, 163, 0, 0,
+ 0, 0, 0, 65, 0, 0, 66, 18, 0, 0,
+ 164, 165, 0, 0, 166, 0, 0, 0, 0, 464,
+ 0, 0, 0, 168, 169, 170, 171, 0, 0, 172,
+ 173, 158, 159, 0, 0, 0, 63, 0, 0, 0,
+ 156, 157, 0, 0, 0, 160, 0, 0, 0, 0,
+ 0, 161, 0, 0, 0, 0, 0, 0, 162, 0,
+ 0, 0, 163, 0, 0, 0, 0, 0, 65, 0,
+ 0, 66, 18, 0, 0, 164, 165, 0, 0, 166,
+ 472, 0, 158, 159, 0, 0, 0, 63, 168, 169,
+ 170, 171, 0, 0, 172, 173, 160, 0, 0, 0,
+ 0, 0, 161, 0, 0, 156, 157, 0, 0, 162,
+ 0, 0, 0, 163, 0, 0, 0, 0, 0, 65,
+ 0, 0, 66, 18, 0, 0, 164, 165, 0, 0,
+ 166, 485, 0, 0, 0, 0, 0, 0, 0, 168,
+ 169, 170, 171, 0, 0, 172, 173, 158, 159, 0,
+ 0, 0, 63, 0, 0, 0, 156, 157, 0, 0,
+ 0, 160, 0, 0, 0, 0, 0, 161, 0, 0,
+ 0, 0, 0, 0, 162, 0, 0, 0, 163, 0,
+ 0, 0, 0, 0, 65, 0, 0, 66, 18, 0,
+ 0, 164, 165, 0, 0, 166, 507, 0, 158, 159,
+ 0, 0, 0, 63, 168, 169, 170, 171, 0, 0,
+ 172, 173, 160, 0, 0, 0, 0, 0, 161, 0,
+ 0, 156, 157, 0, 0, 162, 0, 0, 0, 163,
+ 0, 0, 0, 0, 0, 65, 0, 0, 66, 18,
+ 0, 0, 164, 165, 0, 0, 166, 517, 0, 0,
+ 0, 0, 0, 0, 0, 168, 169, 170, 171, 0,
+ 0, 172, 173, 158, 159, 0, 0, 0, 63, 0,
+ 0, 0, 156, 157, 0, 0, 0, 160, 0, 0,
+ 0, 0, 0, 161, 0, 0, 0, 0, 0, 0,
+ 162, 0, 0, 0, 163, 0, 0, 0, 0, 0,
+ 65, 0, 0, 66, 18, 0, 0, 164, 165, 0,
+ 0, 166, 543, 0, 158, 159, 0, 0, 0, 63,
+ 168, 169, 170, 171, 0, 0, 172, 173, 160, 0,
+ 0, 0, 0, 0, 161, 0, 0, 156, 157, 0,
+ 0, 162, 0, 0, 0, 163, 0, 0, 0, 0,
+ 0, 65, 0, 0, 66, 18, 0, 0, 164, 165,
+ 0, 0, 166, 0, 0, 0, 0, 0, 570, 0,
+ 0, 168, 169, 170, 171, 0, 0, 172, 173, 158,
+ 159, 0, 0, 0, 63, 0, 0, 0, 156, 157,
+ 0, 0, 0, 160, 0, 0, 0, 0, 0, 161,
+ 0, 0, 0, 0, 0, 0, 162, 0, 0, 0,
+ 163, 0, 0, 0, 0, 0, 65, 0, 0, 66,
+ 18, 0, 0, 164, 165, 0, 0, 166, 584, 0,
+ 158, 159, 0, 0, 0, 63, 168, 169, 170, 171,
+ 0, 0, 172, 173, 160, 0, 0, 0, 0, 0,
+ 161, 0, 0, 0, 0, 0, 0, 162, 0, 0,
+ 0, 163, 0, 0, 0, 0, 0, 65, 0, 0,
+ 66, 18, 0, 0, 164, 165, 0, 0, 166, 0,
+ 0, 0, 0, 0, 0, 0, 0, 168, 169, 170,
+ 171, 0, 0, 172, 173, 214, 158, 159, 554, 215,
+ 216, 63, 217, 0, 0, 218, 0, 0, 0, 219,
+ 160, 0, 0, 555, 0, 0, 161, 220, 4, 221,
+ 0, 222, 223, 162, 224, 0, 0, 163, 0, 0,
+ 0, 0, 0, 65, 0, 0, 66, 18, 0, 0,
+ 0, 0, 0, 0, 225, 0, 128, 578, 0, 0,
+ 227, 0, 0, 168, 169, 170, 171, 0, 0, 172,
+ 173, 214, 158, 159, 554, 215, 216, 63, 217, 0,
+ 0, 218, 0, 0, 0, 219, 160, 0, 0, 555,
+ 0, 0, 161, 220, 4, 221, 0, 222, 223, 162,
+ 224, 0, 0, 163, 0, 0, 0, 0, 0, 65,
+ 0, 0, 66, 18, 0, 0, 0, 0, 0, 0,
+ 225, 0, 128, 591, 0, 0, 227, 0, 0, 168,
+ 169, 170, 171, 0, 0, 172, 173, 214, 158, 159,
+ 0, 215, 216, 63, 217, 0, 0, 218, 0, 0,
+ 0, 219, 160, 0, 0, 0, 0, 0, 161, 220,
+ 4, 221, 0, 222, 223, 162, 224, 0, 0, 163,
+ 0, 0, 0, 0, 0, 65, 0, 0, 66, 18,
+ 0, 0, 0, 0, 0, 0, 225, 0, 128, 226,
+ 0, 0, 227, 0, 0, 168, 169, 170, 171, 0,
+ 0, 172, 173, 214, 158, 159, 0, 215, 216, 63,
+ 217, 0, 0, 218, 0, 0, 0, 219, 160, 0,
+ 0, 0, 0, 0, 161, 220, 4, 221, 0, 222,
+ 223, 162, 224, 0, 0, 163, 0, 0, 0, 0,
+ 0, 65, 0, 0, 66, 18, 0, 0, 0, 0,
+ 0, 0, 225, 0, 128, 356, 0, 0, 227, 0,
+ 0, 168, 169, 170, 171, 0, 0, 172, 173, 214,
+ 158, 159, 0, 215, 216, 63, 217, 0, 0, 218,
+ 0, 0, 0, 219, 160, 0, 0, 0, 0, 0,
+ 455, 220, 4, 221, 0, 222, 223, 162, 224, 0,
+ 0, 456, 0, 0, 0, 0, 0, 65, 0, 0,
+ 66, 18, 0, 0, 0, 0, 0, 0, 225, 0,
+ 128, 457, 0, 0, 227, 0, 0, 168, 169, 170,
+ 171, 0, 0, 172, 173, 214, 158, 159, 0, 215,
+ 216, 63, 217, 0, 0, 218, 0, 0, 0, 219,
+ 160, 0, 0, 0, 0, 0, 161, 220, 4, 221,
+ 0, 222, 223, 162, 224, 0, 0, 163, 0, 0,
+ 0, 0, 0, 65, 0, 0, 66, 18, 0, 0,
+ 0, 0, 0, 0, 225, 0, 128, 503, 0, 0,
+ 227, 0, 0, 168, 169, 170, 171, 0, 0, 172,
+ 173, 214, 158, 159, 0, 215, 216, 63, 217, 0,
+ 0, 218, 0, 0, 0, 219, 160, 0, 0, 0,
+ 0, 0, 161, 220, 4, 221, 0, 222, 223, 162,
+ 224, 0, 0, 163, 0, 0, 0, 0, 0, 65,
+ 0, 0, 66, 18, 0, 0, 0, 0, 0, 0,
+ 225, 0, 128, 506, 0, 0, 227, 0, 0, 168,
+ 169, 170, 171, 0, 0, 172, 173, 214, 158, 159,
+ 0, 215, 216, 63, 217, 0, 0, 218, 0, 0,
+ 0, 219, 160, 0, 0, 0, 0, 0, 161, 220,
+ 4, 221, 0, 222, 223, 162, 224, 0, 0, 163,
+ 0, 0, 0, 0, 0, 65, 0, 0, 66, 18,
+ 0, 0, 0, 0, 0, 0, 225, 0, 128, 542,
+ 0, 0, 227, 0, 0, 168, 169, 170, 171, 0,
+ 0, 172, 173, 214, 158, 159, 0, 215, 216, 63,
+ 217, 0, 0, 218, 0, 0, 0, 219, 160, 0,
+ 0, 0, 0, 0, 161, 220, 4, 221, 0, 222,
+ 223, 162, 224, 0, 0, 163, 0, 0, 0, 0,
+ 0, 65, 0, 0, 66, 18, 0, 0, 0, 0,
+ 0, 0, 225, 0, 128, 0, 0, 0, 227, 0,
+ 0, 168, 169, 170, 171, 0, 0, 172, 173, 359,
+ 158, 159, 0, 215, 216, 63, 217, 0, 0, 218,
+ 0, 0, 0, 219, 160, 0, 0, 0, 0, 0,
+ 161, 220, 0, 221, 0, 222, 223, 162, 224, 0,
+ 0, 163, 0, 0, 0, 0, 0, 65, 0, 0,
+ 66, 18, 0, 0, 0, 0, 0, 0, 225, 0,
+ 128, 0, 0, 0, 227, 0, 0, 168, 169, 170,
+ 171, 0, 0, 172, 173, 359, 158, 159, 0, 522,
+ 216, 63, 217, 0, 0, 218, 0, 0, 0, 219,
+ 160, 0, 0, 0, 0, 0, 161, 220, 0, 221,
+ 0, 222, 223, 162, 224, 0, 0, 163, 0, 0,
+ 0, 0, 0, 65, 0, 0, 66, 18, 0, 0,
+ 0, 0, 0, 0, 225, 0, 128, 0, 0, 0,
+ 227, 0, 0, 168, 169, 170, 171, 0, 0, 172,
+ 173, 1, 158, 159, 0, 0, 0, 63, 0, 0,
+ 0, 0, 0, 0, 0, 0, 160, 0, 0, 0,
+ 0, 0, 161, 0, 0, 0, 0, 158, 159, 162,
+ 0, 0, 63, 163, 0, 0, 0, 0, 0, 65,
+ 0, 160, 66, 18, 0, 0, 0, 161, 0, 0,
+ 225, 0, 0, 0, 162, 0, 0, 0, 163, 168,
+ 169, 170, 171, 0, 65, 172, 173, 66, 18, 0,
+ 0, 0, 0, 63, 0, 225, 0, 0, 0, 0,
+ 0, 0, 160, 0, 168, 169, 170, 171, 161, 0,
+ 172, 173, 0, 0, 0, 162, 0, 0, 0, 163,
+ 0, 0, 0, 0, 0, 65, 0, 0, 66, 18,
+ 0, 0, 164, 165, 0, 0, 166, 0, 0, 0,
+ 0, 0, 0, 0, 0, 168, 169, 170, 171, 0,
+ 0, 172, 173
};
static const short yycheck[] = { 3,
- 4, 213, 309, 192, 143, 88, 1, 121, 352, 5,
- 37, 37, 93, 290, 0, 15, 225, 123, 104, 38,
- 229, 230, 8, 9, 10, 119, 45, 8, 32, 33,
- 47, 35, 115, 86, 117, 119, 63, 53, 63, 43,
- 26, 68, 68, 29, 30, 62, 119, 119, 29, 53,
- 72, 37, 138, 57, 44, 555, 510, 63, 44, 78,
- 2, 44, 346, 5, 86, 55, 132, 133, 134, 135,
- 95, 61, 55, 573, 140, 141, 103, 67, 61, 96,
- 94, 97, 68, 367, 67, 75, 100, 87, 92, 93,
- 86, 47, 119, 119, 36, 37, 94, 124, 40, 443,
- 95, 44, 100, 197, 108, 211, 62, 50, 202, 99,
- 204, 138, 566, 197, 72, 142, 99, 103, 76, 123,
- 499, 63, 195, 206, 197, 197, 68, 52, 214, 297,
- 72, 585, 341, 119, 76, 344, 304, 50, 306, 82,
- 96, 101, 85, 86, 93, 86, 430, 526, 97, 57,
- 529, 94, 101, 526, 158, 99, 529, 8, 99, 10,
- 118, 103, 104, 470, 471, 192, 450, 97, 195, 82,
- 197, 197, 85, 86, 86, 37, 118, 119, 29, 245,
- 246, 247, 124, 277, 92, 93, 213, 99, 192, 94,
- 132, 133, 134, 135, 99, 100, 138, 44, 140, 141,
- 142, 63, 283, 510, 583, 482, 68, 211, 9, 97,
- 583, 197, 591, 101, 61, 594, 355, 596, 591, 223,
- 67, 594, 95, 596, 99, 26, 99, 213, 44, 30,
- 257, 109, 516, 97, 94, 239, 240, 101, 515, 428,
- 100, 103, 44, 44, 327, 61, 98, 65, 50, 67,
- 192, 67, 99, 195, 72, 197, 95, 119, 76, 566,
- 287, 100, 124, 290, 142, 143, 97, 94, 86, 273,
- 97, 213, 214, 94, 101, 279, 97, 561, 585, 283,
- 82, 347, 309, 85, 86, 99, 290, 101, 36, 94,
- 502, 480, 40, 297, 99, 100, 92, 100, 575, 326,
- 304, 97, 306, 245, 246, 247, 248, 249, 250, 251,
- 252, 253, 254, 255, 256, 257, 258, 259, 260, 261,
- 262, 263, 264, 309, 72, 439, 407, 67, 76, 192,
- 96, 499, 72, 195, 100, 197, 76, 94, 452, 94,
- 326, 93, 97, 100, 94, 287, 86, 499, 290, 94,
- 100, 213, 98, 94, 341, 100, 104, 344, 526, 100,
- 238, 529, 98, 241, 499, 94, 44, 309, 462, 537,
- 118, 100, 50, 94, 526, 489, 442, 529, 546, 100,
- 44, 60, 192, 497, 326, 64, 50, 265, 95, 416,
- 138, 526, 560, 271, 529, 98, 274, 18, 19, 20,
- 21, 428, 280, 407, 82, 347, 98, 85, 86, 100,
- 352, 253, 254, 255, 256, 583, 94, 511, 82, 99,
- 100, 85, 86, 591, 428, 287, 594, 290, 596, 101,
- 99, 583, 101, 95, 297, 97, 57, 91, 92, 591,
- 499, 304, 594, 306, 596, 343, 309, 345, 583, 5,
- 6, 7, 101, 480, 101, 482, 591, 99, 100, 594,
- 101, 596, 340, 557, 326, 97, 214, 526, 91, 92,
- 529, 11, 350, 12, 416, 502, 480, 355, 482, 13,
- 290, 45, 46, 91, 92, 93, 428, 297, 515, 97,
- 8, 9, 10, 101, 304, 499, 306, 3, 4, 309,
- 442, 443, 91, 92, 91, 92, 93, 16, 17, 513,
- 97, 515, 454, 391, 101, 14, 502, 95, 192, 397,
- 398, 93, 526, 53, 583, 529, 95, 405, 555, 45,
- 46, 97, 591, 537, 67, 594, 97, 596, 480, 44,
- 482, 93, 546, 421, 422, 50, 573, 94, 575, 45,
- 46, 555, 248, 249, 416, 96, 560, 250, 251, 252,
- 502, 44, 67, 258, 259, 428, 67, 50, 93, 573,
- 448, 575, 93, 515, 93, 88, 59, 82, 61, 583,
- 85, 86, 93, 93, 67, 0, 93, 591, 88, 93,
- 594, 99, 596, 8, 9, 10, 99, 99, 95, 82,
- 93, 192, 85, 86, 99, 99, 98, 470, 471, 98,
- 98, 26, 93, 555, 29, 30, 290, 480, 428, 482,
- 99, 99, 37, 297, 99, 192, 99, 94, 506, 44,
- 304, 573, 306, 575, 100, 309, 499, 66, 100, 44,
- 502, 99, 98, 97, 86, 50, 98, 510, 94, 91,
- 92, 93, 515, 68, 59, 97, 61, 94, 94, 101,
- 470, 471, 67, 526, 99, 93, 529, 545, 93, 99,
- 480, 549, 482, 551, 537, 94, 93, 82, 192, 93,
- 85, 86, 95, 546, 94, 93, 56, 56, 99, 499,
- 95, 96, 555, 94, 94, 94, 93, 560, 88, 290,
- 510, 99, 88, 566, 119, 515, 297, 99, 99, 94,
- 573, 99, 575, 304, 94, 306, 526, 99, 309, 529,
- 583, 99, 585, 290, 0, 56, 44, 537, 591, 94,
- 297, 594, 50, 596, 0, 257, 546, 304, 10, 306,
- 46, 59, 309, 61, 80, 555, 197, 108, 195, 67,
- 560, 326, 425, 45, 428, 68, 566, 463, 309, 553,
- 553, 192, 463, 573, 82, 575, 309, 85, 86, 260,
- 225, 261, 454, 583, -1, 585, 290, 95, 96, 263,
- 262, 591, 197, 297, 594, -1, 596, 264, 44, -1,
- 304, -1, 306, -1, 50, 309, 470, 471, 268, -1,
- -1, 44, -1, 59, -1, 61, 480, 50, 482, -1,
- -1, 67, -1, -1, -1, -1, 59, -1, 61, -1,
- -1, -1, -1, -1, 67, 499, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, 510, 428, -1, 82,
- 96, 515, 85, 86, -1, -1, -1, -1, -1, -1,
- -1, -1, 526, 96, -1, 529, -1, -1, -1, 290,
- 192, 428, -1, 537, -1, -1, 297, -1, -1, -1,
- -1, -1, 546, 304, -1, 306, -1, -1, 309, 470,
- 471, 555, -1, -1, -1, -1, 560, -1, -1, 480,
- -1, 482, 566, -1, -1, -1, -1, -1, -1, 573,
- -1, 575, -1, 470, 471, -1, -1, -1, 499, 583,
- -1, 585, -1, 480, 428, 482, -1, 591, -1, 510,
- 594, -1, 596, -1, 515, -1, -1, -1, -1, -1,
- -1, -1, 499, -1, 86, 526, -1, -1, 529, 91,
- 92, 93, -1, 510, -1, 97, 537, -1, 515, 101,
- -1, -1, -1, -1, -1, 546, 470, 471, 290, 526,
- -1, -1, 529, -1, 555, 297, 480, -1, 482, 560,
- 537, -1, 304, -1, 306, 566, -1, 309, -1, 546,
- -1, -1, 573, -1, 575, 499, -1, -1, 555, -1,
- -1, -1, 583, 560, 585, -1, 510, 428, -1, 566,
- 591, 515, -1, 594, -1, 596, 573, -1, 575, -1,
- -1, -1, 526, -1, -1, 529, 583, -1, 585, -1,
- -1, -1, -1, 537, 591, -1, -1, 594, -1, 596,
- -1, -1, 546, -1, -1, -1, -1, -1, -1, 470,
- 471, 555, -1, -1, -1, -1, 560, -1, -1, 480,
- -1, 482, 566, -1, -1, -1, -1, -1, -1, 573,
- -1, 575, -1, -1, -1, -1, -1, -1, 499, 583,
- -1, 585, 44, 45, 46, -1, -1, 591, 50, 510,
- 594, -1, 596, -1, 515, -1, -1, 59, -1, -1,
- -1, -1, -1, 65, -1, 526, 428, -1, 529, -1,
- 72, -1, -1, -1, 76, -1, 537, -1, -1, -1,
- 82, -1, -1, 85, 86, 546, -1, -1, -1, -1,
- -1, 93, -1, -1, 555, -1, -1, -1, -1, 560,
- 102, 103, 104, 105, -1, 566, 108, 109, 470, 471,
- -1, -1, 573, -1, 575, -1, -1, -1, 480, -1,
- 482, -1, 583, -1, 585, -1, -1, -1, -1, -1,
- 591, -1, -1, 594, -1, 596, -1, 499, 132, 133,
- 134, 135, -1, -1, -1, -1, 140, 141, 510, -1,
- -1, -1, -1, 515, -1, -1, -1, -1, -1, -1,
- 132, 133, 134, 135, 526, -1, -1, 529, 140, 141,
- -1, -1, -1, -1, -1, 537, -1, -1, -1, -1,
- -1, -1, -1, -1, 546, 45, 46, -1, -1, -1,
- 50, -1, -1, 555, -1, -1, -1, -1, 560, 59,
- -1, -1, -1, -1, 566, 65, -1, -1, -1, -1,
- -1, 573, 72, 575, -1, -1, 76, -1, -1, -1,
- -1, 583, 82, 585, -1, 85, 86, -1, -1, 591,
- -1, -1, 594, 93, 596, -1, -1, -1, -1, -1,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- -1, 245, 246, 247, 248, 249, 250, 251, 252, 253,
- 254, 255, 256, -1, 258, 259, 260, 261, 262, 263,
- 264, -1, -1, 245, 246, 247, 248, 249, 250, 251,
- 252, 253, 254, 255, 256, -1, 258, 259, 260, 261,
- 262, 263, 264, 1, -1, 3, 4, -1, -1, -1,
+ 4, 235, 499, 128, 283, 112, 167, 254, 147, 102,
+ 5, 110, 1, 36, 0, 395, 39, 53, 15, 107,
+ 51, 107, 8, 9, 10, 389, 86, 107, 32, 33,
+ 53, 35, 53, 44, 57, 63, 57, 8, 42, 10,
+ 26, 107, 97, 29, 30, 133, 410, 133, 79, 51,
+ 61, 131, 138, 133, 140, 162, 67, 43, 29, 47,
+ 64, 97, 488, 488, 68, 51, 47, 133, 123, 488,
+ 125, 95, 74, 570, 62, 67, 107, 79, 63, 2,
+ 72, 62, 5, 106, 76, 106, 100, 142, 99, 112,
+ 87, 86, 589, 79, 86, 52, 476, 101, 102, 463,
+ 526, 526, 133, 529, 529, 107, 95, 526, 96, 111,
+ 529, 44, 116, 36, 94, 96, 39, 50, 92, 483,
+ 100, 107, 559, 97, 128, 111, 99, 44, 51, 131,
+ 53, 133, 54, 8, 57, 228, 222, 59, 55, 162,
+ 577, 505, 281, 147, 61, 94, 148, 133, 97, 82,
+ 67, 74, 85, 86, 29, 101, 79, 156, 157, 158,
+ 159, 587, 587, 68, 99, 164, 165, 89, 587, 595,
+ 595, 72, 598, 598, 600, 600, 595, 284, 182, 598,
+ 100, 600, 99, 106, 107, 86, 242, 86, 111, 112,
+ 97, 488, 44, 249, 295, 251, 101, 102, 299, 300,
+ 99, 565, 449, 450, 526, 128, 86, 529, 131, 61,
+ 133, 99, 491, 101, 218, 67, 44, 272, 94, 99,
+ 224, 97, 50, 97, 228, 148, 128, 461, 95, 526,
+ 232, 235, 529, 156, 157, 158, 159, 398, 242, 162,
+ 93, 164, 165, 166, 97, 249, 93, 251, 101, 44,
+ 44, 376, 499, 99, 82, 101, 50, 85, 86, 51,
+ 55, 284, 355, 98, 94, 587, 61, 97, 254, 271,
+ 504, 101, 67, 595, 98, 97, 598, 281, 600, 101,
+ 75, 283, 74, 384, 98, 271, 387, 79, 82, 293,
+ 587, 85, 86, 94, 91, 92, 94, 283, 595, 100,
+ 94, 598, 100, 600, 99, 309, 310, 95, 94, 232,
+ 128, 99, 235, 99, 100, 107, 315, 316, 317, 111,
+ 97, 96, 98, 570, 101, 100, 44, 18, 19, 20,
+ 21, 254, 50, 235, 459, 98, 128, 9, 94, 131,
+ 242, 133, 589, 50, 100, 579, 60, 249, 271, 251,
+ 64, 355, 254, 94, 26, 441, 148, 128, 30, 100,
+ 283, 284, 364, 94, 82, 95, 57, 85, 86, 100,
+ 162, 43, 376, 472, 166, 82, 94, 94, 85, 86,
+ 95, 94, 99, 100, 94, 93, 485, 100, 99, 100,
+ 100, 390, 315, 316, 317, 318, 319, 320, 321, 322,
+ 323, 324, 325, 326, 327, 328, 329, 330, 331, 332,
+ 333, 334, 384, 512, 500, 387, 65, 235, 67, 94,
+ 386, 520, 388, 72, 242, 100, 53, 76, 91, 92,
+ 93, 249, 488, 251, 97, 100, 254, 86, 101, 86,
+ 232, 364, 101, 235, 91, 92, 93, 5, 6, 7,
+ 97, 99, 100, 376, 101, 459, 95, 461, 97, 91,
+ 92, 93, 254, 101, 235, 97, 101, 390, 101, 101,
+ 526, 242, 395, 529, 376, 561, 475, 97, 249, 271,
+ 251, 537, 11, 254, 488, 323, 324, 325, 326, 491,
+ 12, 283, 128, 13, 550, 14, 86, 93, 502, 93,
+ 504, 91, 92, 93, 93, 491, 93, 97, 564, 91,
+ 92, 101, 8, 9, 10, 320, 321, 322, 45, 46,
+ 3, 4, 526, 16, 17, 529, 91, 92, 44, 318,
+ 319, 587, 93, 537, 50, 327, 459, 88, 461, 595,
+ 45, 46, 598, 59, 600, 61, 550, 449, 450, 328,
+ 329, 67, 475, 476, 99, 559, 99, 459, 376, 461,
+ 564, 45, 46, 99, 487, 99, 82, 93, 491, 85,
+ 86, 95, 364, 577, 99, 579, 97, 67, 96, 95,
+ 96, 504, 97, 587, 376, 93, 488, 94, 67, 93,
+ 99, 595, 94, 99, 598, 66, 600, 499, 99, 235,
+ 128, 99, 504, 100, 99, 376, 242, 93, 100, 98,
+ 98, 44, 93, 249, 88, 251, 98, 50, 254, 94,
+ 98, 94, 44, 93, 526, 94, 93, 529, 50, 94,
+ 93, 449, 450, 99, 67, 537, 559, 59, 99, 61,
+ 93, 459, 97, 461, 98, 67, 95, 94, 550, 82,
+ 93, 56, 85, 86, 577, 56, 579, 559, 99, 94,
+ 82, 93, 564, 85, 86, 94, 94, 459, 570, 461,
+ 488, 88, 99, 95, 96, 577, 99, 579, 449, 450,
+ 99, 499, 94, 99, 128, 587, 504, 589, 459, 88,
+ 461, 99, 94, 595, 56, 99, 598, 94, 600, 491,
+ 0, 0, 327, 10, 45, 61, 116, 235, 526, 133,
+ 131, 529, 504, 373, 242, 271, 44, 488, 79, 537,
+ 557, 249, 254, 251, 557, 295, 254, 330, 499, 331,
+ 442, 254, 550, 504, 332, 334, 442, 487, 333, -1,
+ 376, 559, -1, 128, -1, 338, 564, -1, -1, -1,
+ -1, -1, 570, -1, -1, 526, -1, -1, 529, 577,
+ -1, 579, -1, -1, -1, -1, 537, 559, -1, 587,
+ -1, 589, -1, -1, -1, -1, -1, 595, -1, 550,
+ 598, -1, 600, -1, -1, 577, -1, 579, 559, -1,
+ 128, 235, -1, 564, 44, -1, -1, -1, 242, 570,
+ 50, -1, -1, -1, -1, 249, 577, 251, 579, 59,
+ 254, 61, -1, 449, 450, -1, 587, 67, 589, -1,
+ -1, -1, -1, 459, 595, 461, -1, 598, -1, 600,
+ 0, -1, 82, -1, -1, 85, 86, -1, 8, 9,
+ 10, -1, -1, -1, -1, -1, 96, -1, 376, -1,
+ 235, -1, 488, -1, -1, -1, 26, 242, -1, 29,
+ 30, -1, -1, 499, 249, 44, 251, -1, 504, 254,
+ -1, 50, -1, 43, -1, -1, -1, 44, -1, -1,
+ 59, 51, 61, 50, -1, -1, -1, -1, 67, -1,
+ 526, -1, 59, 529, 61, -1, -1, 235, -1, -1,
+ 67, 537, -1, 82, 242, -1, 85, 86, -1, 79,
+ -1, 249, -1, 251, 550, 82, 254, 96, 85, 86,
+ -1, 449, 450, 559, -1, -1, -1, -1, 564, -1,
+ -1, 459, 376, 461, 570, -1, -1, 107, -1, -1,
+ -1, 577, -1, 579, -1, -1, -1, -1, -1, -1,
+ -1, 587, -1, 589, -1, -1, -1, -1, -1, 595,
+ 488, -1, 598, 133, 600, -1, -1, -1, -1, -1,
+ -1, 499, -1, -1, -1, -1, 504, -1, 117, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 376, -1, -1, -1, -1, -1, -1, 526, -1,
+ -1, 529, -1, -1, -1, 449, 450, -1, -1, 537,
+ -1, -1, -1, -1, -1, 459, -1, 461, -1, -1,
+ -1, -1, 550, -1, -1, -1, -1, 166, 167, -1,
+ -1, 559, -1, -1, -1, -1, 564, -1, 376, -1,
+ -1, -1, 570, -1, 488, -1, -1, -1, -1, 577,
+ -1, 579, -1, -1, -1, 499, -1, -1, -1, 587,
+ 504, 589, -1, -1, 449, 450, -1, 595, -1, -1,
+ 598, -1, 600, -1, 459, -1, 461, 216, -1, -1,
+ 219, -1, 526, -1, -1, 529, 225, -1, -1, -1,
+ -1, -1, -1, 537, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 488, -1, -1, 550, -1, -1, -1,
+ -1, 449, 450, -1, 499, 559, -1, -1, -1, 504,
+ 564, 459, -1, 461, -1, -1, 570, -1, 156, 157,
+ 158, 159, -1, 577, -1, 579, 164, 165, -1, -1,
+ -1, 526, -1, 587, 529, 589, -1, -1, -1, -1,
+ 488, 595, 537, -1, 598, -1, 600, -1, -1, -1,
+ -1, 499, -1, -1, -1, 550, 504, -1, -1, 308,
+ -1, -1, 311, -1, 559, -1, -1, -1, -1, 564,
+ -1, -1, -1, -1, -1, 570, -1, -1, 526, -1,
+ -1, 529, 577, -1, 579, -1, 335, -1, -1, 537,
+ 339, -1, 587, -1, 589, -1, 345, 346, -1, -1,
+ 595, -1, 550, 598, 353, 600, 156, 157, 158, 159,
+ -1, 559, -1, -1, 164, 165, 564, -1, -1, -1,
+ 369, 370, 570, -1, -1, -1, -1, -1, -1, 577,
+ -1, 579, -1, -1, 383, -1, -1, -1, -1, 587,
+ -1, 589, -1, -1, 393, -1, -1, 595, -1, 398,
+ 598, -1, 600, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 315, 316, 317,
+ 318, 319, 320, 321, 322, 323, 324, 325, 326, -1,
+ 328, 329, 330, 331, 332, 333, 334, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 45, 46, -1,
- -1, -1, 50, -1, -1, -1, -1, -1, -1, -1,
- -1, 59, -1, 347, -1, -1, -1, 65, 352, -1,
- -1, -1, -1, -1, 72, -1, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, 347, -1, 85, 86, -1,
- 352, 89, 90, 50, -1, 93, -1, -1, -1, -1,
- -1, -1, 59, -1, 102, 103, 104, 105, 65, -1,
- 108, 109, -1, -1, -1, 72, -1, -1, -1, 76,
- 3, 4, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, -1, 89, 90, -1, -1, 93, -1, -1, -1,
- -1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
- -1, 108, 109, -1, -1, -1, -1, -1, 442, 443,
- -1, -1, 45, 46, -1, -1, -1, 50, -1, -1,
- 454, -1, -1, -1, -1, -1, 59, -1, -1, -1,
- 442, 443, 65, -1, -1, 3, 4, -1, -1, 72,
- -1, -1, 454, 76, -1, -1, -1, -1, -1, 82,
- -1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
- 93, -1, 95, 96, -1, -1, -1, 100, -1, 102,
- 103, 104, 105, -1, -1, 108, 109, 45, 46, -1,
- -1, -1, 50, -1, -1, -1, -1, -1, -1, -1,
- -1, 59, -1, -1, -1, -1, -1, 65, -1, -1,
- 3, 4, -1, -1, 72, -1, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, 89, 90, -1, -1, 93, -1, 95, 96, -1,
- -1, -1, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, 45, 46, -1, -1, -1, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 481, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 495, -1, -1, -1,
+ -1, -1, 390, -1, -1, -1, -1, 395, 1, -1,
+ 3, 4, -1, -1, -1, 315, 316, 317, 318, 319,
+ 320, 321, 322, 323, 324, 325, 326, -1, 328, 329,
+ 330, 331, 332, 333, 334, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 549, -1, 45, 46, 553, -1, 555, 50, -1, -1,
-1, 3, 4, -1, -1, -1, 59, -1, -1, -1,
-1, -1, 65, -1, -1, -1, -1, -1, -1, 72,
- -1, -1, -1, 76, -1, -1, -1, -1, -1, 82,
- -1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
- 93, -1, 95, 45, 46, -1, -1, -1, 50, 102,
+ -1, -1, -1, 76, -1, -1, -1, 475, 476, 82,
+ 390, -1, 85, 86, -1, 395, 89, 90, -1, 487,
+ 93, -1, -1, 45, 46, -1, -1, -1, 50, 102,
103, 104, 105, -1, -1, 108, 109, 59, -1, -1,
-1, -1, -1, 65, -1, -1, 3, 4, -1, -1,
72, -1, -1, -1, 76, -1, -1, -1, -1, -1,
82, -1, -1, 85, 86, -1, -1, 89, 90, -1,
- -1, 93, 94, -1, -1, -1, -1, -1, -1, -1,
+ -1, 93, -1, 95, 96, -1, -1, -1, 100, -1,
102, 103, 104, 105, -1, -1, 108, 109, 45, 46,
- -1, -1, -1, 50, -1, -1, -1, 3, 4, -1,
- -1, -1, 59, -1, -1, -1, -1, -1, 65, -1,
- -1, -1, -1, -1, -1, 72, -1, -1, -1, 76,
+ -1, -1, -1, 50, -1, 475, 476, -1, -1, -1,
+ -1, -1, 59, -1, -1, -1, -1, 487, 65, -1,
+ -1, 3, 4, -1, -1, 72, -1, -1, -1, 76,
-1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, -1, 89, 90, -1, -1, 93, -1, -1, 45,
- 46, -1, 99, -1, 50, 102, 103, 104, 105, -1,
- -1, 108, 109, 59, -1, -1, -1, -1, -1, 65,
- -1, -1, 3, 4, -1, -1, 72, -1, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, 89, 90, -1, -1, 93, -1, -1,
- -1, -1, 98, -1, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, 45, 46, -1, -1, -1, 50,
- -1, -1, -1, 3, 4, -1, -1, -1, 59, -1,
- -1, -1, -1, -1, 65, -1, -1, -1, -1, -1,
+ -1, -1, 89, 90, -1, -1, 93, -1, 95, 96,
+ -1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109, 45, 46, -1, -1, -1, 50, -1,
+ -1, -1, 3, 4, -1, -1, -1, 59, -1, -1,
+ -1, -1, -1, 65, -1, -1, -1, -1, -1, -1,
+ 72, -1, -1, -1, 76, -1, -1, -1, -1, -1,
+ 82, -1, -1, 85, 86, -1, -1, 89, 90, -1,
+ -1, 93, -1, 95, 45, 46, -1, -1, -1, 50,
+ 102, 103, 104, 105, -1, -1, 108, 109, 59, -1,
+ -1, -1, -1, -1, 65, -1, -1, 3, 4, -1,
-1, 72, -1, -1, -1, 76, -1, -1, -1, -1,
-1, 82, -1, -1, 85, 86, -1, -1, 89, 90,
- -1, -1, 93, 94, -1, 45, 46, -1, -1, -1,
- 50, 102, 103, 104, 105, -1, -1, 108, 109, 59,
- -1, -1, -1, -1, -1, 65, -1, -1, 3, 4,
- -1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
- 90, -1, -1, 93, 94, -1, -1, -1, -1, -1,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- 45, 46, -1, -1, -1, 50, -1, -1, -1, 3,
- 4, -1, -1, -1, 59, -1, -1, -1, -1, -1,
- 65, -1, -1, -1, -1, -1, -1, 72, -1, -1,
+ -1, -1, 93, -1, -1, -1, -1, -1, 99, -1,
+ -1, 102, 103, 104, 105, -1, -1, 108, 109, 45,
+ 46, -1, -1, -1, 50, -1, -1, -1, 3, 4,
+ -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
+ -1, -1, -1, -1, -1, -1, 72, -1, -1, -1,
+ 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
+ 86, -1, -1, 89, 90, -1, -1, 93, 94, -1,
+ 45, 46, -1, -1, -1, 50, 102, 103, 104, 105,
+ -1, -1, 108, 109, 59, -1, -1, -1, -1, -1,
+ 65, -1, -1, 3, 4, -1, -1, 72, -1, -1,
-1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
85, 86, -1, -1, 89, 90, -1, -1, 93, -1,
- -1, 45, 46, 98, -1, -1, 50, 102, 103, 104,
- 105, -1, -1, 108, 109, 59, -1, -1, -1, -1,
- -1, 65, -1, -1, 3, 4, -1, -1, 72, -1,
+ -1, -1, -1, 98, -1, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 45, 46, -1, -1, -1,
+ 50, -1, -1, -1, 3, 4, -1, -1, -1, 59,
+ -1, -1, -1, -1, -1, 65, -1, -1, -1, -1,
+ -1, -1, 72, -1, -1, -1, 76, -1, -1, -1,
+ -1, -1, 82, -1, -1, 85, 86, -1, -1, 89,
+ 90, -1, -1, 93, -1, -1, 45, 46, -1, 99,
+ -1, 50, 102, 103, 104, 105, -1, -1, 108, 109,
+ 59, -1, -1, -1, -1, -1, 65, -1, -1, 3,
+ 4, -1, -1, 72, -1, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ 89, 90, -1, -1, 93, -1, -1, -1, -1, 98,
+ -1, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, 45, 46, -1, -1, -1, 50, -1, -1, -1,
+ 3, 4, -1, -1, -1, 59, -1, -1, -1, -1,
+ -1, 65, -1, -1, -1, -1, -1, -1, 72, -1,
-1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
-1, 85, 86, -1, -1, 89, 90, -1, -1, 93,
- -1, -1, -1, -1, -1, 99, -1, -1, 102, 103,
- 104, 105, -1, -1, 108, 109, 45, 46, -1, -1,
- -1, 50, -1, -1, -1, 3, 4, -1, -1, -1,
- 59, -1, -1, -1, -1, -1, 65, -1, -1, -1,
- -1, -1, -1, 72, -1, -1, -1, 76, -1, -1,
- -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
- 89, 90, -1, -1, 93, 94, -1, 45, 46, -1,
- -1, -1, 50, 102, 103, 104, 105, -1, -1, 108,
- 109, 59, -1, -1, -1, -1, -1, 65, -1, -1,
- 3, 4, -1, -1, 72, -1, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, 89, 90, -1, -1, 93, 94, -1, -1, -1,
- -1, -1, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, 45, 46, -1, -1, -1, 50, -1, -1,
- -1, 3, 4, -1, -1, -1, 59, -1, -1, -1,
- -1, -1, 65, -1, -1, -1, -1, -1, -1, 72,
+ 94, -1, 45, 46, -1, -1, -1, 50, 102, 103,
+ 104, 105, -1, -1, 108, 109, 59, -1, -1, -1,
+ -1, -1, 65, -1, -1, 3, 4, -1, -1, 72,
-1, -1, -1, 76, -1, -1, -1, -1, -1, 82,
-1, -1, 85, 86, -1, -1, 89, 90, -1, -1,
- 93, 94, -1, 45, 46, -1, -1, -1, 50, 102,
- 103, 104, 105, -1, -1, 108, 109, 59, -1, -1,
- -1, -1, -1, 65, -1, -1, 3, 4, -1, -1,
+ 93, 94, -1, -1, -1, -1, -1, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 45, 46, -1,
+ -1, -1, 50, -1, -1, -1, 3, 4, -1, -1,
+ -1, 59, -1, -1, -1, -1, -1, 65, -1, -1,
+ -1, -1, -1, -1, 72, -1, -1, -1, 76, -1,
+ -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
+ -1, 89, 90, -1, -1, 93, 94, -1, 45, 46,
+ -1, -1, -1, 50, 102, 103, 104, 105, -1, -1,
+ 108, 109, 59, -1, -1, -1, -1, -1, 65, -1,
+ -1, 3, 4, -1, -1, 72, -1, -1, -1, 76,
+ -1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
+ -1, -1, 89, 90, -1, -1, 93, 94, -1, -1,
+ -1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109, 45, 46, -1, -1, -1, 50, -1,
+ -1, -1, 3, 4, -1, -1, -1, 59, -1, -1,
+ -1, -1, -1, 65, -1, -1, -1, -1, -1, -1,
72, -1, -1, -1, 76, -1, -1, -1, -1, -1,
82, -1, -1, 85, 86, -1, -1, 89, 90, -1,
- -1, 93, -1, -1, -1, -1, -1, 99, -1, -1,
- 102, 103, 104, 105, -1, -1, 108, 109, 45, 46,
- -1, -1, -1, 50, -1, -1, -1, 3, 4, -1,
- -1, -1, 59, -1, -1, -1, -1, -1, 65, -1,
- -1, -1, -1, -1, -1, 72, -1, -1, -1, 76,
- -1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
- -1, -1, 89, 90, -1, -1, 93, 94, -1, 45,
- 46, -1, -1, -1, 50, 102, 103, 104, 105, -1,
- -1, 108, 109, 59, -1, -1, -1, -1, -1, 65,
+ -1, 93, 94, -1, 45, 46, -1, -1, -1, 50,
+ 102, 103, 104, 105, -1, -1, 108, 109, 59, -1,
+ -1, -1, -1, -1, 65, -1, -1, 3, 4, -1,
+ -1, 72, -1, -1, -1, 76, -1, -1, -1, -1,
+ -1, 82, -1, -1, 85, 86, -1, -1, 89, 90,
+ -1, -1, 93, -1, -1, -1, -1, -1, 99, -1,
+ -1, 102, 103, 104, 105, -1, -1, 108, 109, 45,
+ 46, -1, -1, -1, 50, -1, -1, -1, 3, 4,
+ -1, -1, -1, 59, -1, -1, -1, -1, -1, 65,
-1, -1, -1, -1, -1, -1, 72, -1, -1, -1,
76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, 89, 90, -1, -1, 93, -1, -1,
- -1, -1, -1, -1, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, 44, 45, 46, 47, 48, 49,
- 50, 51, -1, -1, 54, -1, -1, -1, 58, 59,
- -1, -1, 62, -1, -1, 65, 66, 67, 68, -1,
- 70, 71, 72, 73, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, 93, -1, 95, 96, -1, -1, 99,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- 44, 45, 46, 47, 48, 49, 50, 51, -1, -1,
- 54, -1, -1, -1, 58, 59, -1, -1, 62, -1,
- -1, 65, 66, 67, 68, -1, 70, 71, 72, 73,
- -1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
- -1, 85, 86, -1, -1, -1, -1, -1, -1, 93,
- -1, 95, 96, -1, -1, 99, -1, -1, 102, 103,
- 104, 105, -1, -1, 108, 109, 44, 45, 46, -1,
- 48, 49, 50, 51, -1, -1, 54, -1, -1, -1,
- 58, 59, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, 71, 72, 73, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, -1, -1, -1, -1, 93, -1, 95, 96, -1,
- -1, 99, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, 44, 45, 46, -1, 48, 49, 50, 51,
- -1, -1, 54, -1, -1, -1, 58, 59, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, 71,
- 72, 73, -1, -1, 76, -1, -1, -1, -1, -1,
- 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
- -1, 93, -1, 95, 96, -1, -1, 99, -1, -1,
- 102, 103, 104, 105, -1, -1, 108, 109, 44, 45,
- 46, -1, 48, 49, 50, 51, -1, -1, 54, -1,
- -1, -1, 58, 59, -1, -1, -1, -1, -1, 65,
- 66, 67, 68, -1, 70, 71, 72, 73, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, -1, 93, -1, 95,
- 96, -1, -1, 99, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, 44, 45, 46, -1, 48, 49,
- 50, 51, -1, -1, 54, -1, -1, -1, 58, 59,
- -1, -1, -1, -1, -1, 65, 66, 67, 68, -1,
- 70, 71, 72, 73, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, 93, -1, 95, 96, -1, -1, 99,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109,
- 44, 45, 46, -1, 48, 49, 50, 51, -1, -1,
- 54, -1, -1, -1, 58, 59, -1, -1, -1, -1,
- -1, 65, 66, 67, 68, -1, 70, 71, 72, 73,
- -1, -1, 76, -1, -1, -1, -1, -1, 82, -1,
- -1, 85, 86, -1, -1, -1, -1, -1, -1, 93,
- -1, 95, 96, -1, -1, 99, -1, -1, 102, 103,
- 104, 105, -1, -1, 108, 109, 44, 45, 46, -1,
- 48, 49, 50, 51, -1, -1, 54, -1, -1, -1,
- 58, 59, -1, -1, -1, -1, -1, 65, 66, 67,
- 68, -1, 70, 71, 72, 73, -1, -1, 76, -1,
- -1, -1, -1, -1, 82, -1, -1, 85, 86, -1,
- -1, -1, -1, -1, -1, 93, -1, 95, 96, -1,
- -1, 99, -1, -1, 102, 103, 104, 105, -1, -1,
- 108, 109, 44, 45, 46, -1, 48, 49, 50, 51,
- -1, -1, 54, -1, -1, -1, 58, 59, -1, -1,
- -1, -1, -1, 65, 66, 67, 68, -1, 70, 71,
- 72, 73, -1, -1, 76, -1, -1, -1, -1, -1,
- 82, -1, -1, 85, 86, -1, -1, -1, -1, -1,
- -1, 93, -1, 95, -1, -1, -1, 99, -1, -1,
- 102, 103, 104, 105, -1, -1, 108, 109, 44, 45,
- 46, -1, 48, 49, 50, 51, -1, -1, 54, -1,
- -1, -1, 58, 59, -1, -1, -1, -1, -1, 65,
- 66, -1, 68, -1, 70, 71, 72, 73, -1, -1,
- 76, -1, -1, -1, -1, -1, 82, -1, -1, 85,
- 86, -1, -1, -1, -1, -1, -1, 93, -1, 95,
- -1, -1, -1, 99, -1, -1, 102, 103, 104, 105,
- -1, -1, 108, 109, 44, 45, 46, -1, 48, 49,
- 50, 51, -1, -1, 54, -1, -1, -1, 58, 59,
- -1, -1, -1, -1, -1, 65, 66, -1, 68, -1,
- 70, 71, 72, 73, -1, -1, 76, -1, -1, -1,
- -1, -1, 82, -1, -1, 85, 86, -1, -1, -1,
- -1, -1, -1, 93, -1, 95, -1, -1, -1, 99,
- -1, -1, 102, 103, 104, 105, -1, -1, 108, 109
+ 86, -1, -1, 89, 90, -1, -1, 93, 94, -1,
+ 45, 46, -1, -1, -1, 50, 102, 103, 104, 105,
+ -1, -1, 108, 109, 59, -1, -1, -1, -1, -1,
+ 65, -1, -1, -1, -1, -1, -1, 72, -1, -1,
+ -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
+ 85, 86, -1, -1, 89, 90, -1, -1, 93, -1,
+ -1, -1, -1, -1, -1, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 44, 45, 46, 47, 48,
+ 49, 50, 51, -1, -1, 54, -1, -1, -1, 58,
+ 59, -1, -1, 62, -1, -1, 65, 66, 67, 68,
+ -1, 70, 71, 72, 73, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, -1, 95, 96, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, 44, 45, 46, 47, 48, 49, 50, 51, -1,
+ -1, 54, -1, -1, -1, 58, 59, -1, -1, 62,
+ -1, -1, 65, 66, 67, 68, -1, 70, 71, 72,
+ 73, -1, -1, 76, -1, -1, -1, -1, -1, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
+ 93, -1, 95, 96, -1, -1, 99, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 44, 45, 46,
+ -1, 48, 49, 50, 51, -1, -1, 54, -1, -1,
+ -1, 58, 59, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, 71, 72, 73, -1, -1, 76,
+ -1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
+ -1, -1, -1, -1, -1, -1, 93, -1, 95, 96,
+ -1, -1, 99, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109, 44, 45, 46, -1, 48, 49, 50,
+ 51, -1, -1, 54, -1, -1, -1, 58, 59, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ 71, 72, 73, -1, -1, 76, -1, -1, -1, -1,
+ -1, 82, -1, -1, 85, 86, -1, -1, -1, -1,
+ -1, -1, 93, -1, 95, 96, -1, -1, 99, -1,
+ -1, 102, 103, 104, 105, -1, -1, 108, 109, 44,
+ 45, 46, -1, 48, 49, 50, 51, -1, -1, 54,
+ -1, -1, -1, 58, 59, -1, -1, -1, -1, -1,
+ 65, 66, 67, 68, -1, 70, 71, 72, 73, -1,
+ -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, 93, -1,
+ 95, 96, -1, -1, 99, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 44, 45, 46, -1, 48,
+ 49, 50, 51, -1, -1, 54, -1, -1, -1, 58,
+ 59, -1, -1, -1, -1, -1, 65, 66, 67, 68,
+ -1, 70, 71, 72, 73, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, -1, 95, 96, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, 44, 45, 46, -1, 48, 49, 50, 51, -1,
+ -1, 54, -1, -1, -1, 58, 59, -1, -1, -1,
+ -1, -1, 65, 66, 67, 68, -1, 70, 71, 72,
+ 73, -1, -1, 76, -1, -1, -1, -1, -1, 82,
+ -1, -1, 85, 86, -1, -1, -1, -1, -1, -1,
+ 93, -1, 95, 96, -1, -1, 99, -1, -1, 102,
+ 103, 104, 105, -1, -1, 108, 109, 44, 45, 46,
+ -1, 48, 49, 50, 51, -1, -1, 54, -1, -1,
+ -1, 58, 59, -1, -1, -1, -1, -1, 65, 66,
+ 67, 68, -1, 70, 71, 72, 73, -1, -1, 76,
+ -1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
+ -1, -1, -1, -1, -1, -1, 93, -1, 95, 96,
+ -1, -1, 99, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109, 44, 45, 46, -1, 48, 49, 50,
+ 51, -1, -1, 54, -1, -1, -1, 58, 59, -1,
+ -1, -1, -1, -1, 65, 66, 67, 68, -1, 70,
+ 71, 72, 73, -1, -1, 76, -1, -1, -1, -1,
+ -1, 82, -1, -1, 85, 86, -1, -1, -1, -1,
+ -1, -1, 93, -1, 95, -1, -1, -1, 99, -1,
+ -1, 102, 103, 104, 105, -1, -1, 108, 109, 44,
+ 45, 46, -1, 48, 49, 50, 51, -1, -1, 54,
+ -1, -1, -1, 58, 59, -1, -1, -1, -1, -1,
+ 65, 66, -1, 68, -1, 70, 71, 72, 73, -1,
+ -1, 76, -1, -1, -1, -1, -1, 82, -1, -1,
+ 85, 86, -1, -1, -1, -1, -1, -1, 93, -1,
+ 95, -1, -1, -1, 99, -1, -1, 102, 103, 104,
+ 105, -1, -1, 108, 109, 44, 45, 46, -1, 48,
+ 49, 50, 51, -1, -1, 54, -1, -1, -1, 58,
+ 59, -1, -1, -1, -1, -1, 65, 66, -1, 68,
+ -1, 70, 71, 72, 73, -1, -1, 76, -1, -1,
+ -1, -1, -1, 82, -1, -1, 85, 86, -1, -1,
+ -1, -1, -1, -1, 93, -1, 95, -1, -1, -1,
+ 99, -1, -1, 102, 103, 104, 105, -1, -1, 108,
+ 109, 44, 45, 46, -1, -1, -1, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, -1, -1, -1,
+ -1, -1, 65, -1, -1, -1, -1, 45, 46, 72,
+ -1, -1, 50, 76, -1, -1, -1, -1, -1, 82,
+ -1, 59, 85, 86, -1, -1, -1, 65, -1, -1,
+ 93, -1, -1, -1, 72, -1, -1, -1, 76, 102,
+ 103, 104, 105, -1, 82, 108, 109, 85, 86, -1,
+ -1, -1, -1, 50, -1, 93, -1, -1, -1, -1,
+ -1, -1, 59, -1, 102, 103, 104, 105, 65, -1,
+ 108, 109, -1, -1, -1, 72, -1, -1, -1, 76,
+ -1, -1, -1, -1, -1, 82, -1, -1, 85, 86,
+ -1, -1, 89, 90, -1, -1, 93, -1, -1, -1,
+ -1, -1, -1, -1, -1, 102, 103, 104, 105, -1,
+ -1, 108, 109
};
#define YYPURE 1
@@ -1920,50 +1951,50 @@ yyreduce:
switch (yyn) {
case 10:
-#line 197 "./parse-scan.y"
+#line 203 "./parse-scan.y"
{
/* use preset global here. FIXME */
yyval.node = xstrdup ("int");
;
break;}
case 11:
-#line 202 "./parse-scan.y"
+#line 208 "./parse-scan.y"
{
/* use preset global here. FIXME */
yyval.node = xstrdup ("double");
;
break;}
case 12:
-#line 207 "./parse-scan.y"
+#line 213 "./parse-scan.y"
{
/* use preset global here. FIXME */
yyval.node = xstrdup ("boolean");
;
break;}
case 19:
-#line 233 "./parse-scan.y"
+#line 239 "./parse-scan.y"
{
yyval.node = concat ("[", yyvsp[-2].node, NULL);
;
break;}
case 20:
-#line 237 "./parse-scan.y"
+#line 243 "./parse-scan.y"
{
yyval.node = concat ("[", yyvsp[-2].node, NULL);
;
break;}
case 24:
-#line 254 "./parse-scan.y"
+#line 260 "./parse-scan.y"
{
yyval.node = concat (yyvsp[-2].node, ".", yyvsp[0].node, NULL);
;
break;}
case 38:
-#line 286 "./parse-scan.y"
+#line 292 "./parse-scan.y"
{ package_name = yyvsp[-1].node; ;
break;}
case 46:
-#line 313 "./parse-scan.y"
+#line 319 "./parse-scan.y"
{
if (yyvsp[0].value == PUBLIC_TK)
modifier_value++;
@@ -1973,7 +2004,7 @@ case 46:
;
break;}
case 47:
-#line 321 "./parse-scan.y"
+#line 327 "./parse-scan.y"
{
if (yyvsp[0].value == PUBLIC_TK)
modifier_value++;
@@ -1983,57 +2014,65 @@ case 47:
;
break;}
case 48:
-#line 333 "./parse-scan.y"
+#line 339 "./parse-scan.y"
{
report_class_declaration(yyvsp[-2].node);
modifier_value = 0;
;
break;}
case 50:
-#line 339 "./parse-scan.y"
+#line 345 "./parse-scan.y"
{ report_class_declaration(yyvsp[-2].node); ;
break;}
case 56:
-#line 353 "./parse-scan.y"
+#line 359 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 57:
-#line 355 "./parse-scan.y"
+#line 361 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
+case 58:
+#line 366 "./parse-scan.y"
+{ pop_class_context (); ;
+ break;}
+case 59:
+#line 368 "./parse-scan.y"
+{ pop_class_context (); ;
+ break;}
case 70:
-#line 385 "./parse-scan.y"
+#line 393 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 71:
-#line 387 "./parse-scan.y"
+#line 395 "./parse-scan.y"
{ modifier_value = 0; ;
break;}
case 76:
-#line 403 "./parse-scan.y"
+#line 411 "./parse-scan.y"
{ bracket_count = 0; USE_ABSORBER; ;
break;}
case 77:
-#line 405 "./parse-scan.y"
+#line 413 "./parse-scan.y"
{ ++bracket_count; ;
break;}
case 81:
-#line 420 "./parse-scan.y"
+#line 428 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 83:
-#line 423 "./parse-scan.y"
+#line 431 "./parse-scan.y"
{ modifier_value = 0; ;
break;}
case 84:
-#line 425 "./parse-scan.y"
+#line 433 "./parse-scan.y"
{
report_main_declaration (yyvsp[-1].declarator);
modifier_value = 0;
;
break;}
case 85:
-#line 433 "./parse-scan.y"
+#line 441 "./parse-scan.y"
{
struct method_declarator *d;
NEW_METHOD_DECLARATOR (d, yyvsp[-2].node, NULL);
@@ -2041,7 +2080,7 @@ case 85:
;
break;}
case 86:
-#line 439 "./parse-scan.y"
+#line 447 "./parse-scan.y"
{
struct method_declarator *d;
NEW_METHOD_DECLARATOR (d, yyvsp[-3].node, yyvsp[-1].node);
@@ -2049,13 +2088,13 @@ case 86:
;
break;}
case 89:
-#line 450 "./parse-scan.y"
+#line 458 "./parse-scan.y"
{
yyval.node = concat (yyvsp[-2].node, ",", yyvsp[0].node, NULL);
;
break;}
case 90:
-#line 457 "./parse-scan.y"
+#line 465 "./parse-scan.y"
{
USE_ABSORBER;
if (bracket_count)
@@ -2072,7 +2111,7 @@ case 90:
;
break;}
case 91:
-#line 472 "./parse-scan.y"
+#line 480 "./parse-scan.y"
{
if (bracket_count)
{
@@ -2088,107 +2127,115 @@ case 91:
;
break;}
case 94:
-#line 493 "./parse-scan.y"
+#line 501 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 95:
-#line 495 "./parse-scan.y"
+#line 503 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 101:
-#line 512 "./parse-scan.y"
+#line 520 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 103:
-#line 523 "./parse-scan.y"
+#line 531 "./parse-scan.y"
{ modifier_value = 0; ;
break;}
case 105:
-#line 528 "./parse-scan.y"
+#line 536 "./parse-scan.y"
{ modifier_value = 0; ;
break;}
case 106:
-#line 535 "./parse-scan.y"
+#line 543 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 107:
-#line 537 "./parse-scan.y"
+#line 545 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 114:
-#line 554 "./parse-scan.y"
+#line 562 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 115:
-#line 556 "./parse-scan.y"
+#line 564 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
case 118:
-#line 568 "./parse-scan.y"
+#line 576 "./parse-scan.y"
+{ report_class_declaration (yyvsp[0].node); modifier_value = 0; ;
+ break;}
+case 120:
+#line 579 "./parse-scan.y"
+{ report_class_declaration (yyvsp[0].node); modifier_value = 0; ;
+ break;}
+case 122:
+#line 582 "./parse-scan.y"
{ report_class_declaration (yyvsp[-1].node); modifier_value = 0; ;
break;}
-case 119:
-#line 570 "./parse-scan.y"
+case 124:
+#line 585 "./parse-scan.y"
{ report_class_declaration (yyvsp[-1].node); modifier_value = 0; ;
break;}
-case 120:
-#line 572 "./parse-scan.y"
-{ report_class_declaration (yyvsp[-2].node); modifier_value = 0; ;
+case 128:
+#line 596 "./parse-scan.y"
+{ pop_class_context (); ;
break;}
-case 121:
-#line 574 "./parse-scan.y"
-{ report_class_declaration (yyvsp[-2].node); modifier_value = 0; ;
+case 129:
+#line 598 "./parse-scan.y"
+{ pop_class_context (); ;
break;}
-case 148:
-#line 643 "./parse-scan.y"
+case 152:
+#line 657 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 149:
-#line 645 "./parse-scan.y"
+case 153:
+#line 659 "./parse-scan.y"
{ modifier_value = 0; ;
break;}
-case 173:
-#line 685 "./parse-scan.y"
+case 177:
+#line 699 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 226:
-#line 832 "./parse-scan.y"
+case 230:
+#line 846 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 243:
-#line 872 "./parse-scan.y"
+case 247:
+#line 886 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 244:
-#line 874 "./parse-scan.y"
+case 248:
+#line 888 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 246:
-#line 880 "./parse-scan.y"
+case 250:
+#line 894 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 255:
-#line 902 "./parse-scan.y"
+case 259:
+#line 916 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 273:
-#line 944 "./parse-scan.y"
+case 277:
+#line 958 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 274:
-#line 946 "./parse-scan.y"
+case 278:
+#line 960 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 279:
-#line 955 "./parse-scan.y"
+case 283:
+#line 969 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 282:
-#line 962 "./parse-scan.y"
+case 286:
+#line 976 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
-case 337:
-#line 1081 "./parse-scan.y"
+case 341:
+#line 1095 "./parse-scan.y"
{ USE_ABSORBER; ;
break;}
}
@@ -2413,7 +2460,7 @@ yyerrhandle:
}
return 1;
}
-#line 1099 "./parse-scan.y"
+#line 1113 "./parse-scan.y"
/* Create a new parser context */
@@ -2428,7 +2475,33 @@ java_push_parser_context ()
ctxp = new;
}
+static void
+push_class_context (name)
+ const char *name;
+{
+ size_t name_length = strlen (name);
+ inner_qualifier = xrealloc (inner_qualifier,
+ inner_qualifier_length + name_length+2);
+ memcpy (inner_qualifier+inner_qualifier_length, name, name_length);
+ inner_qualifier_length += name_length;
+ inner_qualifier [inner_qualifier_length] = '$';
+ inner_qualifier [++inner_qualifier_length] = '\0';
+}
+
+static void
+pop_class_context ()
+{
+ while (--inner_qualifier_length > 0
+ && inner_qualifier [inner_qualifier_length-1] != '$')
+ ;
+ inner_qualifier = xrealloc (inner_qualifier, inner_qualifier_length+1);
+ if (inner_qualifier_length == -1)
+ inner_qualifier_length = 0;
+ inner_qualifier [inner_qualifier_length] = '\0';
+}
+
/* Actions defined here */
+#define INNER_QUALIFIER (inner_qualifier ? inner_qualifier : "")
static void
report_class_declaration (name)
@@ -2446,11 +2519,12 @@ report_class_declaration (name)
}
if (package_name)
- fprintf (out, "%s.%s ", package_name, name);
+ fprintf (out, "%s.%s%s ", package_name, INNER_QUALIFIER, name);
else
- fprintf (out, "%s ", name);
+ fprintf (out, "%s%s ", INNER_QUALIFIER, name);
}
-
+
+ push_class_context (name);
current_class = name;
}
diff --git a/gcc/java/parse-scan.y b/gcc/java/parse-scan.y
index 8d8577baf98..f4d10b840e8 100644
--- a/gcc/java/parse-scan.y
+++ b/gcc/java/parse-scan.y
@@ -66,6 +66,10 @@ static int absorber;
static const char *current_class;
static const char *package_name;
+/* Keep track of the current inner class qualifier. */
+static char *inner_qualifier;
+static int inner_qualifier_length;
+
/* Keep track of whether things have be listed before. */
static int previous_output;
@@ -92,6 +96,8 @@ struct method_declarator {
/* Two actions for this grammar */
static void report_class_declaration PARAMS ((const char *));
static void report_main_declaration PARAMS ((struct method_declarator *));
+static void push_class_context PARAMS ((const char *));
+static void pop_class_context PARAMS ((void));
#include "lex.h"
#include "parse.h"
@@ -357,7 +363,9 @@ interface_type_list:
class_body:
OCB_TK CCB_TK
+ { pop_class_context (); }
| OCB_TK class_body_declarations CCB_TK
+ { pop_class_context (); }
;
class_body_declarations:
@@ -564,14 +572,18 @@ this_or_super: /* Added, simplifies error diagnostics */
/* 19.9 Productions from 9: Interfaces */
/* 19.9.1 Productions from 9.1: Interfaces Declarations */
interface_declaration:
- INTERFACE_TK identifier interface_body
+ INTERFACE_TK identifier
{ report_class_declaration ($2); modifier_value = 0; }
-| modifiers INTERFACE_TK identifier interface_body
+ interface_body
+| modifiers INTERFACE_TK identifier
{ report_class_declaration ($3); modifier_value = 0; }
-| INTERFACE_TK identifier extends_interfaces interface_body
+ interface_body
+| INTERFACE_TK identifier extends_interfaces
{ report_class_declaration ($2); modifier_value = 0; }
-| modifiers INTERFACE_TK identifier extends_interfaces interface_body
+ interface_body
+| modifiers INTERFACE_TK identifier extends_interfaces
{ report_class_declaration ($3); modifier_value = 0; }
+ interface_body
;
extends_interfaces:
@@ -581,7 +593,9 @@ extends_interfaces:
interface_body:
OCB_TK CCB_TK
+ { pop_class_context (); }
| OCB_TK interface_member_declarations CCB_TK
+ { pop_class_context (); }
;
interface_member_declarations:
@@ -1110,7 +1124,33 @@ java_push_parser_context ()
ctxp = new;
}
+static void
+push_class_context (name)
+ const char *name;
+{
+ size_t name_length = strlen (name);
+ inner_qualifier = xrealloc (inner_qualifier,
+ inner_qualifier_length + name_length+2);
+ memcpy (inner_qualifier+inner_qualifier_length, name, name_length);
+ inner_qualifier_length += name_length;
+ inner_qualifier [inner_qualifier_length] = '$';
+ inner_qualifier [++inner_qualifier_length] = '\0';
+}
+
+static void
+pop_class_context ()
+{
+ while (--inner_qualifier_length > 0
+ && inner_qualifier [inner_qualifier_length-1] != '$')
+ ;
+ inner_qualifier = xrealloc (inner_qualifier, inner_qualifier_length+1);
+ if (inner_qualifier_length == -1)
+ inner_qualifier_length = 0;
+ inner_qualifier [inner_qualifier_length] = '\0';
+}
+
/* Actions defined here */
+#define INNER_QUALIFIER (inner_qualifier ? inner_qualifier : "")
static void
report_class_declaration (name)
@@ -1128,11 +1168,12 @@ report_class_declaration (name)
}
if (package_name)
- fprintf (out, "%s.%s ", package_name, name);
+ fprintf (out, "%s.%s%s ", package_name, INNER_QUALIFIER, name);
else
- fprintf (out, "%s ", name);
+ fprintf (out, "%s%s ", INNER_QUALIFIER, name);
}
-
+
+ push_class_context (name);
current_class = name;
}
diff --git a/gcc/java/parse.c b/gcc/java/parse.c
index 7293d89d4a5..f65e21fccf1 100644
--- a/gcc/java/parse.c
+++ b/gcc/java/parse.c
@@ -1,6 +1,7 @@
/* A Bison parser, made from ./parse.y
- by GNU Bison version 1.28 */
+ by GNU Bison version 1.25
+ */
#define YYBISON 1 /* Identify Bison output. */
@@ -11,113 +12,113 @@
#define yychar java_char
#define yydebug java_debug
#define yynerrs java_nerrs
-#define PLUS_TK 257
-#define MINUS_TK 258
-#define MULT_TK 259
-#define DIV_TK 260
-#define REM_TK 261
-#define LS_TK 262
-#define SRS_TK 263
-#define ZRS_TK 264
-#define AND_TK 265
-#define XOR_TK 266
-#define OR_TK 267
-#define BOOL_AND_TK 268
-#define BOOL_OR_TK 269
-#define EQ_TK 270
-#define NEQ_TK 271
-#define GT_TK 272
-#define GTE_TK 273
-#define LT_TK 274
-#define LTE_TK 275
-#define PLUS_ASSIGN_TK 276
-#define MINUS_ASSIGN_TK 277
-#define MULT_ASSIGN_TK 278
-#define DIV_ASSIGN_TK 279
-#define REM_ASSIGN_TK 280
-#define LS_ASSIGN_TK 281
-#define SRS_ASSIGN_TK 282
-#define ZRS_ASSIGN_TK 283
-#define AND_ASSIGN_TK 284
-#define XOR_ASSIGN_TK 285
-#define OR_ASSIGN_TK 286
-#define PUBLIC_TK 287
-#define PRIVATE_TK 288
-#define PROTECTED_TK 289
-#define STATIC_TK 290
-#define FINAL_TK 291
-#define SYNCHRONIZED_TK 292
-#define VOLATILE_TK 293
-#define TRANSIENT_TK 294
-#define NATIVE_TK 295
-#define PAD_TK 296
-#define ABSTRACT_TK 297
-#define MODIFIER_TK 298
-#define DECR_TK 299
-#define INCR_TK 300
-#define DEFAULT_TK 301
-#define IF_TK 302
-#define THROW_TK 303
-#define BOOLEAN_TK 304
-#define DO_TK 305
-#define IMPLEMENTS_TK 306
-#define THROWS_TK 307
-#define BREAK_TK 308
-#define IMPORT_TK 309
-#define ELSE_TK 310
-#define INSTANCEOF_TK 311
-#define RETURN_TK 312
-#define VOID_TK 313
-#define CATCH_TK 314
-#define INTERFACE_TK 315
-#define CASE_TK 316
-#define EXTENDS_TK 317
-#define FINALLY_TK 318
-#define SUPER_TK 319
-#define WHILE_TK 320
-#define CLASS_TK 321
-#define SWITCH_TK 322
-#define CONST_TK 323
-#define TRY_TK 324
-#define FOR_TK 325
-#define NEW_TK 326
-#define CONTINUE_TK 327
-#define GOTO_TK 328
-#define PACKAGE_TK 329
-#define THIS_TK 330
-#define BYTE_TK 331
-#define SHORT_TK 332
-#define INT_TK 333
-#define LONG_TK 334
-#define CHAR_TK 335
-#define INTEGRAL_TK 336
-#define FLOAT_TK 337
-#define DOUBLE_TK 338
-#define FP_TK 339
-#define ID_TK 340
-#define REL_QM_TK 341
-#define REL_CL_TK 342
-#define NOT_TK 343
-#define NEG_TK 344
-#define ASSIGN_ANY_TK 345
-#define ASSIGN_TK 346
-#define OP_TK 347
-#define CP_TK 348
-#define OCB_TK 349
-#define CCB_TK 350
-#define OSB_TK 351
-#define CSB_TK 352
-#define SC_TK 353
-#define C_TK 354
-#define DOT_TK 355
-#define STRING_LIT_TK 356
-#define CHAR_LIT_TK 357
-#define INT_LIT_TK 358
-#define FP_LIT_TK 359
-#define TRUE_TK 360
-#define FALSE_TK 361
-#define BOOL_LIT_TK 362
-#define NULL_TK 363
+#define PLUS_TK 258
+#define MINUS_TK 259
+#define MULT_TK 260
+#define DIV_TK 261
+#define REM_TK 262
+#define LS_TK 263
+#define SRS_TK 264
+#define ZRS_TK 265
+#define AND_TK 266
+#define XOR_TK 267
+#define OR_TK 268
+#define BOOL_AND_TK 269
+#define BOOL_OR_TK 270
+#define EQ_TK 271
+#define NEQ_TK 272
+#define GT_TK 273
+#define GTE_TK 274
+#define LT_TK 275
+#define LTE_TK 276
+#define PLUS_ASSIGN_TK 277
+#define MINUS_ASSIGN_TK 278
+#define MULT_ASSIGN_TK 279
+#define DIV_ASSIGN_TK 280
+#define REM_ASSIGN_TK 281
+#define LS_ASSIGN_TK 282
+#define SRS_ASSIGN_TK 283
+#define ZRS_ASSIGN_TK 284
+#define AND_ASSIGN_TK 285
+#define XOR_ASSIGN_TK 286
+#define OR_ASSIGN_TK 287
+#define PUBLIC_TK 288
+#define PRIVATE_TK 289
+#define PROTECTED_TK 290
+#define STATIC_TK 291
+#define FINAL_TK 292
+#define SYNCHRONIZED_TK 293
+#define VOLATILE_TK 294
+#define TRANSIENT_TK 295
+#define NATIVE_TK 296
+#define PAD_TK 297
+#define ABSTRACT_TK 298
+#define MODIFIER_TK 299
+#define DECR_TK 300
+#define INCR_TK 301
+#define DEFAULT_TK 302
+#define IF_TK 303
+#define THROW_TK 304
+#define BOOLEAN_TK 305
+#define DO_TK 306
+#define IMPLEMENTS_TK 307
+#define THROWS_TK 308
+#define BREAK_TK 309
+#define IMPORT_TK 310
+#define ELSE_TK 311
+#define INSTANCEOF_TK 312
+#define RETURN_TK 313
+#define VOID_TK 314
+#define CATCH_TK 315
+#define INTERFACE_TK 316
+#define CASE_TK 317
+#define EXTENDS_TK 318
+#define FINALLY_TK 319
+#define SUPER_TK 320
+#define WHILE_TK 321
+#define CLASS_TK 322
+#define SWITCH_TK 323
+#define CONST_TK 324
+#define TRY_TK 325
+#define FOR_TK 326
+#define NEW_TK 327
+#define CONTINUE_TK 328
+#define GOTO_TK 329
+#define PACKAGE_TK 330
+#define THIS_TK 331
+#define BYTE_TK 332
+#define SHORT_TK 333
+#define INT_TK 334
+#define LONG_TK 335
+#define CHAR_TK 336
+#define INTEGRAL_TK 337
+#define FLOAT_TK 338
+#define DOUBLE_TK 339
+#define FP_TK 340
+#define ID_TK 341
+#define REL_QM_TK 342
+#define REL_CL_TK 343
+#define NOT_TK 344
+#define NEG_TK 345
+#define ASSIGN_ANY_TK 346
+#define ASSIGN_TK 347
+#define OP_TK 348
+#define CP_TK 349
+#define OCB_TK 350
+#define CCB_TK 351
+#define OSB_TK 352
+#define CSB_TK 353
+#define SC_TK 354
+#define C_TK 355
+#define DOT_TK 356
+#define STRING_LIT_TK 357
+#define CHAR_LIT_TK 358
+#define INT_LIT_TK 359
+#define FP_LIT_TK 360
+#define TRUE_TK 361
+#define FALSE_TK 362
+#define BOOL_LIT_TK 363
+#define NULL_TK 364
#line 48 "./parse.y"
@@ -392,6 +393,7 @@ static void add_inner_class_fields PARAMS ((tree, tree));
static tree build_dot_class_method PARAMS ((tree));
static tree build_dot_class_method_invocation PARAMS ((tree));
+static void create_new_parser_context PARAMS ((int));
/* Number of error found so far. */
int java_error_count;
@@ -484,7 +486,7 @@ static tree package_list = NULL_TREE;
} while (0)
-#line 413 "./parse.y"
+#line 414 "./parse.y"
typedef union {
tree node;
int sub_token;
@@ -494,7 +496,7 @@ typedef union {
} operator;
int value;
} YYSTYPE;
-#line 423 "./parse.y"
+#line 424 "./parse.y"
#include "lex.c"
#ifndef YYDEBUG
@@ -515,7 +517,7 @@ typedef union {
#define YYFLAG -32768
#define YYNTBASE 110
-#define YYTRANSLATE(x) ((unsigned)(x) <= 363 ? yytranslate[x] : 272)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 364 ? yytranslate[x] : 272)
static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -543,18 +545,18 @@ static const char yytranslate[] = { 0,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 1, 3, 4, 5, 6,
- 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
- 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
- 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
- 57, 58, 59, 60, 61, 62, 63, 64, 65, 66,
- 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
- 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
- 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,
- 107, 108, 109
+ 2, 2, 2, 2, 2, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109
};
#if YYDEBUG != 0
@@ -795,57 +797,57 @@ static const short yyrhs[] = { 123,
#if YYDEBUG != 0
static const short yyrline[] = { 0,
- 572, 578, 580, 581, 582, 583, 584, 588, 590, 593,
- 595, 596, 599, 601, 604, 608, 612, 616, 622, 624,
- 626, 628, 633, 635, 638, 642, 647, 652, 654, 655,
- 656, 657, 658, 659, 660, 663, 668, 674, 676, 679,
- 685, 687, 691, 693, 696, 723, 725, 729, 742, 744,
- 748, 751, 753, 755, 765, 770, 785, 789, 789, 792,
- 792, 794, 796, 801, 805, 807, 809, 811, 815, 817,
- 819, 826, 832, 837, 841, 850, 860, 862, 865, 867,
- 868, 869, 876, 878, 880, 881, 883, 888, 891, 901,
- 904, 906, 910, 913, 920, 926, 934, 936, 938, 940,
- 942, 946, 948, 952, 963, 964, 968, 971, 973, 975,
- 977, 982, 984, 986, 988, 995, 1001, 1003, 1012, 1014,
- 1018, 1023, 1028, 1032, 1037, 1042, 1047, 1054, 1064, 1066,
- 1068, 1072, 1075, 1077, 1081, 1083, 1084, 1089, 1095, 1102,
- 1118, 1125, 1128, 1131, 1135, 1141, 1145, 1154, 1156, 1158,
- 1162, 1164, 1167, 1174, 1182, 1184, 1188, 1195, 1205, 1209,
- 1209, 1212, 1212, 1215, 1215, 1218, 1218, 1220, 1224, 1230,
- 1235, 1237, 1241, 1244, 1248, 1250, 1253, 1255, 1256, 1258,
- 1262, 1266, 1272, 1277, 1280, 1282, 1286, 1292, 1296, 1301,
- 1310, 1314, 1319, 1331, 1333, 1336, 1338, 1340, 1347, 1351,
- 1354, 1358, 1360, 1361, 1362, 1363, 1364, 1368, 1370, 1371,
- 1372, 1373, 1377, 1379, 1380, 1381, 1382, 1383, 1384, 1385,
- 1386, 1387, 1388, 1391, 1396, 1407, 1410, 1414, 1421, 1431,
- 1437, 1443, 1449, 1451, 1456, 1458, 1463, 1465, 1467, 1469,
- 1471, 1475, 1477, 1478, 1479, 1480, 1481, 1482, 1485, 1491,
- 1493, 1495, 1499, 1504, 1509, 1515, 1525, 1531, 1533, 1535,
- 1542, 1545, 1547, 1549, 1553, 1555, 1558, 1562, 1564, 1567,
- 1574, 1580, 1582, 1584, 1588, 1596, 1599, 1601, 1603, 1607,
- 1612, 1621, 1626, 1629, 1636, 1638, 1640, 1644, 1647, 1656,
- 1663, 1665, 1669, 1682, 1684, 1690, 1696, 1700, 1702, 1706,
- 1709, 1711, 1715, 1718, 1720, 1722, 1726, 1729, 1731, 1733,
- 1737, 1740, 1742, 1744, 1748, 1754, 1756, 1760, 1767, 1769,
- 1771, 1773, 1777, 1789, 1792, 1794, 1799, 1803, 1805, 1812,
- 1820, 1837, 1839, 1844, 1848, 1851, 1856, 1858, 1861, 1863,
- 1865, 1867, 1868, 1869, 1870, 1871, 1875, 1880, 1882, 1884,
- 1886, 1893, 1899, 1908, 1911, 1913, 1915, 1919, 1922, 1924,
- 1928, 1934, 1935, 1941, 1942, 1944, 1946, 1948, 1950, 1952,
- 1961, 1965, 1995, 1998, 2012, 2015, 2019, 2025, 2030, 2034,
- 2037, 2039, 2041, 2045, 2054, 2062, 2064, 2068, 2071, 2075,
- 2081, 2083, 2091, 2118, 2120, 2124, 2129, 2136, 2140, 2143,
- 2145, 2156, 2167, 2172, 2181, 2183, 2187, 2190, 2192, 2197,
- 2202, 2207, 2214, 2216, 2217, 2218, 2221, 2226, 2231, 2233,
- 2234, 2236, 2238, 2239, 2241, 2245, 2248, 2252, 2255, 2259,
- 2261, 2263, 2265, 2266, 2268, 2272, 2281, 2283, 2285, 2298,
- 2300, 2306, 2308, 2310, 2314, 2316, 2321, 2326, 2331, 2333,
- 2335, 2339, 2341, 2346, 2351, 2353, 2357, 2359, 2364, 2369,
- 2374, 2376, 2378, 2382, 2384, 2389, 2394, 2399, 2404, 2406,
- 2408, 2410, 2412, 2414, 2418, 2420, 2425, 2430, 2432, 2436,
- 2438, 2443, 2447, 2449, 2454, 2458, 2460, 2465, 2469, 2471,
- 2476, 2480, 2482, 2487, 2491, 2493, 2498, 2504, 2506, 2510,
- 2512, 2515, 2518, 2526, 2528, 2529, 2532, 2534, 2537, 2541
+ 573, 579, 581, 582, 583, 584, 585, 589, 591, 594,
+ 596, 597, 600, 602, 605, 609, 613, 617, 623, 625,
+ 627, 629, 634, 636, 639, 643, 648, 653, 655, 656,
+ 657, 658, 659, 660, 661, 664, 669, 675, 677, 680,
+ 686, 688, 692, 694, 697, 724, 726, 730, 743, 745,
+ 749, 752, 754, 756, 766, 771, 786, 790, 790, 793,
+ 793, 795, 797, 802, 806, 808, 810, 812, 816, 818,
+ 820, 827, 833, 838, 842, 851, 861, 863, 866, 868,
+ 869, 870, 877, 879, 881, 882, 884, 889, 892, 902,
+ 905, 907, 911, 914, 921, 927, 935, 937, 939, 941,
+ 943, 947, 949, 953, 964, 965, 969, 972, 974, 976,
+ 978, 983, 985, 987, 989, 996, 1002, 1004, 1013, 1015,
+ 1019, 1024, 1029, 1033, 1038, 1043, 1048, 1055, 1065, 1067,
+ 1069, 1073, 1076, 1078, 1082, 1084, 1085, 1090, 1096, 1103,
+ 1119, 1126, 1129, 1132, 1136, 1142, 1146, 1155, 1157, 1159,
+ 1163, 1165, 1168, 1175, 1183, 1185, 1189, 1196, 1206, 1210,
+ 1210, 1213, 1213, 1216, 1216, 1219, 1219, 1221, 1225, 1231,
+ 1236, 1238, 1242, 1245, 1249, 1251, 1254, 1256, 1257, 1259,
+ 1263, 1267, 1273, 1278, 1281, 1283, 1287, 1293, 1297, 1302,
+ 1311, 1315, 1320, 1332, 1334, 1337, 1339, 1341, 1348, 1352,
+ 1355, 1359, 1361, 1362, 1363, 1364, 1365, 1369, 1371, 1372,
+ 1373, 1374, 1378, 1380, 1381, 1382, 1383, 1384, 1385, 1386,
+ 1387, 1388, 1389, 1392, 1397, 1408, 1411, 1415, 1422, 1432,
+ 1438, 1444, 1450, 1452, 1457, 1459, 1464, 1466, 1468, 1470,
+ 1472, 1476, 1478, 1479, 1480, 1481, 1482, 1483, 1486, 1492,
+ 1494, 1496, 1500, 1505, 1510, 1516, 1526, 1532, 1534, 1536,
+ 1543, 1546, 1548, 1550, 1554, 1556, 1559, 1563, 1565, 1568,
+ 1575, 1581, 1583, 1585, 1589, 1597, 1600, 1602, 1604, 1608,
+ 1613, 1622, 1627, 1630, 1637, 1639, 1641, 1645, 1648, 1657,
+ 1664, 1666, 1670, 1683, 1685, 1691, 1697, 1701, 1703, 1707,
+ 1710, 1712, 1716, 1719, 1721, 1723, 1727, 1730, 1732, 1734,
+ 1738, 1741, 1743, 1745, 1749, 1755, 1757, 1761, 1768, 1770,
+ 1772, 1774, 1778, 1790, 1793, 1795, 1800, 1804, 1806, 1813,
+ 1821, 1838, 1840, 1845, 1849, 1852, 1857, 1859, 1862, 1864,
+ 1866, 1868, 1869, 1870, 1871, 1872, 1876, 1881, 1883, 1885,
+ 1887, 1894, 1900, 1909, 1912, 1914, 1916, 1920, 1923, 1925,
+ 1929, 1935, 1936, 1942, 1943, 1945, 1947, 1949, 1951, 1953,
+ 1962, 1966, 1996, 1999, 2013, 2016, 2020, 2026, 2031, 2035,
+ 2038, 2040, 2042, 2046, 2055, 2063, 2065, 2069, 2072, 2076,
+ 2082, 2084, 2092, 2119, 2121, 2125, 2130, 2137, 2141, 2144,
+ 2146, 2157, 2168, 2173, 2182, 2184, 2188, 2191, 2193, 2198,
+ 2203, 2208, 2215, 2217, 2218, 2219, 2222, 2227, 2232, 2234,
+ 2235, 2237, 2239, 2240, 2242, 2246, 2249, 2253, 2256, 2260,
+ 2262, 2264, 2266, 2267, 2269, 2273, 2282, 2284, 2286, 2299,
+ 2301, 2307, 2309, 2311, 2315, 2317, 2322, 2327, 2332, 2334,
+ 2336, 2340, 2342, 2347, 2352, 2354, 2358, 2360, 2365, 2370,
+ 2375, 2377, 2379, 2383, 2385, 2390, 2395, 2400, 2405, 2407,
+ 2409, 2411, 2413, 2415, 2419, 2421, 2426, 2431, 2433, 2437,
+ 2439, 2444, 2448, 2450, 2455, 2459, 2461, 2466, 2470, 2472,
+ 2477, 2481, 2483, 2488, 2492, 2494, 2499, 2505, 2507, 2511,
+ 2513, 2516, 2519, 2527, 2529, 2530, 2533, 2535, 2538, 2542
};
#endif
@@ -2385,8 +2387,7 @@ static const short yycheck[] = { 3,
#define YYPURE 1
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
-#line 3 "/usr/lib/bison.simple"
-/* This file comes from bison-1.28. */
+#line 3 "/usr/share/misc/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@@ -2403,66 +2404,46 @@ static const short yycheck[] = { 3,
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA. */
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
-/* This is the parser code that is written into each bison parser
- when the %semantic_parser declaration is not specified in the grammar.
- It was written by Richard Stallman by simplifying the hairy parser
- used when %semantic_parser is specified. */
-
-#ifndef YYSTACK_USE_ALLOCA
-#ifdef alloca
-#define YYSTACK_USE_ALLOCA
-#else /* alloca not defined */
+#ifndef alloca
#ifdef __GNUC__
-#define YYSTACK_USE_ALLOCA
#define alloca __builtin_alloca
#else /* not GNU C. */
-#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
-#define YYSTACK_USE_ALLOCA
+#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
#include <alloca.h>
#else /* not sparc */
-/* We think this test detects Watcom and Microsoft C. */
-/* This used to test MSDOS, but that is a bad idea
- since that symbol is in the user namespace. */
-#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
-#if 0 /* No need for malloc.h, which pollutes the namespace;
- instead, just don't use alloca. */
+#if defined (MSDOS) && !defined (__TURBOC__)
#include <malloc.h>
-#endif
#else /* not MSDOS, or __TURBOC__ */
#if defined(_AIX)
-/* I don't know what this was needed for, but it pollutes the namespace.
- So I turned it off. rms, 2 May 1997. */
-/* #include <malloc.h> */
+#include <malloc.h>
#pragma alloca
-#define YYSTACK_USE_ALLOCA
-#else /* not MSDOS, or __TURBOC__, or _AIX */
-#if 0
-#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
- and on HPUX 10. Eventually we can turn this on. */
-#define YYSTACK_USE_ALLOCA
-#define alloca __builtin_alloca
+#else /* not MSDOS, __TURBOC__, or _AIX */
+#ifdef __hpux
+#ifdef __cplusplus
+extern "C" {
+void *alloca (unsigned int);
+};
+#else /* not __cplusplus */
+void *alloca ();
+#endif /* not __cplusplus */
#endif /* __hpux */
-#endif
#endif /* not _AIX */
#endif /* not MSDOS, or __TURBOC__ */
-#endif /* not sparc */
-#endif /* not GNU C */
-#endif /* alloca not defined */
-#endif /* YYSTACK_USE_ALLOCA not defined */
+#endif /* not sparc. */
+#endif /* not GNU C. */
+#endif /* alloca not defined. */
-#ifdef YYSTACK_USE_ALLOCA
-#define YYSTACK_ALLOC alloca
-#else
-#define YYSTACK_ALLOC malloc
-#endif
+/* This is the parser code that is written into each bison parser
+ when the %semantic_parser declaration is not specified in the grammar.
+ It was written by Richard Stallman by simplifying the hairy parser
+ used when %semantic_parser is specified. */
/* Note: there must be only one dollar sign in this file.
It is replaced by the list of actions, each action
@@ -2472,8 +2453,8 @@ static const short yycheck[] = { 3,
#define yyclearin (yychar = YYEMPTY)
#define YYEMPTY -2
#define YYEOF 0
-#define YYACCEPT goto yyacceptlab
-#define YYABORT goto yyabortlab
+#define YYACCEPT return(0)
+#define YYABORT return(1)
#define YYERROR goto yyerrlab1
/* Like YYERROR except do call yyerror.
This remains here temporarily to ease the
@@ -2554,12 +2535,14 @@ int yydebug; /* nonzero means print parse trace */
#ifndef YYMAXDEPTH
#define YYMAXDEPTH 10000
#endif
-
-/* Define __yy_memcpy. Note that the size argument
- should be passed with type unsigned int, because that is what the non-GCC
- definitions require. With GCC, __builtin_memcpy takes an arg
- of type size_t, but it can handle unsigned int. */
+/* Prevent warning if -Wstrict-prototypes. */
+#ifdef __GNUC__
+#ifndef YYPARSE_PARAM
+int yyparse (void);
+#endif
+#endif
+
#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
#else /* not GNU C or C++ */
@@ -2571,7 +2554,7 @@ static void
__yy_memcpy (to, from, count)
char *to;
char *from;
- unsigned int count;
+ int count;
{
register char *f = from;
register char *t = to;
@@ -2586,10 +2569,10 @@ __yy_memcpy (to, from, count)
/* This is the most reliable way to avoid incompatibilities
in available built-in functions on various systems. */
static void
-__yy_memcpy (char *to, char *from, unsigned int count)
+__yy_memcpy (char *to, char *from, int count)
{
- register char *t = to;
register char *f = from;
+ register char *t = to;
register int i = count;
while (i-- > 0)
@@ -2599,7 +2582,7 @@ __yy_memcpy (char *to, char *from, unsigned int count)
#endif
#endif
-#line 217 "/usr/lib/bison.simple"
+#line 196 "/usr/share/misc/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@@ -2620,15 +2603,6 @@ __yy_memcpy (char *to, char *from, unsigned int count)
#define YYPARSE_PARAM_DECL
#endif /* not YYPARSE_PARAM */
-/* Prevent warning if -Wstrict-prototypes. */
-#ifdef __GNUC__
-#ifdef YYPARSE_PARAM
-int yyparse (void *);
-#else
-int yyparse (void);
-#endif
-#endif
-
int
yyparse(YYPARSE_PARAM_ARG)
YYPARSE_PARAM_DECL
@@ -2657,7 +2631,6 @@ yyparse(YYPARSE_PARAM_ARG)
#endif
int yystacksize = YYINITDEPTH;
- int yyfree_stacks = 0;
#ifdef YYPURE
int yychar;
@@ -2742,32 +2715,18 @@ yynewstate:
if (yystacksize >= YYMAXDEPTH)
{
yyerror("parser stack overflow");
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
return 2;
}
yystacksize *= 2;
if (yystacksize > YYMAXDEPTH)
yystacksize = YYMAXDEPTH;
-#ifndef YYSTACK_USE_ALLOCA
- yyfree_stacks = 1;
-#endif
- yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
- __yy_memcpy ((char *)yyss, (char *)yyss1,
- size * (unsigned int) sizeof (*yyssp));
- yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
- __yy_memcpy ((char *)yyvs, (char *)yyvs1,
- size * (unsigned int) sizeof (*yyvsp));
+ yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
+ __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
+ yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
+ __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
#ifdef YYLSP_NEEDED
- yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
- __yy_memcpy ((char *)yyls, (char *)yyls1,
- size * (unsigned int) sizeof (*yylsp));
+ yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
+ __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
#endif
#endif /* no yyoverflow */
@@ -2928,69 +2887,69 @@ yyreduce:
switch (yyn) {
case 1:
-#line 574 "./parse.y"
+#line 575 "./parse.y"
{;
break;}
case 18:
-#line 618 "./parse.y"
+#line 619 "./parse.y"
{
yyval.node = build_java_array_type (yyvsp[-2].node, -1);
CLASS_LOADED_P (yyval.node) = 1;
;
break;}
case 19:
-#line 623 "./parse.y"
+#line 624 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 20:
-#line 625 "./parse.y"
+#line 626 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 21:
-#line 627 "./parse.y"
+#line 628 "./parse.y"
{RULE ("']' expected"); RECOVER;;
break;}
case 22:
-#line 629 "./parse.y"
+#line 630 "./parse.y"
{RULE ("']' expected"); RECOVER;;
break;}
case 26:
-#line 644 "./parse.y"
+#line 645 "./parse.y"
{ yyval.node = make_qualified_name (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
break;}
case 28:
-#line 653 "./parse.y"
+#line 654 "./parse.y"
{yyval.node = NULL;;
break;}
case 36:
-#line 665 "./parse.y"
+#line 666 "./parse.y"
{
yyval.node = NULL;
;
break;}
case 37:
-#line 669 "./parse.y"
+#line 670 "./parse.y"
{
yyval.node = NULL;
;
break;}
case 40:
-#line 681 "./parse.y"
+#line 682 "./parse.y"
{
ctxp->package = EXPR_WFL_NODE (yyvsp[-1].node);
package_list = tree_cons (ctxp->package, NULL, package_list);
;
break;}
case 41:
-#line 686 "./parse.y"
+#line 687 "./parse.y"
{yyerror ("Missing name"); RECOVER;;
break;}
case 42:
-#line 688 "./parse.y"
+#line 689 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 45:
-#line 698 "./parse.y"
+#line 699 "./parse.y"
{
tree name = EXPR_WFL_NODE (yyvsp[-1].node), node, last_name;
int i = IDENTIFIER_LENGTH (name)-1;
@@ -3018,15 +2977,15 @@ case 45:
;
break;}
case 46:
-#line 724 "./parse.y"
+#line 725 "./parse.y"
{yyerror ("Missing name"); RECOVER;;
break;}
case 47:
-#line 726 "./parse.y"
+#line 727 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 48:
-#line 731 "./parse.y"
+#line 732 "./parse.y"
{
tree name = EXPR_WFL_NODE (yyvsp[-3].node);
/* Don't import java.lang.* twice. */
@@ -3040,40 +2999,40 @@ case 48:
;
break;}
case 49:
-#line 743 "./parse.y"
+#line 744 "./parse.y"
{yyerror ("'*' expected"); RECOVER;;
break;}
case 50:
-#line 745 "./parse.y"
+#line 746 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 51:
-#line 750 "./parse.y"
+#line 751 "./parse.y"
{ end_class_declaration (0); ;
break;}
case 52:
-#line 752 "./parse.y"
+#line 753 "./parse.y"
{ end_class_declaration (0); ;
break;}
case 53:
-#line 754 "./parse.y"
+#line 755 "./parse.y"
{ yyval.node = NULL; ;
break;}
case 54:
-#line 756 "./parse.y"
+#line 757 "./parse.y"
{
YYERROR_NOW;
yyerror ("Class or interface declaration expected");
;
break;}
case 55:
-#line 767 "./parse.y"
+#line 768 "./parse.y"
{
yyval.value = (1 << yyvsp[0].value);
;
break;}
case 56:
-#line 771 "./parse.y"
+#line 772 "./parse.y"
{
int acc = (1 << yyvsp[0].value);
if (yyval.value & acc)
@@ -3087,83 +3046,83 @@ case 56:
;
break;}
case 57:
-#line 787 "./parse.y"
+#line 788 "./parse.y"
{ create_class (yyvsp[-4].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 59:
-#line 790 "./parse.y"
+#line 791 "./parse.y"
{ create_class (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 61:
-#line 793 "./parse.y"
+#line 794 "./parse.y"
{yyerror ("Missing class name"); RECOVER;;
break;}
case 62:
-#line 795 "./parse.y"
+#line 796 "./parse.y"
{yyerror ("Missing class name"); RECOVER;;
break;}
case 63:
-#line 797 "./parse.y"
+#line 798 "./parse.y"
{
if (!ctxp->class_err) yyerror ("'{' expected");
DRECOVER(class1);
;
break;}
case 64:
-#line 802 "./parse.y"
+#line 803 "./parse.y"
{if (!ctxp->class_err) yyerror ("'{' expected"); RECOVER;;
break;}
case 65:
-#line 806 "./parse.y"
+#line 807 "./parse.y"
{ yyval.node = NULL; ;
break;}
case 66:
-#line 808 "./parse.y"
+#line 809 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 67:
-#line 810 "./parse.y"
+#line 811 "./parse.y"
{yyerror ("'{' expected"); ctxp->class_err=1;;
break;}
case 68:
-#line 812 "./parse.y"
+#line 813 "./parse.y"
{yyerror ("Missing super class name"); ctxp->class_err=1;;
break;}
case 69:
-#line 816 "./parse.y"
+#line 817 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 70:
-#line 818 "./parse.y"
+#line 819 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 71:
-#line 820 "./parse.y"
+#line 821 "./parse.y"
{
ctxp->class_err=1;
yyerror ("Missing interface name");
;
break;}
case 72:
-#line 828 "./parse.y"
+#line 829 "./parse.y"
{
ctxp->interface_number = 1;
yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
;
break;}
case 73:
-#line 833 "./parse.y"
+#line 834 "./parse.y"
{
ctxp->interface_number++;
yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
;
break;}
case 74:
-#line 838 "./parse.y"
+#line 839 "./parse.y"
{yyerror ("Missing interface name"); RECOVER;;
break;}
case 75:
-#line 843 "./parse.y"
+#line 844 "./parse.y"
{
/* Store the location of the `}' when doing xrefs */
if (flag_emit_xref)
@@ -3173,7 +3132,7 @@ case 75:
;
break;}
case 76:
-#line 851 "./parse.y"
+#line 852 "./parse.y"
{
/* Store the location of the `}' when doing xrefs */
if (flag_emit_xref)
@@ -3183,30 +3142,30 @@ case 76:
;
break;}
case 82:
-#line 870 "./parse.y"
+#line 871 "./parse.y"
{
TREE_CHAIN (yyvsp[0].node) = CPC_INSTANCE_INITIALIZER_STMT (ctxp);
SET_CPC_INSTANCE_INITIALIZER_STMT (ctxp, yyvsp[0].node);
;
break;}
case 84:
-#line 879 "./parse.y"
+#line 880 "./parse.y"
{ yyval.node = yyvsp[-1].node; ;
break;}
case 86:
-#line 882 "./parse.y"
+#line 883 "./parse.y"
{ end_class_declaration (1); ;
break;}
case 87:
-#line 884 "./parse.y"
+#line 885 "./parse.y"
{ end_class_declaration (1); ;
break;}
case 88:
-#line 890 "./parse.y"
+#line 891 "./parse.y"
{ register_fields (0, yyvsp[-2].node, yyvsp[-1].node); ;
break;}
case 89:
-#line 892 "./parse.y"
+#line 893 "./parse.y"
{
check_modifiers
("Illegal modifier `%s' for field declaration",
@@ -3216,19 +3175,19 @@ case 89:
;
break;}
case 91:
-#line 905 "./parse.y"
+#line 906 "./parse.y"
{ yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 92:
-#line 907 "./parse.y"
+#line 908 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 93:
-#line 912 "./parse.y"
+#line 913 "./parse.y"
{ yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE); ;
break;}
case 94:
-#line 914 "./parse.y"
+#line 915 "./parse.y"
{
if (java_error_count)
yyvsp[0].node = NULL_TREE;
@@ -3237,7 +3196,7 @@ case 94:
;
break;}
case 95:
-#line 921 "./parse.y"
+#line 922 "./parse.y"
{
yyerror ("Missing variable initializer");
yyval.node = build_tree_list (yyvsp[-2].node, NULL_TREE);
@@ -3245,7 +3204,7 @@ case 95:
;
break;}
case 96:
-#line 927 "./parse.y"
+#line 928 "./parse.y"
{
yyerror ("';' expected");
yyval.node = build_tree_list (yyvsp[-3].node, NULL_TREE);
@@ -3253,23 +3212,23 @@ case 96:
;
break;}
case 98:
-#line 937 "./parse.y"
+#line 938 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 99:
-#line 939 "./parse.y"
+#line 940 "./parse.y"
{yyerror ("Invalid declaration"); DRECOVER(vdi);;
break;}
case 100:
-#line 941 "./parse.y"
+#line 942 "./parse.y"
{yyerror ("']' expected"); DRECOVER(vdi);;
break;}
case 101:
-#line 943 "./parse.y"
+#line 944 "./parse.y"
{yyerror ("Unbalanced ']'"); DRECOVER(vdi);;
break;}
case 104:
-#line 954 "./parse.y"
+#line 955 "./parse.y"
{
current_function_decl = yyvsp[0].node;
if (current_function_decl
@@ -3280,68 +3239,68 @@ case 104:
;
break;}
case 105:
-#line 963 "./parse.y"
+#line 964 "./parse.y"
{ finish_method_declaration (yyvsp[0].node); ;
break;}
case 106:
-#line 965 "./parse.y"
+#line 966 "./parse.y"
{YYNOT_TWICE yyerror ("'{' expected"); RECOVER;;
break;}
case 107:
-#line 970 "./parse.y"
+#line 971 "./parse.y"
{ yyval.node = method_header (0, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 108:
-#line 972 "./parse.y"
+#line 973 "./parse.y"
{ yyval.node = method_header (0, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 109:
-#line 974 "./parse.y"
+#line 975 "./parse.y"
{ yyval.node = method_header (yyvsp[-3].value, yyvsp[-2].node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 110:
-#line 976 "./parse.y"
+#line 977 "./parse.y"
{ yyval.node = method_header (yyvsp[-3].value, void_type_node, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 111:
-#line 978 "./parse.y"
+#line 979 "./parse.y"
{
yyerror ("Invalid method declaration, method name required");
RECOVER;
;
break;}
case 112:
-#line 983 "./parse.y"
+#line 984 "./parse.y"
{RECOVER;;
break;}
case 113:
-#line 985 "./parse.y"
+#line 986 "./parse.y"
{yyerror ("Identifier expected"); RECOVER;;
break;}
case 114:
-#line 987 "./parse.y"
+#line 988 "./parse.y"
{yyerror ("Identifier expected"); RECOVER;;
break;}
case 115:
-#line 989 "./parse.y"
+#line 990 "./parse.y"
{
yyerror ("Invalid method declaration, return type required");
RECOVER;
;
break;}
case 116:
-#line 997 "./parse.y"
+#line 998 "./parse.y"
{
ctxp->formal_parameter_number = 0;
yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE);
;
break;}
case 117:
-#line 1002 "./parse.y"
+#line 1003 "./parse.y"
{ yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 118:
-#line 1004 "./parse.y"
+#line 1005 "./parse.y"
{
EXPR_WFL_LINECOL (wfl_operator) = yyvsp[-1].operator.location;
TREE_PURPOSE (yyvsp[-2].node) =
@@ -3352,59 +3311,59 @@ case 118:
;
break;}
case 119:
-#line 1013 "./parse.y"
+#line 1014 "./parse.y"
{yyerror ("')' expected"); DRECOVER(method_declarator);;
break;}
case 120:
-#line 1015 "./parse.y"
+#line 1016 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
case 121:
-#line 1020 "./parse.y"
+#line 1021 "./parse.y"
{
ctxp->formal_parameter_number = 1;
;
break;}
case 122:
-#line 1024 "./parse.y"
+#line 1025 "./parse.y"
{
ctxp->formal_parameter_number += 1;
yyval.node = chainon (yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 123:
-#line 1029 "./parse.y"
+#line 1030 "./parse.y"
{ yyerror ("Missing formal parameter term"); RECOVER; ;
break;}
case 124:
-#line 1034 "./parse.y"
+#line 1035 "./parse.y"
{
yyval.node = build_tree_list (yyvsp[0].node, yyvsp[-1].node);
;
break;}
case 125:
-#line 1038 "./parse.y"
+#line 1039 "./parse.y"
{
yyval.node = build_tree_list (yyvsp[0].node, yyvsp[-1].node);
ARG_FINAL_P (yyval.node) = 1;
;
break;}
case 126:
-#line 1043 "./parse.y"
+#line 1044 "./parse.y"
{
yyerror ("Missing identifier"); RECOVER;
yyval.node = NULL_TREE;
;
break;}
case 127:
-#line 1048 "./parse.y"
+#line 1049 "./parse.y"
{
yyerror ("Missing identifier"); RECOVER;
yyval.node = NULL_TREE;
;
break;}
case 128:
-#line 1056 "./parse.y"
+#line 1057 "./parse.y"
{
check_modifiers ("Illegal modifier `%s'. Only `final' was expected here",
yyvsp[0].value, ACC_FINAL);
@@ -3413,49 +3372,49 @@ case 128:
;
break;}
case 129:
-#line 1065 "./parse.y"
+#line 1066 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 130:
-#line 1067 "./parse.y"
+#line 1068 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 131:
-#line 1069 "./parse.y"
+#line 1070 "./parse.y"
{yyerror ("Missing class type term"); RECOVER;;
break;}
case 132:
-#line 1074 "./parse.y"
+#line 1075 "./parse.y"
{ yyval.node = build_tree_list (yyvsp[0].node, yyvsp[0].node); ;
break;}
case 133:
-#line 1076 "./parse.y"
+#line 1077 "./parse.y"
{ yyval.node = tree_cons (yyvsp[0].node, yyvsp[0].node, yyvsp[-2].node); ;
break;}
case 134:
-#line 1078 "./parse.y"
+#line 1079 "./parse.y"
{yyerror ("Missing class type term"); RECOVER;;
break;}
case 137:
-#line 1085 "./parse.y"
+#line 1086 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 138:
-#line 1091 "./parse.y"
+#line 1092 "./parse.y"
{
TREE_CHAIN (yyvsp[0].node) = CPC_STATIC_INITIALIZER_STMT (ctxp);
SET_CPC_STATIC_INITIALIZER_STMT (ctxp, yyvsp[0].node);
;
break;}
case 139:
-#line 1096 "./parse.y"
+#line 1097 "./parse.y"
{
TREE_CHAIN (yyvsp[-1].node) = CPC_STATIC_INITIALIZER_STMT (ctxp);
SET_CPC_STATIC_INITIALIZER_STMT (ctxp, yyvsp[-1].node);
;
break;}
case 140:
-#line 1104 "./parse.y"
+#line 1105 "./parse.y"
{
check_modifiers ("Illegal modifier `%s' for static initializer", yyvsp[0].value, ACC_STATIC);
/* Can't have a static initializer in an innerclass */
@@ -3469,56 +3428,56 @@ case 140:
;
break;}
case 141:
-#line 1120 "./parse.y"
+#line 1121 "./parse.y"
{
current_function_decl = yyvsp[0].node;
source_start_java_method (current_function_decl);
;
break;}
case 142:
-#line 1125 "./parse.y"
+#line 1126 "./parse.y"
{ finish_method_declaration (yyvsp[0].node); ;
break;}
case 143:
-#line 1130 "./parse.y"
+#line 1131 "./parse.y"
{ yyval.node = method_header (0, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 144:
-#line 1132 "./parse.y"
+#line 1133 "./parse.y"
{ yyval.node = method_header (yyvsp[-2].value, NULL_TREE, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 145:
-#line 1137 "./parse.y"
+#line 1138 "./parse.y"
{
ctxp->formal_parameter_number = 0;
yyval.node = method_declarator (yyvsp[-2].node, NULL_TREE);
;
break;}
case 146:
-#line 1142 "./parse.y"
+#line 1143 "./parse.y"
{ yyval.node = method_declarator (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 147:
-#line 1150 "./parse.y"
+#line 1151 "./parse.y"
{
BLOCK_EXPR_BODY (yyvsp[0].node) = empty_stmt_node;
yyval.node = yyvsp[0].node;
;
break;}
case 148:
-#line 1155 "./parse.y"
+#line 1156 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 149:
-#line 1157 "./parse.y"
+#line 1158 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 150:
-#line 1159 "./parse.y"
+#line 1160 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 153:
-#line 1169 "./parse.y"
+#line 1170 "./parse.y"
{
yyval.node = build_method_invocation (yyvsp[-3].node, NULL_TREE);
yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-3].node), yyval.node);
@@ -3526,7 +3485,7 @@ case 153:
;
break;}
case 154:
-#line 1175 "./parse.y"
+#line 1176 "./parse.y"
{
yyval.node = build_method_invocation (yyvsp[-4].node, yyvsp[-2].node);
yyval.node = build_debugable_stmt (EXPR_WFL_LINECOL (yyvsp[-4].node), yyval.node);
@@ -3534,15 +3493,15 @@ case 154:
;
break;}
case 155:
-#line 1183 "./parse.y"
+#line 1184 "./parse.y"
{yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
break;}
case 156:
-#line 1185 "./parse.y"
+#line 1186 "./parse.y"
{yyval.node = parse_jdk1_1_error ("explicit constructor invocation"); ;
break;}
case 157:
-#line 1190 "./parse.y"
+#line 1191 "./parse.y"
{
tree wfl = build_wfl_node (this_identifier_node);
EXPR_WFL_LINECOL (wfl) = yyvsp[0].operator.location;
@@ -3550,7 +3509,7 @@ case 157:
;
break;}
case 158:
-#line 1196 "./parse.y"
+#line 1197 "./parse.y"
{
tree wfl = build_wfl_node (super_identifier_node);
EXPR_WFL_LINECOL (wfl) = yyvsp[0].operator.location;
@@ -3558,109 +3517,109 @@ case 158:
;
break;}
case 159:
-#line 1207 "./parse.y"
+#line 1208 "./parse.y"
{ create_interface (0, yyvsp[0].node, NULL_TREE); ;
break;}
case 161:
-#line 1210 "./parse.y"
+#line 1211 "./parse.y"
{ create_interface (yyvsp[-2].value, yyvsp[0].node, NULL_TREE); ;
break;}
case 163:
-#line 1213 "./parse.y"
+#line 1214 "./parse.y"
{ create_interface (0, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 165:
-#line 1216 "./parse.y"
+#line 1217 "./parse.y"
{ create_interface (yyvsp[-3].value, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 167:
-#line 1219 "./parse.y"
+#line 1220 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
case 168:
-#line 1221 "./parse.y"
+#line 1222 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
case 169:
-#line 1226 "./parse.y"
+#line 1227 "./parse.y"
{
ctxp->interface_number = 1;
yyval.node = build_tree_list (yyvsp[0].node, NULL_TREE);
;
break;}
case 170:
-#line 1231 "./parse.y"
+#line 1232 "./parse.y"
{
ctxp->interface_number++;
yyval.node = chainon (yyvsp[-2].node, build_tree_list (yyvsp[0].node, NULL_TREE));
;
break;}
case 171:
-#line 1236 "./parse.y"
+#line 1237 "./parse.y"
{yyerror ("Invalid interface type"); RECOVER;;
break;}
case 172:
-#line 1238 "./parse.y"
+#line 1239 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 173:
-#line 1243 "./parse.y"
+#line 1244 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 174:
-#line 1245 "./parse.y"
+#line 1246 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 179:
-#line 1257 "./parse.y"
+#line 1258 "./parse.y"
{ end_class_declaration (1); ;
break;}
case 180:
-#line 1259 "./parse.y"
+#line 1260 "./parse.y"
{ end_class_declaration (1); ;
break;}
case 182:
-#line 1268 "./parse.y"
+#line 1269 "./parse.y"
{
check_abstract_method_header (yyvsp[-1].node);
current_function_decl = NULL_TREE; /* FIXME ? */
;
break;}
case 183:
-#line 1273 "./parse.y"
+#line 1274 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 184:
-#line 1279 "./parse.y"
+#line 1280 "./parse.y"
{ yyval.node = build_new_array_init (yyvsp[-1].operator.location, NULL_TREE); ;
break;}
case 185:
-#line 1281 "./parse.y"
+#line 1282 "./parse.y"
{ yyval.node = build_new_array_init (yyvsp[-2].operator.location, yyvsp[-1].node); ;
break;}
case 186:
-#line 1283 "./parse.y"
+#line 1284 "./parse.y"
{ yyval.node = build_new_array_init (yyvsp[-3].operator.location, yyvsp[-2].node); ;
break;}
case 187:
-#line 1288 "./parse.y"
+#line 1289 "./parse.y"
{
yyval.node = tree_cons (maybe_build_array_element_wfl (yyvsp[0].node),
yyvsp[0].node, NULL_TREE);
;
break;}
case 188:
-#line 1293 "./parse.y"
+#line 1294 "./parse.y"
{
yyval.node = tree_cons (maybe_build_array_element_wfl (yyvsp[0].node), yyvsp[0].node, yyvsp[-2].node);
;
break;}
case 189:
-#line 1297 "./parse.y"
+#line 1298 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 190:
-#line 1303 "./parse.y"
+#line 1304 "./parse.y"
{
/* Store the location of the `}' when doing xrefs */
if (current_function_decl && flag_emit_xref)
@@ -3670,15 +3629,15 @@ case 190:
;
break;}
case 191:
-#line 1311 "./parse.y"
+#line 1312 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 192:
-#line 1316 "./parse.y"
+#line 1317 "./parse.y"
{ enter_block (); ;
break;}
case 193:
-#line 1321 "./parse.y"
+#line 1322 "./parse.y"
{
maybe_absorb_scoping_blocks ();
/* Store the location of the `}' when doing xrefs */
@@ -3689,38 +3648,38 @@ case 193:
;
break;}
case 197:
-#line 1339 "./parse.y"
+#line 1340 "./parse.y"
{ java_method_add_stmt (current_function_decl, yyvsp[0].node); ;
break;}
case 198:
-#line 1341 "./parse.y"
+#line 1342 "./parse.y"
{
LOCAL_CLASS_P (TREE_TYPE (GET_CPC ())) = 1;
end_class_declaration (1);
;
break;}
case 200:
-#line 1353 "./parse.y"
+#line 1354 "./parse.y"
{ declare_local_variables (0, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 201:
-#line 1355 "./parse.y"
+#line 1356 "./parse.y"
{ declare_local_variables (yyvsp[-2].value, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 207:
-#line 1365 "./parse.y"
+#line 1366 "./parse.y"
{ yyval.node = exit_block (); ;
break;}
case 212:
-#line 1374 "./parse.y"
+#line 1375 "./parse.y"
{ yyval.node = exit_block (); ;
break;}
case 224:
-#line 1393 "./parse.y"
+#line 1394 "./parse.y"
{ yyval.node = empty_stmt_node; ;
break;}
case 225:
-#line 1398 "./parse.y"
+#line 1399 "./parse.y"
{
yyval.node = build_labeled_block (EXPR_WFL_LINECOL (yyvsp[-1].node),
EXPR_WFL_NODE (yyvsp[-1].node));
@@ -3730,19 +3689,19 @@ case 225:
;
break;}
case 226:
-#line 1409 "./parse.y"
+#line 1410 "./parse.y"
{ yyval.node = finish_labeled_statement (yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 227:
-#line 1411 "./parse.y"
+#line 1412 "./parse.y"
{yyerror ("':' expected"); RECOVER;;
break;}
case 228:
-#line 1416 "./parse.y"
+#line 1417 "./parse.y"
{ yyval.node = finish_labeled_statement (yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 229:
-#line 1423 "./parse.y"
+#line 1424 "./parse.y"
{
/* We have a statement. Generate a WFL around it so
we can debug it */
@@ -3753,7 +3712,7 @@ case 229:
;
break;}
case 230:
-#line 1432 "./parse.y"
+#line 1433 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
@@ -3761,7 +3720,7 @@ case 230:
;
break;}
case 231:
-#line 1438 "./parse.y"
+#line 1439 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
@@ -3769,7 +3728,7 @@ case 231:
;
break;}
case 232:
-#line 1444 "./parse.y"
+#line 1445 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid expression statement");
@@ -3777,82 +3736,82 @@ case 232:
;
break;}
case 233:
-#line 1450 "./parse.y"
+#line 1451 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 234:
-#line 1452 "./parse.y"
+#line 1453 "./parse.y"
{
parse_ctor_invocation_error ();
RECOVER;
;
break;}
case 235:
-#line 1457 "./parse.y"
+#line 1458 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 236:
-#line 1459 "./parse.y"
+#line 1460 "./parse.y"
{
parse_ctor_invocation_error ();
RECOVER;
;
break;}
case 237:
-#line 1464 "./parse.y"
+#line 1465 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 238:
-#line 1466 "./parse.y"
+#line 1467 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 239:
-#line 1468 "./parse.y"
+#line 1469 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 240:
-#line 1470 "./parse.y"
+#line 1471 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 241:
-#line 1472 "./parse.y"
+#line 1473 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 249:
-#line 1487 "./parse.y"
+#line 1488 "./parse.y"
{
yyval.node = build_if_else_statement (yyvsp[-3].operator.location, yyvsp[-2].node,
yyvsp[0].node, NULL_TREE);
;
break;}
case 250:
-#line 1492 "./parse.y"
+#line 1493 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 251:
-#line 1494 "./parse.y"
+#line 1495 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 252:
-#line 1496 "./parse.y"
+#line 1497 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 253:
-#line 1501 "./parse.y"
+#line 1502 "./parse.y"
{ yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 254:
-#line 1506 "./parse.y"
+#line 1507 "./parse.y"
{ yyval.node = build_if_else_statement (yyvsp[-5].operator.location, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 255:
-#line 1511 "./parse.y"
+#line 1512 "./parse.y"
{
enter_block ();
;
break;}
case 256:
-#line 1515 "./parse.y"
+#line 1516 "./parse.y"
{
/* Make into "proper list" of COMPOUND_EXPRs.
I.e. make the last statment also have its own
@@ -3863,42 +3822,42 @@ case 256:
;
break;}
case 257:
-#line 1527 "./parse.y"
+#line 1528 "./parse.y"
{
yyval.node = build (SWITCH_EXPR, NULL_TREE, yyvsp[-1].node, NULL_TREE);
EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
;
break;}
case 258:
-#line 1532 "./parse.y"
+#line 1533 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 259:
-#line 1534 "./parse.y"
+#line 1535 "./parse.y"
{yyerror ("Missing term or ')'"); DRECOVER(switch_statement);;
break;}
case 260:
-#line 1536 "./parse.y"
+#line 1537 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
case 261:
-#line 1544 "./parse.y"
+#line 1545 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 262:
-#line 1546 "./parse.y"
+#line 1547 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 263:
-#line 1548 "./parse.y"
+#line 1549 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 264:
-#line 1550 "./parse.y"
+#line 1551 "./parse.y"
{ yyval.node = NULL_TREE; ;
break;}
case 270:
-#line 1569 "./parse.y"
+#line 1570 "./parse.y"
{
tree lab = build1 (CASE_EXPR, NULL_TREE, yyvsp[-1].node);
EXPR_WFL_LINECOL (lab) = yyvsp[-2].operator.location;
@@ -3906,7 +3865,7 @@ case 270:
;
break;}
case 271:
-#line 1575 "./parse.y"
+#line 1576 "./parse.y"
{
tree lab = build1 (DEFAULT_EXPR, NULL_TREE, NULL_TREE);
EXPR_WFL_LINECOL (lab) = yyvsp[-1].operator.location;
@@ -3914,61 +3873,61 @@ case 271:
;
break;}
case 272:
-#line 1581 "./parse.y"
+#line 1582 "./parse.y"
{yyerror ("Missing or invalid constant expression"); RECOVER;;
break;}
case 273:
-#line 1583 "./parse.y"
+#line 1584 "./parse.y"
{yyerror ("':' expected"); RECOVER;;
break;}
case 274:
-#line 1585 "./parse.y"
+#line 1586 "./parse.y"
{yyerror ("':' expected"); RECOVER;;
break;}
case 275:
-#line 1590 "./parse.y"
+#line 1591 "./parse.y"
{
tree body = build_loop_body (yyvsp[-2].operator.location, yyvsp[-1].node, 0);
yyval.node = build_new_loop (body);
;
break;}
case 276:
-#line 1598 "./parse.y"
+#line 1599 "./parse.y"
{ yyval.node = finish_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
break;}
case 277:
-#line 1600 "./parse.y"
+#line 1601 "./parse.y"
{YYERROR_NOW; yyerror ("'(' expected"); RECOVER;;
break;}
case 278:
-#line 1602 "./parse.y"
+#line 1603 "./parse.y"
{yyerror ("Missing term and ')' expected"); RECOVER;;
break;}
case 279:
-#line 1604 "./parse.y"
+#line 1605 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 280:
-#line 1609 "./parse.y"
+#line 1610 "./parse.y"
{ yyval.node = finish_loop_body (0, NULL_TREE, yyvsp[0].node, 0); ;
break;}
case 281:
-#line 1614 "./parse.y"
+#line 1615 "./parse.y"
{
tree body = build_loop_body (0, NULL_TREE, 1);
yyval.node = build_new_loop (body);
;
break;}
case 282:
-#line 1623 "./parse.y"
+#line 1624 "./parse.y"
{ yyval.node = finish_loop_body (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[-5].node, 1); ;
break;}
case 283:
-#line 1628 "./parse.y"
+#line 1629 "./parse.y"
{ yyval.node = finish_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 284:
-#line 1630 "./parse.y"
+#line 1631 "./parse.y"
{
yyval.node = finish_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */
@@ -3977,23 +3936,23 @@ case 284:
;
break;}
case 285:
-#line 1637 "./parse.y"
+#line 1638 "./parse.y"
{yyerror ("Invalid control expression"); RECOVER;;
break;}
case 286:
-#line 1639 "./parse.y"
+#line 1640 "./parse.y"
{yyerror ("Invalid update expression"); RECOVER;;
break;}
case 287:
-#line 1641 "./parse.y"
+#line 1642 "./parse.y"
{yyerror ("Invalid update expression"); RECOVER;;
break;}
case 288:
-#line 1646 "./parse.y"
+#line 1647 "./parse.y"
{ yyval.node = finish_for_loop (EXPR_WFL_LINECOL (yyvsp[-4].node), yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);;
break;}
case 289:
-#line 1648 "./parse.y"
+#line 1649 "./parse.y"
{
yyval.node = finish_for_loop (0, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
/* We have not condition, so we get rid of the EXIT_EXPR */
@@ -4002,7 +3961,7 @@ case 289:
;
break;}
case 290:
-#line 1658 "./parse.y"
+#line 1659 "./parse.y"
{
/* This scope defined for local variable that may be
defined within the scope of the for loop */
@@ -4010,15 +3969,15 @@ case 290:
;
break;}
case 291:
-#line 1664 "./parse.y"
+#line 1665 "./parse.y"
{yyerror ("'(' expected"); DRECOVER(for_1);;
break;}
case 292:
-#line 1666 "./parse.y"
+#line 1667 "./parse.y"
{yyerror ("Invalid init statement"); RECOVER;;
break;}
case 293:
-#line 1671 "./parse.y"
+#line 1672 "./parse.y"
{
/* We now declare the loop body. The loop is
declared as a for loop. */
@@ -4031,11 +3990,11 @@ case 293:
;
break;}
case 294:
-#line 1683 "./parse.y"
+#line 1684 "./parse.y"
{ yyval.node = empty_stmt_node; ;
break;}
case 295:
-#line 1685 "./parse.y"
+#line 1686 "./parse.y"
{
/* Init statement recorded within the previously
defined block scope */
@@ -4043,7 +4002,7 @@ case 295:
;
break;}
case 296:
-#line 1691 "./parse.y"
+#line 1692 "./parse.y"
{
/* Local variable are recorded within the previously
defined block scope */
@@ -4051,94 +4010,94 @@ case 296:
;
break;}
case 297:
-#line 1697 "./parse.y"
+#line 1698 "./parse.y"
{yyerror ("';' expected"); DRECOVER(for_init_1);;
break;}
case 298:
-#line 1701 "./parse.y"
+#line 1702 "./parse.y"
{yyval.node = empty_stmt_node;;
break;}
case 299:
-#line 1703 "./parse.y"
+#line 1704 "./parse.y"
{ yyval.node = build_debugable_stmt (BUILD_LOCATION (), yyvsp[0].node); ;
break;}
case 300:
-#line 1708 "./parse.y"
+#line 1709 "./parse.y"
{ yyval.node = add_stmt_to_compound (NULL_TREE, NULL_TREE, yyvsp[0].node); ;
break;}
case 301:
-#line 1710 "./parse.y"
+#line 1711 "./parse.y"
{ yyval.node = add_stmt_to_compound (yyvsp[-2].node, NULL_TREE, yyvsp[0].node); ;
break;}
case 302:
-#line 1712 "./parse.y"
+#line 1713 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 303:
-#line 1717 "./parse.y"
+#line 1718 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-1].operator.location, 1, NULL_TREE); ;
break;}
case 304:
-#line 1719 "./parse.y"
+#line 1720 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-2].operator.location, 1, yyvsp[-1].node); ;
break;}
case 305:
-#line 1721 "./parse.y"
+#line 1722 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 306:
-#line 1723 "./parse.y"
+#line 1724 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 307:
-#line 1728 "./parse.y"
+#line 1729 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-1].operator.location, 0, NULL_TREE); ;
break;}
case 308:
-#line 1730 "./parse.y"
+#line 1731 "./parse.y"
{ yyval.node = build_bc_statement (yyvsp[-2].operator.location, 0, yyvsp[-1].node); ;
break;}
case 309:
-#line 1732 "./parse.y"
+#line 1733 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 310:
-#line 1734 "./parse.y"
+#line 1735 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 311:
-#line 1739 "./parse.y"
+#line 1740 "./parse.y"
{ yyval.node = build_return (yyvsp[-1].operator.location, NULL_TREE); ;
break;}
case 312:
-#line 1741 "./parse.y"
+#line 1742 "./parse.y"
{ yyval.node = build_return (yyvsp[-2].operator.location, yyvsp[-1].node); ;
break;}
case 313:
-#line 1743 "./parse.y"
+#line 1744 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 314:
-#line 1745 "./parse.y"
+#line 1746 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 315:
-#line 1750 "./parse.y"
+#line 1751 "./parse.y"
{
yyval.node = build1 (THROW_EXPR, NULL_TREE, yyvsp[-1].node);
EXPR_WFL_LINECOL (yyval.node) = yyvsp[-2].operator.location;
;
break;}
case 316:
-#line 1755 "./parse.y"
+#line 1756 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 317:
-#line 1757 "./parse.y"
+#line 1758 "./parse.y"
{yyerror ("';' expected"); RECOVER;;
break;}
case 318:
-#line 1762 "./parse.y"
+#line 1763 "./parse.y"
{
yyval.node = build (SYNCHRONIZED_EXPR, NULL_TREE, yyvsp[-2].node, yyvsp[0].node);
EXPR_WFL_LINECOL (yyval.node) =
@@ -4146,23 +4105,23 @@ case 318:
;
break;}
case 319:
-#line 1768 "./parse.y"
+#line 1769 "./parse.y"
{yyerror ("'{' expected"); RECOVER;;
break;}
case 320:
-#line 1770 "./parse.y"
+#line 1771 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 321:
-#line 1772 "./parse.y"
+#line 1773 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 322:
-#line 1774 "./parse.y"
+#line 1775 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 323:
-#line 1779 "./parse.y"
+#line 1780 "./parse.y"
{
check_modifiers (
"Illegal modifier `%s'. Only `synchronized' was expected here",
@@ -4173,33 +4132,33 @@ case 323:
;
break;}
case 324:
-#line 1791 "./parse.y"
+#line 1792 "./parse.y"
{ yyval.node = build_try_statement (yyvsp[-2].operator.location, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 325:
-#line 1793 "./parse.y"
+#line 1794 "./parse.y"
{ yyval.node = build_try_finally_statement (yyvsp[-2].operator.location, yyvsp[-1].node, yyvsp[0].node); ;
break;}
case 326:
-#line 1795 "./parse.y"
+#line 1796 "./parse.y"
{ yyval.node = build_try_finally_statement
(yyvsp[-3].operator.location, build_try_statement (yyvsp[-3].operator.location,
yyvsp[-2].node, yyvsp[-1].node), yyvsp[0].node);
;
break;}
case 327:
-#line 1800 "./parse.y"
+#line 1801 "./parse.y"
{yyerror ("'{' expected"); DRECOVER (try_statement);;
break;}
case 329:
-#line 1806 "./parse.y"
+#line 1807 "./parse.y"
{
TREE_CHAIN (yyvsp[0].node) = yyvsp[-1].node;
yyval.node = yyvsp[0].node;
;
break;}
case 330:
-#line 1814 "./parse.y"
+#line 1815 "./parse.y"
{
java_method_add_stmt (current_function_decl, yyvsp[0].node);
exit_block ();
@@ -4207,7 +4166,7 @@ case 330:
;
break;}
case 331:
-#line 1822 "./parse.y"
+#line 1823 "./parse.y"
{
/* We add a block to define a scope for
formal_parameter (CCBP). The formal parameter is
@@ -4225,96 +4184,96 @@ case 331:
;
break;}
case 332:
-#line 1838 "./parse.y"
+#line 1839 "./parse.y"
{yyerror ("'(' expected"); RECOVER; yyval.node = NULL_TREE;;
break;}
case 333:
-#line 1840 "./parse.y"
+#line 1841 "./parse.y"
{
yyerror ("Missing term or ')' expected");
RECOVER; yyval.node = NULL_TREE;
;
break;}
case 334:
-#line 1845 "./parse.y"
+#line 1846 "./parse.y"
{yyerror ("Missing term"); RECOVER; yyval.node = NULL_TREE;;
break;}
case 335:
-#line 1850 "./parse.y"
+#line 1851 "./parse.y"
{ yyval.node = yyvsp[0].node; ;
break;}
case 336:
-#line 1852 "./parse.y"
+#line 1853 "./parse.y"
{yyerror ("'{' expected"); RECOVER; ;
break;}
case 340:
-#line 1864 "./parse.y"
+#line 1865 "./parse.y"
{ yyval.node = build_this (yyvsp[0].operator.location); ;
break;}
case 341:
-#line 1866 "./parse.y"
+#line 1867 "./parse.y"
{yyval.node = yyvsp[-1].node;;
break;}
case 347:
-#line 1876 "./parse.y"
+#line 1877 "./parse.y"
{
tree wfl = build_wfl_node (this_identifier_node);
yyval.node = make_qualified_primary (yyvsp[-2].node, wfl, EXPR_WFL_LINECOL (yyvsp[-2].node));
;
break;}
case 348:
-#line 1881 "./parse.y"
+#line 1882 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 349:
-#line 1883 "./parse.y"
+#line 1884 "./parse.y"
{yyerror ("'class' or 'this' expected" ); RECOVER;;
break;}
case 350:
-#line 1885 "./parse.y"
+#line 1886 "./parse.y"
{yyerror ("'class' expected" ); RECOVER;;
break;}
case 351:
-#line 1887 "./parse.y"
+#line 1888 "./parse.y"
{yyerror ("'class' expected" ); RECOVER;;
break;}
case 352:
-#line 1895 "./parse.y"
+#line 1896 "./parse.y"
{
yyval.node = build_java_array_type (yyvsp[-2].node, -1);
CLASS_LOADED_P (yyval.node) = 1;
;
break;}
case 353:
-#line 1900 "./parse.y"
+#line 1901 "./parse.y"
{ yyval.node = build_unresolved_array_type (yyvsp[-2].node); ;
break;}
case 354:
-#line 1910 "./parse.y"
+#line 1911 "./parse.y"
{ yyval.node = build_incomplete_class_ref (yyvsp[-1].operator.location, yyvsp[-2].node); ;
break;}
case 355:
-#line 1912 "./parse.y"
+#line 1913 "./parse.y"
{ yyval.node = build_incomplete_class_ref (yyvsp[-1].operator.location, yyvsp[-2].node); ;
break;}
case 356:
-#line 1914 "./parse.y"
+#line 1915 "./parse.y"
{ yyval.node = build_class_ref (yyvsp[-2].node); ;
break;}
case 357:
-#line 1916 "./parse.y"
+#line 1917 "./parse.y"
{ yyval.node = build_class_ref (void_type_node); ;
break;}
case 358:
-#line 1921 "./parse.y"
+#line 1922 "./parse.y"
{ yyval.node = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 359:
-#line 1923 "./parse.y"
+#line 1924 "./parse.y"
{ yyval.node = build_new_invocation (yyvsp[-2].node, NULL_TREE); ;
break;}
case 361:
-#line 1929 "./parse.y"
+#line 1930 "./parse.y"
{
tree ctor = build_new_invocation (yyvsp[-2].node, NULL_TREE);
yyval.node = make_qualified_primary (yyvsp[-3].node, ctor,
@@ -4322,7 +4281,7 @@ case 361:
;
break;}
case 363:
-#line 1936 "./parse.y"
+#line 1937 "./parse.y"
{
tree ctor = build_new_invocation (yyvsp[-3].node, yyvsp[-1].node);
yyval.node = make_qualified_primary (yyvsp[-4].node, ctor,
@@ -4330,35 +4289,35 @@ case 363:
;
break;}
case 365:
-#line 1943 "./parse.y"
+#line 1944 "./parse.y"
{yyerror ("'(' expected"); DRECOVER(new_1);;
break;}
case 366:
-#line 1945 "./parse.y"
+#line 1946 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 367:
-#line 1947 "./parse.y"
+#line 1948 "./parse.y"
{yyerror ("')' or term expected"); RECOVER;;
break;}
case 368:
-#line 1949 "./parse.y"
+#line 1950 "./parse.y"
{yyerror ("')' expected"); RECOVER;;
break;}
case 369:
-#line 1951 "./parse.y"
+#line 1952 "./parse.y"
{YYERROR_NOW; yyerror ("Identifier expected"); RECOVER;;
break;}
case 370:
-#line 1953 "./parse.y"
+#line 1954 "./parse.y"
{yyerror ("'(' expected"); RECOVER;;
break;}
case 371:
-#line 1963 "./parse.y"
+#line 1964 "./parse.y"
{ create_anonymous_class (yyvsp[-4].operator.location, yyvsp[-3].node); ;
break;}
case 372:
-#line 1965 "./parse.y"
+#line 1966 "./parse.y"
{
tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL (yyvsp[-5].node);
@@ -4391,11 +4350,11 @@ case 372:
;
break;}
case 373:
-#line 1996 "./parse.y"
+#line 1997 "./parse.y"
{ create_anonymous_class (yyvsp[-3].operator.location, yyvsp[-2].node); ;
break;}
case 374:
-#line 1998 "./parse.y"
+#line 1999 "./parse.y"
{
tree id = build_wfl_node (DECL_NAME (GET_CPC ()));
EXPR_WFL_LINECOL (id) = EXPR_WFL_LINECOL (yyvsp[-4].node);
@@ -4410,49 +4369,49 @@ case 374:
;
break;}
case 375:
-#line 2014 "./parse.y"
+#line 2015 "./parse.y"
{ yyval.node = yyvsp[-2].node; ;
break;}
case 376:
-#line 2016 "./parse.y"
+#line 2017 "./parse.y"
{ yyval.node = yyvsp[-2].node; ;
break;}
case 377:
-#line 2021 "./parse.y"
+#line 2022 "./parse.y"
{
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, NULL_TREE);
ctxp->formal_parameter_number = 1;
;
break;}
case 378:
-#line 2026 "./parse.y"
+#line 2027 "./parse.y"
{
ctxp->formal_parameter_number += 1;
yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyvsp[-2].node);
;
break;}
case 379:
-#line 2031 "./parse.y"
+#line 2032 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 380:
-#line 2036 "./parse.y"
+#line 2037 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;}
case 381:
-#line 2038 "./parse.y"
+#line 2039 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-1].node, yyvsp[0].node, 0); ;
break;}
case 382:
-#line 2040 "./parse.y"
+#line 2041 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, CURRENT_OSB (ctxp));;
break;}
case 383:
-#line 2042 "./parse.y"
+#line 2043 "./parse.y"
{ yyval.node = build_newarray_node (yyvsp[-2].node, yyvsp[-1].node, CURRENT_OSB (ctxp));;
break;}
case 384:
-#line 2046 "./parse.y"
+#line 2047 "./parse.y"
{
char *sig;
while (CURRENT_OSB (ctxp)--)
@@ -4463,7 +4422,7 @@ case 384:
;
break;}
case 385:
-#line 2055 "./parse.y"
+#line 2056 "./parse.y"
{
tree type = yyvsp[-2].node;
while (CURRENT_OSB (ctxp)--)
@@ -4473,34 +4432,34 @@ case 385:
;
break;}
case 386:
-#line 2063 "./parse.y"
+#line 2064 "./parse.y"
{yyerror ("'[' expected"); DRECOVER ("]");;
break;}
case 387:
-#line 2065 "./parse.y"
+#line 2066 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
case 388:
-#line 2070 "./parse.y"
+#line 2071 "./parse.y"
{ yyval.node = build_tree_list (NULL_TREE, yyvsp[0].node); ;
break;}
case 389:
-#line 2072 "./parse.y"
+#line 2073 "./parse.y"
{ yyval.node = tree_cons (NULL_TREE, yyvsp[0].node, yyval.node); ;
break;}
case 390:
-#line 2077 "./parse.y"
+#line 2078 "./parse.y"
{
EXPR_WFL_LINECOL (yyvsp[-1].node) = yyvsp[-2].operator.location;
yyval.node = yyvsp[-1].node;
;
break;}
case 391:
-#line 2082 "./parse.y"
+#line 2083 "./parse.y"
{yyerror ("']' expected"); RECOVER;;
break;}
case 392:
-#line 2084 "./parse.y"
+#line 2085 "./parse.y"
{
yyerror ("Missing term");
yyerror ("']' expected");
@@ -4508,7 +4467,7 @@ case 392:
;
break;}
case 393:
-#line 2093 "./parse.y"
+#line 2094 "./parse.y"
{
int allocate = 0;
/* If not initialized, allocate memory for the osb
@@ -4536,19 +4495,19 @@ case 393:
;
break;}
case 394:
-#line 2119 "./parse.y"
+#line 2120 "./parse.y"
{ CURRENT_OSB (ctxp)++; ;
break;}
case 395:
-#line 2121 "./parse.y"
+#line 2122 "./parse.y"
{ yyerror ("']' expected"); RECOVER;;
break;}
case 396:
-#line 2126 "./parse.y"
+#line 2127 "./parse.y"
{ yyval.node = make_qualified_primary (yyvsp[-2].node, yyvsp[0].node, yyvsp[-1].operator.location); ;
break;}
case 397:
-#line 2130 "./parse.y"
+#line 2131 "./parse.y"
{
tree super_wfl =
build_wfl_node (super_identifier_node);
@@ -4557,19 +4516,19 @@ case 397:
;
break;}
case 398:
-#line 2137 "./parse.y"
+#line 2138 "./parse.y"
{yyerror ("Field expected"); DRECOVER (super_field_acces);;
break;}
case 399:
-#line 2142 "./parse.y"
+#line 2143 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-2].node, NULL_TREE); ;
break;}
case 400:
-#line 2144 "./parse.y"
+#line 2145 "./parse.y"
{ yyval.node = build_method_invocation (yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 401:
-#line 2146 "./parse.y"
+#line 2147 "./parse.y"
{
if (TREE_CODE (yyvsp[-4].node) == THIS_EXPR)
yyval.node = build_this_super_qualified_invocation
@@ -4582,7 +4541,7 @@ case 401:
;
break;}
case 402:
-#line 2157 "./parse.y"
+#line 2158 "./parse.y"
{
if (TREE_CODE (yyvsp[-5].node) == THIS_EXPR)
yyval.node = build_this_super_qualified_invocation
@@ -4595,121 +4554,121 @@ case 402:
;
break;}
case 403:
-#line 2168 "./parse.y"
+#line 2169 "./parse.y"
{
yyval.node = build_this_super_qualified_invocation
(0, yyvsp[-2].node, NULL_TREE, yyvsp[-4].operator.location, yyvsp[-3].operator.location);
;
break;}
case 404:
-#line 2173 "./parse.y"
+#line 2174 "./parse.y"
{
yyval.node = build_this_super_qualified_invocation
(0, yyvsp[-3].node, yyvsp[-1].node, yyvsp[-5].operator.location, yyvsp[-4].operator.location);
;
break;}
case 405:
-#line 2182 "./parse.y"
+#line 2183 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;}
case 406:
-#line 2184 "./parse.y"
+#line 2185 "./parse.y"
{ yyerror ("'(' expected"); DRECOVER (method_invocation); ;
break;}
case 407:
-#line 2189 "./parse.y"
+#line 2190 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 408:
-#line 2191 "./parse.y"
+#line 2192 "./parse.y"
{ yyval.node = build_array_ref (yyvsp[-2].operator.location, yyvsp[-3].node, yyvsp[-1].node); ;
break;}
case 409:
-#line 2193 "./parse.y"
+#line 2194 "./parse.y"
{
yyerror ("Missing term and ']' expected");
DRECOVER(array_access);
;
break;}
case 410:
-#line 2198 "./parse.y"
+#line 2199 "./parse.y"
{
yyerror ("']' expected");
DRECOVER(array_access);
;
break;}
case 411:
-#line 2203 "./parse.y"
+#line 2204 "./parse.y"
{
yyerror ("Missing term and ']' expected");
DRECOVER(array_access);
;
break;}
case 412:
-#line 2208 "./parse.y"
+#line 2209 "./parse.y"
{
yyerror ("']' expected");
DRECOVER(array_access);
;
break;}
case 417:
-#line 2223 "./parse.y"
+#line 2224 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;}
case 418:
-#line 2228 "./parse.y"
+#line 2229 "./parse.y"
{ yyval.node = build_incdec (yyvsp[0].operator.token, yyvsp[0].operator.location, yyvsp[-1].node, 1); ;
break;}
case 421:
-#line 2235 "./parse.y"
+#line 2236 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
case 422:
-#line 2237 "./parse.y"
+#line 2238 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
case 424:
-#line 2240 "./parse.y"
+#line 2241 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 425:
-#line 2242 "./parse.y"
+#line 2243 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 426:
-#line 2247 "./parse.y"
+#line 2248 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;}
case 427:
-#line 2249 "./parse.y"
+#line 2250 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 428:
-#line 2254 "./parse.y"
+#line 2255 "./parse.y"
{yyval.node = build_incdec (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node, 0); ;
break;}
case 429:
-#line 2256 "./parse.y"
+#line 2257 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 431:
-#line 2262 "./parse.y"
+#line 2263 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
case 432:
-#line 2264 "./parse.y"
+#line 2265 "./parse.y"
{yyval.node = build_unaryop (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[0].node); ;
break;}
case 434:
-#line 2267 "./parse.y"
+#line 2268 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 435:
-#line 2269 "./parse.y"
+#line 2270 "./parse.y"
{yyerror ("Missing term"); RECOVER;
break;}
case 436:
-#line 2274 "./parse.y"
+#line 2275 "./parse.y"
{
tree type = yyvsp[-3].node;
while (CURRENT_OSB (ctxp)--)
@@ -4719,15 +4678,15 @@ case 436:
;
break;}
case 437:
-#line 2282 "./parse.y"
+#line 2283 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 438:
-#line 2284 "./parse.y"
+#line 2285 "./parse.y"
{ yyval.node = build_cast (yyvsp[-3].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 439:
-#line 2286 "./parse.y"
+#line 2287 "./parse.y"
{
const char *ptr;
while (CURRENT_OSB (ctxp)--)
@@ -4742,11 +4701,11 @@ case 439:
;
break;}
case 440:
-#line 2299 "./parse.y"
+#line 2300 "./parse.y"
{yyerror ("']' expected, invalid type expression");;
break;}
case 441:
-#line 2301 "./parse.y"
+#line 2302 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Invalid type expression"); RECOVER;
@@ -4754,243 +4713,243 @@ case 441:
;
break;}
case 442:
-#line 2307 "./parse.y"
+#line 2308 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 443:
-#line 2309 "./parse.y"
+#line 2310 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 444:
-#line 2311 "./parse.y"
+#line 2312 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 446:
-#line 2317 "./parse.y"
+#line 2318 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token),
yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 447:
-#line 2322 "./parse.y"
+#line 2323 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 448:
-#line 2327 "./parse.y"
+#line 2328 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 449:
-#line 2332 "./parse.y"
+#line 2333 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 450:
-#line 2334 "./parse.y"
+#line 2335 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 451:
-#line 2336 "./parse.y"
+#line 2337 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 453:
-#line 2342 "./parse.y"
+#line 2343 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 454:
-#line 2347 "./parse.y"
+#line 2348 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 455:
-#line 2352 "./parse.y"
+#line 2353 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 456:
-#line 2354 "./parse.y"
+#line 2355 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 458:
-#line 2360 "./parse.y"
+#line 2361 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 459:
-#line 2365 "./parse.y"
+#line 2366 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 460:
-#line 2370 "./parse.y"
+#line 2371 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 461:
-#line 2375 "./parse.y"
+#line 2376 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 462:
-#line 2377 "./parse.y"
+#line 2378 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 463:
-#line 2379 "./parse.y"
+#line 2380 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 465:
-#line 2385 "./parse.y"
+#line 2386 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 466:
-#line 2390 "./parse.y"
+#line 2391 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 467:
-#line 2395 "./parse.y"
+#line 2396 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 468:
-#line 2400 "./parse.y"
+#line 2401 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 469:
-#line 2405 "./parse.y"
+#line 2406 "./parse.y"
{ yyval.node = build_binop (INSTANCEOF_EXPR, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 470:
-#line 2407 "./parse.y"
+#line 2408 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 471:
-#line 2409 "./parse.y"
+#line 2410 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 472:
-#line 2411 "./parse.y"
+#line 2412 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 473:
-#line 2413 "./parse.y"
+#line 2414 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 474:
-#line 2415 "./parse.y"
+#line 2416 "./parse.y"
{yyerror ("Invalid reference type"); RECOVER;;
break;}
case 476:
-#line 2421 "./parse.y"
+#line 2422 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 477:
-#line 2426 "./parse.y"
+#line 2427 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 478:
-#line 2431 "./parse.y"
+#line 2432 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 479:
-#line 2433 "./parse.y"
+#line 2434 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 481:
-#line 2439 "./parse.y"
+#line 2440 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 482:
-#line 2444 "./parse.y"
+#line 2445 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 484:
-#line 2450 "./parse.y"
+#line 2451 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 485:
-#line 2455 "./parse.y"
+#line 2456 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 487:
-#line 2461 "./parse.y"
+#line 2462 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 488:
-#line 2466 "./parse.y"
+#line 2467 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 490:
-#line 2472 "./parse.y"
+#line 2473 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 491:
-#line 2477 "./parse.y"
+#line 2478 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 493:
-#line 2483 "./parse.y"
+#line 2484 "./parse.y"
{
yyval.node = build_binop (BINOP_LOOKUP (yyvsp[-1].operator.token), yyvsp[-1].operator.location,
yyvsp[-2].node, yyvsp[0].node);
;
break;}
case 494:
-#line 2488 "./parse.y"
+#line 2489 "./parse.y"
{yyerror ("Missing term"); RECOVER;;
break;}
case 496:
-#line 2494 "./parse.y"
+#line 2495 "./parse.y"
{
yyval.node = build (CONDITIONAL_EXPR, NULL_TREE, yyvsp[-4].node, yyvsp[-2].node, yyvsp[0].node);
EXPR_WFL_LINECOL (yyval.node) = yyvsp[-3].operator.location;
;
break;}
case 497:
-#line 2499 "./parse.y"
+#line 2500 "./parse.y"
{
YYERROR_NOW;
yyerror ("Missing term");
@@ -4998,19 +4957,19 @@ case 497:
;
break;}
case 498:
-#line 2505 "./parse.y"
+#line 2506 "./parse.y"
{yyerror ("Missing term"); DRECOVER (2);;
break;}
case 499:
-#line 2507 "./parse.y"
+#line 2508 "./parse.y"
{yyerror ("Missing term"); DRECOVER (3);;
break;}
case 502:
-#line 2517 "./parse.y"
+#line 2518 "./parse.y"
{ yyval.node = build_assignment (yyvsp[-1].operator.token, yyvsp[-1].operator.location, yyvsp[-2].node, yyvsp[0].node); ;
break;}
case 503:
-#line 2519 "./parse.y"
+#line 2520 "./parse.y"
{
if (ctxp->prevent_ese != lineno)
yyerror ("Missing term");
@@ -5019,7 +4978,7 @@ case 503:
break;}
}
/* the action file gets copied in in place of this dollarsign */
-#line 543 "/usr/lib/bison.simple"
+#line 498 "/usr/share/misc/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;
@@ -5214,32 +5173,8 @@ yyerrhandle:
yystate = yyn;
goto yynewstate;
-
- yyacceptlab:
- /* YYACCEPT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 0;
-
- yyabortlab:
- /* YYABORT comes here. */
- if (yyfree_stacks)
- {
- free (yyss);
- free (yyvs);
-#ifdef YYLSP_NEEDED
- free (yyls);
-#endif
- }
- return 1;
}
-#line 2545 "./parse.y"
+#line 2546 "./parse.y"
@@ -7267,12 +7202,22 @@ check_modifiers_consistency (flags)
int acc_count = 0;
tree cl = NULL_TREE;
- THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
if (acc_count > 1)
parse_error_context
- (cl, "Inconsistent member declaration. At most one of `public', `private', or `protected' may be specified");
+ (cl, "Inconsistent member declaration. At most one of `public', `private', or `protected' may be specified");
+
+ acc_count = 0;
+ cl = NULL_TREE;
+ THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK - PUBLIC_TK,
+ acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK - PUBLIC_TK,
+ acc_count, cl);
+ if (acc_count > 1)
+ parse_error_context (cl,
+ "Inconsistent member declaration. At most one of `final' or `volatile' may be specified");
}
/* Check the methode header METH for abstract specifics features */
@@ -12536,22 +12481,29 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
/* Search interfaces */
if (CLASS_INTERFACE (TYPE_NAME (class)))
{
- static tree searched_interfaces = NULL_TREE;
+ static struct hash_table t, *searched_interfaces = NULL;
static int search_not_done = 0;
int i, n;
tree basetype_vec = TYPE_BINFO_BASETYPES (class);
- /* Have we searched this interface already? We shoud use a hash
- table, FIXME */
+ /* Search in the hash table, otherwise create a new one if
+ necessary and insert the new entry. */
+
if (searched_interfaces)
- {
- tree current;
- for (current = searched_interfaces;
- current; current = TREE_CHAIN (current))
- if (TREE_VALUE (current) == class)
- return NULL;
+ {
+ if (hash_lookup (searched_interfaces,
+ (const hash_table_key) class, FALSE, NULL))
+ return NULL;
}
- searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
+ else
+ {
+ hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
+ java_hash_compare_tree_node);
+ searched_interfaces = &t;
+ }
+
+ hash_lookup (searched_interfaces,
+ (const hash_table_key) class, TRUE, NULL);
search_applicable_methods_list (lc, TYPE_METHODS (class),
name, arglist, &list, &all_list);
@@ -12576,7 +12528,8 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
search_applicable_methods_list (lc,
TYPE_METHODS (object_type_node),
name, arglist, &list, &all_list);
- searched_interfaces = NULL_TREE;
+ hash_table_free (searched_interfaces);
+ searched_interfaces = NULL;
}
}
/* Search classes */
@@ -14100,10 +14053,16 @@ check_final_assignment (lvalue, wfl)
&& JDECL_P (TREE_OPERAND (lvalue, 1)))
lvalue = TREE_OPERAND (lvalue, 1);
- if (TREE_CODE (lvalue) == FIELD_DECL
- && FIELD_FINAL (lvalue)
- && !DECL_CLINIT_P (current_function_decl)
- && !DECL_FINIT_P (current_function_decl))
+ /* When generating class files, references to the `length' field
+ look a bit different. */
+ if ((flag_emit_class_files
+ && TREE_CODE (lvalue) == COMPONENT_REF
+ && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
+ && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
+ || (TREE_CODE (lvalue) == FIELD_DECL
+ && FIELD_FINAL (lvalue)
+ && !DECL_CLINIT_P (current_function_decl)
+ && !DECL_FINIT_P (current_function_decl)))
{
parse_error_context
(wfl, "Can't assign a value to the final variable `%s'",
diff --git a/gcc/java/parse.h b/gcc/java/parse.h
index bea4b70a089..b19edbe43b1 100644
--- a/gcc/java/parse.h
+++ b/gcc/java/parse.h
@@ -89,7 +89,7 @@ extern tree stabilize_reference PARAMS ((tree));
#define THIS_MODIFIER_ONLY(f, m, v, count, l) \
if ((f) & (m)) \
{ \
- tree node = ctxp->modifier_ctx [v]; \
+ tree node = MODIFIER_WFL (v); \
if ((l) \
&& ((EXPR_WFL_COLNO (node) > EXPR_WFL_COLNO (l)) \
|| (EXPR_WFL_LINENO (node) > EXPR_WFL_LINENO (l)))) \
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 985e3708a65..17e74c2dd59 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -317,6 +317,7 @@ static void add_inner_class_fields PARAMS ((tree, tree));
static tree build_dot_class_method PARAMS ((tree));
static tree build_dot_class_method_invocation PARAMS ((tree));
+static void create_new_parser_context PARAMS ((int));
/* Number of error found so far. */
int java_error_count;
@@ -4569,12 +4570,22 @@ check_modifiers_consistency (flags)
int acc_count = 0;
tree cl = NULL_TREE;
- THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, 0, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, 1, acc_count, cl);
- THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, 2, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PUBLIC, PUBLIC_TK, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PRIVATE, PRIVATE_TK, acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_PROTECTED, PROTECTED_TK, acc_count, cl);
if (acc_count > 1)
parse_error_context
- (cl, "Inconsistent member declaration. At most one of `public', `private', or `protected' may be specified");
+ (cl, "Inconsistent member declaration. At most one of `public', `private', or `protected' may be specified");
+
+ acc_count = 0;
+ cl = NULL_TREE;
+ THIS_MODIFIER_ONLY (flags, ACC_FINAL, FINAL_TK - PUBLIC_TK,
+ acc_count, cl);
+ THIS_MODIFIER_ONLY (flags, ACC_VOLATILE, VOLATILE_TK - PUBLIC_TK,
+ acc_count, cl);
+ if (acc_count > 1)
+ parse_error_context (cl,
+ "Inconsistent member declaration. At most one of `final' or `volatile' may be specified");
}
/* Check the methode header METH for abstract specifics features */
@@ -9838,22 +9849,29 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
/* Search interfaces */
if (CLASS_INTERFACE (TYPE_NAME (class)))
{
- static tree searched_interfaces = NULL_TREE;
+ static struct hash_table t, *searched_interfaces = NULL;
static int search_not_done = 0;
int i, n;
tree basetype_vec = TYPE_BINFO_BASETYPES (class);
- /* Have we searched this interface already? We shoud use a hash
- table, FIXME */
+ /* Search in the hash table, otherwise create a new one if
+ necessary and insert the new entry. */
+
if (searched_interfaces)
- {
- tree current;
- for (current = searched_interfaces;
- current; current = TREE_CHAIN (current))
- if (TREE_VALUE (current) == class)
- return NULL;
+ {
+ if (hash_lookup (searched_interfaces,
+ (const hash_table_key) class, FALSE, NULL))
+ return NULL;
}
- searched_interfaces = tree_cons (NULL_TREE, class, searched_interfaces);
+ else
+ {
+ hash_table_init (&t, hash_newfunc, java_hash_hash_tree_node,
+ java_hash_compare_tree_node);
+ searched_interfaces = &t;
+ }
+
+ hash_lookup (searched_interfaces,
+ (const hash_table_key) class, TRUE, NULL);
search_applicable_methods_list (lc, TYPE_METHODS (class),
name, arglist, &list, &all_list);
@@ -9878,7 +9896,8 @@ find_applicable_accessible_methods_list (lc, class, name, arglist)
search_applicable_methods_list (lc,
TYPE_METHODS (object_type_node),
name, arglist, &list, &all_list);
- searched_interfaces = NULL_TREE;
+ hash_table_free (searched_interfaces);
+ searched_interfaces = NULL;
}
}
/* Search classes */
@@ -11402,10 +11421,16 @@ check_final_assignment (lvalue, wfl)
&& JDECL_P (TREE_OPERAND (lvalue, 1)))
lvalue = TREE_OPERAND (lvalue, 1);
- if (TREE_CODE (lvalue) == FIELD_DECL
- && FIELD_FINAL (lvalue)
- && !DECL_CLINIT_P (current_function_decl)
- && !DECL_FINIT_P (current_function_decl))
+ /* When generating class files, references to the `length' field
+ look a bit different. */
+ if ((flag_emit_class_files
+ && TREE_CODE (lvalue) == COMPONENT_REF
+ && TYPE_ARRAY_P (TREE_TYPE (TREE_OPERAND (lvalue, 0)))
+ && FIELD_FINAL (TREE_OPERAND (lvalue, 1)))
+ || (TREE_CODE (lvalue) == FIELD_DECL
+ && FIELD_FINAL (lvalue)
+ && !DECL_CLINIT_P (current_function_decl)
+ && !DECL_FINIT_P (current_function_decl)))
{
parse_error_context
(wfl, "Can't assign a value to the final variable `%s'",
diff --git a/gcc/jump.c b/gcc/jump.c
index 9f37973a493..18303e6eea8 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -342,7 +342,7 @@ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan,
if (nlabel != JUMP_LABEL (insn))
changed |= redirect_jump (insn, nlabel);
- if (! optimize || ! minimal)
+ if (! optimize || minimal)
continue;
/* If a dispatch table always goes to the same place,
@@ -2265,6 +2265,15 @@ mark_all_labels (f, cross_jump)
for (insn = f; insn; insn = NEXT_INSN (insn))
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
+ if (GET_CODE (insn) == CALL_INSN
+ && GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
+ {
+ mark_all_labels (XEXP (PATTERN (insn), 0), cross_jump);
+ mark_all_labels (XEXP (PATTERN (insn), 1), cross_jump);
+ mark_all_labels (XEXP (PATTERN (insn), 2), cross_jump);
+ continue;
+ }
+
mark_jump_label (PATTERN (insn), insn, cross_jump, 0);
if (! INSN_DELETED_P (insn) && GET_CODE (insn) == JUMP_INSN)
{
@@ -4998,7 +5007,8 @@ mark_modified_reg (dest, x, data)
rtx x ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
{
- int regno, i;
+ int regno;
+ unsigned int i;
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
@@ -5286,7 +5296,7 @@ rtx_equal_for_thread_p (x, y, yinsn)
return 1;
}
else
- return (same_regs[REGNO (x)] == REGNO (y));
+ return (same_regs[REGNO (x)] == (int) REGNO (y));
break;
@@ -5310,7 +5320,7 @@ rtx_equal_for_thread_p (x, y, yinsn)
if (GET_CODE (SET_DEST (x)) == REG
&& GET_CODE (SET_DEST (y)) == REG)
{
- if (same_regs[REGNO (SET_DEST (x))] == REGNO (SET_DEST (y)))
+ if (same_regs[REGNO (SET_DEST (x))] == (int) REGNO (SET_DEST (y)))
{
same_regs[REGNO (SET_DEST (x))] = -1;
num_same_regs--;
diff --git a/gcc/libgcc2.h b/gcc/libgcc2.h
index ad585815c54..652427f311b 100644
--- a/gcc/libgcc2.h
+++ b/gcc/libgcc2.h
@@ -74,6 +74,10 @@ extern short int __get_eh_table_version (struct exception_descriptor *);
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE LONG_DOUBLE_TYPE_SIZE
#endif
+#ifndef MIN_UNITS_PER_WORD
+#define MIN_UNITS_PER_WORD UNITS_PER_WORD
+#endif
+
/* In the first part of this file, we are interfacing to calls generated
by the compiler itself. These calls pass values into these routines
which have very specific modes (rather than very specific types), and
@@ -87,11 +91,11 @@ typedef int QItype __attribute__ ((mode (QI)));
typedef unsigned int UQItype __attribute__ ((mode (QI)));
typedef int HItype __attribute__ ((mode (HI)));
typedef unsigned int UHItype __attribute__ ((mode (HI)));
-#if UNITS_PER_WORD > 1
+#if MIN_UNITS_PER_WORD > 1
/* These typedefs are usually forbidden on dsp's with UNITS_PER_WORD 1 */
typedef int SItype __attribute__ ((mode (SI)));
typedef unsigned int USItype __attribute__ ((mode (SI)));
-#if UNITS_PER_WORD > 2
+#if MIN_UNITS_PER_WORD > 2
/* These typedefs are usually forbidden on archs with UNITS_PER_WORD 2 */
typedef int DItype __attribute__ ((mode (DI)));
typedef unsigned int UDItype __attribute__ ((mode (DI)));
@@ -149,7 +153,7 @@ typedef int word_type __attribute__ ((mode (__word__)));
#define float bogus_type
#define double bogus_type
-#if UNITS_PER_WORD > 2
+#if MIN_UNITS_PER_WORD > 2
#define W_TYPE_SIZE (4 * BITS_PER_UNIT)
#define Wtype SItype
#define UWtype USItype
@@ -159,7 +163,7 @@ typedef int word_type __attribute__ ((mode (__word__)));
#define UDWtype UDItype
#define __NW(a,b) __ ## a ## si ## b
#define __NDW(a,b) __ ## a ## di ## b
-#elif UNITS_PER_WORD > 1
+#elif MIN_UNITS_PER_WORD > 1
#define W_TYPE_SIZE (2 * BITS_PER_UNIT)
#define Wtype HItype
#define UWtype UHItype
diff --git a/gcc/limity.h b/gcc/limity.h
index 8bb398f6786..b2831fc459b 100644
--- a/gcc/limity.h
+++ b/gcc/limity.h
@@ -4,7 +4,7 @@
#else /* not _GCC_LIMITS_H_ */
#ifdef _GCC_NEXT_LIMITS_H
-#include_next <limits.h> /* recurse down to the real one */
+ #include_next <limits.h> /* recurse down to the real one */
#endif
#endif /* not _GCC_LIMITS_H_ */
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index a6231e2d7e0..e277f803425 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -1252,9 +1252,10 @@ block_alloc (b)
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_DEAD
&& GET_CODE (XEXP (link, 0)) == REG
- && combined_regno != REGNO (XEXP (link, 0))
- && (no_conflict_combined_regno != REGNO (XEXP (link, 0))
- || ! find_reg_note (insn, REG_NO_CONFLICT, XEXP (link, 0))))
+ && combined_regno != (int) REGNO (XEXP (link, 0))
+ && (no_conflict_combined_regno != (int) REGNO (XEXP (link, 0))
+ || ! find_reg_note (insn, REG_NO_CONFLICT,
+ XEXP (link, 0))))
wipe_dead_reg (XEXP (link, 0), 0);
/* Allocate qty numbers for all registers local to this block
diff --git a/gcc/loop.c b/gcc/loop.c
index 74ff0a6a7fd..cbb1731deae 100644
--- a/gcc/loop.c
+++ b/gcc/loop.c
@@ -162,7 +162,7 @@ static int num_mem_sets;
/* Bound on pseudo register number before loop optimization.
A pseudo has valid regscan info if its number is < max_reg_before_loop. */
-int max_reg_before_loop;
+unsigned int max_reg_before_loop;
/* The value to pass to the next call of reg_scan_update. */
static int loop_max_reg;
@@ -194,7 +194,7 @@ struct movable
of any registers used within the LIBCALL. */
int consec; /* Number of consecutive following insns
that must be moved with this one. */
- int regno; /* The register it sets */
+ unsigned int regno; /* The register it sets */
short lifetime; /* lifetime of that register;
may be adjusted when matching movables
that load the same value are found. */
@@ -306,7 +306,7 @@ static int insert_loop_mem PARAMS ((rtx *, void *));
static int replace_loop_mem PARAMS ((rtx *, void *));
static int replace_loop_reg PARAMS ((rtx *, void *));
static void note_reg_stored PARAMS ((rtx, rtx, void *));
-static void try_copy_prop PARAMS ((const struct loop *, rtx, int));
+static void try_copy_prop PARAMS ((const struct loop *, rtx, unsigned int));
static int replace_label PARAMS ((rtx *, void *));
typedef struct rtx_and_int {
@@ -1536,8 +1536,8 @@ regs_match_p (x, y, movables)
rtx x, y;
struct movable *movables;
{
- int xn = REGNO (x);
- int yn = REGNO (y);
+ unsigned int xn = REGNO (x);
+ unsigned int yn = REGNO (y);
struct movable *mx, *my;
for (mx = movables; mx; mx = mx->next)
@@ -3348,8 +3348,8 @@ consec_sets_invariant_p (loop, reg, n_sets, insn)
int n_sets;
rtx reg, insn;
{
- register rtx p = insn;
- register int regno = REGNO (reg);
+ rtx p = insn;
+ unsigned int regno = REGNO (reg);
rtx temp;
/* Number of sets we have to insist on finding after INSN. */
int count = n_sets - 1;
@@ -3657,7 +3657,7 @@ struct iv_class *loop_iv_list;
/* Givs made from biv increments are always splittable for loop unrolling.
Since there is no regscan info for them, we have to keep track of them
separately. */
-int first_increment_giv, last_increment_giv;
+unsigned int first_increment_giv, last_increment_giv;
/* Communication with routines called via `note_stores'. */
@@ -4089,7 +4089,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
&& CONSTANT_P (XEXP (src, 1))
&& ((increment = biv_total_increment (bl)) != NULL_RTX))
{
- int regno = REGNO (XEXP (src, 0));
+ unsigned int regno = REGNO (XEXP (src, 0));
for (bl2 = loop_iv_list; bl2; bl2 = bl2->next)
if (bl2->regno == regno)
@@ -4215,7 +4215,7 @@ strength_reduce (loop, insn_count, unroll_p, bct_p)
markers. */
if (n_extra_increment && ! loop_info->has_volatile)
{
- int nregs = first_increment_giv + n_extra_increment;
+ unsigned int nregs = first_increment_giv + n_extra_increment;
/* Reallocate reg_iv_type and reg_iv_info. */
VARRAY_GROW (reg_iv_type, nregs);
@@ -8458,7 +8458,7 @@ maybe_eliminate_biv (loop, bl, eliminate_p, threshold, insn_count)
if (set && GET_CODE (SET_DEST (set)) == REG)
{
- int regno = REGNO (SET_DEST (set));
+ unsigned int regno = REGNO (SET_DEST (set));
if (regno < max_reg_before_loop
&& REG_IV_TYPE (regno) == GENERAL_INDUCT
@@ -10064,11 +10064,12 @@ note_reg_stored (x, setter, arg)
There must be exactly one insn that sets this pseudo; it will be
deleted if all replacements succeed and we can prove that the register
is not used after the loop. */
+
static void
try_copy_prop (loop, replacement, regno)
const struct loop *loop;
rtx replacement;
- int regno;
+ unsigned int regno;
{
/* This is the reg that we are copying from. */
rtx reg_rtx = regno_reg_rtx[regno];
diff --git a/gcc/loop.h b/gcc/loop.h
index f7769f8ea4a..703073372b6 100644
--- a/gcc/loop.h
+++ b/gcc/loop.h
@@ -137,7 +137,7 @@ struct induction
/* A `struct iv_class' is created for each biv. */
struct iv_class {
- int regno; /* Pseudo reg which is the biv. */
+ unsigned int regno; /* Pseudo reg which is the biv. */
int biv_count; /* Number of insns setting this reg. */
struct induction *biv; /* List of all insns that set this reg. */
int giv_count; /* Number of DEST_REG givs computed from this
@@ -211,7 +211,7 @@ enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT,
extern int *uid_luid;
extern int max_uid_for_loop;
-extern int max_reg_before_loop;
+extern unsigned int max_reg_before_loop;
extern struct loop **uid_loop;
extern FILE *loop_dump_stream;
@@ -226,7 +226,7 @@ extern varray_type reg_iv_info;
extern struct iv_class **reg_biv_class;
extern struct iv_class *loop_iv_list;
-extern int first_increment_giv, last_increment_giv;
+extern unsigned int first_increment_giv, last_increment_giv;
/* Forward declarations for non-static functions declared in loop.c and
unroll.c. */
diff --git a/gcc/machmode.h b/gcc/machmode.h
index fd2101bcf51..ee2d7249eb6 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -68,12 +68,12 @@ extern const enum mode_class mode_class[];
/* Get the size in bytes of an object of mode MODE. */
-extern const int mode_size[];
+extern const unsigned int mode_size[];
#define GET_MODE_SIZE(MODE) (mode_size[(int) (MODE)])
/* Get the size in bytes of the basic parts of an object of mode MODE. */
-extern const int mode_unit_size[];
+extern const unsigned int mode_unit_size[];
#define GET_MODE_UNIT_SIZE(MODE) (mode_unit_size[(int) (MODE)])
/* Get the number of units in the object. */
@@ -106,12 +106,13 @@ extern const unsigned char mode_wider_mode[];
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
The value is BLKmode if no other mode is found. */
-extern enum machine_mode mode_for_size PARAMS ((int, enum mode_class, int));
+extern enum machine_mode mode_for_size PARAMS ((unsigned int,
+ enum mode_class, int));
/* Similar, but find the smallest mode for a given width. */
extern enum machine_mode smallest_mode_for_size
- PARAMS ((int, enum mode_class));
+ PARAMS ((unsigned int, enum mode_class));
/* Return an integer mode of the exact same size as the input mode,
diff --git a/gcc/md.texi b/gcc/md.texi
index c019312e4eb..0b46d8164ee 100644
--- a/gcc/md.texi
+++ b/gcc/md.texi
@@ -1822,8 +1822,10 @@ to store the specified value in the part of the register that corresponds
to mode @var{m}. The effect on the rest of the register is undefined.
This class of patterns is special in several ways. First of all, each
-of these names @emph{must} be defined, because there is no other way
-to copy a datum from one place to another.
+of these names up to and including full word size @emph{must} be defined,
+because there is no other way to copy a datum from one place to another.
+If there are patterns accepting operands in larger modes,
+@samp{mov@var{m}} must be defined for integer modes of those sizes.
Second, these patterns are not used solely in the RTL generation pass.
Even the reload pass can generate move insns to copy values from stack
diff --git a/gcc/objc/lang-specs.h b/gcc/objc/lang-specs.h
index 69d0fec667d..a8411f3ea85 100644
--- a/gcc/objc/lang-specs.h
+++ b/gcc/objc/lang-specs.h
@@ -35,6 +35,7 @@ Boston, MA 02111-1307, USA. */
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
%{fleading-underscore} %{fno-leading-underscore}\
+ %{fshow-column} %{fno-show-column}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}",
"%{!M:%{!MM:%{!E:cc1obj %i %1 \
@@ -68,6 +69,7 @@ Boston, MA 02111-1307, USA. */
%{traditional} %{ftraditional:-traditional}\
%{traditional-cpp:-traditional}\
%{fleading-underscore} %{fno-leading-underscore}\
+ %{fshow-column} %{fno-show-column}\
%{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\
%i %{!M:%{!MM:%{!E:%{!pipe:%g.mi}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n",
"%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.mi} %1 \
diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c
index 1c2f3591cdc..842944d43d3 100644
--- a/gcc/objc/objc-act.c
+++ b/gcc/objc/objc-act.c
@@ -3817,13 +3817,8 @@ build_ivar_list_initializer (type, field_decl)
ivar);
obstack_free (&util_obstack, util_firstobj);
- /* set offset */
- ivar
- = tree_cons
- (NULL_TREE,
- build_int_2 ((int_bit_position (field_decl) / BITS_PER_UNIT), 0),
- ivar);
-
+ /* Set offset. */
+ ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
initlist = tree_cons (NULL_TREE,
build_constructor (type, nreverse (ivar)),
initlist);
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 6474a533a7b..dbdea0412ba 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -829,7 +829,7 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
&& GET_MODE_SIZE (mode) > UNITS_PER_WORD
&& binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
{
- int i;
+ unsigned int i;
rtx insns;
rtx equiv_value;
@@ -1120,10 +1120,10 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
&& GET_MODE_SIZE (mode) >= 2 * UNITS_PER_WORD
&& binoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
{
- int i;
+ unsigned int i;
rtx carry_tmp = gen_reg_rtx (word_mode);
optab otheroptab = binoptab == add_optab ? sub_optab : add_optab;
- int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
+ unsigned int nwords = GET_MODE_BITSIZE (mode) / BITS_PER_WORD;
rtx carry_in = NULL_RTX, carry_out = NULL_RTX;
rtx xop0, xop1;
@@ -2090,7 +2090,7 @@ expand_unop (mode, unoptab, op0, target, unsignedp)
&& GET_MODE_SIZE (mode) > UNITS_PER_WORD
&& unoptab->handlers[(int) word_mode].insn_code != CODE_FOR_nothing)
{
- int i;
+ unsigned int i;
rtx insns;
if (target == 0 || target == op0)
@@ -2699,7 +2699,16 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
set_unique_reg_note (last, REG_EQUAL, equiv);
}
else
- last = get_last_insn ();
+ {
+ last = get_last_insn ();
+
+ /* Remove any existing REG_EQUAL note from "last", or else it will
+ be mistaken for a note referring to the full contents of the
+ alleged libcall value when found together with the REG_RETVAL
+ note added below. An existing note can come from an insn
+ expansion at "last". */
+ remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
+ }
if (prev == 0)
first = get_insns ();
@@ -2810,6 +2819,15 @@ emit_libcall_block (insns, target, result, equiv)
if (mov_optab->handlers[(int) GET_MODE (target)].insn_code
!= CODE_FOR_nothing)
set_unique_reg_note (last, REG_EQUAL, copy_rtx (equiv));
+ else
+ {
+ /* Remove any existing REG_EQUAL note from "last", or else it will
+ be mistaken for a note referring to the full contents of the
+ libcall value when found together with the REG_RETVAL note added
+ below. An existing note can come from an insn expansion at
+ "last". */
+ remove_note (last, find_reg_note (last, REG_EQUAL, NULL_RTX));
+ }
if (prev == 0)
first = get_insns ();
@@ -2916,6 +2934,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
rtx x = *px, y = *py;
int unsignedp = *punsignedp;
enum mode_class class;
+ rtx opalign ATTRIBUTE_UNUSED = GEN_INT (align / BITS_PER_UNIT);;
class = GET_MODE_CLASS (mode);
@@ -2932,10 +2951,12 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
/* If we are inside an appropriately-short loop and one operand is an
expensive constant, force it into a register. */
- if (CONSTANT_P (x) && preserve_subexpressions_p () && rtx_cost (x, COMPARE) > 2)
+ if (CONSTANT_P (x) && preserve_subexpressions_p ()
+ && rtx_cost (x, COMPARE) > 2)
x = force_reg (mode, x);
- if (CONSTANT_P (y) && preserve_subexpressions_p () && rtx_cost (y, COMPARE) > 2)
+ if (CONSTANT_P (y) && preserve_subexpressions_p ()
+ && rtx_cost (y, COMPARE) > 2)
y = force_reg (mode, y);
#ifdef HAVE_cc0
@@ -2970,7 +2991,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
{
result_mode = insn_data[(int) CODE_FOR_cmpstrqi].operand[0].mode;
result = gen_reg_rtx (result_mode);
- emit_insn (gen_cmpstrqi (result, x, y, size, GEN_INT (align)));
+ emit_insn (gen_cmpstrqi (result, x, y, size, opalign));
}
else
#endif
@@ -2981,7 +3002,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
{
result_mode = insn_data[(int) CODE_FOR_cmpstrhi].operand[0].mode;
result = gen_reg_rtx (result_mode);
- emit_insn (gen_cmpstrhi (result, x, y, size, GEN_INT (align)));
+ emit_insn (gen_cmpstrhi (result, x, y, size, opalign));
}
else
#endif
@@ -2993,7 +3014,7 @@ prepare_cmp_insn (px, py, pcomparison, size, pmode, punsignedp, align,
size = protect_from_queue (size, 0);
emit_insn (gen_cmpstrsi (result, x, y,
convert_to_mode (SImode, size, 1),
- GEN_INT (align)));
+ opalign));
}
else
#endif
@@ -3190,7 +3211,7 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
rtx size;
enum machine_mode mode;
int unsignedp;
- int align;
+ unsigned int align;
rtx label;
{
rtx op0;
@@ -3227,6 +3248,7 @@ emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, label)
}
/* Like emit_cmp_and_jump_insns, but generate only the comparison. */
+
void
emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
rtx x, y;
@@ -3234,7 +3256,7 @@ emit_cmp_insn (x, y, comparison, size, mode, unsignedp, align)
rtx size;
enum machine_mode mode;
int unsignedp;
- int align;
+ unsigned int align;
{
emit_cmp_and_jump_insns (x, y, comparison, size, mode, unsignedp, align, 0);
}
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 82b20b157d4..3f2787e47a5 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,12 @@
+2000-04-05 Geoff Keating <geoffk@cygnus.com>
+
+ * POTFILES.in: Update for config/rs6000 changes. Comment out
+ rs6000 files which are not built into GCC.
+
+2000-03-29 Philipp Thomas <pthomas@suse.de>
+
+ * POTFILES.in: Remove config/rs6000/cygwin.h
+
2000-02-05 Zack Weinberg <zack@wolery.cumb.org>
* POTFILES.in: Remove stupid.c.
diff --git a/gcc/po/POTFILES.in b/gcc/po/POTFILES.in
index 48e1b5dcfd2..7a8a232a0a4 100644
--- a/gcc/po/POTFILES.in
+++ b/gcc/po/POTFILES.in
@@ -445,30 +445,30 @@ config/pyr/xm-pyr.h
config/romp/romp.c
config/romp/romp.h
config/romp/xm-romp.h
+config/rs6000/aix.h
config/rs6000/aix31.h
config/rs6000/aix3newas.h
config/rs6000/aix41.h
-config/rs6000/cygwin.h
-config/rs6000/eabi-ctors.c
+config/rs6000/aix43.h
+config/rs6000/beos.h
+#config/rs6000/eabi-ctors.c
config/rs6000/eabi.h
config/rs6000/eabiaix.h
-config/rs6000/eabile.h
-config/rs6000/eabilesim.h
config/rs6000/eabisim.h
config/rs6000/linux.h
config/rs6000/lynx.h
config/rs6000/mach.h
config/rs6000/netware.h
-#config/rs6000/powerpc.h does not exist anymore in egcs
+config/rs6000/rs6000-protos.h
config/rs6000/rs6000.c
config/rs6000/rs6000.h
config/rs6000/rtems.h
-config/rs6000/sol-c0.c
+#config/rs6000/sol-c0.c
config/rs6000/sol2.h
config/rs6000/sysv4.h
config/rs6000/sysv4le.h
config/rs6000/vxppc.h
-config/rs6000/win-nt.h
+config/rs6000/xm-beos.h
config/rs6000/xm-cygwin.h
config/rs6000/xm-lynx.h
config/rs6000/xm-mach.h
diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c
index 2c7194a48cb..4c591632123 100644
--- a/gcc/print-rtl.c
+++ b/gcc/print-rtl.c
@@ -450,6 +450,21 @@ debug_rtx_list (x, n)
debug_rtx (insn);
}
+/* Call this function to print an rtx list from START to END inclusive. */
+
+void
+debug_rtx_range (start, end)
+ rtx start, end;
+{
+ while (1)
+ {
+ debug_rtx (start);
+ if (!start || start == end)
+ break;
+ start = NEXT_INSN (start);
+ }
+}
+
/* Call this function to search an rtx list to find one with insn uid UID,
and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
The found insn is returned to enable further debugging analysis. */
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 2ffd4424a13..6439423c89c 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -347,34 +347,37 @@ print_node (file, prefix, node, indent)
fputs (" external", file);
if (DECL_REGISTER (node))
fputs (" regdecl", file);
- if (DECL_PACKED (node))
- fputs (" packed", file);
if (DECL_NONLOCAL (node))
fputs (" nonlocal", file);
- if (DECL_INLINE (node))
- fputs (" inline", file);
if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
fputs (" suppress-debug", file);
+ if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
+ fputs (" inline", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
fputs (" built-in", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN_NONANSI (node))
fputs (" built-in-nonansi", file);
+ if (TREE_CODE (node) == FIELD_DECL && DECL_PACKED (node))
+ fputs (" packed", file);
if (TREE_CODE (node) == FIELD_DECL && DECL_BIT_FIELD (node))
fputs (" bit-field", file);
+
if (TREE_CODE (node) == LABEL_DECL && DECL_TOO_LATE (node))
fputs (" too-late", file);
+
if (TREE_CODE (node) == VAR_DECL && DECL_IN_TEXT_SECTION (node))
fputs (" in-text-section", file);
+ if (TREE_CODE (node) == PARM_DECL && DECL_TRANSPARENT_UNION (node))
+ fputs (" transparent-union", file);
+
if (DECL_VIRTUAL_P (node))
fputs (" virtual", file);
if (DECL_DEFER_OUTPUT (node))
fputs (" defer-output", file);
- if (DECL_TRANSPARENT_UNION (node))
- fputs (" transparent-union", file);
if (DECL_LANG_FLAG_0 (node))
fputs (" decl_0", file);
@@ -421,7 +424,11 @@ print_node (file, prefix, node, indent)
fprintf (file, " alias set %d", DECL_POINTER_ALIAS_SET (node));
if (TREE_CODE (node) == FIELD_DECL)
- print_node (file, "bitpos", DECL_FIELD_BITPOS (node), indent + 4);
+ {
+ print_node (file, "offset", DECL_FIELD_OFFSET (node), indent + 4);
+ print_node (file, "bit offset", DECL_FIELD_BIT_OFFSET (node),
+ indent + 4);
+ }
print_node_brief (file, "context", DECL_CONTEXT (node), indent + 4);
print_node_brief (file, "machine_attributes",
@@ -430,7 +437,7 @@ print_node (file, prefix, node, indent)
DECL_ABSTRACT_ORIGIN (node), indent + 4);
print_node (file, "arguments", DECL_ARGUMENTS (node), indent + 4);
- print_node (file, "result", DECL_RESULT (node), indent + 4);
+ print_node (file, "result", DECL_RESULT_FLD (node), indent + 4);
print_node_brief (file, "initial", DECL_INITIAL (node), indent + 4);
print_lang_decl (file, node, indent);
@@ -441,20 +448,18 @@ print_node (file, prefix, node, indent)
print_rtl (file, DECL_RTL (node));
}
- if (DECL_SAVED_INSNS (node) != 0)
+ if (TREE_CODE (node) == PARM_DECL && DECL_INCOMING_RTL (node) != 0)
{
indent_to (file, indent + 4);
- if (TREE_CODE (node) == PARM_DECL)
- {
- fprintf (file, "incoming-rtl ");
- print_rtl (file, DECL_INCOMING_RTL (node));
- }
- else if (TREE_CODE (node) == FUNCTION_DECL)
- {
- fprintf (file, "saved-insns ");
- fprintf (file, HOST_PTR_PRINTF,
- (char *) DECL_SAVED_INSNS (node));
- }
+ fprintf (file, "incoming-rtl ");
+ print_rtl (file, DECL_INCOMING_RTL (node));
+ }
+ else if (TREE_CODE (node) == FUNCTION_DECL
+ && DECL_SAVED_INSNS (node) != 0)
+ {
+ indent_to (file, indent + 4);
+ fprintf (file, "saved-insns ");
+ fprintf (file, HOST_PTR_PRINTF, (char *) DECL_SAVED_INSNS (node));
}
/* Print the decl chain only if decl is at second level. */
diff --git a/gcc/real.c b/gcc/real.c
index 0e4b71654e3..f26635b89de 100644
--- a/gcc/real.c
+++ b/gcc/real.c
@@ -6843,7 +6843,7 @@ esqrt (x, y)
floating point mode. The mode can hold an integer value
that many bits wide, without losing any bits. */
-int
+unsigned int
significand_size (mode)
enum machine_mode mode;
{
diff --git a/gcc/real.h b/gcc/real.h
index 66981f02fd2..3aba2e245d4 100644
--- a/gcc/real.h
+++ b/gcc/real.h
@@ -119,7 +119,7 @@ typedef struct {
#endif /* no TFmode support */
#endif /* no XFmode support */
-extern int significand_size PARAMS ((enum machine_mode));
+extern unsigned int significand_size PARAMS ((enum machine_mode));
/* If emulation has been enabled by defining REAL_ARITHMETIC or by
setting LONG_DOUBLE_TYPE_SIZE to 96 or 128, then define macros so that
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 41d33533566..3d7ba5f20da 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -140,7 +140,7 @@ static unsigned int_reg_class_contents[N_REG_CLASSES][N_REG_INTS]
/* For each reg class, number of regs it contains. */
-int reg_class_size[N_REG_CLASSES];
+unsigned int reg_class_size[N_REG_CLASSES];
/* For each reg class, table listing all the containing classes. */
@@ -554,8 +554,8 @@ memory_move_secondary_cost (mode, class, in)
enum machine_mode
choose_hard_reg_mode (regno, nregs)
- int regno ATTRIBUTE_UNUSED;
- int nregs;
+ unsigned int regno ATTRIBUTE_UNUSED;
+ unsigned int nregs;
{
enum machine_mode found_mode = VOIDmode, mode;
@@ -730,7 +730,7 @@ static void record_address_regs PARAMS ((rtx, enum reg_class, int));
#ifdef FORBIDDEN_INC_DEC_CLASSES
static int auto_inc_dec_reg_p PARAMS ((rtx, enum machine_mode));
#endif
-static void reg_scan_mark_refs PARAMS ((rtx, rtx, int, int));
+static void reg_scan_mark_refs PARAMS ((rtx, rtx, int, unsigned int));
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
This function is sometimes called before the info has been computed.
@@ -1681,10 +1681,10 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
for (i = 0; i <= 1; i++)
if (REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
{
- int regno = REGNO (ops[!i]);
+ unsigned int regno = REGNO (ops[!i]);
enum machine_mode mode = GET_MODE (ops[!i]);
int class;
- int nr;
+ unsigned int nr;
if (regno >= FIRST_PSEUDO_REGISTER && reg_pref != 0)
{
@@ -1704,13 +1704,14 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
op_costs[i].cost[class] = -1;
else
{
- for (nr = 0; nr < HARD_REGNO_NREGS(regno, mode); nr++)
+ for (nr = 0; nr < HARD_REGNO_NREGS (regno, mode); nr++)
{
- if (!TEST_HARD_REG_BIT (reg_class_contents[class], regno + nr))
+ if (! TEST_HARD_REG_BIT (reg_class_contents[class],
+ regno + nr))
break;
}
- if (nr == HARD_REGNO_NREGS(regno,mode))
+ if (nr == HARD_REGNO_NREGS (regno,mode))
op_costs[i].cost[class] = -1;
}
}
@@ -2142,7 +2143,7 @@ int max_parallel;
void
reg_scan (f, nregs, repeat)
rtx f;
- int nregs;
+ unsigned int nregs;
int repeat ATTRIBUTE_UNUSED;
{
register rtx insn;
@@ -2171,10 +2172,10 @@ reg_scan (f, nregs, repeat)
such a REG. We only update information for those. */
void
-reg_scan_update(first, last, old_max_regno)
+reg_scan_update (first, last, old_max_regno)
rtx first;
rtx last;
- int old_max_regno;
+ unsigned int old_max_regno;
{
register rtx insn;
@@ -2205,7 +2206,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
rtx x;
rtx insn;
int note_flag;
- int min_regno;
+ unsigned int min_regno;
{
register enum rtx_code code;
register rtx dest;
@@ -2227,7 +2228,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
case REG:
{
- register int regno = REGNO (x);
+ unsigned int regno = REGNO (x);
if (regno >= min_regno)
{
diff --git a/gcc/regmove.c b/gcc/regmove.c
index 932e8503fce..3b4a7e660e0 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -2088,7 +2088,7 @@ stable_and_no_regs_but_for_p (x, src, dst)
struct csa_memlist
{
HOST_WIDE_INT sp_offset;
- rtx insn, mem;
+ rtx insn, *mem;
struct csa_memlist *next;
};
@@ -2096,7 +2096,7 @@ static int stack_memref_p PARAMS ((rtx));
static rtx single_set_for_csa PARAMS ((rtx));
static void free_csa_memlist PARAMS ((struct csa_memlist *));
static struct csa_memlist *record_one_stack_memref
- PARAMS ((rtx, rtx, struct csa_memlist *));
+ PARAMS ((rtx, rtx *, struct csa_memlist *));
static int try_apply_stack_adjustment
PARAMS ((rtx, struct csa_memlist *, HOST_WIDE_INT, HOST_WIDE_INT));
static void combine_stack_adjustments_for_block PARAMS ((basic_block));
@@ -2188,17 +2188,17 @@ free_csa_memlist (memlist)
static struct csa_memlist *
record_one_stack_memref (insn, mem, next_memlist)
- rtx insn, mem;
+ rtx insn, *mem;
struct csa_memlist *next_memlist;
{
struct csa_memlist *ml;
ml = (struct csa_memlist *) xmalloc (sizeof (*ml));
- if (XEXP (mem, 0) == stack_pointer_rtx)
+ if (XEXP (*mem, 0) == stack_pointer_rtx)
ml->sp_offset = 0;
else
- ml->sp_offset = INTVAL (XEXP (XEXP (mem, 0), 1));
+ ml->sp_offset = INTVAL (XEXP (XEXP (*mem, 0), 1));
ml->insn = insn;
ml->mem = mem;
@@ -2241,8 +2241,9 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta)
return 0;
}
- validate_change (ml->insn, &XEXP (ml->mem, 0),
- plus_constant (stack_pointer_rtx, c), 1);
+ validate_change (ml->insn, ml->mem,
+ gen_rtx_MEM (GET_MODE (*ml->mem),
+ plus_constant (stack_pointer_rtx, c)), 1);
}
if (apply_change_group ())
@@ -2340,7 +2341,7 @@ combine_stack_adjustments_for_block (bb)
if (last_sp_set && stack_memref_p (src)
&& ! reg_mentioned_p (stack_pointer_rtx, dest))
{
- memlist = record_one_stack_memref (insn, src, memlist);
+ memlist = record_one_stack_memref (insn, &SET_SRC (set), memlist);
goto processed;
}
@@ -2348,7 +2349,8 @@ combine_stack_adjustments_for_block (bb)
if (last_sp_set && stack_memref_p (dest)
&& ! reg_mentioned_p (stack_pointer_rtx, src))
{
- memlist = record_one_stack_memref (insn, dest, memlist);
+ memlist = record_one_stack_memref (insn, &SET_DEST (set),
+ memlist);
goto processed;
}
diff --git a/gcc/reload.c b/gcc/reload.c
index 272ce4c8195..128af489756 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -253,11 +253,12 @@ static int find_reusable_reload PARAMS ((rtx *, rtx, enum reg_class,
static rtx find_dummy_reload PARAMS ((rtx, rtx, rtx *, rtx *,
enum machine_mode, enum machine_mode,
enum reg_class, int, int));
-static int hard_reg_set_here_p PARAMS ((int, int, rtx));
+static int hard_reg_set_here_p PARAMS ((unsigned int, unsigned int, rtx));
static struct decomposition decompose PARAMS ((rtx));
static int immune_p PARAMS ((rtx, rtx, struct decomposition));
static int alternative_allows_memconst PARAMS ((const char *, int));
-static rtx find_reloads_toplev PARAMS ((rtx, int, enum reload_type, int, int, rtx));
+static rtx find_reloads_toplev PARAMS ((rtx, int, enum reload_type, int,
+ int, rtx));
static rtx make_memloc PARAMS ((rtx, int));
static int find_reloads_address PARAMS ((enum machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int, rtx));
@@ -659,7 +660,7 @@ find_valid_class (m1, n)
int class;
int regno;
enum reg_class best_class = NO_REGS;
- int best_size = 0;
+ unsigned int best_size = 0;
for (class = 1; class < N_REG_CLASSES; class++)
{
@@ -1823,8 +1824,8 @@ find_dummy_reload (real_in, real_out, inloc, outloc,
if (GET_CODE (out) == REG
&& REGNO (out) < FIRST_PSEUDO_REGISTER)
{
- register int regno = REGNO (out) + out_offset;
- int nwords = HARD_REGNO_NREGS (regno, outmode);
+ unsigned int regno = REGNO (out) + out_offset;
+ unsigned int nwords = HARD_REGNO_NREGS (regno, outmode);
rtx saved_rtx;
/* When we consider whether the insn uses OUT,
@@ -1843,7 +1844,8 @@ find_dummy_reload (real_in, real_out, inloc, outloc,
&& ! refers_to_regno_for_reload_p (regno, regno + nwords,
PATTERN (this_insn), outloc))
{
- int i;
+ unsigned int i;
+
for (i = 0; i < nwords; i++)
if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
regno + i))
@@ -1882,8 +1884,8 @@ find_dummy_reload (real_in, real_out, inloc, outloc,
(GET_MODE (out) != VOIDmode
? GET_MODE (out) : outmode)))
{
- register int regno = REGNO (in) + in_offset;
- int nwords = HARD_REGNO_NREGS (regno, inmode);
+ unsigned int regno = REGNO (in) + in_offset;
+ unsigned int nwords = HARD_REGNO_NREGS (regno, inmode);
if (! refers_to_regno_for_reload_p (regno, regno + nwords, out, NULL_PTR)
&& ! hard_reg_set_here_p (regno, regno + nwords,
@@ -1892,7 +1894,8 @@ find_dummy_reload (real_in, real_out, inloc, outloc,
|| ! refers_to_regno_for_reload_p (regno, regno + nwords,
PATTERN (this_insn), inloc)))
{
- int i;
+ unsigned int i;
+
for (i = 0; i < nwords; i++)
if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
regno + i))
@@ -1942,17 +1945,19 @@ earlyclobber_operand_p (x)
static int
hard_reg_set_here_p (beg_regno, end_regno, x)
- register int beg_regno, end_regno;
+ unsigned int beg_regno, end_regno;
rtx x;
{
if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
{
register rtx op0 = SET_DEST (x);
+
while (GET_CODE (op0) == SUBREG)
op0 = SUBREG_REG (op0);
if (GET_CODE (op0) == REG)
{
- register int r = REGNO (op0);
+ unsigned int r = REGNO (op0);
+
/* See if this reg overlaps range under consideration. */
if (r < end_regno
&& r + HARD_REGNO_NREGS (r, GET_MODE (op0)) > beg_regno)
@@ -1962,6 +1967,7 @@ hard_reg_set_here_p (beg_regno, end_regno, x)
else if (GET_CODE (x) == PARALLEL)
{
register int i = XVECLEN (x, 0) - 1;
+
for (; i >= 0; i--)
if (hard_reg_set_here_p (beg_regno, end_regno, XVECEXP (x, 0, i)))
return 1;
@@ -5689,13 +5695,14 @@ find_replacement (loc)
int
refers_to_regno_for_reload_p (regno, endregno, x, loc)
- int regno, endregno;
+ unsigned int regno, endregno;
rtx x;
rtx *loc;
{
- register int i;
- register RTX_CODE code;
- register const char *fmt;
+ int i;
+ unsigned int r;
+ RTX_CODE code;
+ const char *fmt;
if (x == 0)
return 0;
@@ -5706,26 +5713,26 @@ refers_to_regno_for_reload_p (regno, endregno, x, loc)
switch (code)
{
case REG:
- i = REGNO (x);
+ r = REGNO (x);
/* If this is a pseudo, a hard register must not have been allocated.
X must therefore either be a constant or be in memory. */
- if (i >= FIRST_PSEUDO_REGISTER)
+ if (r >= FIRST_PSEUDO_REGISTER)
{
- if (reg_equiv_memory_loc[i])
+ if (reg_equiv_memory_loc[r])
return refers_to_regno_for_reload_p (regno, endregno,
- reg_equiv_memory_loc[i],
+ reg_equiv_memory_loc[r],
NULL_PTR);
- if (reg_equiv_constant[i])
+ if (reg_equiv_constant[r])
return 0;
abort ();
}
- return (endregno > i
- && regno < i + (i < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (i, GET_MODE (x))
+ return (endregno > r
+ && regno < r + (r < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (r, GET_MODE (x))
: 1));
case SUBREG:
@@ -5734,8 +5741,8 @@ refers_to_regno_for_reload_p (regno, endregno, x, loc)
if (GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
{
- int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int inner_endregno
+ unsigned int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
+ unsigned int inner_endregno
= inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
@@ -5983,21 +5990,24 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
p = PREV_INSN (p);
if (p == 0 || GET_CODE (p) == CODE_LABEL)
return 0;
+
if (GET_CODE (p) == INSN
/* If we don't want spill regs ... */
&& (! (reload_reg_p != 0
&& reload_reg_p != (short *) (HOST_WIDE_INT) 1)
- /* ... then ignore insns introduced by reload; they aren't useful
- and can cause results in reload_as_needed to be different
- from what they were when calculating the need for spills.
- If we notice an input-reload insn here, we will reject it below,
- but it might hide a usable equivalent. That makes bad code.
- It may even abort: perhaps no reg was spilled for this insn
- because it was assumed we would find that equivalent. */
+ /* ... then ignore insns introduced by reload; they aren't
+ useful and can cause results in reload_as_needed to be
+ different from what they were when calculating the need for
+ spills. If we notice an input-reload insn here, we will
+ reject it below, but it might hide a usable equivalent.
+ That makes bad code. It may even abort: perhaps no reg was
+ spilled for this insn because it was assumed we would find
+ that equivalent. */
|| INSN_UID (p) < reload_first_uid))
{
rtx tem;
pat = single_set (p);
+
/* First check for something that sets some reg equal to GOAL. */
if (pat != 0
&& ((regno >= 0
@@ -6098,8 +6108,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
/* Reject registers that overlap GOAL. */
if (!goal_mem && !goal_const
- && regno + HARD_REGNO_NREGS (regno, mode) > valueno
- && regno < valueno + HARD_REGNO_NREGS (valueno, mode))
+ && regno + (int) HARD_REGNO_NREGS (regno, mode) > valueno
+ && regno < valueno + (int) HARD_REGNO_NREGS (valueno, mode))
return 0;
/* Reject VALUE if it is one of the regs reserved for reloads.
@@ -6180,6 +6190,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
If GOAL is a memory ref and its address is not constant,
and this insn P changes a register used in GOAL, return 0. */
+ if (GET_CODE (pat) == COND_EXEC)
+ pat = COND_EXEC_CODE (pat);
if (GET_CODE (pat) == SET || GET_CODE (pat) == CLOBBER)
{
register rtx dest = SET_DEST (pat);
@@ -6222,6 +6234,8 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
for (i = XVECLEN (pat, 0) - 1; i >= 0; i--)
{
register rtx v1 = XVECEXP (pat, 0, i);
+ if (GET_CODE (v1) == COND_EXEC)
+ v1 = COND_EXEC_CODE (v1);
if (GET_CODE (v1) == SET || GET_CODE (v1) == CLOBBER)
{
register rtx dest = SET_DEST (v1);
@@ -6388,7 +6402,7 @@ find_inc_amount (x, inced)
int
regno_clobbered_p (regno, insn)
- int regno;
+ unsigned int regno;
rtx insn;
{
if (GET_CODE (PATTERN (insn)) == CLOBBER
diff --git a/gcc/reload.h b/gcc/reload.h
index ef456277392..34b93cf2b20 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -104,7 +104,7 @@ struct reload
enum machine_mode mode;
/* the largest number of registers this reload will require. */
- int nregs;
+ unsigned int nregs;
/* Positive amount to increment or decrement by if
reload_in is a PRE_DEC, PRE_INC, POST_DEC, POST_INC.
@@ -319,7 +319,8 @@ extern rtx find_replacement PARAMS ((rtx *));
/* Return nonzero if register in range [REGNO, ENDREGNO)
appears either explicitly or implicitly in X
other than being stored into. */
-extern int refers_to_regno_for_reload_p PARAMS ((int, int, rtx, rtx *));
+extern int refers_to_regno_for_reload_p PARAMS ((unsigned int, unsigned int,
+ rtx, rtx *));
/* Nonzero if modifying X will affect IN. */
extern int reg_overlap_mentioned_for_reload_p PARAMS ((rtx, rtx));
@@ -334,7 +335,7 @@ extern rtx find_equiv_reg PARAMS ((rtx, rtx, enum reg_class, int, short *,
int, enum machine_mode));
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
-extern int regno_clobbered_p PARAMS ((int, rtx));
+extern int regno_clobbered_p PARAMS ((unsigned int, rtx));
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
int earlyclobber_operand_p PARAMS ((rtx));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 37670e8cc8a..3520883f316 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -120,7 +120,7 @@ rtx *reg_equiv_address;
rtx *reg_equiv_mem;
/* Widest width in which each pseudo reg is referred to (via subreg). */
-static int *reg_max_ref_width;
+static unsigned int *reg_max_ref_width;
/* Element N is the list of insns that initialized reg N from its equivalent
constant or memory slot. */
@@ -237,7 +237,7 @@ char double_reg_address_ok;
static rtx spill_stack_slot[FIRST_PSEUDO_REGISTER];
/* Width allocated so far for that stack slot. */
-static int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
+static unsigned int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
/* Record which pseudos needed to be spilled. */
static regset_head spilled_pseudos;
@@ -393,7 +393,7 @@ static void set_initial_label_offsets PARAMS ((void));
static void set_offsets_for_label PARAMS ((rtx));
static void init_elim_table PARAMS ((void));
static void update_eliminables PARAMS ((HARD_REG_SET *));
-static void spill_hard_reg PARAMS ((int, FILE *, int));
+static void spill_hard_reg PARAMS ((unsigned int, FILE *, int));
static int finish_spills PARAMS ((int, FILE *));
static void ior_hard_reg_set PARAMS ((HARD_REG_SET *, HARD_REG_SET *));
static void scan_paradoxical_subregs PARAMS ((rtx));
@@ -402,28 +402,33 @@ static void order_regs_for_reload PARAMS ((struct insn_chain *));
static void reload_as_needed PARAMS ((int));
static void forget_old_reloads_1 PARAMS ((rtx, rtx, void *));
static int reload_reg_class_lower PARAMS ((const PTR, const PTR));
-static void mark_reload_reg_in_use PARAMS ((int, int, enum reload_type,
- enum machine_mode));
-static void clear_reload_reg_in_use PARAMS ((int, int, enum reload_type,
- enum machine_mode));
-static int reload_reg_free_p PARAMS ((int, int, enum reload_type));
+static void mark_reload_reg_in_use PARAMS ((unsigned int, int,
+ enum reload_type,
+ enum machine_mode));
+static void clear_reload_reg_in_use PARAMS ((unsigned int, int,
+ enum reload_type,
+ enum machine_mode));
+static int reload_reg_free_p PARAMS ((unsigned int, int,
+ enum reload_type));
static int reload_reg_free_for_value_p PARAMS ((int, int, enum reload_type,
- rtx, rtx, int, int));
-static int reload_reg_reaches_end_p PARAMS ((int, int, enum reload_type));
-static int allocate_reload_reg PARAMS ((struct insn_chain *, int, int));
+ rtx, rtx, int, int));
+static int reload_reg_reaches_end_p PARAMS ((unsigned int, int,
+ enum reload_type));
+static int allocate_reload_reg PARAMS ((struct insn_chain *, int,
+ int));
static void failed_reload PARAMS ((rtx, int));
static int set_reload_reg PARAMS ((int, int));
static void choose_reload_regs_init PARAMS ((struct insn_chain *, rtx *));
static void choose_reload_regs PARAMS ((struct insn_chain *));
static void merge_assigned_reloads PARAMS ((rtx));
static void emit_input_reload_insns PARAMS ((struct insn_chain *,
- struct reload *, rtx, int));
+ struct reload *, rtx, int));
static void emit_output_reload_insns PARAMS ((struct insn_chain *,
- struct reload *, int));
+ struct reload *, int));
static void do_input_reload PARAMS ((struct insn_chain *,
- struct reload *, int));
+ struct reload *, int));
static void do_output_reload PARAMS ((struct insn_chain *,
- struct reload *, int));
+ struct reload *, int));
static void emit_reload_insns PARAMS ((struct insn_chain *));
static void delete_output_reload PARAMS ((rtx, int, int));
static void delete_address_reloads PARAMS ((rtx, rtx));
@@ -434,18 +439,20 @@ static void reload_cse_regs_1 PARAMS ((rtx));
static int reload_cse_noop_set_p PARAMS ((rtx));
static int reload_cse_simplify_set PARAMS ((rtx, rtx));
static int reload_cse_simplify_operands PARAMS ((rtx));
-static void reload_combine PARAMS ((void));
-static void reload_combine_note_use PARAMS ((rtx *, rtx));
-static void reload_combine_note_store PARAMS ((rtx, rtx, void *));
-static void reload_cse_move2add PARAMS ((rtx));
-static void move2add_note_store PARAMS ((rtx, rtx, void *));
+static void reload_combine PARAMS ((void));
+static void reload_combine_note_use PARAMS ((rtx *, rtx));
+static void reload_combine_note_store PARAMS ((rtx, rtx, void *));
+static void reload_cse_move2add PARAMS ((rtx));
+static void move2add_note_store PARAMS ((rtx, rtx, void *));
#ifdef AUTO_INC_DEC
-static void add_auto_inc_notes PARAMS ((rtx, rtx));
+static void add_auto_inc_notes PARAMS ((rtx, rtx));
#endif
static rtx gen_mode_int PARAMS ((enum machine_mode,
- HOST_WIDE_INT));
+ HOST_WIDE_INT));
static void failed_reload PARAMS ((rtx, int));
static int set_reload_reg PARAMS ((int, int));
+static void reload_cse_delete_noop_set PARAMS ((rtx, rtx));
+static void reload_cse_simplify PARAMS ((rtx));
extern void dump_needs PARAMS ((struct insn_chain *, FILE *));
/* Initialize the reload pass once per compilation. */
@@ -534,17 +541,20 @@ new_insn_chain ()
/* Small utility function to set all regs in hard reg set TO which are
allocated to pseudos in regset FROM. */
+
void
compute_use_by_pseudos (to, from)
HARD_REG_SET *to;
regset from;
{
- int regno;
+ unsigned int regno;
+
EXECUTE_IF_SET_IN_REG_SET
(from, FIRST_PSEUDO_REGISTER, regno,
{
int r = reg_renumber[regno];
int nregs;
+
if (r < 0)
{
/* reload_combine uses the information from
@@ -1475,6 +1485,7 @@ static int spill_cost[FIRST_PSEUDO_REGISTER];
static int spill_add_cost[FIRST_PSEUDO_REGISTER];
/* Update the spill cost arrays, considering that pseudo REG is live. */
+
static void
count_pseudo (reg)
int reg;
@@ -1552,6 +1563,7 @@ static HARD_REG_SET used_spill_regs_local;
SPILLED_NREGS. Determine how pseudo REG, which is live during the insn,
is affected. We will add it to SPILLED_PSEUDOS if necessary, and we will
update SPILL_COST/SPILL_ADD_COST. */
+
static void
count_spilled_pseudo (spilled, spilled_nregs, reg)
int spilled, spilled_nregs, reg;
@@ -1582,7 +1594,8 @@ find_reg (chain, order, dumpfile)
struct reload *rl = rld + rnum;
int best_cost = INT_MAX;
int best_reg = -1;
- int i, j;
+ unsigned int i, j;
+ int k;
HARD_REG_SET not_usable;
HARD_REG_SET used_by_other_reload;
@@ -1591,9 +1604,10 @@ find_reg (chain, order, dumpfile)
IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->class]);
CLEAR_HARD_REG_SET (used_by_other_reload);
- for (i = 0; i < order; i++)
+ for (k = 0; k < order; k++)
{
- int other = reload_order[i];
+ int other = reload_order[k];
+
if (rld[other].regno >= 0 && reloads_conflict (other, rnum))
for (j = 0; j < rld[other].nregs; j++)
SET_HARD_REG_BIT (used_by_other_reload, rld[other].regno + j);
@@ -1601,14 +1615,15 @@ find_reg (chain, order, dumpfile)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
- int regno = i;
+ unsigned int regno = i;
+
if (! TEST_HARD_REG_BIT (not_usable, regno)
&& ! TEST_HARD_REG_BIT (used_by_other_reload, regno)
&& HARD_REGNO_MODE_OK (regno, rl->mode))
{
int this_cost = spill_cost[regno];
int ok = 1;
- int this_nregs = HARD_REGNO_NREGS (regno, rl->mode);
+ unsigned int this_nregs = HARD_REGNO_NREGS (regno, rl->mode);
for (j = 1; j < this_nregs; j++)
{
@@ -1643,8 +1658,10 @@ find_reg (chain, order, dumpfile)
}
if (best_reg == -1)
return 0;
+
if (dumpfile)
fprintf (dumpfile, "Using reg %d for reload %d\n", best_reg, rnum);
+
rl->nregs = HARD_REGNO_NREGS (best_reg, rl->mode);
rl->regno = best_reg;
@@ -1653,6 +1670,7 @@ find_reg (chain, order, dumpfile)
{
count_spilled_pseudo (best_reg, rl->nregs, j);
});
+
EXECUTE_IF_SET_IN_REG_SET
(&chain->dead_or_set, FIRST_PSEUDO_REGISTER, j,
{
@@ -1693,7 +1711,8 @@ find_reload_regs (chain, dumpfile)
{
int regno = REGNO (chain->rld[i].reg_rtx);
chain->rld[i].regno = regno;
- chain->rld[i].nregs = HARD_REGNO_NREGS (regno, GET_MODE (chain->rld[i].reg_rtx));
+ chain->rld[i].nregs
+ = HARD_REGNO_NREGS (regno, GET_MODE (chain->rld[i].reg_rtx));
}
else
chain->rld[i].regno = -1;
@@ -1868,8 +1887,8 @@ alter_reg (i, from_reg)
&& reg_equiv_memory_loc[i] == 0)
{
register rtx x;
- int inherent_size = PSEUDO_REGNO_BYTES (i);
- int total_size = MAX (inherent_size, reg_max_ref_width[i]);
+ unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
+ unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
int adjust = 0;
/* Each pseudo reg has an inherent size which comes from its own mode,
@@ -1970,6 +1989,7 @@ mark_home_live (regno)
int regno;
{
register int i, lim;
+
i = reg_renumber[regno];
if (i < 0)
return;
@@ -3419,7 +3439,7 @@ init_elim_table ()
static void
spill_hard_reg (regno, dumpfile, cant_eliminate)
- register int regno;
+ unsigned int regno;
FILE *dumpfile ATTRIBUTE_UNUSED;
int cant_eliminate;
{
@@ -3436,9 +3456,9 @@ spill_hard_reg (regno, dumpfile, cant_eliminate)
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
if (reg_renumber[i] >= 0
- && reg_renumber[i] <= regno
- && (reg_renumber[i]
- + HARD_REGNO_NREGS (reg_renumber[i],
+ && (unsigned int) reg_renumber[i] <= regno
+ && ((unsigned int) reg_renumber[i]
+ + HARD_REGNO_NREGS ((unsigned int) reg_renumber[i],
PSEUDO_REGNO_MODE (i))
> regno))
SET_REGNO_REG_SET (&spilled_pseudos, i);
@@ -3446,6 +3466,7 @@ spill_hard_reg (regno, dumpfile, cant_eliminate)
/* I'm getting weird preprocessor errors if I use IOR_HARD_REG_SET
from within EXECUTE_IF_SET_IN_REG_SET. Hence this awkwardness. */
+
static void
ior_hard_reg_set (set1, set2)
HARD_REG_SET *set1, *set2;
@@ -3956,8 +3977,8 @@ forget_old_reloads_1 (x, ignored, data)
rtx ignored ATTRIBUTE_UNUSED;
void *data ATTRIBUTE_UNUSED;
{
- register int regno;
- int nr;
+ unsigned int regno;
+ unsigned int nr;
int offset = 0;
/* note_stores does give us subregs of hard regs. */
@@ -3976,7 +3997,8 @@ forget_old_reloads_1 (x, ignored, data)
nr = 1;
else
{
- int i;
+ unsigned int i;
+
nr = HARD_REGNO_NREGS (regno, GET_MODE (x));
/* Storing into a spilled-reg invalidates its contents.
This can happen if a block-local pseudo is allocated to that reg
@@ -4045,13 +4067,13 @@ static HARD_REG_SET reg_used_in_insn;
static void
mark_reload_reg_in_use (regno, opnum, type, mode)
- int regno;
+ unsigned int regno;
int opnum;
enum reload_type type;
enum machine_mode mode;
{
- int nregs = HARD_REGNO_NREGS (regno, mode);
- int i;
+ unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
+ unsigned int i;
for (i = regno; i < nregs + regno; i++)
{
@@ -4110,13 +4132,13 @@ mark_reload_reg_in_use (regno, opnum, type, mode)
static void
clear_reload_reg_in_use (regno, opnum, type, mode)
- int regno;
+ unsigned int regno;
int opnum;
enum reload_type type;
enum machine_mode mode;
{
- int nregs = HARD_REGNO_NREGS (regno, mode);
- int start_regno, end_regno;
+ unsigned int nregs = HARD_REGNO_NREGS (regno, mode);
+ unsigned int start_regno, end_regno, r;
int i;
/* A complication is that for some reload types, inheritance might
allow multiple reloads of the same types to share a reload register.
@@ -4196,8 +4218,8 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
&& (check_any || rld[i].opnum == opnum)
&& rld[i].reg_rtx)
{
- int conflict_start = true_regnum (rld[i].reg_rtx);
- int conflict_end
+ unsigned int conflict_start = true_regnum (rld[i].reg_rtx);
+ unsigned int conflict_end
= (conflict_start
+ HARD_REGNO_NREGS (conflict_start, rld[i].mode));
@@ -4212,8 +4234,9 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
}
}
}
- for (i = start_regno; i < end_regno; i++)
- CLEAR_HARD_REG_BIT (*used_in_set, i);
+
+ for (r = start_regno; r < end_regno; r++)
+ CLEAR_HARD_REG_BIT (*used_in_set, r);
}
/* 1 if reg REGNO is free as a reload reg for a reload of the sort
@@ -4221,7 +4244,7 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
static int
reload_reg_free_p (regno, opnum, type)
- int regno;
+ unsigned int regno;
int opnum;
enum reload_type type;
{
@@ -4381,7 +4404,7 @@ reload_reg_free_p (regno, opnum, type)
static int
reload_reg_reaches_end_p (regno, opnum, type)
- int regno;
+ unsigned int regno;
int opnum;
enum reload_type type;
{
@@ -5101,7 +5124,7 @@ choose_reload_regs (chain)
{
rtx insn = chain->insn;
register int i, j;
- int max_group_size = 1;
+ unsigned int max_group_size = 1;
enum reg_class group_class = NO_REGS;
int pass, win, inheritance;
@@ -5124,7 +5147,8 @@ choose_reload_regs (chain)
if (rld[j].nregs > 1)
{
max_group_size = MAX (rld[j].nregs, max_group_size);
- group_class = reg_class_superunion[(int)rld[j].class][(int)group_class];
+ group_class
+ = reg_class_superunion[(int)rld[j].class][(int)group_class];
}
save_reload_reg_rtx[j] = rld[j].reg_rtx;
@@ -5146,11 +5170,11 @@ choose_reload_regs (chain)
/* Process the reloads in order of preference just found.
Beyond this point, subregs can be found in reload_reg_rtx.
- This used to look for an existing reloaded home for all
- of the reloads, and only then perform any new reloads.
- But that could lose if the reloads were done out of reg-class order
- because a later reload with a looser constraint might have an old
- home in a register needed by an earlier reload with a tighter constraint.
+ This used to look for an existing reloaded home for all of the
+ reloads, and only then perform any new reloads. But that could lose
+ if the reloads were done out of reg-class order because a later
+ reload with a looser constraint might have an old home in a register
+ needed by an earlier reload with a tighter constraint.
To solve this, we make two passes over the reloads, in the order
described above. In the first pass we try to inherit a reload
@@ -5873,6 +5897,7 @@ static HARD_REG_SET reg_reloaded_died;
/* Generate insns to perform reload RL, which is for the insn in CHAIN and
has the number J. OLD contains the value to be used as input. */
+
static void
emit_input_reload_insns (chain, rl, old, j)
struct insn_chain *chain;
@@ -5957,7 +5982,7 @@ emit_input_reload_insns (chain, rl, old, j)
if (oldequiv)
{
- int regno = true_regnum (oldequiv);
+ unsigned int regno = true_regnum (oldequiv);
/* Don't use OLDEQUIV if any other reload changes it at an
earlier stage of this insn or at this stage. */
@@ -8784,6 +8809,7 @@ reload_combine_note_use (xp, insn)
reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if
reg_set_luid[n] is larger than last_label_luid[n] . */
static int reg_set_luid[FIRST_PSEUDO_REGISTER];
+
/* reg_offset[n] has to be CONST_INT for it and reg_base_reg[n] /
reg_mode[n] to be valid.
If reg_offset[n] is a CONST_INT and reg_base_reg[n] is negative, register n
@@ -8794,12 +8820,14 @@ static int reg_set_luid[FIRST_PSEUDO_REGISTER];
static rtx reg_offset[FIRST_PSEUDO_REGISTER];
static int reg_base_reg[FIRST_PSEUDO_REGISTER];
static enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER];
+
/* move2add_luid is linearily increased while scanning the instructions
from first to last. It is used to set reg_set_luid in
reload_cse_move2add and move2add_note_store. */
static int move2add_luid;
/* Generate a CONST_INT and force it in the range of MODE. */
+
static rtx
gen_mode_int (mode, value)
enum machine_mode mode;
@@ -8900,7 +8928,7 @@ reload_cse_move2add (first)
...
(set (REGX) (plus (REGX) (CONST_INT B-A))) */
else if (GET_CODE (src) == REG
- && reg_base_reg[regno] == REGNO (src)
+ && reg_base_reg[regno] == (int) REGNO (src)
&& reg_set_luid[regno] > reg_set_luid[REGNO (src)])
{
rtx next = next_nonnote_insn (insn);
@@ -8985,20 +9013,22 @@ reload_cse_move2add (first)
/* SET is a SET or CLOBBER that sets DST.
Update reg_set_luid, reg_offset and reg_base_reg accordingly.
Called from reload_cse_move2add via note_stores. */
+
static void
move2add_note_store (dst, set, data)
rtx dst, set;
void *data ATTRIBUTE_UNUSED;
{
- int regno = 0;
- int i;
-
+ unsigned int regno = 0;
+ unsigned int i;
enum machine_mode mode = GET_MODE (dst);
+
if (GET_CODE (dst) == SUBREG)
{
regno = SUBREG_WORD (dst);
dst = SUBREG_REG (dst);
}
+
if (GET_CODE (dst) != REG)
return;
@@ -9017,6 +9047,7 @@ move2add_note_store (dst, set, data)
case PLUS:
{
rtx src0 = XEXP (src, 0);
+
if (GET_CODE (src0) == REG)
{
if (REGNO (src0) != regno
@@ -9025,9 +9056,11 @@ move2add_note_store (dst, set, data)
reg_base_reg[regno] = REGNO (src0);
reg_set_luid[regno] = move2add_luid;
}
+
reg_offset[regno] = XEXP (src, 1);
break;
}
+
reg_set_luid[regno] = move2add_luid;
reg_offset[regno] = set; /* Invalidate contents. */
break;
@@ -9048,7 +9081,9 @@ move2add_note_store (dst, set, data)
}
else
{
- for (i = regno + HARD_REGNO_NREGS (regno, mode) - 1; i >= regno; i--)
+ unsigned int endregno = regno + HARD_REGNO_NREGS (regno, mode);
+
+ for (i = regno; i < endregno; i++)
{
/* Indicate that this register has been recently written to,
but the exact contents are not available. */
diff --git a/gcc/reorg.c b/gcc/reorg.c
index dd54f93bfdf..3997c746ed8 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1246,7 +1246,7 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
{
rtx trial = XEXP (temp, 0);
- mark_set_resources (trial, &cc_set, 0, 1);
+ mark_set_resources (trial, &cc_set, 0, MARK_SRC_DEST_CALL);
if (insn_references_resource_p (XVECEXP (seq , 0, 0), &cc_set, 0))
return delay_list;
}
@@ -1498,7 +1498,7 @@ try_merge_delay_insns (insn, thread)
next_to_match = XVECEXP (PATTERN (insn), 0, slot_number);
}
- mark_set_resources (trial, &set, 0, 1);
+ mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (trial, &needed, 1);
}
@@ -1513,7 +1513,7 @@ try_merge_delay_insns (insn, thread)
rtx filled_insn = XVECEXP (pat, 0, 0);
/* Account for resources set/needed by the filled insn. */
- mark_set_resources (filled_insn, &set, 0, 1);
+ mark_set_resources (filled_insn, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (filled_insn, &needed, 1);
for (i = 1; i < XVECLEN (pat, 0); i++)
@@ -1552,7 +1552,7 @@ try_merge_delay_insns (insn, thread)
{
/* Keep track of the set/referenced resources for the delay
slots of any trial insns we encounter. */
- mark_set_resources (dtrial, &set, 0, 1);
+ mark_set_resources (dtrial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (dtrial, &needed, 1);
}
}
@@ -1687,7 +1687,7 @@ redundant_insn (insn, target, delay_list)
CLEAR_RESOURCE (&needed);
CLEAR_RESOURCE (&set);
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (insn, &needed, 1);
/* If TARGET is a SEQUENCE, get the main insn. */
@@ -2124,7 +2124,7 @@ fill_simple_delay_slots (non_jumps_p)
{
CLEAR_RESOURCE (&needed);
CLEAR_RESOURCE (&set);
- mark_set_resources (insn, &set, 0, 0);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST);
mark_referenced_resources (insn, &needed, 0);
for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, 1);
@@ -2170,7 +2170,7 @@ fill_simple_delay_slots (non_jumps_p)
}
}
- mark_set_resources (trial, &set, 0, 1);
+ mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (trial, &needed, 1);
}
}
@@ -2218,13 +2218,13 @@ fill_simple_delay_slots (non_jumps_p)
if (GET_CODE (insn) == CALL_INSN)
{
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (insn, &needed, 1);
maybe_never = 1;
}
else
{
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (insn, &needed, 1);
if (GET_CODE (insn) == JUMP_INSN)
target = JUMP_LABEL (insn);
@@ -2303,7 +2303,7 @@ fill_simple_delay_slots (non_jumps_p)
continue;
}
- mark_set_resources (trial, &set, 0, 1);
+ mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (trial, &needed, 1);
/* Ensure we don't put insns between the setting of cc and the
@@ -2467,7 +2467,7 @@ fill_simple_delay_slots (non_jumps_p)
}
}
- mark_set_resources (trial, &set, 0, 1);
+ mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (trial, &needed, 1);
}
@@ -2719,7 +2719,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
/* This insn can't go into a delay slot. */
lose = 1;
- mark_set_resources (trial, &set, 0, 1);
+ mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
mark_referenced_resources (trial, &needed, 1);
/* Ensure we don't put insns between the setting of cc and the comparison
diff --git a/gcc/resource.c b/gcc/resource.c
index 9d580867a9a..61b8b0ca48a 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -185,8 +185,9 @@ mark_referenced_resources (x, res, include_delayed_effects)
register struct resources *res;
register int include_delayed_effects;
{
- register enum rtx_code code = GET_CODE (x);
- register int i, j;
+ enum rtx_code code = GET_CODE (x);
+ int i, j;
+ unsigned int r;
register const char *format_ptr;
/* Handle leaf items for which we set resource flags. Also, special-case
@@ -206,16 +207,18 @@ mark_referenced_resources (x, res, include_delayed_effects)
mark_referenced_resources (SUBREG_REG (x), res, 0);
else
{
- int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int last_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- for (i = regno; i < last_regno; i++)
- SET_HARD_REG_BIT (res->regs, i);
+ unsigned int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
+ unsigned int last_regno
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+ for (r = regno; r < last_regno; r++)
+ SET_HARD_REG_BIT (res->regs, r);
}
return;
case REG:
- for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
- SET_HARD_REG_BIT (res->regs, REGNO (x) + i);
+ for (r = 0; r < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); r++)
+ SET_HARD_REG_BIT (res->regs, REGNO (x) + r);
return;
case MEM:
@@ -441,7 +444,8 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
underlying insn. Any registers set by the underlying insn
are live since the insn is being done somewhere else. */
if (GET_RTX_CLASS (GET_CODE (XEXP (PATTERN (insn), 0))) == 'i')
- mark_set_resources (XEXP (PATTERN (insn), 0), res, 0, 1);
+ mark_set_resources (XEXP (PATTERN (insn), 0), res, 0,
+ MARK_SRC_DEST_CALL);
/* All other USE insns are to be ignored. */
continue;
@@ -515,17 +519,18 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
= ! INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i));
target_set = set;
- mark_set_resources (insn, &target_set, 0, 1);
+ mark_set_resources (insn, &target_set, 0,
+ MARK_SRC_DEST_CALL);
for (i = 1; i < XVECLEN (PATTERN (insn), 0); i++)
INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i))
= ! INSN_FROM_TARGET_P (XVECEXP (PATTERN (insn), 0, i));
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
}
else
{
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
target_set = set;
}
@@ -563,7 +568,7 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
}
mark_referenced_resources (insn, &needed, 1);
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
COPY_HARD_REG_SET (scratch, set.regs);
AND_COMPL_HARD_REG_SET (scratch, needed.regs);
@@ -575,8 +580,8 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
/* Given X, a part of an insn, and a pointer to a `struct resource',
RES, indicate which resources are modified by the insn. If
- INCLUDE_DELAYED_EFFECTS is nonzero, also mark resources potentially
- set by the called routine.
+ MARK_TYPE is MARK_SRC_DEST_CALL, also mark resources potentially
+ set by the called routine. If MARK_TYPE is MARK_DEST, only mark SET_DESTs
If IN_DEST is nonzero, it means we are inside a SET. Otherwise,
objects are being referenced instead of set.
@@ -588,15 +593,16 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
our computation and thus may be placed in a delay slot. */
void
-mark_set_resources (x, res, in_dest, include_delayed_effects)
+mark_set_resources (x, res, in_dest, mark_type)
register rtx x;
register struct resources *res;
int in_dest;
- int include_delayed_effects;
+ enum mark_resource_type mark_type;
{
- register enum rtx_code code;
- register int i, j;
- register const char *format_ptr;
+ enum rtx_code code;
+ int i, j;
+ unsigned int r;
+ const char *format_ptr;
restart:
@@ -627,16 +633,16 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
that aren't saved across calls, global registers and anything
explicitly CLOBBERed immediately after the CALL_INSN. */
- if (include_delayed_effects)
+ if (mark_type == MARK_SRC_DEST_CALL)
{
rtx next = NEXT_INSN (x);
rtx prev = PREV_INSN (x);
rtx link;
res->cc = res->memory = 1;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (call_used_regs[i] || global_regs[i])
- SET_HARD_REG_BIT (res->regs, i);
+ for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
+ if (call_used_regs[r] || global_regs[r])
+ SET_HARD_REG_BIT (res->regs, r);
/* If X is part of a delay slot sequence, then NEXT should be
the first insn after the sequence. */
@@ -646,7 +652,8 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
for (link = CALL_INSN_FUNCTION_USAGE (x);
link; link = XEXP (link, 1))
if (GET_CODE (XEXP (link, 0)) == CLOBBER)
- mark_set_resources (SET_DEST (XEXP (link, 0)), res, 1, 0);
+ mark_set_resources (SET_DEST (XEXP (link, 0)), res, 1,
+ MARK_SRC_DEST);
/* Check for a NOTE_INSN_SETJMP. If it exists, then we must
assume that this call can clobber any register. */
@@ -664,7 +671,7 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
and doesn't actually do anything, so we ignore it. */
#ifdef INSN_SETS_ARE_DELAYED
- if (! include_delayed_effects
+ if (mark_type != MARK_SRC_DEST_CALL
&& INSN_SETS_ARE_DELAYED (x))
return;
#endif
@@ -680,36 +687,40 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
effects of the calling routine. */
mark_set_resources (SET_DEST (x), res,
- (include_delayed_effects
+ (mark_type == MARK_SRC_DEST_CALL
|| GET_CODE (SET_SRC (x)) != CALL),
- 0);
+ mark_type);
- mark_set_resources (SET_SRC (x), res, 0, 0);
+ if (mark_type != MARK_DEST)
+ mark_set_resources (SET_SRC (x), res, 0, MARK_SRC_DEST);
return;
case CLOBBER:
- mark_set_resources (XEXP (x, 0), res, 1, 0);
+ mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST);
return;
case SEQUENCE:
for (i = 0; i < XVECLEN (x, 0); i++)
if (! (INSN_ANNULLED_BRANCH_P (XVECEXP (x, 0, 0))
&& INSN_FROM_TARGET_P (XVECEXP (x, 0, i))))
- mark_set_resources (XVECEXP (x, 0, i), res, 0,
- include_delayed_effects);
+ mark_set_resources (XVECEXP (x, 0, i), res, 0, mark_type);
return;
case POST_INC:
case PRE_INC:
case POST_DEC:
case PRE_DEC:
- mark_set_resources (XEXP (x, 0), res, 1, 0);
+ mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST);
return;
+ case SIGN_EXTRACT:
case ZERO_EXTRACT:
- mark_set_resources (XEXP (x, 0), res, in_dest, 0);
- mark_set_resources (XEXP (x, 1), res, 0, 0);
- mark_set_resources (XEXP (x, 2), res, 0, 0);
+ if (! (mark_type == MARK_DEST && in_dest))
+ {
+ mark_set_resources (XEXP (x, 0), res, in_dest, MARK_SRC_DEST);
+ mark_set_resources (XEXP (x, 1), res, 0, MARK_SRC_DEST);
+ mark_set_resources (XEXP (x, 2), res, 0, MARK_SRC_DEST);
+ }
return;
case MEM:
@@ -720,31 +731,39 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
res->volatil |= MEM_VOLATILE_P (x);
}
- mark_set_resources (XEXP (x, 0), res, 0, 0);
+ mark_set_resources (XEXP (x, 0), res, 0, MARK_SRC_DEST);
return;
case SUBREG:
if (in_dest)
{
if (GET_CODE (SUBREG_REG (x)) != REG)
- mark_set_resources (SUBREG_REG (x), res,
- in_dest, include_delayed_effects);
+ mark_set_resources (SUBREG_REG (x), res, in_dest, mark_type);
else
{
- int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int last_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
- for (i = regno; i < last_regno; i++)
- SET_HARD_REG_BIT (res->regs, i);
+ unsigned int regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
+ unsigned int last_regno
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (x));
+
+ for (r = regno; r < last_regno; r++)
+ SET_HARD_REG_BIT (res->regs, r);
}
}
return;
case REG:
if (in_dest)
- for (i = 0; i < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); i++)
- SET_HARD_REG_BIT (res->regs, REGNO (x) + i);
+ for (r = 0; r < HARD_REGNO_NREGS (REGNO (x), GET_MODE (x)); r++)
+ SET_HARD_REG_BIT (res->regs, REGNO (x) + r);
return;
+ case STRICT_LOW_PART:
+ if (! (mark_type == MARK_DEST && in_dest))
+ {
+ mark_set_resources (XEXP (x, 0), res, 0, MARK_SRC_DEST);
+ return;
+ }
+
case UNSPEC_VOLATILE:
case ASM_INPUT:
/* Traditional asm's are always volatile. */
@@ -764,7 +783,8 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
traditional asms unlike their normal usage. */
for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
- mark_set_resources (ASM_OPERANDS_INPUT (x, i), res, in_dest, 0);
+ mark_set_resources (ASM_OPERANDS_INPUT (x, i), res, in_dest,
+ MARK_SRC_DEST);
return;
default:
@@ -777,13 +797,12 @@ mark_set_resources (x, res, in_dest, include_delayed_effects)
switch (*format_ptr++)
{
case 'e':
- mark_set_resources (XEXP (x, i), res, in_dest, include_delayed_effects);
+ mark_set_resources (XEXP (x, i), res, in_dest, mark_type);
break;
case 'E':
for (j = 0; j < XVECLEN (x, i); j++)
- mark_set_resources (XVECEXP (x, i, j), res, in_dest,
- include_delayed_effects);
+ mark_set_resources (XVECEXP (x, i, j), res, in_dest, mark_type);
break;
}
}
@@ -905,8 +924,8 @@ mark_target_live_regs (insns, target, res)
if (b != -1)
{
regset regs_live = BASIC_BLOCK (b)->global_live_at_start;
- int j;
- int regno;
+ unsigned int j;
+ unsigned int regno;
rtx start_insn, stop_insn;
/* Compute hard regs live at start of block -- this is the real hard regs
@@ -918,12 +937,15 @@ mark_target_live_regs (insns, target, res)
EXECUTE_IF_SET_IN_REG_SET
(regs_live, FIRST_PSEUDO_REGISTER, 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 (current_live_regs, j);
+ if (reg_renumber[i] >= 0)
+ {
+ regno = reg_renumber[i];
+ for (j = regno;
+ j < regno + HARD_REGNO_NREGS (regno,
+ PSEUDO_REGNO_MODE (i));
+ j++)
+ SET_HARD_REG_BIT (current_live_regs, j);
+ }
});
/* Get starting and ending insn, handling the case where each might
@@ -1089,7 +1111,7 @@ mark_target_live_regs (insns, target, res)
AND_COMPL_HARD_REG_SET (scratch, set.regs);
IOR_HARD_REG_SET (new_resources.regs, scratch);
- mark_set_resources (insn, &set, 0, 1);
+ mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL);
}
IOR_HARD_REG_SET (res->regs, new_resources.regs);
@@ -1169,7 +1191,8 @@ init_resource_info (epilogue_insn)
start_of_epilogue_needs = end_of_function_needs;
while ((epilogue_insn = next_nonnote_insn (epilogue_insn)))
- mark_set_resources (epilogue_insn, &end_of_function_needs, 0, 1);
+ mark_set_resources (epilogue_insn, &end_of_function_needs, 0,
+ MARK_SRC_DEST_CALL);
/* Allocate and initialize the tables used by mark_target_live_regs. */
target_hash_table = (struct target_info **)
@@ -1268,7 +1291,8 @@ find_free_register (current_insn, last_insn, class_str, mode, reg_set)
while (current_insn != last_insn)
{
/* Exclude anything set in this insn. */
- mark_set_resources (PATTERN (current_insn), &used, 0, 1);
+ mark_set_resources (PATTERN (current_insn), &used, 0,
+ MARK_SRC_DEST_CALL);
current_insn = next_nonnote_insn (current_insn);
}
diff --git a/gcc/resource.h b/gcc/resource.h
index 5c11e4c061b..718ec651341 100644
--- a/gcc/resource.h
+++ b/gcc/resource.h
@@ -33,9 +33,17 @@ struct resources
HARD_REG_SET regs; /* Which registers are set or needed. */
};
+/* The kinds of rtl mark_*_resources will consider */
+enum mark_resource_type
+{
+ MARK_SRC_DEST = 0,
+ MARK_SRC_DEST_CALL = 1,
+ MARK_DEST = 2
+};
+
extern void mark_target_live_regs PARAMS ((rtx, rtx, struct resources *));
extern void mark_set_resources PARAMS ((rtx, struct resources *, int,
- int));
+ enum mark_resource_type));
extern void mark_referenced_resources PARAMS ((rtx, struct resources *, int));
extern void clear_hashed_info_for_insn PARAMS ((rtx));
extern void incr_ticks_for_insn PARAMS ((rtx));
diff --git a/gcc/rtl.c b/gcc/rtl.c
index a8b1a9de63a..bfe3806c06d 100644
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -136,7 +136,7 @@ const enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) SIZE,
-const int mode_size[(int) MAX_MACHINE_MODE] = {
+const unsigned int mode_size[(int) MAX_MACHINE_MODE] = {
#include "machmode.def"
};
@@ -147,7 +147,7 @@ const int mode_size[(int) MAX_MACHINE_MODE] = {
#define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER) UNIT,
-const int mode_unit_size[(int) MAX_MACHINE_MODE] = {
+const unsigned int mode_unit_size[(int) MAX_MACHINE_MODE] = {
#include "machmode.def" /* machine modes are documented here */
};
@@ -188,7 +188,7 @@ const enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS] = {
/* MODE_COMPLEX_INT */ CQImode,
/* MODE_COMPLEX_FLOAT */ QCmode
};
-
+
/* Indexed by rtx code, gives a sequence of operand-types for
rtx's of that code. The sequence is a C string in which
@@ -228,34 +228,38 @@ const char * const rtx_format[] = {
that rtx code. See rtl.def for documentation on the defined classes. */
const char rtx_class[] = {
-#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
+#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) CLASS,
#include "rtl.def" /* rtl expressions are defined here */
#undef DEF_RTL_EXPR
};
/* Names for kinds of NOTEs and REG_NOTEs. */
-const char * const note_insn_name[] = { 0 , "NOTE_INSN_DELETED",
- "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
- "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
- "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
- "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
- "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
- "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
- "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
- "NOTE_REPEATED_LINE_NUMBER", "NOTE_INSN_RANGE_START",
- "NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE",
- "NOTE_INSN_BASIC_BLOCK" };
-
-const char * const reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
- "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
- "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
- "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
- "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
- "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA",
- "REG_BR_PRED", "REG_EH_CONTEXT",
- "REG_FRAME_RELATED_EXPR", "REG_EH_REGION",
- "REG_EH_RETHROW", "REG_SAVE_NOTE" };
+const char * const note_insn_name[] =
+{
+ 0, "NOTE_INSN_DELETED",
+ "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
+ "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
+ "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
+ "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
+ "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
+ "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG",
+ "NOTE_INSN_EH_REGION_BEG", "NOTE_INSN_EH_REGION_END",
+ "NOTE_REPEATED_LINE_NUMBER", "NOTE_INSN_RANGE_START",
+ "NOTE_INSN_RANGE_END", "NOTE_INSN_LIVE",
+ "NOTE_INSN_BASIC_BLOCK"
+};
+
+const char * const reg_note_name[] =
+{
+ "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_EQUAL",
+ "REG_WAS_0", "REG_RETVAL", "REG_LIBCALL", "REG_NONNEG",
+ "REG_NO_CONFLICT", "REG_UNUSED", "REG_CC_SETTER", "REG_CC_USER",
+ "REG_LABEL", "REG_DEP_ANTI", "REG_DEP_OUTPUT", "REG_BR_PROB",
+ "REG_EXEC_COUNT", "REG_NOALIAS", "REG_SAVE_AREA", "REG_BR_PRED",
+ "REG_FRAME_RELATED_EXPR", "REG_EH_CONTEXT", "REG_EH_REGION",
+ "REG_EH_RETHROW", "REG_SAVE_NOTE"
+};
static void fatal_with_file_and_line PARAMS ((FILE *, const char *, ...))
ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
@@ -271,7 +275,7 @@ rtvec_alloc (n)
int n;
{
rtvec rt;
-
+
if (ggc_p)
rt = ggc_alloc_rtvec (n);
else
@@ -311,7 +315,7 @@ rtx_alloc (code)
/* This function is called more than any other in GCC, so we
manipulate the obstack directly.
-
+
Even though rtx objects are word aligned, we may be sharing
an obstack with tree nodes, which may have to be double-word
aligned. So align our length to the alignment mask in the
@@ -451,7 +455,7 @@ copy_rtx (orig)
case '0':
/* These are left unchanged. */
break;
-
+
default:
abort ();
}
@@ -498,7 +502,7 @@ copy_most_rtx (orig, may_share)
copy->volatil = orig->volatil;
copy->unchanging = orig->unchanging;
copy->integrated = orig->integrated;
-
+
format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
@@ -609,22 +613,32 @@ rtx_equal_p (x, y)
if (GET_MODE (x) != GET_MODE (y))
return 0;
- /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
-
- if (code == REG)
- /* Until rtl generation is complete, don't consider a reference to the
- return register of the current function the same as the return from a
- called function. This eases the job of function integration. Once the
- distinction is no longer needed, they can be considered equivalent. */
- return (REGNO (x) == REGNO (y)
- && (! rtx_equal_function_value_matters
- || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
- else if (code == LABEL_REF)
- return XEXP (x, 0) == XEXP (y, 0);
- else if (code == SYMBOL_REF)
- return XSTR (x, 0) == XSTR (y, 0);
- else if (code == SCRATCH || code == CONST_DOUBLE)
- return 0;
+ /* Some RTL can be compared nonrecursively. */
+ switch (code)
+ {
+ case REG:
+ /* Until rtl generation is complete, don't consider a reference to the
+ return register of the current function the same as the return from a
+ called function. This eases the job of function integration. Once the
+ distinction is no longer needed, they can be considered equivalent. */
+ return (REGNO (x) == REGNO (y)
+ && (! rtx_equal_function_value_matters
+ || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
+
+ case LABEL_REF:
+ return XEXP (x, 0) == XEXP (y, 0);
+
+ case SYMBOL_REF:
+ return XSTR (x, 0) == XSTR (y, 0);
+
+ case SCRATCH:
+ case CONST_DOUBLE:
+ case CONST_INT:
+ return 0;
+
+ default:
+ break;
+ }
/* Compare the elements. If any pair of corresponding elements
fail to match, return 0 for the whole things. */
@@ -771,7 +785,7 @@ read_skip_spaces (infile)
break;
case ';':
- do
+ do
c = getc (infile);
while (c != '\n' && c != EOF);
read_rtx_lineno++;
@@ -783,7 +797,7 @@ read_skip_spaces (infile)
c = getc (infile);
if (c != '*')
fatal_expected_char (infile, '*', c);
-
+
prevc = 0;
while ((c = getc (infile)) && c != EOF)
{
@@ -977,7 +991,7 @@ read_rtx (infile)
break;
}
/* Now process the vector. */
-
+
case 'E':
{
register struct rtx_list *next_rtx, *rtx_list_link;
@@ -1088,7 +1102,7 @@ read_rtx (infile)
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
tmp_wide = atol (tmp_char);
#else
- /* Prefer atoll over atoq, since the former is in the ISO C9X draft.
+ /* Prefer atoll over atoq, since the former is in the ISO C9X draft.
But prefer not to use our hand-rolled function above either. */
#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
tmp_wide = atoll (tmp_char);
diff --git a/gcc/rtl.def b/gcc/rtl.def
index 570abdc1a97..69c14e0c1b7 100644
--- a/gcc/rtl.def
+++ b/gcc/rtl.def
@@ -900,6 +900,13 @@ DEF_RTL_EXPR(CALL_PLACEHOLDER, "call_placeholder", "uuuu", 'x')
of canonical RTL. It is, however, easier to manipulate this way. */
DEF_RTL_EXPR(PHI, "phi", "E", 'x')
+/* Conditionally execute code.
+ Operand 0 is the condition that if true, the code is executed.
+ Operand 1 is the code to be executed (typically a SET).
+
+ Semantics are that there are no side effects if the condition
+ is false. */
+DEF_RTL_EXPR(COND_EXEC, "cond_exec", "ee", 'x')
/*
Local variables:
diff --git a/gcc/rtl.h b/gcc/rtl.h
index fc344cef75b..124c6bf3d92 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -87,6 +87,7 @@ typedef union rtunion_def
{
HOST_WIDE_INT rtwint;
int rtint;
+ unsigned int rtuint;
const char *rtstr;
struct rtx_def *rtx;
struct rtvec_def *rtvec;
@@ -148,7 +149,7 @@ typedef struct rtx_def
0 if the MEM was a variable or the result of a * operator in C;
1 if it was the result of a . or -> operator (on a struct) in C.
1 in a REG if the register is used only in exit code a loop.
- 1 in a SUBREG expression if was generated from a variable with a
+ 1 in a SUBREG expression if was generated from a variable with a
promoted mode.
1 in a CODE_LABEL if the label is used for nonlocal gotos
and must not be deleted even if its count is zero.
@@ -162,7 +163,7 @@ typedef struct rtx_def
unsigned int in_struct : 1;
/* 1 if this rtx is used. This is used for copying shared structure.
See `unshare_all_rtl'.
- In a REG, this is not needed for that purpose, and used instead
+ In a REG, this is not needed for that purpose, and used instead
in `leaf_renumber_regs_insn'.
In a SYMBOL_REF, means that emit_library_call
has used it as the function. */
@@ -173,7 +174,7 @@ typedef struct rtx_def
unsigned integrated : 1;
/* 1 in an INSN or a SET if this rtx is related to the call frame,
either changing how we compute the frame address or saving and
- restoring registers in the prologue and epilogue.
+ restoring registers in the prologue and epilogue.
1 in a MEM if the MEM refers to a scalar, rather than a member of
an aggregate. */
unsigned frame_related : 1;
@@ -338,6 +339,7 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
#define XCWINT(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtwint)
#define XCINT(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtint)
+#define XCUINT(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtuint)
#define XCSTR(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtstr)
#define XCEXP(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtx)
#define XCVEC(RTX, N, C) (RTL_CHECKC1(RTX, N, C).rtvec)
@@ -355,6 +357,9 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
/* ACCESS MACROS for particular fields of insns. */
+/* Determines whether X is an insn. */
+#define INSN_P(X) (GET_RTX_CLASS (GET_CODE(X)) == 'i')
+
/* Holds a unique number for each insn.
These are not necessarily sequentially increasing. */
#define INSN_UID(INSN) XINT(INSN, 0)
@@ -396,101 +401,141 @@ extern void rtvec_check_failed_bounds PARAMS ((rtvec, int,
clear, the insn should be executed only if the branch is not taken. */
#define INSN_FROM_TARGET_P(INSN) ((INSN)->in_struct)
+#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4)
+
+#define CSELIB_VAL_PTR(RTX) X0CSELIB(RTX, 0)
+
/* Holds a list of notes on what this insn does to various REGs.
- It is a chain of EXPR_LIST rtx's, where the second operand
- is the chain pointer and the first operand is the REG being described.
+ It is a chain of EXPR_LIST rtx's, where the second operand is the
+ chain pointer and the first operand is the REG being described.
The mode field of the EXPR_LIST contains not a real machine mode
- but a value that says what this note says about the REG:
- REG_DEAD means that the value in REG dies in this insn (i.e., it is
- not needed past this insn). If REG is set in this insn, the REG_DEAD
- note may, but need not, be omitted.
- REG_INC means that the REG is autoincremented or autodecremented.
- REG_EQUIV describes the insn as a whole; it says that the insn
- sets a register to a constant value or to be equivalent to a memory
- address. If the register is spilled to the stack then the constant
- value should be substituted for it. The contents of the REG_EQUIV
- is the constant value or memory address, which may be different
- from the source of the SET although it has the same value. A
- REG_EQUIV note may also appear on an insn which copies a register
- parameter to a pseudo-register, if there is a memory address which
- could be used to hold that pseudo-register throughout the function.
- REG_EQUAL is like REG_EQUIV except that the destination
- is only momentarily equal to the specified rtx. Therefore, it
- cannot be used for substitution; but it can be used for cse.
- REG_RETVAL means that this insn copies the return-value of
- a library call out of the hard reg for return values. This note
- is actually an INSN_LIST and it points to the first insn involved
- in setting up arguments for the call. flow.c uses this to delete
- the entire library call when its result is dead.
- REG_LIBCALL is the inverse of REG_RETVAL: it goes on the first insn
- of the library call and points at the one that has the REG_RETVAL.
- REG_WAS_0 says that the register set in this insn held 0 before the insn.
- The contents of the note is the insn that stored the 0.
- If that insn is deleted or patched to a NOTE, the REG_WAS_0 is inoperative.
- The REG_WAS_0 note is actually an INSN_LIST, not an EXPR_LIST.
- REG_NONNEG means that the register is always nonnegative during
- the containing loop. This is used in branches so that decrement and
- branch instructions terminating on zero can be matched. There must be
- an insn pattern in the md file named `decrement_and_branch_until_zero'
- or else this will never be added to any instructions.
- REG_NO_CONFLICT means there is no conflict *after this insn*
- between the register in the note and the destination of this insn.
- REG_UNUSED identifies a register set in this insn and never used.
- REG_CC_SETTER and REG_CC_USER link a pair of insns that set and use
- CC0, respectively. Normally, these are required to be consecutive insns,
- but we permit putting a cc0-setting insn in the delay slot of a branch
- as long as only one copy of the insn exists. In that case, these notes
- point from one to the other to allow code generation to determine what
- any require information and to properly update CC_STATUS.
- REG_LABEL points to a CODE_LABEL. Used by non-JUMP_INSNs to
- say that the CODE_LABEL contained in the REG_LABEL note is used
- by the insn.
- REG_DEP_ANTI is used in LOG_LINKS which represent anti (write after read)
- dependencies. REG_DEP_OUTPUT is used in LOG_LINKS which represent output
- (write after write) dependencies. Data dependencies, which are the only
- type of LOG_LINK created by flow, are represented by a 0 reg note kind. */
-/* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs when the flag
- -fbranch-probabilities is given. It has an integer value. For jumps,
- it is the probability that this is a taken branch. For calls, it is the
- probability that this call won't return.
- REG_EXEC_COUNT is attached to the first insn of each basic block, and
- the first insn after each CALL_INSN. It indicates how many times this
- block was executed.
- REG_SAVE_AREA is used to optimize rtl generated by dynamic stack
- allocations for targets where SETJMP_VIA_SAVE_AREA is true.
- REG_BR_PRED is attached to JUMP_INSNs only, it holds the branch prediction
- flags computed by get_jump_flags() after dbr scheduling is complete.
- REG_FRAME_RELATED_EXPR is attached to insns that are RTX_FRAME_RELATED_P,
- but are too complex for DWARF to interpret what they imply. The attached
- rtx is used instead of intuition.
- REG_EH_REGION is used to indicate what exception region an INSN
- belongs in. This can be used to indicate what region a call may throw
- to. a REGION of 0 indicates that a call cannot throw at all.
- a REGION of -1 indicates that it cannot throw, nor will it execute
- a non-local goto.
- REG_EH_RETHROW is used to indicate that a call is actually a
- call to rethrow, and specifies the rethrow symbol for the region
- the rethrow is targetting. This provides a way to generate the
- non standard flow edges required for a rethrow.
- REG_SAVE_NOTE is used by haifa-sched to save NOTE_INSN notes
- across scheduling. */
+ but a value from enum reg_note. */
#define REG_NOTES(INSN) XEXP(INSN, 6)
-#define ADDR_DIFF_VEC_FLAGS(RTX) X0ADVFLAGS(RTX, 4)
-
-#define CSELIB_VAL_PTR(RTX) X0CSELIB(RTX, 0)
-
/* Don't forget to change reg_note_name in rtl.c. */
-enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4,
- REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7,
- REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10,
- REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13,
- REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15, REG_BR_PROB = 16,
- REG_EXEC_COUNT = 17, REG_NOALIAS = 18, REG_SAVE_AREA = 19,
- REG_BR_PRED = 20, REG_EH_CONTEXT = 21,
- REG_FRAME_RELATED_EXPR = 22, REG_EH_REGION = 23,
- REG_EH_RETHROW = 24, REG_SAVE_NOTE = 25 };
+enum reg_note
+{
+ /* The value in REG dies in this insn (i.e., it is not needed past
+ this insn). If REG is set in this insn, the REG_DEAD note may,
+ but need not, be omitted. */
+ REG_DEAD = 1,
+
+ /* The REG is autoincremented or autodecremented. */
+ REG_INC,
+
+ /* Describes the insn as a whole; it says that the insn sets a register
+ to a constant value or to be equivalent to a memory address. If the
+ register is spilled to the stack then the constant value should be
+ substituted for it. The contents of the REG_EQUIV is the constant
+ value or memory address, which may be different from the source of
+ the SET although it has the same value. A REG_EQUIV note may also
+ appear on an insn which copies a register parameter to a pseudo-register,
+ if there is a memory address which could be used to hold that
+ pseudo-register throughout the function. */
+ REG_EQUIV,
+
+ /* Like REG_EQUIV except that the destination is only momentarily equal
+ to the specified rtx. Therefore, it cannot be used for substitution;
+ but it can be used for cse. */
+ REG_EQUAL,
+
+ /* The register set in this insn held 0 before the insn. The contents of
+ the note is the insn that stored the 0. If that insn is deleted or
+ patched to a NOTE, the REG_WAS_0 is inoperative. The REG_WAS_0 note
+ is actually an INSN_LIST, not an EXPR_LIST. */
+ REG_WAS_0,
+
+ /* This insn copies the return-value of a library call out of the hard reg
+ for return values. This note is actually an INSN_LIST and it points to
+ the first insn involved in setting up arguments for the call. flow.c
+ uses this to delete the entire library call when its result is dead. */
+ REG_RETVAL,
+
+ /* The inverse of REG_RETVAL: it goes on the first insn of the library call
+ and points at the one that has the REG_RETVAL. */
+ REG_LIBCALL,
+
+ /* The register is always nonnegative during the containing loop. This is
+ used in branches so that decrement and branch instructions terminating
+ on zero can be matched. There must be an insn pattern in the md file
+ named `decrement_and_branch_until_zero' or else this will never be added
+ to any instructions. */
+ REG_NONNEG,
+
+ /* There is no conflict *after this insn* between the register in the note
+ and the destination of this insn. */
+ REG_NO_CONFLICT,
+
+ /* Identifies a register set in this insn and never used. */
+ REG_UNUSED,
+
+ /* REG_CC_SETTER and REG_CC_USER link a pair of insns that set and use CC0,
+ respectively. Normally, these are required to be consecutive insns, but
+ we permit putting a cc0-setting insn in the delay slot of a branch as
+ long as only one copy of the insn exists. In that case, these notes
+ point from one to the other to allow code generation to determine what
+ any require information and to properly update CC_STATUS. */
+ REG_CC_SETTER, REG_CC_USER,
+
+ /* Points to a CODE_LABEL. Used by non-JUMP_INSNs to say that the
+ CODE_LABEL contained in the REG_LABEL note is used by the insn. */
+ REG_LABEL,
+
+ /* REG_DEP_ANTI and REG_DEP_OUTPUT are used in LOG_LINKS to represent
+ write-after-read and write-after-write dependencies respectively.
+ Data dependencies, which are the only type of LOG_LINK created by
+ flow, are represented by a 0 reg note kind. */
+ REG_DEP_ANTI, REG_DEP_OUTPUT,
+
+ /* REG_BR_PROB is attached to JUMP_INSNs and CALL_INSNs when the flag
+ -fbranch-probabilities is given. It has an integer value. For jumps,
+ it is the probability that this is a taken branch. For calls, it is
+ the probability that this call won't return. */
+ REG_BR_PROB,
+
+ /* REG_EXEC_COUNT is attached to the first insn of each basic block, and
+ the first insn after each CALL_INSN. It indicates how many times this
+ block was executed. */
+ REG_EXEC_COUNT,
+
+ /* Attached to a call insn; indicates that the call is malloc-like and
+ that the pointer returned cannot alias anything else. */
+ REG_NOALIAS,
+
+ /* Used to optimize rtl generated by dynamic stack allocations for targets
+ where SETJMP_VIA_SAVE_AREA is true. */
+ REG_SAVE_AREA,
+
+ /* Attached to JUMP_INSNs only, it holds the branch prediction flags
+ computed by get_jump_flags() after dbr scheduling is complete. */
+ REG_BR_PRED,
+
+ /* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
+ for DWARF to interpret what they imply. The attached rtx is used
+ instead of intuition. */
+ REG_FRAME_RELATED_EXPR,
+
+ /* Indicates that REG holds the exception context for the function.
+ This context is shared by inline functions, so the code to acquire
+ the real exception context is delayed until after inlining. */
+ REG_EH_CONTEXT,
+
+ /* Indicates what exception region an INSN belongs in. This is used to
+ indicate what region to which a call may throw. REGION 0 indicates
+ that a call cannot throw at all. REGION -1 indicates that it cannot
+ throw, nor will it execute a non-local goto. */
+ REG_EH_REGION,
+
+ /* Indicates that a call is actually a call to rethrow, and specifies the
+ rethrow symbol for the region the rethrow is targetting. This provides
+ a way to generate the non standard flow edges required for a rethrow. */
+ REG_EH_RETHROW,
+
+ /* Used by haifa-sched to save NOTE_INSN notes across scheduling. */
+ REG_SAVE_NOTE
+};
+
/* The base value for branch probability notes. */
#define REG_BR_PROB_BASE 10000
@@ -613,7 +658,7 @@ extern const char * const note_insn_name[];
#define LABEL_ALTERNATE_NAME(RTX) XCSTR(RTX, 7, CODE_LABEL)
/* The original regno this ADDRESSOF was built for. */
-#define ADDRESSOF_REGNO(RTX) XCINT(RTX, 1, ADDRESSOF)
+#define ADDRESSOF_REGNO(RTX) XCUINT(RTX, 1, ADDRESSOF)
/* The variable in the register we took the address of. */
#define ADDRESSOF_DECL(RTX) XCTREE(RTX, 2, ADDRESSOF)
@@ -642,7 +687,7 @@ extern const char * const note_insn_name[];
/* For a REG rtx, REGNO extracts the register number. */
-#define REGNO(RTX) XCINT(RTX, 0, REG)
+#define REGNO(RTX) XCUINT(RTX, 0, REG)
/* For a REG rtx, REG_FUNCTION_VALUE_P is nonzero if the reg
is the current function's return value. */
@@ -660,12 +705,12 @@ extern const char * const note_insn_name[];
SUBREG_WORD extracts the word-number. */
#define SUBREG_REG(RTX) XCEXP(RTX, 0, SUBREG)
-#define SUBREG_WORD(RTX) XCINT(RTX, 1, SUBREG)
+#define SUBREG_WORD(RTX) XCUINT(RTX, 1, SUBREG)
/* 1 if the REG contained in SUBREG_REG is already known to be
sign- or zero-extended from the mode of the SUBREG to the mode of
the reg. SUBREG_PROMOTED_UNSIGNED_P gives the signedness of the
- extension.
+ extension.
When used as a LHS, is means that this extension must be done
when assigning to SUBREG_REG. */
@@ -762,6 +807,12 @@ extern const char * const note_insn_name[];
#define TRAP_CONDITION(RTX) XCEXP(RTX, 0, TRAP_IF)
#define TRAP_CODE(RTX) XCEXP(RTX, 1, TRAP_IF)
+/* For a COND_EXEC rtx, COND_EXEC_TEST is the condition to base
+ conditionally executing the code on, COND_EXEC_CODE is the code
+ to execute if the condition is true. */
+#define COND_EXEC_TEST(RTX) XCEXP(RTX, 0, COND_EXEC)
+#define COND_EXEC_CODE(RTX) XCEXP(RTX, 1, COND_EXEC)
+
/* 1 in a SYMBOL_REF if it addresses this function's constants pool. */
#define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging)
@@ -939,6 +990,12 @@ extern const char * const note_insn_name[];
/* For a NOTE_INSN_LIVE note, the original basic block number. */
#define RANGE_LIVE_ORIG_BLOCK(INSN) (XINT (INSN, 1))
+
+/* Determine if the insn is a PHI node. */
+#define PHI_NODE_P(X) \
+ (X && GET_CODE (X) == INSN \
+ && GET_CODE (PATTERN (X)) == SET \
+ && GET_CODE (SET_SRC (PATTERN (X))) == PHI)
/* Nonzero if we need to distinguish between the return value of this function
and the return value of a function called by this function. This helps
@@ -999,8 +1056,10 @@ extern rtx gen_lowpart_if_possible PARAMS ((enum machine_mode, rtx));
extern rtx gen_highpart PARAMS ((enum machine_mode, rtx));
extern rtx gen_realpart PARAMS ((enum machine_mode, rtx));
extern rtx gen_imagpart PARAMS ((enum machine_mode, rtx));
-extern rtx operand_subword PARAMS ((rtx, int, int, enum machine_mode));
-extern rtx operand_subword_force PARAMS ((rtx, int, enum machine_mode));
+extern rtx operand_subword PARAMS ((rtx, unsigned int, int,
+ enum machine_mode));
+extern rtx operand_subword_force PARAMS ((rtx, unsigned int,
+ enum machine_mode));
extern int subreg_lowpart_p PARAMS ((rtx));
extern rtx make_safe_from PARAMS ((rtx, rtx));
extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx));
@@ -1101,8 +1160,10 @@ extern rtx gen_bge PARAMS ((rtx));
extern rtx gen_ble PARAMS ((rtx));
extern rtx gen_mem_addressof PARAMS ((rtx, union tree_node *));
extern rtx eliminate_constant_term PARAMS ((rtx, rtx *));
-extern rtx expand_complex_abs PARAMS ((enum machine_mode, rtx, rtx, int));
-extern enum machine_mode choose_hard_reg_mode PARAMS ((int, int));
+extern rtx expand_complex_abs PARAMS ((enum machine_mode, rtx, rtx,
+ int));
+extern enum machine_mode choose_hard_reg_mode PARAMS ((unsigned int,
+ unsigned int));
extern void set_unique_reg_note PARAMS ((rtx, enum reg_note, rtx));
/* Functions in rtlanal.c */
@@ -1126,16 +1187,21 @@ extern int reg_set_p PARAMS ((rtx, rtx));
extern rtx single_set PARAMS ((rtx));
extern int multiple_sets PARAMS ((rtx));
extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int));
-extern int refers_to_regno_p PARAMS ((int, int, rtx, rtx *));
+extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int,
+ rtx, rtx *));
extern int reg_overlap_mentioned_p PARAMS ((rtx, rtx));
-extern void note_stores PARAMS ((rtx, void (*)(rtx, rtx, void *), void *));
+extern void note_stores PARAMS ((rtx,
+ void (*) (rtx, rtx, void *),
+ void *));
extern rtx reg_set_last PARAMS ((rtx, rtx));
extern int dead_or_set_p PARAMS ((rtx, rtx));
-extern int dead_or_set_regno_p PARAMS ((rtx, int));
+extern int dead_or_set_regno_p PARAMS ((rtx, unsigned int));
extern rtx find_reg_note PARAMS ((rtx, enum reg_note, rtx));
-extern rtx find_regno_note PARAMS ((rtx, enum reg_note, int));
+extern rtx find_regno_note PARAMS ((rtx, enum reg_note,
+ unsigned int));
extern int find_reg_fusage PARAMS ((rtx, enum rtx_code, rtx));
-extern int find_regno_fusage PARAMS ((rtx, enum rtx_code, int));
+extern int find_regno_fusage PARAMS ((rtx, enum rtx_code,
+ unsigned int));
extern void remove_note PARAMS ((rtx, rtx));
extern int side_effects_p PARAMS ((rtx));
extern int volatile_refs_p PARAMS ((rtx));
@@ -1143,11 +1209,12 @@ extern int volatile_insn_p PARAMS ((rtx));
extern int may_trap_p PARAMS ((rtx));
extern int inequality_comparisons_p PARAMS ((rtx));
extern rtx replace_rtx PARAMS ((rtx, rtx, rtx));
-extern rtx replace_regs PARAMS ((rtx, rtx *, int, int));
+extern rtx replace_regs PARAMS ((rtx, rtx *, unsigned int,
+ int));
extern int computed_jump_p PARAMS ((rtx));
typedef int (*rtx_function) PARAMS ((rtx *, void *));
extern int for_each_rtx PARAMS ((rtx *, rtx_function, void *));
-extern rtx regno_use_in PARAMS ((int, rtx));
+extern rtx regno_use_in PARAMS ((unsigned int, rtx));
extern int auto_inc_p PARAMS ((rtx));
extern void remove_node_from_expr_list PARAMS ((rtx, rtx *));
extern int insns_safe_to_move_p PARAMS ((rtx, rtx, rtx *));
@@ -1199,7 +1266,7 @@ extern rtx const_true_rtx;
extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE];
-/* Returns a constant 0 rtx in mode MODE. Integer modes are treated the
+/* Returns a constant 0 rtx in mode MODE. Integer modes are treated the
same as VOIDmode. */
#define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)])
@@ -1339,7 +1406,7 @@ extern rtx gen_rtx_MEM PARAMS ((enum machine_mode, rtx));
/* This points to the Canonical Frame Address of the function. This
should corrospond to the CFA produced by INCOMING_FRAME_SP_OFFSET,
but is calculated relative to the arg pointer for simplicity; the
- frame pointer nor stack pointer are necessarily fixed relative to
+ frame pointer nor stack pointer are necessarily fixed relative to
the CFA until after reload. */
#define virtual_cfa_rtx (global_rtl[GR_VIRTUAL_CFA])
@@ -1486,9 +1553,9 @@ extern void remove_unncessary_notes PARAMS ((void));
extern void add_clobbers PARAMS ((rtx, int));
/* In combine.c */
-extern int combine_instructions PARAMS ((rtx, int));
-extern int extended_count PARAMS ((rtx, enum machine_mode, int));
-extern rtx remove_death PARAMS ((int, rtx));
+extern int combine_instructions PARAMS ((rtx, unsigned int));
+extern unsigned int extended_count PARAMS ((rtx, enum machine_mode, int));
+extern rtx remove_death PARAMS ((unsigned int, rtx));
#ifdef BUFSIZ
extern void dump_combine_stats PARAMS ((FILE *));
extern void dump_combine_total_stats PARAMS ((FILE *));
@@ -1503,6 +1570,7 @@ extern void fix_sched_param PARAMS ((const char *, const char *));
/* In print-rtl.c */
extern void debug_rtx PARAMS ((rtx));
extern void debug_rtx_list PARAMS ((rtx, int));
+extern void debug_rtx_range PARAMS ((rtx, rtx));
extern rtx debug_rtx_find PARAMS ((rtx, int));
#ifdef BUFSIZ
extern void print_rtl PARAMS ((FILE *, rtx));
@@ -1585,8 +1653,8 @@ extern void init_reg_sets PARAMS ((void));
extern void regset_release_memory PARAMS ((void));
extern void regclass_init PARAMS ((void));
extern void regclass PARAMS ((rtx, int, FILE *));
-extern void reg_scan PARAMS ((rtx, int, int));
-extern void reg_scan_update PARAMS ((rtx, rtx, int));
+extern void reg_scan PARAMS ((rtx, unsigned int, int));
+extern void reg_scan_update PARAMS ((rtx, rtx, unsigned int));
extern void fix_register PARAMS ((const char *, int, int));
extern void delete_null_pointer_checks PARAMS ((rtx));
@@ -1709,6 +1777,7 @@ extern void fancy_abort PARAMS ((const char *, int, const char *))
#endif
/* In alias.c */
+extern rtx canon_rtx PARAMS ((rtx));
extern int true_dependence PARAMS ((rtx, enum machine_mode, rtx,
int (*)(rtx)));
extern int read_dependence PARAMS ((rtx, rtx));
@@ -1740,9 +1809,18 @@ extern int stack_regs_mentioned PARAMS ((rtx insn));
/* In ssa.c */
extern void convert_to_ssa PARAMS ((void));
extern void convert_from_ssa PARAMS ((void));
+typedef int (*successor_phi_fn) PARAMS ((rtx, int, int, void *));
+extern int for_each_successor_phi PARAMS ((int bb,
+ successor_phi_fn,
+ void *));
+extern int in_ssa_form;
/* In toplev.c */
extern rtx stack_limit_rtx;
+/* In regrename.c */
+
+extern void regrename_optimize PARAMS ((void));
+
#endif /* _RTL_H */
diff --git a/gcc/rtl.texi b/gcc/rtl.texi
index 06fe3836e6b..55208ae6263 100644
--- a/gcc/rtl.texi
+++ b/gcc/rtl.texi
@@ -1,4 +1,4 @@
-@c Copyright (C) 1988, 89, 92, 94, 97, 1998, 1999 Free Software Foundation, Inc.
+@c Copyright (C) 1988, 89, 92, 94, 97, 1998, 1999, 2000 Free Software Foundation, Inc.
@c This is part of the GCC manual.
@c For copying conditions, see the file gcc.texi.
@@ -2917,9 +2917,7 @@ referring to it.
@cindex @code{const_int}, RTL sharing
@item
-There is only one @code{const_int} expression with value 0, only
-one with value 1, and only one with value @minus{}1.
-Some other integer values are also stored uniquely.
+All @code{const_int} expressions with equal values are shared.
@cindex @code{pc}, RTL sharing
@item
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index b10a3bf3438..d9087cd51f9 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -429,6 +429,11 @@ reg_referenced_p (x, body)
return 1;
return 0;
+ case COND_EXEC:
+ if (reg_overlap_mentioned_p (x, COND_EXEC_TEST (body)))
+ return 1;
+ return reg_referenced_p (x, COND_EXEC_CODE (body));
+
default:
return 0;
}
@@ -824,13 +829,14 @@ find_last_value (x, pinsn, valid_to, allow_hwreg)
int
refers_to_regno_p (regno, endregno, x, loc)
- int regno, endregno;
+ unsigned int regno, endregno;
rtx x;
rtx *loc;
{
- register int i;
- register RTX_CODE code;
- register const char *fmt;
+ int i;
+ unsigned int x_regno;
+ RTX_CODE code;
+ const char *fmt;
repeat:
/* The contents of a REG_NONNEG note is always zero, so we must come here
@@ -843,22 +849,22 @@ refers_to_regno_p (regno, endregno, x, loc)
switch (code)
{
case REG:
- i = REGNO (x);
+ x_regno = REGNO (x);
/* If we modifying the stack, frame, or argument pointer, it will
clobber a virtual register. In fact, we could be more precise,
but it isn't worth it. */
- if ((i == STACK_POINTER_REGNUM
+ if ((x_regno == STACK_POINTER_REGNUM
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- || i == ARG_POINTER_REGNUM
+ || x_regno == ARG_POINTER_REGNUM
#endif
- || i == FRAME_POINTER_REGNUM)
+ || x_regno == FRAME_POINTER_REGNUM)
&& regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
return 1;
- return (endregno > i
- && regno < i + (i < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (i, GET_MODE (x))
+ return (endregno > x_regno
+ && regno < x_regno + (x_regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (x_regno, GET_MODE (x))
: 1));
case SUBREG:
@@ -867,8 +873,8 @@ refers_to_regno_p (regno, endregno, x, loc)
if (GET_CODE (SUBREG_REG (x)) == REG
&& REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
{
- int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
- int inner_endregno
+ unsigned int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
+ unsigned int inner_endregno
= inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
@@ -939,7 +945,7 @@ int
reg_overlap_mentioned_p (x, in)
rtx x, in;
{
- int regno, endregno;
+ unsigned int regno, endregno;
/* Overly conservative. */
if (GET_CODE (x) == STRICT_LOW_PART)
@@ -948,59 +954,68 @@ reg_overlap_mentioned_p (x, in)
/* If either argument is a constant, then modifying X can not affect IN. */
if (CONSTANT_P (x) || CONSTANT_P (in))
return 0;
- else if (GET_CODE (x) == SUBREG)
+
+ switch (GET_CODE (x))
{
+ case SUBREG:
regno = REGNO (SUBREG_REG (x));
if (regno < FIRST_PSEUDO_REGISTER)
regno += SUBREG_WORD (x);
- }
- else if (GET_CODE (x) == REG)
- regno = REGNO (x);
- else if (GET_CODE (x) == MEM)
- {
- const char *fmt;
- int i;
+ goto do_reg;
- if (GET_CODE (in) == MEM)
- return 1;
+ case REG:
+ regno = REGNO (x);
+ do_reg:
+ endregno = regno + (regno < FIRST_PSEUDO_REGISTER
+ ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ return refers_to_regno_p (regno, endregno, in, NULL_PTR);
- fmt = GET_RTX_FORMAT (GET_CODE (in));
+ case MEM:
+ {
+ const char *fmt;
+ int i;
- for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
- if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
+ if (GET_CODE (in) == MEM)
return 1;
- return 0;
- }
- else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
- || GET_CODE (x) == CC0)
- return reg_mentioned_p (x, in);
- else if (GET_CODE (x) == PARALLEL
- && GET_MODE (x) == BLKmode)
- {
- register int i;
+ fmt = GET_RTX_FORMAT (GET_CODE (in));
+ for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
+ if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
+ return 1;
- /* If any register in here refers to it
- we return true. */
- for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
- if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
- return 1;
- return 0;
- }
- else
- abort ();
+ return 0;
+ }
+
+ case SCRATCH:
+ case PC:
+ case CC0:
+ return reg_mentioned_p (x, in);
+
+ case PARALLEL:
+ if (GET_MODE (x) == BLKmode)
+ {
+ register int i;
+
+ /* If any register in here refers to it we return true. */
+ for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
+ if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
+ return 1;
+ return 0;
+ }
+ break;
- endregno = regno + (regno < FIRST_PSEUDO_REGISTER
- ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
+ default:
+ break;
+ }
- return refers_to_regno_p (regno, endregno, in, NULL_PTR);
+ abort ();
}
/* Used for communications between the next few functions. */
static int reg_set_last_unknown;
static rtx reg_set_last_value;
-static int reg_set_last_first_regno, reg_set_last_last_regno;
+static unsigned int reg_set_last_first_regno, reg_set_last_last_regno;
/* Called via note_stores from reg_set_last. */
@@ -1010,7 +1025,7 @@ reg_set_last_1 (x, pat, data)
rtx pat;
void *data ATTRIBUTE_UNUSED;
{
- int first, last;
+ unsigned int first, last;
/* If X is not a register, or is not one in the range we care
about, ignore. */
@@ -1107,7 +1122,9 @@ note_stores (x, fun, data)
void (*fun) PARAMS ((rtx, rtx, void *));
void *data;
{
- if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
+ if (GET_CODE (x) == COND_EXEC)
+ x = COND_EXEC_CODE (x);
+ if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
{
register rtx dest = SET_DEST (x);
while ((GET_CODE (dest) == SUBREG
@@ -1134,6 +1151,8 @@ note_stores (x, fun, data)
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
{
register rtx y = XVECEXP (x, 0, i);
+ if (GET_CODE (y) == COND_EXEC)
+ y = COND_EXEC_CODE (y);
if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
{
register rtx dest = SET_DEST (y);
@@ -1149,6 +1168,7 @@ note_stores (x, fun, data)
&& GET_MODE (dest) == BLKmode)
{
register int i;
+
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
(*fun) (SET_DEST (XVECEXP (dest, 0, i)), y, data);
}
@@ -1181,8 +1201,8 @@ dead_or_set_p (insn, x)
rtx insn;
rtx x;
{
- register int regno, last_regno;
- register int i;
+ unsigned int regno, last_regno;
+ unsigned int i;
/* Can't use cc0_rtx below since this file is used by genattrtab.c. */
if (GET_CODE (x) == CC0)
@@ -1208,10 +1228,10 @@ dead_or_set_p (insn, x)
int
dead_or_set_regno_p (insn, test_regno)
rtx insn;
- int test_regno;
+ unsigned int test_regno;
{
- int regno, endregno;
- rtx link;
+ unsigned int regno, endregno;
+ rtx link, pattern;
/* See if there is a death note for something that includes
TEST_REGNO. */
@@ -1234,7 +1254,12 @@ dead_or_set_regno_p (insn, test_regno)
&& find_regno_fusage (insn, CLOBBER, test_regno))
return 1;
- if (GET_CODE (PATTERN (insn)) == SET)
+ pattern = PATTERN (insn);
+
+ if (GET_CODE (pattern) == COND_EXEC)
+ pattern = COND_EXEC_CODE (pattern);
+
+ if (GET_CODE (pattern) == SET)
{
rtx dest = SET_DEST (PATTERN (insn));
@@ -1257,13 +1282,16 @@ dead_or_set_regno_p (insn, test_regno)
return (test_regno >= regno && test_regno < endregno);
}
- else if (GET_CODE (PATTERN (insn)) == PARALLEL)
+ else if (GET_CODE (pattern) == PARALLEL)
{
register int i;
- for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
+ for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
{
- rtx body = XVECEXP (PATTERN (insn), 0, i);
+ rtx body = XVECEXP (pattern, 0, i);
+
+ if (GET_CODE (body) == COND_EXEC)
+ body = COND_EXEC_CODE (body);
if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
{
@@ -1323,7 +1351,7 @@ rtx
find_regno_note (insn, kind, regno)
rtx insn;
enum reg_note kind;
- int regno;
+ unsigned int regno;
{
register rtx link;
@@ -1376,15 +1404,16 @@ find_reg_fusage (insn, code, datum)
}
else
{
- register int regno = REGNO (datum);
+ unsigned int regno = REGNO (datum);
/* CALL_INSN_FUNCTION_USAGE information cannot contain references
to pseudo registers, so don't bother checking. */
if (regno < FIRST_PSEUDO_REGISTER)
{
- int end_regno = regno + HARD_REGNO_NREGS (regno, GET_MODE (datum));
- int i;
+ unsigned int end_regno
+ = regno + HARD_REGNO_NREGS (regno, GET_MODE (datum));
+ unsigned int i;
for (i = regno; i < end_regno; i++)
if (find_regno_fusage (insn, code, i))
@@ -1402,7 +1431,7 @@ int
find_regno_fusage (insn, code, regno)
rtx insn;
enum rtx_code code;
- int regno;
+ unsigned int regno;
{
register rtx link;
@@ -1415,8 +1444,8 @@ find_regno_fusage (insn, code, regno)
for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
{
- register int regnote;
- register rtx op, reg;
+ unsigned int regnote;
+ rtx op, reg;
if (GET_CODE (op = XEXP (link, 0)) == code
&& GET_CODE (reg = XEXP (op, 0)) == REG
@@ -1889,7 +1918,7 @@ rtx
replace_regs (x, reg_map, nregs, replace_dest)
rtx x;
rtx *reg_map;
- int nregs;
+ unsigned int nregs;
int replace_dest;
{
register enum rtx_code code;
@@ -2165,7 +2194,7 @@ for_each_rtx (x, f, data)
rtx
regno_use_in (regno, x)
- int regno;
+ unsigned int regno;
rtx x;
{
register const char *fmt;
diff --git a/gcc/sdbout.c b/gcc/sdbout.c
index 557ecf0deb3..6433c67a2a1 100644
--- a/gcc/sdbout.c
+++ b/gcc/sdbout.c
@@ -1358,7 +1358,6 @@ sdbout_parms (parms)
current_sym_value = 0;
if (GET_CODE (DECL_RTL (parms)) == REG
- && REGNO (DECL_RTL (parms)) >= 0
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
type = DECL_ARG_TYPE (parms);
else
@@ -1406,8 +1405,7 @@ sdbout_parms (parms)
pretend the parm was passed there. It would be more consistent
to describe the register where the parm was passed,
but in practice that register usually holds something else. */
- if (REGNO (DECL_RTL (parms)) >= 0
- && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
+ if (REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
best_rtl = DECL_RTL (parms);
/* If the parm lives nowhere,
use the register where it was passed. */
@@ -1469,7 +1467,6 @@ sdbout_reg_parms (parms)
/* Report parms that live in registers during the function
but were passed in memory. */
if (GET_CODE (DECL_RTL (parms)) == REG
- && REGNO (DECL_RTL (parms)) >= 0
&& REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
&& PARM_PASSED_IN_MEMORY (parms))
{
diff --git a/gcc/sibcall.c b/gcc/sibcall.c
index 1a3a310388d..34cf5a93348 100644
--- a/gcc/sibcall.c
+++ b/gcc/sibcall.c
@@ -53,10 +53,12 @@ identify_call_return_value (cp, p_hard_return, p_soft_return)
{
rtx insn, set, hard, soft;
- /* Search forward through the "normal" call sequence to the CALL insn. */
insn = XEXP (cp, 0);
- while (GET_CODE (insn) != CALL_INSN)
+ /* Search backward through the "normal" call sequence to the CALL insn. */
+ while (NEXT_INSN (insn))
insn = NEXT_INSN (insn);
+ while (GET_CODE (insn) != CALL_INSN)
+ insn = PREV_INSN (insn);
/* Assume the pattern is (set (dest) (call ...)), or that the first
member of a parallel is. This is the hard return register used
@@ -75,6 +77,11 @@ identify_call_return_value (cp, p_hard_return, p_soft_return)
if (GET_CODE (hard) != REG)
return 0;
+ /* Stack adjustment done after call may appear here. */
+ insn = skip_stack_adjustment (insn);
+ if (! insn)
+ return 0;
+
/* If there's nothing after, there's no soft return value. */
insn = NEXT_INSN (insn);
if (! insn)
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 08abf699757..9e2674304ba 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -149,7 +149,7 @@ simplify_unary_operation (code, mode, op, op_mode)
rtx op;
enum machine_mode op_mode;
{
- register int width = GET_MODE_BITSIZE (mode);
+ unsigned int width = GET_MODE_BITSIZE (mode);
/* The order of these tests is critical so that, for example, we don't
check the wrong mode (input vs. output) for a conversion operation,
@@ -550,7 +550,7 @@ simplify_binary_operation (code, mode, op0, op1)
{
register HOST_WIDE_INT arg0, arg1, arg0s, arg1s;
HOST_WIDE_INT val;
- int width = GET_MODE_BITSIZE (mode);
+ unsigned int width = GET_MODE_BITSIZE (mode);
rtx tem;
/* Relational operations don't work here. We must know the mode
@@ -1975,16 +1975,20 @@ static int discard_useless_locs PARAMS ((void **, void *));
static int discard_useless_values PARAMS ((void **, void *));
static void remove_useless_values PARAMS ((void));
static unsigned int hash_rtx PARAMS ((rtx, enum machine_mode, int));
-static cselib_val *new_cselib_val PARAMS ((unsigned int, enum machine_mode));
-static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *, rtx));
+static cselib_val *new_cselib_val PARAMS ((unsigned int,
+ enum machine_mode));
+static void add_mem_for_addr PARAMS ((cselib_val *, cselib_val *,
+ rtx));
static cselib_val *cselib_lookup_mem PARAMS ((rtx, int));
static rtx cselib_subst_to_values PARAMS ((rtx));
-static void cselib_invalidate_regno PARAMS ((int, enum machine_mode));
+static void cselib_invalidate_regno PARAMS ((unsigned int,
+ enum machine_mode));
static int cselib_mem_conflict_p PARAMS ((rtx, rtx));
static int cselib_invalidate_mem_1 PARAMS ((void **, void *));
static void cselib_invalidate_mem PARAMS ((rtx));
static void cselib_invalidate_rtx PARAMS ((rtx, rtx, void *));
-static void cselib_record_set PARAMS ((rtx, cselib_val *, cselib_val *));
+static void cselib_record_set PARAMS ((rtx, cselib_val *,
+ cselib_val *));
static void cselib_record_sets PARAMS ((rtx));
/* There are three ways in which cselib can look up an rtx:
@@ -2137,7 +2141,7 @@ entry_and_rtx_equal_p (entry, x_arg)
const void *entry, *x_arg;
{
struct elt_loc_list *l;
- cselib_val *v = (cselib_val *)entry;
+ const cselib_val *v = (const cselib_val *)entry;
rtx x = (rtx)x_arg;
/* We don't guarantee that distinct rtx's have different hash values,
@@ -2155,7 +2159,7 @@ static unsigned int
get_value_hash (entry)
const void *entry;
{
- cselib_val *v = (cselib_val *) entry;
+ const cselib_val *v = (const cselib_val *) entry;
return v->value;
}
@@ -2539,7 +2543,7 @@ hash_rtx (x, mode, create)
}
else if (fmt[i] == 's')
{
- unsigned char *p = (unsigned char *) XSTR (x, i);
+ const unsigned char *p = (const unsigned char *) XSTR (x, i);
if (p)
while (*p)
hash += *p++;
@@ -2779,13 +2783,14 @@ cselib_lookup (x, mode, create)
is used to determine how many hard registers are being changed. If MODE
is VOIDmode, then only REGNO is being changed; this is used when
invalidating call clobbered registers across a call. */
+
static void
cselib_invalidate_regno (regno, mode)
- int regno;
+ unsigned int regno;
enum machine_mode mode;
{
- int endregno;
- int i;
+ unsigned int endregno;
+ unsigned int i;
/* If we see pseudos after reload, something is _wrong_. */
if (reload_completed && regno >= FIRST_PSEUDO_REGISTER
@@ -2810,15 +2815,17 @@ cselib_invalidate_regno (regno, mode)
{
cselib_val *v = (*l)->elt;
struct elt_loc_list **p;
- int this_last = i;
+ unsigned int this_last = i;
if (i < FIRST_PSEUDO_REGISTER)
this_last += HARD_REGNO_NREGS (i, GET_MODE (v->u.val_rtx)) - 1;
+
if (this_last < regno)
{
l = &(*l)->next;
continue;
}
+
/* We have an overlap. */
unchain_one_elt_list (l);
@@ -2827,6 +2834,7 @@ cselib_invalidate_regno (regno, mode)
for (p = &v->locs; ; p = &(*p)->next)
{
rtx x = (*p)->loc;
+
if (GET_CODE (x) == REG && REGNO (x) == i)
{
unchain_one_elt_loc_list (p);
@@ -2986,12 +2994,13 @@ cselib_invalidate_rtx (dest, ignore, data)
/* Record the result of a SET instruction. DEST is being set; the source
contains the value described by SRC_ELT. If DEST is a MEM, DEST_ADDR_ELT
describes its address. */
+
static void
cselib_record_set (dest, src_elt, dest_addr_elt)
rtx dest;
cselib_val *src_elt, *dest_addr_elt;
{
- int dreg = GET_CODE (dest) == REG ? REGNO (dest) : -1;
+ int dreg = GET_CODE (dest) == REG ? (int) REGNO (dest) : -1;
if (src_elt == 0 || side_effects_p (dest))
return;
diff --git a/gcc/ssa.c b/gcc/ssa.c
index 8a36bbd9226..af7b6ad6eb1 100644
--- a/gcc/ssa.c
+++ b/gcc/ssa.c
@@ -1,22 +1,22 @@
/* Static Single Assignment conversion routines for the GNU compiler.
Copyright (C) 2000 Free Software Foundation, Inc.
- This file is part of GNU CC.
+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 free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free 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.
+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. */
+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. */
/* References:
@@ -48,6 +48,13 @@
/* TODO:
+ Handle subregs better, maybe. For now, if a reg that's set in a
+ subreg expression is duplicated going into SSA form, an extra copy
+ is inserted first that copies the entire reg into the duplicate, so
+ that the other bits are preserved. This isn't strictly SSA, since
+ at least part of the reg is assigned in more than one place (though
+ they are adjacent).
+
??? What to do about strict_low_part. Probably I'll have to split
them out of their current instructions first thing.
@@ -55,9 +62,18 @@
in which the RTL encodes exactly what we want, without exposing a
lot of niggling processor details. At some later point we lower
the representation, calling back into optabs to finish any necessary
- expansion.
-*/
+ expansion. */
+
+
+/* If conservative_reg_partition is non-zero, use a conservative
+ register partitioning algorithm (which leaves more regs after
+ emerging from SSA) instead of the coalescing one. This is being
+ left in for a limited time only, as a debugging tool until the
+ coalescing algorithm is validated. */
+static int conservative_reg_partition;
+/* This flag is set when the CFG is in SSA form. */
+int in_ssa_form = 0;
/* Element I is the single instruction that sets register I+PSEUDO. */
varray_type ssa_definition;
@@ -73,7 +89,7 @@ varray_type ssa_rename_from;
static rtx *ssa_rename_to;
/* The number of registers that were live on entry to the SSA routines. */
-static int ssa_max_reg_num;
+static unsigned int ssa_max_reg_num;
/* Local function prototypes. */
@@ -115,25 +131,40 @@ static void ephi_create
PARAMS ((int t, sbitmap visited, sbitmap *pred, sbitmap *succ, rtx *nodes));
static void eliminate_phi
PARAMS ((edge e, partition reg_partition));
-
static int make_regs_equivalent_over_bad_edges
PARAMS ((int bb, partition reg_partition));
+
+/* These are used only in the conservative register partitioning
+ algorithms. */
static int make_equivalent_phi_alternatives_equivalent
PARAMS ((int bb, partition reg_partition));
static partition compute_conservative_reg_partition
+ PARAMS ((void));
+static int rename_equivalent_regs_in_insn
+ PARAMS ((rtx *ptr, void *data));
+
+/* These are used in the register coalescing algorithm. */
+static int coalesce_if_unconflicting
+ PARAMS ((partition p, conflict_graph conflicts, int reg1, int reg2));
+static int coalesce_regs_in_copies
+ PARAMS ((int bb, partition p, conflict_graph conflicts));
+static int coalesce_reg_in_phi
+ PARAMS ((rtx, int dest_regno, int src_regno, void *data));
+static int coalesce_regs_in_successor_phi_nodes
+ PARAMS ((int bb, partition p, conflict_graph conflicts));
+static partition compute_coalesced_reg_partition
PARAMS (());
+static int mark_reg_in_phi
+ PARAMS ((rtx *ptr, void *data));
+static void mark_phi_and_copy_regs
+ PARAMS ((regset phi_set));
+
static int rename_equivalent_regs_in_insn
PARAMS ((rtx *ptr, void *data));
static void rename_equivalent_regs
PARAMS ((partition reg_partition));
-/* Determine if the insn is a PHI node. */
-#define PHI_NODE_P(X) \
- (X && GET_CODE (X) == INSN \
- && GET_CODE (PATTERN (X)) == SET \
- && GET_CODE (SET_SRC (PATTERN (X))) == PHI)
-
/* Given the SET of a PHI node, return the address of the alternative
for predecessor block C. */
@@ -494,6 +525,15 @@ struct rename_set_data
rtx set_dest;
rtx new_reg;
rtx prev_reg;
+ rtx set_insn;
+};
+
+/* This struct is used to pass information to callback functions while
+ renaming registers. */
+struct rename_context
+{
+ struct rename_set_data *set_data;
+ rtx current_insn;
};
static void new_registers_for_updates
@@ -518,7 +558,8 @@ rename_insn_1 (ptr, data)
void *data;
{
rtx x = *ptr;
- struct rename_set_data **set_datap = data;
+ struct rename_context *context = data;
+ struct rename_set_data **set_datap = &(context->set_data);
if (x == NULL_RTX)
return 0;
@@ -551,6 +592,7 @@ rename_insn_1 (ptr, data)
r->reg_loc = destp;
r->set_dest = SET_DEST (x);
+ r->set_insn = context->current_insn;
r->next = *set_datap;
*set_datap = r;
@@ -577,7 +619,6 @@ rename_insn_1 (ptr, data)
if (GET_MODE (x) != GET_MODE (new_reg))
abort ();
*ptr = new_reg;
- /* ??? Mark for a new ssa_uses entry. */
}
/* Else this is a use before a set. Warn? */
}
@@ -663,12 +704,15 @@ rename_block (bb, idom)
insn = next;
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
- struct rename_set_data *old_set_data = set_data;
+ struct rename_context context;
+ context.set_data = set_data;
+ context.current_insn = insn;
- for_each_rtx (&PATTERN (insn), rename_insn_1, &set_data);
- for_each_rtx (&REG_NOTES (insn), rename_insn_1, &set_data);
+ for_each_rtx (&PATTERN (insn), rename_insn_1, &context);
+ for_each_rtx (&REG_NOTES (insn), rename_insn_1, &context);
- new_registers_for_updates (set_data, old_set_data, insn);
+ new_registers_for_updates (context.set_data, set_data, insn);
+ set_data = context.set_data;
}
next = NEXT_INSN (insn);
@@ -689,7 +733,7 @@ rename_block (bb, idom)
while (PHI_NODE_P (insn))
{
rtx phi = PATTERN (insn);
- int regno;
+ unsigned int regno;
rtx reg;
/* Find out which of our outgoing registers this node is
@@ -741,9 +785,23 @@ rename_block (bb, idom)
while (set_data)
{
struct rename_set_data *next;
- rtx old_reg;
+ rtx old_reg = *set_data->reg_loc;
+
+ /* If the set is of a subreg only, copy the entire reg first so
+ that unmodified bits are preserved. Of course, we don't
+ strictly have SSA any more, but that's the best we can do
+ without a lot of hard work. */
+
+ if (GET_CODE (set_data->set_dest) == SUBREG)
+ {
+ if (old_reg != set_data->new_reg)
+ {
+ rtx copy = gen_rtx_SET (GET_MODE (old_reg),
+ set_data->new_reg, old_reg);
+ emit_insn_before (copy, set_data->set_insn);
+ }
+ }
- old_reg = *set_data->reg_loc;
*set_data->reg_loc = set_data->new_reg;
ssa_rename_to[REGNO (old_reg)-FIRST_PSEUDO_REGISTER]
= set_data->prev_reg;
@@ -793,11 +851,14 @@ convert_to_ssa()
int nregs;
- find_basic_blocks (get_insns (), max_reg_num(), NULL);
- /* The dominator algorithms assume all blocks are reachable, clean
- up first. */
- cleanup_cfg (get_insns ());
- life_analysis (get_insns (), max_reg_num (), NULL, 1);
+ /* Don't do it twice. */
+ if (in_ssa_form)
+ abort ();
+
+ /* Don't eliminate dead code here. The CFG we computed above must
+ remain unchanged until we are finished emerging from SSA form --
+ the phi node representation depends on it. */
+ life_analysis (get_insns (), max_reg_num (), NULL, 0);
/* Compute dominators. */
dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
@@ -862,38 +923,11 @@ convert_to_ssa()
sbitmap_vector_free (dfs);
sbitmap_vector_free (evals);
sbitmap_vector_free (idfs);
-}
-
-
-/* This is intended to be the FIND of a UNION/FIND algorithm managing
- the partitioning of the pseudos. Glancing through the rest of the
- global optimizations, it seems things will work out best if the
- partition is set up just before convert_from_ssa is called. See
- section 11.4 of Morgan.
-
- ??? Morgan's algorithm, perhaps with some care, may allow copy
- propagation to happen concurrently with the conversion from SSA.
-
- However, it presents potential problems with critical edges -- to
- split or not to split. He mentions beginning the partitioning by
- unioning registers associated by a PHI across abnormal critical
- edges. This is the approache taken here. It is unclear to me how
- we are able to do that arbitrarily, though.
-
- Alternately, Briggs presents an algorithm in which critical edges
- need not be split, at the expense of the creation of new pseudos,
- and the need for some concurrent register renaming. Moreover, it
- is ameanable for modification such that the instructions can be
- placed anywhere in the target block, which solves the before-call
- placement problem. However, I don't immediately see how we could
- do that concurrently with copy propoagation.
-
- More study is required. */
+ in_ssa_form = 1;
+ reg_scan (get_insns (), max_reg_num (), 1);
+}
-/*
- * Eliminate the PHI across the edge from C to B.
- */
/* REG is the representative temporary of its partition. Add it to the
set of nodes to be processed, if it hasn't been already. Return the
@@ -1086,10 +1120,11 @@ eliminate_phi (e, reg_partition)
if (GET_CODE (reg) != REG || GET_CODE (tgt) != REG)
abort();
+ reg = regno_reg_rtx[partition_find (reg_partition, REGNO (reg))];
+ tgt = regno_reg_rtx[partition_find (reg_partition, REGNO (tgt))];
/* If the two registers are already in the same partition,
nothing will need to be done. */
- if (partition_find (reg_partition, REGNO (reg))
- != partition_find (reg_partition, REGNO (tgt)))
+ if (reg != tgt)
{
int ireg, itgt;
@@ -1305,7 +1340,6 @@ make_equivalent_phi_alternatives_equivalent (bb, reg_partition)
return changed;
}
-
/* Compute a conservative partition of outstanding pseudo registers.
See Morgan 7.3.1. */
@@ -1341,6 +1375,322 @@ compute_conservative_reg_partition ()
return p;
}
+/* The following functions compute a register partition that attempts
+ to eliminate as many reg copies and phi node copies as possible by
+ coalescing registers. This is the strategy:
+
+ 1. As in the conservative case, the top priority is to coalesce
+ registers that otherwise would cause copies to be placed on
+ abnormal critical edges (which isn't possible).
+
+ 2. Figure out which regs are involved (in the LHS or RHS) of
+ copies and phi nodes. Compute conflicts among these regs.
+
+ 3. Walk around the instruction stream, placing two regs in the
+ same class of the partition if one appears on the LHS and the
+ other on the RHS of a copy or phi node and the two regs don't
+ conflict. The conflict information of course needs to be
+ updated.
+
+ 4. If anything has changed, there may be new opportunities to
+ coalesce regs, so go back to 2.
+*/
+
+/* If REG1 and REG2 don't conflict in CONFLICTS, place them in the
+ same class of partition P, if they aren't already. Update
+ CONFLICTS appropriately.
+
+ Returns one if REG1 and REG2 were placed in the same class but were
+ not previously; zero otherwise.
+
+ See Morgan figure 11.15. */
+
+static int
+coalesce_if_unconflicting (p, conflicts, reg1, reg2)
+ partition p;
+ conflict_graph conflicts;
+ int reg1;
+ int reg2;
+{
+ int reg;
+
+ /* Don't mess with hard regs. */
+ if (reg1 < FIRST_PSEUDO_REGISTER || reg2 < FIRST_PSEUDO_REGISTER)
+ return 0;
+
+ /* Find the canonical regs for the classes containing REG1 and
+ REG2. */
+ reg1 = partition_find (p, reg1);
+ reg2 = partition_find (p, reg2);
+
+ /* If they're already in the same class, there's nothing to do. */
+ if (reg1 == reg2)
+ return 0;
+
+ /* If the regs conflict, our hands are tied. */
+ if (conflict_graph_conflict_p (conflicts, reg1, reg2))
+ return 0;
+
+ /* We're good to go. Put the regs in the same partition. */
+ partition_union (p, reg1, reg2);
+
+ /* Find the new canonical reg for the merged class. */
+ reg = partition_find (p, reg1);
+
+ /* Merge conflicts from the two previous classes. */
+ conflict_graph_merge_regs (conflicts, reg, reg1);
+ conflict_graph_merge_regs (conflicts, reg, reg2);
+
+ return 1;
+}
+
+/* For each register copy insn in basic block BB, place the LHS and
+ RHS regs in the same class in partition P if they do not conflict
+ according to CONFLICTS.
+
+ Returns the number of changes that were made to P.
+
+ See Morgan figure 11.14. */
+
+static int
+coalesce_regs_in_copies (bb, p, conflicts)
+ int bb;
+ partition p;
+ conflict_graph conflicts;
+{
+ int changed = 0;
+ rtx insn;
+ rtx end = BLOCK_END (bb);
+
+ /* Scan the instruction stream of the block. */
+ for (insn = BLOCK_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
+ {
+ rtx pattern;
+ rtx src;
+ rtx dest;
+
+ /* If this isn't a set insn, go to the next insn. */
+ if (GET_CODE (insn) != INSN)
+ continue;
+ pattern = PATTERN (insn);
+ if (GET_CODE (pattern) != SET)
+ continue;
+
+ src = SET_SRC (pattern);
+ dest = SET_DEST (pattern);
+
+ /* If src or dest are subregs, find the underlying reg. */
+ while (GET_CODE (src) == SUBREG
+ && SUBREG_WORD (src) != 0)
+ src = SUBREG_REG (src);
+ while (GET_CODE (dest) == SUBREG
+ && SUBREG_WORD (dest) != 0)
+ dest = SUBREG_REG (dest);
+
+ /* We're only looking for copies. */
+ if (GET_CODE (src) != REG || GET_CODE (dest) != REG)
+ continue;
+
+ /* Coalesce only if the reg modes are the same. As long as
+ each reg's rtx is unique, it can have only one mode, so two
+ pseudos of different modes can't be coalesced into one.
+
+ FIXME: We can probably get around this by inserting SUBREGs
+ where appropriate, but for now we don't bother. */
+ if (GET_MODE (src) != GET_MODE (dest))
+ continue;
+
+ /* Found a copy; see if we can use the same reg for both the
+ source and destination (and thus eliminate the copy,
+ ultimately). */
+ changed += coalesce_if_unconflicting (p, conflicts,
+ REGNO (src), REGNO (dest));
+ }
+
+ return changed;
+}
+
+
+struct phi_coalesce_context
+{
+ partition p;
+ conflict_graph conflicts;
+ int changed;
+};
+
+/* Callback function for for_each_successor_phi. If the set
+ destination and the phi alternative regs do not conflict, place
+ them in the same paritition class. DATA is a pointer to a
+ phi_coalesce_context struct. */
+
+static int
+coalesce_reg_in_phi (insn, dest_regno, src_regno, data)
+ rtx insn ATTRIBUTE_UNUSED;
+ int dest_regno;
+ int src_regno;
+ void *data;
+{
+ struct phi_coalesce_context *context =
+ (struct phi_coalesce_context *) data;
+
+ /* Attempt to use the same reg, if they don't conflict. */
+ context->changed
+ += coalesce_if_unconflicting (context->p, context->conflicts,
+ dest_regno, src_regno);
+ return 0;
+}
+
+/* For each alternative in a phi function corresponding to basic block
+ BB (in phi nodes in successor block to BB), place the reg in the
+ phi alternative and the reg to which the phi value is set into the
+ same class in partition P, if allowed by CONFLICTS.
+
+ Return the number of changes that were made to P.
+
+ See Morgan figure 11.14. */
+
+static int
+coalesce_regs_in_successor_phi_nodes (bb, p, conflicts)
+ int bb;
+ partition p;
+ conflict_graph conflicts;
+{
+ struct phi_coalesce_context context;
+ context.p = p;
+ context.conflicts = conflicts;
+ context.changed = 0;
+
+ for_each_successor_phi (bb, &coalesce_reg_in_phi, &context);
+
+ return context.changed;
+}
+
+/* Compute and return a partition of pseudos. Where possible,
+ non-conflicting pseudos are placed in the same class.
+
+ The caller is responsible for deallocating the returned partition. */
+
+static partition
+compute_coalesced_reg_partition ()
+{
+ int bb;
+ int changed = 0;
+
+ /* We don't actually work with hard registers, but it's easier to
+ carry them around anyway rather than constantly doing register
+ number arithmetic. */
+ partition p =
+ partition_new (ssa_definition->num_elements + FIRST_PSEUDO_REGISTER);
+
+ /* The first priority is to make sure registers that might have to
+ be copied on abnormal critical edges are placed in the same
+ partition. This saves us from having to split abnormal critical
+ edges (which can't be done). */
+ for (bb = n_basic_blocks; --bb >= 0; )
+ make_regs_equivalent_over_bad_edges (bb, p);
+
+ do
+ {
+ regset_head phi_set;
+ conflict_graph conflicts;
+
+ changed = 0;
+
+ /* Build the set of registers involved in phi nodes, either as
+ arguments to the phi function or as the target of a set. */
+ INITIALIZE_REG_SET (phi_set);
+ mark_phi_and_copy_regs (&phi_set);
+
+ /* Compute conflicts. */
+ conflicts = conflict_graph_compute (&phi_set, p);
+
+ /* FIXME: Better would be to process most frequently executed
+ blocks first, so that most frequently executed copies would
+ be more likely to be removed by register coalescing. But any
+ order will generate correct, if non-optimal, results. */
+ for (bb = n_basic_blocks; --bb >= 0; )
+ {
+ changed += coalesce_regs_in_copies (bb, p, conflicts);
+ changed += coalesce_regs_in_successor_phi_nodes (bb, p, conflicts);
+ }
+
+ conflict_graph_delete (conflicts);
+ }
+ while (changed > 0);
+
+ return p;
+}
+
+/* Mark the regs in a phi node. PTR is a phi expression or one of its
+ components (a REG or a CONST_INT). DATA is a reg set in which to
+ set all regs. Called from for_each_rtx. */
+
+static int
+mark_reg_in_phi (ptr, data)
+ rtx *ptr;
+ void *data;
+{
+ rtx expr = *ptr;
+ regset set = (regset) data;
+
+ switch (GET_CODE (expr))
+ {
+ case REG:
+ SET_REGNO_REG_SET (set, REGNO (expr));
+ /* Fall through. */
+ case CONST_INT:
+ case PHI:
+ return 0;
+ default:
+ abort ();
+ }
+}
+
+/* Mark in PHI_SET all pseudos that are used in a phi node -- either
+ set from a phi expression, or used as an argument in one. Also
+ mark regs that are the source or target of a reg copy. Uses
+ ssa_definition. */
+
+static void
+mark_phi_and_copy_regs (phi_set)
+ regset phi_set;
+{
+ int reg;
+
+ /* Scan the definitions of all regs. */
+ for (reg = VARRAY_SIZE (ssa_definition);
+ --reg >= FIRST_PSEUDO_REGISTER;
+ )
+ {
+ rtx insn = VARRAY_RTX (ssa_definition, reg);
+ rtx pattern;
+ rtx src;
+
+ if (insn == NULL)
+ continue;
+ pattern = PATTERN (insn);
+ /* Sometimes we get PARALLEL insns. These aren't phi nodes or
+ copies. */
+ if (GET_CODE (pattern) != SET)
+ continue;
+ src = SET_SRC (pattern);
+
+ if (GET_CODE (src) == REG)
+ {
+ /* It's a reg copy. */
+ SET_REGNO_REG_SET (phi_set, reg);
+ SET_REGNO_REG_SET (phi_set, REGNO (src));
+ }
+ else if (GET_CODE (src) == PHI)
+ {
+ /* It's a phi node. Mark the reg being set. */
+ SET_REGNO_REG_SET (phi_set, reg);
+ /* Mark the regs used in the phi function. */
+ for_each_rtx (&src, mark_reg_in_phi, phi_set);
+ }
+ /* ... else nothing to do. */
+ }
+}
/* Rename regs in insn PTR that are equivalent. DATA is the register
partition which specifies equivalences. */
@@ -1379,7 +1729,7 @@ rename_equivalent_regs_in_insn (ptr, data)
int regno = REGNO (dest);
int new_regno = partition_find (reg_partition, regno);
if (regno != new_regno)
- *destp = regno_reg_rtx [new_regno];
+ *destp = regno_reg_rtx[new_regno];
for_each_rtx (&SET_SRC (x),
rename_equivalent_regs_in_insn,
@@ -1418,7 +1768,6 @@ rename_equivalent_regs_in_insn (ptr, data)
}
}
-
/* Rename regs that are equivalent in REG_PARTITION. */
static void
@@ -1453,7 +1802,6 @@ rename_equivalent_regs (reg_partition)
}
}
-
/* The main entry point for moving from SSA. */
void
@@ -1461,8 +1809,18 @@ convert_from_ssa()
{
int bb;
partition reg_partition;
-
- reg_partition = compute_conservative_reg_partition ();
+ rtx insns = get_insns ();
+
+ /* We need up-to-date life information. */
+ life_analysis (insns, max_reg_num (), NULL, 0);
+
+ /* Figure out which regs in copies and phi nodes don't conflict and
+ therefore can be coalesced. */
+ if (conservative_reg_partition)
+ reg_partition = compute_conservative_reg_partition ();
+ else
+ reg_partition = compute_coalesced_reg_partition ();
+
rename_equivalent_regs (reg_partition);
/* Eliminate the PHI nodes. */
@@ -1488,6 +1846,11 @@ convert_from_ssa()
insn = next_nonnote_insn (insn);
while (PHI_NODE_P (insn))
{
+ /* If a phi node is the last insn in the block, there must
+ have been nothing else. Set the block end to the block
+ head. */
+ if (insn == BLOCK_END (bb))
+ BLOCK_END (bb) = BLOCK_HEAD (bb);
insn = delete_insn (insn);
if (GET_CODE (insn) == NOTE)
insn = next_nonnote_insn (insn);
@@ -1499,5 +1862,80 @@ convert_from_ssa()
/* Commit all the copy nodes needed to convert out of SSA form. */
commit_edge_insertions ();
+ in_ssa_form = 0;
+
count_or_remove_death_notes (NULL, 1);
}
+
+/* Scan phi nodes in successors to BB. For each such phi node that
+ has a phi alternative value corresponding to BB, invoke FN. FN
+ is passed the entire phi node insn, the regno of the set
+ destination, the regno of the phi argument corresponding to BB,
+ and DATA.
+
+ If FN ever returns non-zero, stops immediately and returns this
+ value. Otherwise, returns zero. */
+
+int
+for_each_successor_phi (bb, fn, data)
+ int bb;
+ successor_phi_fn fn;
+ void *data;
+{
+ basic_block block;
+ edge e;
+
+ if (bb == EXIT_BLOCK)
+ return 0;
+ else if (bb == ENTRY_BLOCK)
+ block = ENTRY_BLOCK_PTR;
+ else
+ block = BASIC_BLOCK (bb);
+
+ /* Scan outgoing edges. */
+ for (e = block->succ; e != NULL; e = e->succ_next)
+ {
+ rtx insn;
+
+ basic_block successor = e->dest;
+ if (successor->index == ENTRY_BLOCK
+ || successor->index == EXIT_BLOCK)
+ continue;
+
+ /* Advance to the first non-label insn of the successor block. */
+ insn = successor->head;
+ while (insn != NULL
+ && (GET_CODE (insn) == CODE_LABEL
+ || GET_CODE (insn) == NOTE))
+ insn = NEXT_INSN (insn);
+
+ if (insn == NULL)
+ continue;
+
+ /* Scan phi nodes in the successor. */
+ for ( ; PHI_NODE_P (insn); insn = NEXT_INSN (insn))
+ {
+ int result;
+ rtx phi_set = PATTERN (insn);
+ rtx *alternative = phi_alternative (phi_set, block->index);
+ rtx phi_src;
+
+ /* This phi function may not have an alternative
+ corresponding to the incoming edge, indicating the
+ assigned variable is not defined along the edge. */
+ if (alternative == NULL)
+ continue;
+ phi_src = *alternative;
+
+ /* Invoke the callback. */
+ result = (*fn) (insn, REGNO (SET_DEST (phi_set)),
+ REGNO (phi_src), data);
+
+ /* Terminate if requested. */
+ if (result != 0)
+ return result;
+ }
+ }
+
+ return 0;
+}
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 7aa29e7eb89..8516e368964 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -539,6 +539,7 @@ mark_goto_fixup (g)
{
while (g)
{
+ ggc_mark (g);
ggc_mark_rtx (g->before_jump);
ggc_mark_tree (g->target);
ggc_mark_tree (g->context);
@@ -1002,7 +1003,7 @@ expand_fixup (tree_label, rtl_label, last_insn)
{
/* Ok, a fixup is needed. Add a fixup to the list of such. */
struct goto_fixup *fixup
- = (struct goto_fixup *) oballoc (sizeof (struct goto_fixup));
+ = (struct goto_fixup *) ggc_alloc_obj (sizeof (struct goto_fixup), 0);
/* In case an old stack level is restored, make sure that comes
after any pending stack adjust. */
/* ?? If the fixup isn't to come at the present position,
@@ -2618,7 +2619,10 @@ expand_exit_loop_if_false (whichloop, cond)
int
stmt_loop_nest_empty ()
{
- return (loop_stack == NULL);
+ /* cfun->stmt can be NULL if we are building a call to get the
+ EH context for a setjmp/longjmp EH target and the current
+ function was a deferred inline function. */
+ return (cfun->stmt == NULL || loop_stack == NULL);
}
/* Return non-zero if we should preserve sub-expressions as separate
@@ -2722,7 +2726,7 @@ expand_value_return (val)
#endif
if (GET_CODE (return_reg) == PARALLEL)
emit_group_load (return_reg, val, int_size_in_bytes (type),
- TYPE_ALIGN (type) / BITS_PER_UNIT);
+ TYPE_ALIGN (type));
else
emit_move_insn (return_reg, val);
}
@@ -2872,7 +2876,14 @@ expand_return (retval)
}
/* Attempt to optimize the call if it is tail recursive. */
- if (optimize_tail_recursion (retval_rhs, last_insn))
+ if (flag_optimize_sibling_calls
+ && retval_rhs != NULL_TREE
+ && frame_offset == 0
+ && TREE_CODE (retval_rhs) == CALL_EXPR
+ && TREE_CODE (TREE_OPERAND (retval_rhs, 0)) == ADDR_EXPR
+ && (TREE_OPERAND (TREE_OPERAND (retval_rhs, 0), 0)
+ == current_function_decl)
+ && optimize_tail_recursion (TREE_OPERAND (retval_rhs, 1), last_insn))
return;
#ifdef HAVE_return
@@ -2952,12 +2963,14 @@ expand_return (retval)
&& TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
&& GET_CODE (result_rtl) == REG)
{
- int i, bitpos, xbitpos;
- int big_endian_correction = 0;
- int bytes = int_size_in_bytes (TREE_TYPE (retval_rhs));
+ int i;
+ unsigned HOST_WIDE_INT bitpos, xbitpos;
+ unsigned HOST_WIDE_INT big_endian_correction = 0;
+ unsigned HOST_WIDE_INT bytes
+ = int_size_in_bytes (TREE_TYPE (retval_rhs));
int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
- int bitsize = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)),
- (unsigned int)BITS_PER_WORD);
+ unsigned int bitsize
+ = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)), BITS_PER_WORD);
rtx *result_pseudos = (rtx *) alloca (sizeof (rtx) * n_regs);
rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
rtx result_val = expand_expr (retval_rhs, NULL_RTX, VOIDmode, 0);
@@ -3002,11 +3015,9 @@ expand_return (retval)
store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
extract_bit_field (src, bitsize,
bitpos % BITS_PER_WORD, 1,
- NULL_RTX, word_mode,
- word_mode,
- bitsize / BITS_PER_UNIT,
- BITS_PER_WORD),
- bitsize / BITS_PER_UNIT, BITS_PER_WORD);
+ NULL_RTX, word_mode, word_mode,
+ bitsize, BITS_PER_WORD),
+ bitsize, BITS_PER_WORD);
}
/* Find the smallest integer mode large enough to hold the
@@ -3082,33 +3093,20 @@ drop_through_at_end_p ()
return insn && GET_CODE (insn) != BARRIER;
}
-/* Test CALL_EXPR to determine if it is a potential tail recursion call
- and emit code to optimize the tail recursion. LAST_INSN indicates where
- to place the jump to the tail recursion label. Return TRUE if the
- call was optimized into a goto.
-
- This is only used by expand_return, but expand_call is expected to
- use it soon. */
+/* Attempt to optimize a potential tail recursion call into a goto.
+ ARGUMENTS are the arguments to a CALL_EXPR; LAST_INSN indicates
+ where to place the jump to the tail recursion label.
+
+ Return TRUE if the call was optimized into a goto. */
int
-optimize_tail_recursion (call_expr, last_insn)
- tree call_expr;
+optimize_tail_recursion (arguments, last_insn)
+ tree arguments;
rtx last_insn;
{
- /* For tail-recursive call to current function,
- just jump back to the beginning.
- It's unsafe if any auto variable in this function
- has its address taken; for simplicity,
- require stack frame to be empty. */
- if (optimize && call_expr != 0
- && frame_offset == 0
- && TREE_CODE (call_expr) == CALL_EXPR
- && TREE_CODE (TREE_OPERAND (call_expr, 0)) == ADDR_EXPR
- && TREE_OPERAND (TREE_OPERAND (call_expr, 0), 0) == current_function_decl
- /* Finish checking validity, and if valid emit code
- to set the argument variables for the new call. */
- && tail_recursion_args (TREE_OPERAND (call_expr, 1),
- DECL_ARGUMENTS (current_function_decl)))
+ /* Finish checking validity, and if valid emit code to set the
+ argument variables for the new call. */
+ if (tail_recursion_args (arguments, DECL_ARGUMENTS (current_function_decl)))
{
if (tail_recursion_label == 0)
{
@@ -3121,7 +3119,6 @@ optimize_tail_recursion (call_expr, last_insn)
emit_barrier ();
return 1;
}
-
return 0;
}
@@ -3795,8 +3792,8 @@ expand_decl (decl)
if (POINTER_TYPE_P (type))
mark_reg_pointer (DECL_RTL (decl),
- (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl)))
- / BITS_PER_UNIT));
+ TYPE_ALIGN (TREE_TYPE (TREE_TYPE (decl))));
+
}
else if (TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST
@@ -4905,8 +4902,8 @@ add_case_node (low, high, label, duplicate)
/* Returns the number of possible values of TYPE.
- Returns -1 if the number is unknown or variable.
- Returns -2 if the number does not fit in a HOST_WIDE_INT.
+ Returns -1 if the number is unknown, variable, or if the number does not
+ fit in a HOST_WIDE_INT.
Sets *SPARENESS to 2 if TYPE is an ENUMERAL_TYPE whose values
do not increase monotonically (there may be duplicates);
to 1 if the values increase monotonically, but not always by 1;
@@ -4917,73 +4914,60 @@ all_cases_count (type, spareness)
tree type;
int *spareness;
{
- HOST_WIDE_INT count;
+ tree t;
+ HOST_WIDE_INT count, minval, lastval;
+
*spareness = 0;
switch (TREE_CODE (type))
{
- tree t;
case BOOLEAN_TYPE:
count = 2;
break;
+
case CHAR_TYPE:
count = 1 << BITS_PER_UNIT;
break;
+
default:
case INTEGER_TYPE:
- if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
- || TYPE_MAX_VALUE (type) == NULL
- || TREE_CODE (TYPE_MAX_VALUE (type)) != INTEGER_CST)
- return -1;
+ if (TYPE_MAX_VALUE (type) != 0
+ && 0 != (t = fold (build (MINUS_EXPR, type, TYPE_MAX_VALUE (type),
+ TYPE_MIN_VALUE (type))))
+ && 0 != (t = fold (build (PLUS_EXPR, type, t,
+ convert (type, integer_zero_node))))
+ && host_integerp (t, 1))
+ count = tree_low_cst (t, 1);
else
- {
- /* count
- = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))
- - TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + 1
- but with overflow checking. */
- tree mint = TYPE_MIN_VALUE (type);
- tree maxt = TYPE_MAX_VALUE (type);
- HOST_WIDE_INT lo, hi;
- neg_double(TREE_INT_CST_LOW (mint), TREE_INT_CST_HIGH (mint),
- &lo, &hi);
- add_double(TREE_INT_CST_LOW (maxt), TREE_INT_CST_HIGH (maxt),
- lo, hi, &lo, &hi);
- add_double (lo, hi, 1, 0, &lo, &hi);
- if (hi != 0 || lo < 0)
- return -2;
- count = lo;
- }
+ return -1;
break;
+
case ENUMERAL_TYPE:
+ /* Don't waste time with enumeral types with huge values. */
+ if (! host_integerp (TYPE_MIN_VALUE (type), 0)
+ || TYPE_MAX_VALUE (type) == 0
+ || ! host_integerp (TYPE_MAX_VALUE (type), 0))
+ return -1;
+
+ lastval = minval = tree_low_cst (TYPE_MIN_VALUE (type), 0);
count = 0;
+
for (t = TYPE_VALUES (type); t != NULL_TREE; t = TREE_CHAIN (t))
{
- if (TREE_CODE (TYPE_MIN_VALUE (type)) != INTEGER_CST
- || TREE_CODE (TREE_VALUE (t)) != INTEGER_CST
- || (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) + count
- != TREE_INT_CST_LOW (TREE_VALUE (t))))
+ HOST_WIDE_INT thisval = tree_low_cst (TREE_VALUE (t), 0);
+
+ if (*spareness == 2 || thisval < lastval)
+ *spareness = 2;
+ else if (thisval != minval + count)
*spareness = 1;
+
count++;
}
- if (*spareness == 1)
- {
- tree prev = TREE_VALUE (TYPE_VALUES (type));
- for (t = TYPE_VALUES (type); t = TREE_CHAIN (t), t != NULL_TREE; )
- {
- if (! tree_int_cst_lt (prev, TREE_VALUE (t)))
- {
- *spareness = 2;
- break;
- }
- prev = TREE_VALUE (t);
- }
-
- }
}
+
return count;
}
-
#define BITARRAY_TEST(ARRAY, INDEX) \
((ARRAY)[(unsigned) (INDEX) / HOST_BITS_PER_CHAR]\
& (1 << ((unsigned) (INDEX) % HOST_BITS_PER_CHAR)))
@@ -5003,21 +4987,22 @@ void
mark_seen_cases (type, cases_seen, count, sparseness)
tree type;
unsigned char *cases_seen;
- long count;
+ HOST_WIDE_INT count;
int sparseness;
{
tree next_node_to_try = NULL_TREE;
- long next_node_offset = 0;
+ HOST_WIDE_INT next_node_offset = 0;
register struct case_node *n, *root = case_stack->data.case_stmt.case_list;
tree val = make_node (INTEGER_CST);
+
TREE_TYPE (val) = type;
if (! root)
; /* Do nothing */
else if (sparseness == 2)
{
tree t;
- HOST_WIDE_INT xlo;
+ unsigned HOST_WIDE_INT xlo;
/* This less efficient loop is only needed to handle
duplicate case values (multiple enum constants
@@ -5053,6 +5038,7 @@ mark_seen_cases (type, cases_seen, count, sparseness)
{
if (root->left)
case_stack->data.case_stmt.case_list = root = case_tree2list (root, 0);
+
for (n = root; n; n = n->right)
{
TREE_INT_CST_LOW (val) = TREE_INT_CST_LOW (n->low);
@@ -5063,8 +5049,10 @@ mark_seen_cases (type, cases_seen, count, sparseness)
The element with lowest value has offset 0, the next smallest
element has offset 1, etc. */
- HOST_WIDE_INT xlo, xhi;
+ unsigned HOST_WIDE_INT xlo;
+ HOST_WIDE_INT xhi;
tree t;
+
if (sparseness && TYPE_VALUES (type) != NULL_TREE)
{
/* The TYPE_VALUES will be in increasing order, so
@@ -5107,8 +5095,9 @@ mark_seen_cases (type, cases_seen, count, sparseness)
&xlo, &xhi);
}
- if (xhi == 0 && xlo >= 0 && xlo < count)
+ if (xhi == 0 && xlo < (unsigned HOST_WIDE_INT) count)
BITARRAY_SET (cases_seen, xlo);
+
add_double (TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val),
1, 0,
&TREE_INT_CST_LOW (val), &TREE_INT_CST_HIGH (val));
@@ -5150,7 +5139,7 @@ check_for_full_enumeration_handling (type)
unsigned char *cases_seen;
/* The allocated size of cases_seen, in chars. */
- long bytes_needed;
+ HOST_WIDE_INT bytes_needed;
if (! warn_switch)
return;
@@ -5164,7 +5153,7 @@ check_for_full_enumeration_handling (type)
aborting, as xmalloc would do. */
&& (cases_seen = (unsigned char *) calloc (bytes_needed, 1)) != NULL)
{
- long i;
+ HOST_WIDE_INT i;
tree v = TYPE_VALUES (type);
/* The time complexity of this code is normally O(N), where
@@ -5174,12 +5163,10 @@ check_for_full_enumeration_handling (type)
mark_seen_cases (type, cases_seen, size, sparseness);
- for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
- {
- if (BITARRAY_TEST(cases_seen, i) == 0)
- warning ("enumeration value `%s' not handled in switch",
- IDENTIFIER_POINTER (TREE_PURPOSE (v)));
- }
+ for (i = 0; v != NULL_TREE && i < size; i++, v = TREE_CHAIN (v))
+ if (BITARRAY_TEST(cases_seen, i) == 0)
+ warning ("enumeration value `%s' not handled in switch",
+ IDENTIFIER_POINTER (TREE_PURPOSE (v)));
free (cases_seen);
}
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 8773fa9a8a8..c27cc229e35 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -50,11 +50,10 @@ unsigned int maximum_field_alignment;
May be overridden by front-ends. */
unsigned int set_alignment = 0;
-static void finalize_record_size PARAMS ((record_layout_info));
-static void compute_record_mode PARAMS ((tree));
-static void finalize_type_size PARAMS ((tree));
-static void layout_union_field PARAMS ((record_layout_info, tree));
-static void finish_union_layout PARAMS ((record_layout_info));
+static void finalize_record_size PARAMS ((record_layout_info));
+static void compute_record_mode PARAMS ((tree));
+static void finalize_type_size PARAMS ((tree));
+static void place_union_field PARAMS ((record_layout_info, tree));
/* SAVE_EXPRs for sizes of types and decls, waiting to be expanded. */
@@ -65,6 +64,8 @@ static tree pending_sizes;
int immediate_size_expand;
+/* Get a list of all the objects put on the pending sizes list. */
+
tree
get_pending_sizes ()
{
@@ -79,6 +80,9 @@ get_pending_sizes ()
return chain;
}
+/* Put a chain of objects into the pending sizes list, which must be
+ empty. */
+
void
put_pending_sizes (chain)
tree chain;
@@ -131,8 +135,7 @@ variable_size (size)
Also, we would like to pass const0_rtx here, but don't have it. */
expand_expr (size, expand_expr (integer_zero_node, NULL_PTR, VOIDmode, 0),
VOIDmode, 0);
- else if (cfun != 0
- && cfun->x_dont_save_pending_sizes_p)
+ else if (cfun != 0 && cfun->x_dont_save_pending_sizes_p)
/* The front-end doesn't want us to keep a list of the expressions
that determine sizes for variable size objects. */
;
@@ -153,7 +156,7 @@ variable_size (size)
enum machine_mode
mode_for_size (size, class, limit)
- int size;
+ unsigned int size;
enum mode_class class;
int limit;
{
@@ -194,7 +197,7 @@ mode_for_size_tree (size, class, limit)
enum machine_mode
smallest_mode_for_size (size, class)
- int size;
+ unsigned int size;
enum mode_class class;
{
register enum machine_mode mode;
@@ -296,37 +299,38 @@ layout_decl (decl, known_align)
if (type == error_mark_node)
type = void_type_node;
- /* Usually the size and mode come from the data type without change. */
+ /* Usually the size and mode come from the data type without change,
+ however, the front-end may set the explicit width of the field, so its
+ size may not be the same as the size of its type. This happens with
+ bitfields, of course (an `int' bitfield may be only 2 bits, say), but it
+ also happens with other fields. For example, the C++ front-end creates
+ zero-sized fields corresponding to empty base classes, and depends on
+ layout_type setting DECL_FIELD_BITPOS correctly for the field. Set the
+ size in bytes from the size in bits. */
+
DECL_MODE (decl) = TYPE_MODE (type);
TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
+
if (DECL_SIZE (decl) == 0)
{
DECL_SIZE (decl) = TYPE_SIZE (type);
DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
}
- else if (code == FIELD_DECL)
- {
- HOST_WIDE_INT spec_size;
-
- /* Size is specified in number of bits. */
- spec_size = TREE_INT_CST_LOW (DECL_SIZE (decl));
- if (spec_size % BITS_PER_UNIT == 0)
- DECL_SIZE_UNIT (decl) = size_int (spec_size / BITS_PER_UNIT);
- else
- DECL_SIZE_UNIT (decl) = 0;
- }
+ else
+ DECL_SIZE_UNIT (decl)
+ = convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
+ bitsize_unit_node));
/* Force alignment required for the data type.
But if the decl itself wants greater alignment, don't override that.
Likewise, if the decl is packed, don't override it. */
- if (!(code == FIELD_DECL && DECL_BIT_FIELD (decl))
+ if (! (code == FIELD_DECL && DECL_BIT_FIELD (decl))
&& (DECL_ALIGN (decl) == 0
- || (! DECL_PACKED (decl) && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
+ || (! (code == FIELD_DECL && DECL_PACKED (decl))
+ && TYPE_ALIGN (type) > DECL_ALIGN (decl))))
DECL_ALIGN (decl) = TYPE_ALIGN (type);
- /* See if we can use an ordinary integer mode for a bit-field.
- Conditions are: a fixed size that is correct for another mode
- and occupying a complete byte or bytes on proper boundary. */
+ /* For fields, set the bit field type and update the alignment. */
if (code == FIELD_DECL)
{
DECL_BIT_FIELD_TYPE (decl) = DECL_BIT_FIELD (decl) ? type : 0;
@@ -336,7 +340,10 @@ layout_decl (decl, known_align)
DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
}
- if (DECL_BIT_FIELD (decl)
+ /* See if we can use an ordinary integer mode for a bit-field.
+ Conditions are: a fixed size that is correct for another mode
+ and occupying a complete byte or bytes on proper boundary. */
+ if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
&& TYPE_SIZE (type) != 0
&& TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
&& GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
@@ -344,24 +351,21 @@ layout_decl (decl, known_align)
register enum machine_mode xmode
= mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
- if (xmode != BLKmode
- && known_align % GET_MODE_ALIGNMENT (xmode) == 0)
+ if (xmode != BLKmode && known_align > GET_MODE_ALIGNMENT (xmode))
{
DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
DECL_ALIGN (decl));
DECL_MODE (decl) = xmode;
- DECL_SIZE (decl) = bitsize_int (GET_MODE_BITSIZE (xmode));
- DECL_SIZE_UNIT (decl) = size_int (GET_MODE_SIZE (xmode));
- /* This no longer needs to be accessed as a bit field. */
DECL_BIT_FIELD (decl) = 0;
}
}
/* Turn off DECL_BIT_FIELD if we won't need it set. */
- if (DECL_BIT_FIELD (decl) && TYPE_MODE (type) == BLKmode
- && known_align % TYPE_ALIGN (type) == 0
- && DECL_SIZE_UNIT (decl) != 0
- && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
+ if (code == FIELD_DECL && DECL_BIT_FIELD (decl)
+ && TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
+ && known_align > TYPE_ALIGN (type)
+ && DECL_ALIGN (decl) >= TYPE_ALIGN (type)
+ && DECL_SIZE_UNIT (decl) != 0)
DECL_BIT_FIELD (decl) = 0;
/* Evaluate nonconstant size only once, either now or as soon as safe. */
@@ -373,7 +377,7 @@ layout_decl (decl, known_align)
/* If requested, warn about definitions of large data objects. */
if (warn_larger_than
- && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL)
+ && (code == VAR_DECL || code == PARM_DECL)
&& ! DECL_EXTERNAL (decl))
{
tree size = DECL_SIZE_UNIT (decl);
@@ -392,23 +396,28 @@ layout_decl (decl, known_align)
}
}
-/* Create a new record_layout_info for T, which may be a RECORD_TYPE,
- UNION_TYPE, or QUAL_UNION_TYPE. It is the responsibility of the
- caller to call `free' for the storage the returned. */
+/* Begin laying out type T, which may be a RECORD_TYPE, UNION_TYPE, or
+ QUAL_UNION_TYPE. Return a pointer to a struct record_layout_info which
+ is to be passed to all other layout functions for this record. It is the
+ responsibility of the caller to call `free' for the storage returned.
+ Note that garbage collection is not permitted until we finish laying
+ out the record. */
record_layout_info
-new_record_layout_info (t)
+start_record_layout (t)
tree t;
{
record_layout_info rli
- = (record_layout_info) xcalloc (1, sizeof (struct record_layout_info_s));
+ = (record_layout_info) xmalloc (sizeof (struct record_layout_info));
rli->t = t;
+
/* If the type has a minimum specified alignment (via an attribute
declaration, for example) use it -- otherwise, start with a
one-byte alignment. */
rli->record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (t));
rli->unpacked_align = rli->record_align;
+ rli->offset_align = MAX (rli->record_align, BIGGEST_ALIGNMENT);
#ifdef STRUCTURE_SIZE_BOUNDARY
/* Packed structures don't need to have minimum size. */
@@ -416,30 +425,156 @@ new_record_layout_info (t)
rli->record_align = MAX (rli->record_align, STRUCTURE_SIZE_BOUNDARY);
#endif
+ rli->offset = size_zero_node;
+ rli->bitpos = bitsize_zero_node;
+ rli->pending_statics = 0;
+ rli->packed_maybe_necessary = 0;
+
return rli;
}
-/* Like layout_field, but for unions. */
+/* These four routines perform computations that convert between
+ the offset/bitpos forms and byte and bit offsets. */
-static void
-layout_union_field (rli, field)
+tree
+bit_from_pos (offset, bitpos)
+ tree offset, bitpos;
+{
+ return size_binop (PLUS_EXPR, bitpos,
+ size_binop (MULT_EXPR, convert (bitsizetype, offset),
+ bitsize_unit_node));
+}
+
+tree
+byte_from_pos (offset, bitpos)
+ tree offset, bitpos;
+{
+ return size_binop (PLUS_EXPR, offset,
+ convert (sizetype,
+ size_binop (TRUNC_DIV_EXPR, bitpos,
+ bitsize_unit_node)));
+}
+
+void
+pos_from_byte (poffset, pbitpos, off_align, pos)
+ tree *poffset, *pbitpos;
+ unsigned int off_align;
+ tree pos;
+{
+ *poffset
+ = size_binop (MULT_EXPR,
+ convert (sizetype,
+ size_binop (FLOOR_DIV_EXPR, pos,
+ bitsize_int (off_align
+ / BITS_PER_UNIT))),
+ size_int (off_align / BITS_PER_UNIT));
+ *pbitpos = size_binop (MULT_EXPR,
+ size_binop (FLOOR_MOD_EXPR, pos,
+ bitsize_int (off_align / BITS_PER_UNIT)),
+ bitsize_unit_node);
+}
+
+void
+pos_from_bit (poffset, pbitpos, off_align, pos)
+ tree *poffset, *pbitpos;
+ unsigned int off_align;
+ tree pos;
+{
+ *poffset = size_binop (MULT_EXPR,
+ convert (sizetype,
+ size_binop (FLOOR_DIV_EXPR, pos,
+ bitsize_int (off_align))),
+ size_int (off_align / BITS_PER_UNIT));
+ *pbitpos = size_binop (FLOOR_MOD_EXPR, pos, bitsize_int (off_align));
+}
+
+/* Given a pointer to bit and byte offsets and an offset alignment,
+ normalize the offsets so they are within the alignment. */
+
+void
+normalize_offset (poffset, pbitpos, off_align)
+ tree *poffset, *pbitpos;
+ unsigned int off_align;
+{
+ /* If the bit position is now larger than it should be, adjust it
+ downwards. */
+ if (compare_tree_int (*pbitpos, off_align) >= 0)
+ {
+ tree extra_aligns = size_binop (FLOOR_DIV_EXPR, *pbitpos,
+ bitsize_int (off_align));
+
+ *poffset
+ = size_binop (PLUS_EXPR, *poffset,
+ size_binop (MULT_EXPR, convert (sizetype, extra_aligns),
+ size_int (off_align / BITS_PER_UNIT)));
+
+ *pbitpos
+ = size_binop (FLOOR_MOD_EXPR, *pbitpos, bitsize_int (off_align));
+ }
+}
+
+/* Print debugging information about the information in RLI. */
+
+void
+debug_rli (rli)
record_layout_info rli;
- tree field;
{
- tree dsize;
-
- /* This function should only be used for unions; use layout_field
- for RECORD_TYPEs. */
- if (TREE_CODE (rli->t) != UNION_TYPE
- && TREE_CODE (rli->t) != QUAL_UNION_TYPE)
- abort ();
+ print_node_brief (stderr, "type", rli->t, 0);
+ print_node_brief (stderr, "\noffset", rli->offset, 0);
+ print_node_brief (stderr, " bitpos", rli->bitpos, 0);
- /* By now, we should only be seeing FIELD_DECLs. */
- if (TREE_CODE (field) != FIELD_DECL)
- abort ();
+ fprintf (stderr, "\nrec_align = %u, unpack_align = %u, off_align = %u\n",
+ rli->record_align, rli->unpacked_align, rli->offset_align);
+ if (rli->packed_maybe_necessary)
+ fprintf (stderr, "packed may be necessary\n");
+ if (rli->pending_statics)
+ {
+ fprintf (stderr, "pending statics:\n");
+ debug_tree (rli->pending_statics);
+ }
+}
+
+/* Given an RLI with a possibly-incremented BITPOS, adjust OFFSET and
+ BITPOS if necessary to keep BITPOS below OFFSET_ALIGN. */
+
+void
+normalize_rli (rli)
+ record_layout_info rli;
+{
+ normalize_offset (&rli->offset, &rli->bitpos, rli->offset_align);
+}
+
+/* Returns the size in bytes allocated so far. */
+
+tree
+rli_size_unit_so_far (rli)
+ record_layout_info rli;
+{
+ return byte_from_pos (rli->offset, rli->bitpos);
+}
+
+/* Returns the size in bits allocated so far. */
+
+tree
+rli_size_so_far (rli)
+ record_layout_info rli;
+{
+ return bit_from_pos (rli->offset, rli->bitpos);
+}
+
+/* Called from place_field to handle unions. */
+
+static void
+place_union_field (rli, field)
+ record_layout_info rli;
+ tree field;
+{
layout_decl (field, 0);
- DECL_FIELD_BITPOS (field) = bitsize_int (0);
+
+ DECL_FIELD_OFFSET (field) = size_zero_node;
+ DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
+ DECL_OFFSET_ALIGN (field) = BIGGEST_ALIGNMENT;
/* Union must be at least as aligned as any field requires. */
rli->record_align = MAX (rli->record_align, DECL_ALIGN (field));
@@ -452,30 +587,14 @@ layout_union_field (rli, field)
TYPE_ALIGN (TREE_TYPE (field)));
#endif
- dsize = DECL_SIZE (field);
+ /* We assume the union's size will be a multiple of a byte so we don't
+ bother with BITPOS. */
if (TREE_CODE (rli->t) == UNION_TYPE)
- {
- /* Set union_size to max (decl_size, union_size). There are
- more and less general ways to do this. Use only CONST_SIZE
- unless forced to use VAR_SIZE. */
-
- if (TREE_CODE (dsize) == INTEGER_CST
- && ! TREE_CONSTANT_OVERFLOW (dsize)
- && TREE_INT_CST_HIGH (dsize) == 0)
- rli->const_size
- = MAX (rli->const_size, TREE_INT_CST_LOW (dsize));
- else if (rli->var_size == 0)
- rli->var_size = dsize;
- else
- rli->var_size = size_binop (MAX_EXPR, rli->var_size, dsize);
- }
+ rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
- rli->var_size = fold (build (COND_EXPR, bitsizetype,
- DECL_QUALIFIER (field),
- DECL_SIZE (field),
- (rli->var_size
- ? rli->var_size
- : bitsize_int (0))));
+ rli->offset = fold (build (COND_EXPR, sizetype,
+ DECL_QUALIFIER (field),
+ DECL_SIZE_UNIT (field), rli->offset));
}
/* RLI contains information about the layout of a RECORD_TYPE. FIELD
@@ -484,7 +603,7 @@ layout_union_field (rli, field)
callers that desire that behavior must manually perform that step.) */
void
-layout_field (rli, field)
+place_field (rli, field)
record_layout_info rli;
tree field;
{
@@ -493,11 +612,10 @@ layout_field (rli, field)
/* The alignment FIELD would have if we just dropped it into the
record as it presently stands. */
unsigned int known_align;
+ unsigned int actual_align;
/* The type of this field. */
tree type = TREE_TYPE (field);
- /* The size of this field, in bits. */
- tree dsize;
-
+
/* If FIELD is static, then treat it like a separate variable, not
really like a structure field. If it is a FUNCTION_DECL, it's a
method. In both cases, all we do is lay out the decl, and we do
@@ -508,29 +626,40 @@ layout_field (rli, field)
rli->pending_statics);
return;
}
+
/* Enumerators and enum types which are local to this class need not
be laid out. Likewise for initialized constant fields. */
else if (TREE_CODE (field) != FIELD_DECL)
return;
- /* This function should only be used for records; use
- layout_union_field for unions. */
+
+ /* Unions are laid out very differently than records, so split
+ that code off to another function. */
else if (TREE_CODE (rli->t) != RECORD_TYPE)
{
- layout_union_field (rli, field);
+ place_union_field (rli, field);
return;
}
- /* Work out the known alignment so far. */
- known_align = rli->var_size ? rli->var_align : rli->const_size;
+ /* Work out the known alignment so far. Note that A & (-A) is the
+ value of the least-significant bit in A that is one. */
+ if (! integer_zerop (rli->bitpos) && TREE_CONSTANT (rli->offset))
+ known_align = (tree_low_cst (rli->bitpos, 1)
+ & - tree_low_cst (rli->bitpos, 1));
+ else if (host_integerp (rli->offset, 1))
+ known_align = (BITS_PER_UNIT
+ * (tree_low_cst (rli->offset, 1)
+ & - tree_low_cst (rli->offset, 1)));
+ else
+ known_align = rli->offset_align;
/* Lay out the field so we know what alignment it needs. For a
packed field, use the alignment as specified, disregarding what
the type would want. */
- if (DECL_PACKED (field))
- desired_align = DECL_ALIGN (field);
+ desired_align = DECL_ALIGN (field);
layout_decl (field, known_align);
if (! DECL_PACKED (field))
desired_align = DECL_ALIGN (field);
+
/* Some targets (i.e. VMS) limit struct field alignment
to a lower boundary than alignment of variables. */
#ifdef BIGGEST_FIELD_ALIGNMENT
@@ -556,6 +685,7 @@ layout_field (rli, field)
rli->record_align = MAX (rli->record_align, desired_align);
else if (! DECL_PACKED (field))
desired_align = TYPE_ALIGN (type);
+
/* A named bit field of declared type `int'
forces the entire structure to have `int' alignment. */
if (DECL_NAME (field) != 0)
@@ -577,15 +707,12 @@ layout_field (rli, field)
#endif
{
rli->record_align = MAX (rli->record_align, desired_align);
- if (warn_packed)
- rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+ rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
}
if (warn_packed && DECL_PACKED (field))
{
- if (rli->const_size % TYPE_ALIGN (type) == 0
- || (rli->var_align % TYPE_ALIGN (type) == 0
- && rli->var_size != NULL_TREE))
+ if (known_align > TYPE_ALIGN (type))
{
if (TYPE_ALIGN (type) > desired_align)
{
@@ -601,9 +728,7 @@ layout_field (rli, field)
/* Does this field automatically have alignment it needs by virtue
of the fields that precede it and the record's own alignment? */
- if (rli->const_size % desired_align != 0
- || (rli->var_align % desired_align != 0
- && rli->var_size != NULL_TREE))
+ if (known_align < desired_align)
{
/* No, we need to skip space before this field.
Bump the cumulative size to multiple of field alignment. */
@@ -611,55 +736,72 @@ layout_field (rli, field)
if (warn_padded)
warning_with_decl (field, "padding struct to align `%s'");
- if (rli->var_size == NULL_TREE || rli->var_align % desired_align == 0)
- rli->const_size
- = CEIL (rli->const_size, desired_align) * desired_align;
+ /* If the alignment is still within offset_align, just align
+ the bit position. */
+ if (desired_align < rli->offset_align)
+ rli->bitpos = round_up (rli->bitpos, desired_align);
else
{
- if (rli->const_size > 0)
- rli->var_size = size_binop (PLUS_EXPR, rli->var_size,
- bitsize_int (rli->const_size));
- rli->const_size = 0;
- rli->var_size = round_up (rli->var_size, desired_align);
- rli->var_align = MIN (rli->var_align, desired_align);
+ /* First adjust OFFSET by the partial bits, then align. */
+ rli->offset
+ = size_binop (PLUS_EXPR, rli->offset,
+ convert (sizetype,
+ size_binop (CEIL_DIV_EXPR, rli->bitpos,
+ bitsize_unit_node)));
+ rli->bitpos = bitsize_zero_node;
+
+ rli->offset = round_up (rli->offset, desired_align / BITS_PER_UNIT);
}
+
}
+ /* Handle compatibility with PCC. Note that if the record has any
+ variable-sized fields, we need not worry about compatibility. */
#ifdef PCC_BITFIELD_TYPE_MATTERS
if (PCC_BITFIELD_TYPE_MATTERS
&& TREE_CODE (field) == FIELD_DECL
&& type != error_mark_node
- && DECL_BIT_FIELD_TYPE (field)
- && !DECL_PACKED (field)
+ && DECL_BIT_FIELD (field)
+ && ! DECL_PACKED (field)
&& maximum_field_alignment == 0
- && !integer_zerop (DECL_SIZE (field)))
+ && ! integer_zerop (DECL_SIZE (field))
+ && host_integerp (DECL_SIZE (field), 1)
+ && host_integerp (rli->offset, 1)
+ && host_integerp (TYPE_SIZE (type), 1))
{
unsigned int type_align = TYPE_ALIGN (type);
- register tree dsize = DECL_SIZE (field);
- unsigned int field_size = TREE_INT_CST_LOW (dsize);
+ tree dsize = DECL_SIZE (field);
+ HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
+ HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
+ HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
/* A bit field may not span more units of alignment of its type
than its type itself. Advance to next boundary if necessary. */
- if (((rli->const_size + field_size + type_align - 1) / type_align
- - rli->const_size / type_align)
- > TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (field))) / type_align)
- rli->const_size = CEIL (rli->const_size, type_align) * type_align;
+ if ((((offset * BITS_PER_UNIT + bit_offset + field_size +
+ type_align - 1)
+ / type_align)
+ - (offset * BITS_PER_UNIT + bit_offset) / type_align)
+ > tree_low_cst (TYPE_SIZE (type), 1) / type_align)
+ rli->bitpos = round_up (rli->bitpos, type_align);
}
#endif
- /* No existing machine description uses this parameter. So I have
- made it in this aspect identical to PCC_BITFIELD_TYPE_MATTERS. */
#ifdef BITFIELD_NBYTES_LIMITED
if (BITFIELD_NBYTES_LIMITED
&& TREE_CODE (field) == FIELD_DECL
&& type != error_mark_node
&& DECL_BIT_FIELD_TYPE (field)
- && !DECL_PACKED (field)
- && !integer_zerop (DECL_SIZE (field)))
+ && ! DECL_PACKED (field)
+ && ! integer_zerop (DECL_SIZE (field))
+ && host_integerp (DECL_SIZE (field), 1)
+ && host_integerp (rli->size, 1)
+ && host_integerp (TYPE_SIZE (type), 1))
{
unsigned int type_align = TYPE_ALIGN (type);
- register tree dsize = DECL_SIZE (field);
- int field_size = TREE_INT_CST_LOW (dsize);
+ tree dsize = DECL_SIZE (field);
+ HOST_WIDE_INT field_size = tree_low_cst (dsize, 1);
+ HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
+ HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
if (maximum_field_alignment != 0)
type_align = MIN (type_align, maximum_field_alignment);
@@ -672,51 +814,63 @@ layout_field (rli, field)
Advance to next boundary if necessary. */
/* ??? This code should match the code above for the
PCC_BITFIELD_TYPE_MATTERS case. */
- if (rli->const_size / type_align
- != (rli->const_size + field_size - 1) / type_align)
- rli->const_size = CEIL (rli->const_size, type_align) * type_align;
+ if ((offset * BITS_PER_UNIT + bit_offset) / type_align
+ != ((offset * BITS_PER_UNIT + bit_offset + field_size - 1)
+ / type_align))
+ rli->bitpos = round_up (rli->bitpos, type_align);
}
#endif
- /* Size so far becomes the position of this field. */
-
- if (rli->var_size && rli->const_size)
- DECL_FIELD_BITPOS (field)
- = size_binop (PLUS_EXPR, rli->var_size, bitsize_int (rli->const_size));
- else if (rli->var_size)
- DECL_FIELD_BITPOS (field) = rli->var_size;
+ if (! TREE_CONSTANT (rli->offset))
+ rli->offset_align = DECL_ALIGN (field);
+
+ /* Offset so far becomes the position of this field after normalizing. */
+ normalize_rli (rli);
+ DECL_FIELD_OFFSET (field) = rli->offset;
+ DECL_FIELD_BIT_OFFSET (field) = rli->bitpos;
+ DECL_OFFSET_ALIGN (field) = rli->offset_align;
+
+ /* If this field ended up more aligned than we thought it would be (we
+ approximate this by seeing if its position changed), lay out the field
+ again; perhaps we can use an integral mode for it now. */
+ if (! integer_zerop (DECL_FIELD_BIT_OFFSET (field))
+ && TREE_CONSTANT (DECL_FIELD_OFFSET (field)))
+ actual_align = (tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1)
+ & - tree_low_cst (DECL_FIELD_BIT_OFFSET (field), 1));
+ else if (host_integerp (DECL_FIELD_OFFSET (field), 1))
+ actual_align = (BITS_PER_UNIT
+ * (tree_low_cst (DECL_FIELD_OFFSET (field), 1)
+ & - tree_low_cst (DECL_FIELD_OFFSET (field), 1)));
else
+ actual_align = DECL_OFFSET_ALIGN (field);
+
+ if (known_align != actual_align)
+ layout_decl (field, actual_align);
+
+ /* Now add size of this field to the size of the record. If the size is
+ not constant, treat the field as being a multiple of bytes and just
+ adjust the offset, resetting the bit position. Otherwise, apportion the
+ size amongst the bit position and offset. First handle the case of an
+ unspecified size, which can happen when we have an invalid nested struct
+ definition, such as struct j { struct j { int i; } }. The error message
+ is printed in finish_struct. */
+ if (DECL_SIZE (field) == 0)
+ /* Do nothing. */;
+ else if (! TREE_CONSTANT (DECL_SIZE_UNIT (field)))
{
- DECL_FIELD_BITPOS (field) = bitsize_int (rli->const_size);
-
- /* If this field ended up more aligned than we thought it
- would be (we approximate this by seeing if its position
- changed), lay out the field again; perhaps we can use an
- integral mode for it now. */
- if (known_align != rli->const_size)
- layout_decl (field, rli->const_size);
+ rli->offset
+ = size_binop (PLUS_EXPR, rli->offset,
+ convert (sizetype,
+ size_binop (CEIL_DIV_EXPR, rli->bitpos,
+ bitsize_unit_node)));
+ rli->offset
+ = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field));
+ rli->bitpos = bitsize_zero_node;
}
-
- /* Now add size of this field to the size of the record. */
- dsize = DECL_SIZE (field);
-
- /* This can happen when we have an invalid nested struct definition,
- such as struct j { struct j { int i; } }. The error message is
- printed in finish_struct. */
- if (dsize == 0)
- /* Do nothing. */;
- else if (TREE_CODE (dsize) == INTEGER_CST
- && ! TREE_CONSTANT_OVERFLOW (dsize)
- && TREE_INT_CST_HIGH (dsize) == 0
- && TREE_INT_CST_LOW (dsize) + rli->const_size >= rli->const_size)
- /* Use const_size if there's no overflow. */
- rli->const_size += TREE_INT_CST_LOW (dsize);
else
{
- if (rli->var_size == NULL_TREE)
- rli->var_size = dsize;
- else
- rli->var_size = size_binop (PLUS_EXPR, rli->var_size, dsize);
+ rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, DECL_SIZE (field));
+ normalize_rli (rli);
}
}
@@ -728,18 +882,15 @@ static void
finalize_record_size (rli)
record_layout_info rli;
{
- /* Work out the total size and alignment of the record as one
- expression and store in the record type. Round it up to a
- multiple of the record's alignment. */
- if (rli->var_size == NULL_TREE)
- TYPE_SIZE (rli->t) = bitsize_int (rli->const_size);
- else
- {
- if (rli->const_size)
- rli->var_size = size_binop (PLUS_EXPR, rli->var_size,
- bitsize_int (rli->const_size));
- TYPE_SIZE (rli->t) = rli->var_size;
- }
+ tree unpadded_size, unpadded_size_unit;
+
+ /* Next move any full bytes of bits into the byte size. */
+ rli->offset
+ = size_binop (PLUS_EXPR, rli->offset,
+ convert (sizetype,
+ size_binop (TRUNC_DIV_EXPR, rli->bitpos,
+ bitsize_unit_node)));
+ rli->bitpos = size_binop (TRUNC_MOD_EXPR, rli->bitpos, bitsize_unit_node);
/* Determine the desired alignment. */
#ifdef ROUND_TYPE_ALIGN
@@ -749,45 +900,55 @@ finalize_record_size (rli)
TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
#endif
+ unpadded_size
+ = size_binop (PLUS_EXPR, rli->bitpos,
+ size_binop (MULT_EXPR, convert (bitsizetype, rli->offset),
+ bitsize_unit_node));
+
+ unpadded_size_unit
+ = size_binop (PLUS_EXPR, rli->offset,
+ convert (sizetype,
+ size_binop (CEIL_DIV_EXPR, rli->bitpos,
+ bitsize_unit_node)));
+
/* Record the un-rounded size in the binfo node. But first we check
the size of TYPE_BINFO to make sure that BINFO_SIZE is available. */
if (TYPE_BINFO (rli->t) && TREE_VEC_LENGTH (TYPE_BINFO (rli->t)) > 6)
{
- TYPE_BINFO_SIZE (rli->t) = TYPE_SIZE (rli->t);
- TYPE_BINFO_SIZE_UNIT (rli->t)
- = convert (sizetype,
- size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rli->t),
- bitsize_int (BITS_PER_UNIT)));
+ TYPE_BINFO_SIZE (rli->t) = unpadded_size;
+ TYPE_BINFO_SIZE_UNIT (rli->t) = unpadded_size_unit;
}
-
- {
- tree unpadded_size = TYPE_SIZE (rli->t);
+ /* Round the size up to be a multiple of the required alignment */
#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
- TYPE_ALIGN (rli->t));
+ TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, unpadded_size,
+ TYPE_ALIGN (rli->t));
+ TYPE_SIZE_UNIT (rli->t)
+ = ROUND_TYPE_SIZE_UNIT (rli->t, unpaded_size_unit,
+ TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
#else
- /* Round the size up to be a multiple of the required alignment */
- TYPE_SIZE (rli->t) = round_up (TYPE_SIZE (rli->t), TYPE_ALIGN (rli->t));
+ TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t));
+ TYPE_SIZE_UNIT (rli->t) = round_up (unpadded_size_unit,
+ TYPE_ALIGN (rli->t) / BITS_PER_UNIT);
#endif
- if (warn_padded && rli->var_size == NULL_TREE
- && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
- warning ("padding struct size to alignment boundary");
- }
+ if (warn_padded && TREE_CONSTANT (unpadded_size)
+ && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0)
+ warning ("padding struct size to alignment boundary");
- if (warn_packed && TYPE_PACKED (rli->t) && !rli->packed_maybe_necessary
- && rli->var_size == NULL_TREE)
+ if (warn_packed && TREE_CODE (rli->t) == RECORD_TYPE
+ && TYPE_PACKED (rli->t) && ! rli->packed_maybe_necessary
+ && TREE_CONSTANT (unpadded_size))
{
tree unpacked_size;
- TYPE_PACKED (rli->t) = 0;
#ifdef ROUND_TYPE_ALIGN
rli->unpacked_align
= ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t), rli->unpacked_align);
#else
rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align);
#endif
+
#ifdef ROUND_TYPE_SIZE
unpacked_size = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
rli->unpacked_align);
@@ -797,6 +958,8 @@ finalize_record_size (rli)
if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t)))
{
+ TYPE_PACKED (rli->t) = 0;
+
if (TYPE_NAME (rli->t))
{
char *name;
@@ -805,6 +968,7 @@ finalize_record_size (rli)
name = IDENTIFIER_POINTER (TYPE_NAME (rli->t));
else
name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (rli->t)));
+
if (STRICT_ALIGNMENT)
warning ("packed attribute causes inefficient alignment for `%s'", name);
else
@@ -818,7 +982,6 @@ finalize_record_size (rli)
warning ("packed attribute is unnecessary");
}
}
- TYPE_PACKED (rli->t) = 1;
}
}
@@ -828,79 +991,77 @@ static void
compute_record_mode (type)
tree type;
{
+ tree field;
+ enum machine_mode mode = VOIDmode;
+
/* Most RECORD_TYPEs have BLKmode, so we start off assuming that.
However, if possible, we use a mode that fits in a register
instead, in order to allow for better optimization down the
line. */
TYPE_MODE (type) = BLKmode;
- if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
- {
- tree field;
- enum machine_mode mode = VOIDmode;
-
- /* A record which has any BLKmode members must itself be
- BLKmode; it can't go in a register. Unless the member is
- BLKmode only because it isn't aligned. */
- for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- {
- unsigned HOST_WIDE_INT bitpos;
-
- if (TREE_CODE (field) != FIELD_DECL
- || TREE_CODE (TREE_TYPE (field)) == ERROR_MARK)
- continue;
- if (TYPE_MODE (TREE_TYPE (field)) == BLKmode
- && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)))
- return;
-
- if (TREE_CODE (DECL_FIELD_BITPOS (field)) != INTEGER_CST)
- return;
+ if (! host_integerp (TYPE_SIZE (type), 1))
+ return;
- bitpos = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
+ /* A record which has any BLKmode members must itself be
+ BLKmode; it can't go in a register. Unless the member is
+ BLKmode only because it isn't aligned. */
+ for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+ {
+ unsigned HOST_WIDE_INT bitpos;
- /* Must be BLKmode if any field crosses a word boundary,
- since extract_bit_field can't handle that in registers. */
- if (bitpos / BITS_PER_WORD
- != ((TREE_INT_CST_LOW (DECL_SIZE (field)) + bitpos - 1)
- / BITS_PER_WORD)
- /* But there is no problem if the field is entire words. */
- && TREE_INT_CST_LOW (DECL_SIZE (field)) % BITS_PER_WORD != 0)
- return;
+ if (TREE_CODE (field) != FIELD_DECL)
+ continue;
- /* If this field is the whole struct, remember its mode so
- that, say, we can put a double in a class into a DF
- register instead of forcing it to live in the stack. */
- if (simple_cst_equal (TYPE_SIZE (type), DECL_SIZE (field)))
- mode = DECL_MODE (field);
+ if (TREE_CODE (TREE_TYPE (field)) == ERROR_MARK
+ || (TYPE_MODE (TREE_TYPE (field)) == BLKmode
+ && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)))
+ || ! host_integerp (bit_position (field), 1)
+ || ! host_integerp (DECL_SIZE (field), 1))
+ return;
+
+ bitpos = int_bit_position (field);
+
+ /* Must be BLKmode if any field crosses a word boundary,
+ since extract_bit_field can't handle that in registers. */
+ if (bitpos / BITS_PER_WORD
+ != ((TREE_INT_CST_LOW (DECL_SIZE (field)) + bitpos - 1)
+ / BITS_PER_WORD)
+ /* But there is no problem if the field is entire words. */
+ && tree_low_cst (DECL_SIZE (field), 1) % BITS_PER_WORD != 0)
+ return;
+
+ /* If this field is the whole struct, remember its mode so
+ that, say, we can put a double in a class into a DF
+ register instead of forcing it to live in the stack. */
+ if (field == TYPE_FIELDS (type) && TREE_CHAIN (field) == 0)
+ mode = DECL_MODE (field);
#ifdef STRUCT_FORCE_BLK
- /* With some targets, eg. c4x, it is sub-optimal
- to access an aligned BLKmode structure as a scalar. */
- if (mode == VOIDmode && STRUCT_FORCE_BLK (field))
- return;
+ /* With some targets, eg. c4x, it is sub-optimal
+ to access an aligned BLKmode structure as a scalar. */
+ if (mode == VOIDmode && STRUCT_FORCE_BLK (field))
+ return;
#endif /* STRUCT_FORCE_BLK */
- }
+ }
- if (mode != VOIDmode)
- /* We only have one real field; use its mode. */
- TYPE_MODE (type) = mode;
- else
- TYPE_MODE (type)
- = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
-
- /* If structure's known alignment is less than what the scalar
- mode would need, and it matters, then stick with BLKmode. */
- if (TYPE_MODE (type) != BLKmode
- && STRICT_ALIGNMENT
- && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
- || (TYPE_ALIGN (type) >=
- GET_MODE_ALIGNMENT (TYPE_MODE (type)))))
- {
- /* If this is the only reason this type is BLKmode, then
- don't force containing types to be BLKmode. */
- TYPE_NO_FORCE_BLK (type) = 1;
- TYPE_MODE (type) = BLKmode;
- }
+ if (mode != VOIDmode)
+ /* We only have one real field; use its mode. */
+ TYPE_MODE (type) = mode;
+ else
+ TYPE_MODE (type) = mode_for_size_tree (TYPE_SIZE (type), MODE_INT, 1);
+
+ /* If structure's known alignment is less than what the scalar
+ mode would need, and it matters, then stick with BLKmode. */
+ if (TYPE_MODE (type) != BLKmode
+ && STRICT_ALIGNMENT
+ && ! (TYPE_ALIGN (type) >= BIGGEST_ALIGNMENT
+ || TYPE_ALIGN (type) >= GET_MODE_ALIGNMENT (TYPE_MODE (type))))
+ {
+ /* If this is the only reason this type is BLKmode, then
+ don't force containing types to be BLKmode. */
+ TYPE_NO_FORCE_BLK (type) = 1;
+ TYPE_MODE (type) = BLKmode;
}
}
@@ -929,18 +1090,8 @@ finalize_type_size (type)
= ROUND_TYPE_ALIGN (type, TYPE_ALIGN (type), BITS_PER_UNIT);
#endif
-#ifdef ROUND_TYPE_SIZE
- if (TYPE_SIZE (type) != 0)
- TYPE_SIZE (type)
- = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
-#endif
-
- /* Evaluate nonconstant size only once, either now or as soon as safe. */
- if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
-
/* If we failed to find a simple way to calculate the unit size
- of the type above, find it by division. */
+ of the type, find it by division. */
if (TYPE_SIZE_UNIT (type) == 0 && TYPE_SIZE (type) != 0)
/* TYPE_SIZE (type) is computed in bitsizetype. After the division, the
result will fit in sizetype. We will get more efficient code using
@@ -948,9 +1099,26 @@ finalize_type_size (type)
TYPE_SIZE_UNIT (type)
= convert (sizetype,
size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type),
- bitsize_int (BITS_PER_UNIT)));
+ bitsize_unit_node));
- /* Once again evaluate only once, either now or as soon as safe. */
+ if (TYPE_SIZE (type) != 0)
+ {
+#ifdef ROUND_TYPE_SIZE
+ TYPE_SIZE (type)
+ = ROUND_TYPE_SIZE (type, TYPE_SIZE (type), TYPE_ALIGN (type));
+ TYPE_SIZE_UNIT (type)
+ = ROUND_TYPE_SIZE_UNIT (type, TYPE_SIZE_UNIT (type),
+ TYPE_ALIGN (type) / BITS_PER_UNIT);
+#else
+ TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type));
+ TYPE_SIZE_UNIT (type)
+ = round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN (type) / BITS_PER_UNIT);
+#endif
+ }
+
+ /* Evaluate nonconstant sizes only once, either now or as soon as safe. */
+ if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ TYPE_SIZE (type) = variable_size (TYPE_SIZE (type));
if (TYPE_SIZE_UNIT (type) != 0
&& TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
TYPE_SIZE_UNIT (type) = variable_size (TYPE_SIZE_UNIT (type));
@@ -987,16 +1155,11 @@ void
finish_record_layout (rli)
record_layout_info rli;
{
- /* Use finish_union_layout for unions. */
- if (TREE_CODE (rli->t) != RECORD_TYPE)
- finish_union_layout (rli);
- else
- {
- /* Compute the final size. */
- finalize_record_size (rli);
- /* Compute the TYPE_MODE for the record. */
- compute_record_mode (rli->t);
- }
+ /* Compute the final size. */
+ finalize_record_size (rli);
+
+ /* Compute the TYPE_MODE for the record. */
+ compute_record_mode (rli->t);
/* Lay out any static members. This is done now because their type
may use the record's type. */
@@ -1008,83 +1171,10 @@ finish_record_layout (rli)
/* Perform any last tweaks to the TYPE_SIZE, etc. */
finalize_type_size (rli->t);
+
/* Clean up. */
free (rli);
}
-
-/* Like finish_record_layout, but for unions. */
-
-static void
-finish_union_layout (rli)
- record_layout_info rli;
-{
- /* This function should only be used for unions; use
- finish_record_layout for RECORD_TYPEs. */
- if (TREE_CODE (rli->t) != UNION_TYPE
- && TREE_CODE (rli->t) != QUAL_UNION_TYPE)
- abort ();
-
- /* Determine the ultimate size of the union (in bytes). */
- if (NULL == rli->var_size)
- TYPE_SIZE (rli->t)
- = bitsize_int (CEIL (rli->const_size, BITS_PER_UNIT) * BITS_PER_UNIT);
-
- else if (rli->const_size == 0)
- TYPE_SIZE (rli->t) = rli->var_size;
- else
- TYPE_SIZE (rli->t) = size_binop (MAX_EXPR, rli->var_size,
- round_up (bitsize_int (rli->const_size),
- BITS_PER_UNIT));
-
- /* Determine the desired alignment. */
-#ifdef ROUND_TYPE_ALIGN
- TYPE_ALIGN (rli->t) = ROUND_TYPE_ALIGN (rli->t, TYPE_ALIGN (rli->t),
- rli->record_align);
-#else
- TYPE_ALIGN (rli->t) = MAX (TYPE_ALIGN (rli->t), rli->record_align);
-#endif
-
-#ifdef ROUND_TYPE_SIZE
- TYPE_SIZE (rli->t) = ROUND_TYPE_SIZE (rli->t, TYPE_SIZE (rli->t),
- TYPE_ALIGN (rli->t));
-#else
- /* Round the size up to be a multiple of the required alignment */
- TYPE_SIZE (rli->t) = round_up (TYPE_SIZE (rli->t),
- TYPE_ALIGN (rli->t));
-#endif
-
- TYPE_MODE (rli->t) = BLKmode;
- if (TREE_CODE (TYPE_SIZE (rli->t)) == INTEGER_CST
- /* If structure's known alignment is less than
- what the scalar mode would need, and it matters,
- then stick with BLKmode. */
- && (! STRICT_ALIGNMENT
- || TYPE_ALIGN (rli->t) >= BIGGEST_ALIGNMENT
- || compare_tree_int (TYPE_SIZE (rli->t),
- TYPE_ALIGN (rli->t)) <= 0))
- {
- tree field;
-
- /* A union which has any BLKmode members must itself be BLKmode;
- it can't go in a register.
- Unless the member is BLKmode only because it isn't aligned. */
- for (field = TYPE_FIELDS (rli->t);
- field;
- field = TREE_CHAIN (field))
- {
- if (TREE_CODE (field) != FIELD_DECL)
- continue;
-
- if (TYPE_MODE (TREE_TYPE (field)) == BLKmode
- && ! TYPE_NO_FORCE_BLK (TREE_TYPE (field)))
- return;
- }
-
- TYPE_MODE (rli->t)
- = mode_for_size_tree (TYPE_SIZE (rli->t), MODE_INT, 1);
- }
-}
-
/* Calculate the mode, size, and alignment for TYPE.
For an array type, calculate the element separation as well.
@@ -1163,8 +1253,7 @@ layout_type (type)
break;
case VOID_TYPE:
- /* VOID_TYPE is an incompletable type, it has no size */
- TYPE_SIZE_UNIT (type) = size_zero_node;
+ /* This is an incomplete type and so doesn't have a size. */
TYPE_ALIGN (type) = 1;
TYPE_MODE (type) = VOIDmode;
break;
@@ -1325,17 +1414,21 @@ layout_type (type)
record_layout_info rli;
/* Initialize the layout information. */
- rli = new_record_layout_info (type);
+ rli = start_record_layout (type);
+
/* If this is a QUAL_UNION_TYPE, we want to process the fields
in the reverse order in building the COND_EXPR that denotes
its size. We reverse them again later. */
if (TREE_CODE (type) == QUAL_UNION_TYPE)
TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
- /* Layout all the fields. */
+
+ /* Place all the fields. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
- layout_field (rli, field);
+ place_field (rli, field);
+
if (TREE_CODE (type) == QUAL_UNION_TYPE)
TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type));
+
/* Finish laying out the record. */
finish_record_layout (rli);
}
@@ -1395,10 +1488,7 @@ layout_type (type)
/* If this type is created before sizetype has been permanently set,
record it so set_sizetype can fix it up. */
if (! sizetype_set)
- {
- TREE_CHAIN (type) = early_type_list;
- early_type_list = type;
- }
+ early_type_list = tree_cons (NULL_TREE, type, early_type_list);
}
/* Create and return a type for signed integers of PRECISION bits. */
@@ -1448,6 +1538,7 @@ initialize_sizetypes ()
TREE_UNSIGNED (t) = 1;
TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode);
TYPE_MIN_VALUE (t) = build_int_2 (0, 0);
+ TYPE_IS_SIZETYPE (t) = 1;
/* 1000 avoids problems with possible overflow and is certainly
larger than any size value we'd want to be storing. */
@@ -1475,7 +1566,7 @@ set_sizetype (type)
int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1,
2 * HOST_BITS_PER_WIDE_INT);
unsigned int i;
- tree t, next;
+ tree t;
if (sizetype_set)
abort ();
@@ -1483,9 +1574,11 @@ set_sizetype (type)
/* Make copies of nodes since we'll be setting TYPE_IS_SIZETYPE. */
sizetype = copy_node (type);
TYPE_DOMAIN (sizetype) = type;
+ TYPE_IS_SIZETYPE (sizetype) = 1;
bitsizetype = make_node (INTEGER_TYPE);
TYPE_NAME (bitsizetype) = TYPE_NAME (type);
TYPE_PRECISION (bitsizetype) = precision;
+ TYPE_IS_SIZETYPE (bitsizetype) = 1;
if (TREE_UNSIGNED (type))
fixup_unsigned_type (bitsizetype);
@@ -1526,16 +1619,13 @@ set_sizetype (type)
/* Go down each of the types we already made and set the proper type
for the sizes in them. */
- for (t = early_type_list; t != 0; t = next)
+ for (t = early_type_list; t != 0; t = TREE_CHAIN (t))
{
- next = TREE_CHAIN (t);
- TREE_CHAIN (t) = 0;
-
- if (TREE_CODE (t) != INTEGER_TYPE)
+ if (TREE_CODE (TREE_VALUE (t)) != INTEGER_TYPE)
abort ();
- TREE_TYPE (TYPE_SIZE (t)) = bitsizetype;
- TREE_TYPE (TYPE_SIZE_UNIT (t)) = sizetype;
+ TREE_TYPE (TYPE_SIZE (TREE_VALUE (t))) = bitsizetype;
+ TREE_TYPE (TYPE_SIZE_UNIT (TREE_VALUE (t))) = sizetype;
}
early_type_list = 0;
@@ -1624,7 +1714,7 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
int volatilep;
{
enum machine_mode mode;
- int unit = 0;
+ unsigned int unit = 0;
/* Find the narrowest integer mode that contains the bit field. */
for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
@@ -1643,7 +1733,7 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
if the extra 4th byte is past the end of memory.
(Though at least one Unix compiler ignores this problem:
that on the Sequent 386 machine. */
- || MIN (unit, BIGGEST_ALIGNMENT) > (int) align
+ || MIN (unit, BIGGEST_ALIGNMENT) > align
|| (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE (largest_mode)))
return VOIDmode;
@@ -1657,7 +1747,7 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep)
unit = GET_MODE_BITSIZE (tmode);
if (bitpos / unit == (bitpos + bitsize - 1) / unit
&& unit <= BITS_PER_WORD
- && unit <= (int) MIN (align, BIGGEST_ALIGNMENT)
+ && unit <= MIN (align, BIGGEST_ALIGNMENT)
&& (largest_mode == VOIDmode
|| unit <= GET_MODE_BITSIZE (largest_mode)))
wide_mode = tmode;
@@ -1677,12 +1767,10 @@ unsigned int
get_mode_alignment (mode)
enum machine_mode mode;
{
- unsigned alignment = GET_MODE_UNIT_SIZE (mode);
+ unsigned int alignment = GET_MODE_UNIT_SIZE (mode) * BITS_PER_UNIT;
/* Extract the LSB of the size. */
alignment = alignment & -alignment;
-
- alignment *= BITS_PER_UNIT;
alignment = MIN (BIGGEST_ALIGNMENT, MAX (1, alignment));
return alignment;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 163776a7ff2..6602129ede9 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,78 @@
+2000-04-08 Neil Booth <NeilB@earthling.net>
+
+ * gcc.dg/cpp-nullchar.c: Remove test as
+ embedded nulls cause problems.
+
+2000-04-08 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/compare2.c: New test.
+
+2000-04-08 Neil Booth <NeilB@earthling.net>
+
+ * gcc.dg/cpp-nullchar.c: New test.
+
+2000-04-07 Zack Weinberg <zack@wolery.cumb.org>
+
+ * gcc.dg/cpp-mi2.c: New test.
+ * gcc.dg/cpp-mi2[abc].h: New files.
+
+2000-04-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.old-deja/g++.abi/vmihint.C: Adjust __vmi_class_type_info
+ member name.
+
+2000-04-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.old-deja/g++.abi/vmihint.C: New test.
+
+2000-04-06 Neil Booth <NeilB@earthling.net>
+
+ * cpp-ifparen.c, cpp-missingop.c, cpp-missingparen.c,
+ cpp-shift.c, cpp-shortcircuit.c, cpp-unary.c: Add FSF
+ copyright.
+
+2000-04-04 Geoff Keating <geoffk@cygnus.com>
+
+ * gcc.dg/cast-qual-1.c: Revert last change.
+
+2000-04-04 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/cast-qual-1.c: Check casts through a pointer typedef.
+
+2000-04-03 Zack Weinberg <zack@wolery.cumb.org>
+
+ * gcc.dg/cpp-redef-2.c, gcc.dg/cpp-tradwarn1.c,
+ gcc.dg/cpp-unc.c: Add -fno-show-column to compiler options.
+
+Mon Apr 3 02:35:34 2000 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/compile/20000403-2.c: New test.
+ * gcc.c-torture/compile/20000403-1.c: New test.
+
+2000-04-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * gcc.c-torture/compile/981211-1.c: Move to...
+ * gcc.dg/cpp-as1.c: ...here.
+ * gcc.dg/cpp-as2.c: New file.
+
+ * gcc.dg/cpp-tradwarn1.c: Change warning regexps to match the
+ compiler.
+
+2000-04-02 Neil Booth <NeilB@earthling.net>
+
+ * gcc.dg/cpp-cond.c New tests.
+ * gcc.dg/cpp-ifparen.c New tests. Amend existing tests to make
+ accidental success less likely.
+ * gcc.dg/cpp-missingop.c New tests.
+ * gcc.dg/cpp-missingparen.c New tests.
+ * gcc.dg/cpp-shift.c New tests.
+ * gcc.dg/cpp-shortcircuit.c New tests.
+ * gcc.dg/cpp-unary.c New tests.
+
+Wed Mar 29 13:44:23 2000 Jeffrey A Law (law@cygnus.com)
+
+ * gcc.c-torture/compile/20000329-1.c: New test.
+
2000-03-23 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.ext/array4.C: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.abi/vtable.C b/gcc/testsuite/g++.old-deja/g++.abi/vtable.C
index aafcad8d19c..4c811a8c5ab 100644
--- a/gcc/testsuite/g++.old-deja/g++.abi/vtable.C
+++ b/gcc/testsuite/g++.old-deja/g++.abi/vtable.C
@@ -65,7 +65,7 @@ int main ()
if (vtable (&s4) != vtable (s2))
return 1;
- if (vtable (s2) >= vtable (s3))
+ if (vtable (s2) >= vtable (s3))
return 2;
if (vtable (s3) >= vtable (s1))
return 3;
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C b/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
index 4c352c87ae4..a6249546d34 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900205_03.C
@@ -25,10 +25,10 @@ struct00 global_function_1 () {
struct struct0 {
int struct0_member_function_0 () {
- } // ERROR -
+ } // ERROR - XFAIL
struct0 struct0_member_function_1 () {
- } // ERROR -
+ } // ERROR - XFAIL
};
struct struct1 {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C b/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
index 6d333f098bc..a67a1ddc9dc 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/dcast3.C
@@ -28,5 +28,5 @@ int main ()
ap = (C2*)&e2;
// ap points to base subobject shared by two Bs; fails
if (dynamic_cast <B2*> (ap) != 0)
- return 1;
+ return 2;
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/offset2.C b/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
index a598d433431..1ce6386446d 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/offset2.C
@@ -3,7 +3,7 @@
int status = 1;
struct foo {
- foo& operator= (const foo&) { status = 0; }
+ foo& operator= (const foo&) { status = 0; return *this; }
};
struct xx {
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/opeq.C b/gcc/testsuite/g++.old-deja/g++.jason/opeq.C
index f488a7c6d88..c0718506582 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/opeq.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/opeq.C
@@ -8,7 +8,7 @@ class Y
{
public:
Y(char*) {}
- Y& operator = (const Y&) {}
+ Y& operator = (const Y&) { return *this; }
};
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators16.C b/gcc/testsuite/g++.old-deja/g++.law/operators16.C
index 945d7078251..e4c176f0912 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators16.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators16.C
@@ -11,7 +11,7 @@ int pass = 0;
struct A {
A(void) {}
A(const A& a) { ; }
- A& operator = (const A& a) { pass = 1; }
+ A& operator = (const A& a) { pass = 1; return *this; }
};
struct B {
diff --git a/gcc/testsuite/g++.old-deja/g++.law/operators17.C b/gcc/testsuite/g++.old-deja/g++.law/operators17.C
index e652d9cdd79..9c1a03b5531 100644
--- a/gcc/testsuite/g++.old-deja/g++.law/operators17.C
+++ b/gcc/testsuite/g++.old-deja/g++.law/operators17.C
@@ -8,5 +8,5 @@
// Message-ID: <9304291053.AA00090@mencon>
struct A {
- A& operator = (const A& a) {}// ERROR -
+ A& operator = (const A& a) {}// ERROR - XFAIL
};
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net26.C b/gcc/testsuite/g++.old-deja/g++.mike/net26.C
index 753c5f6cd2b..ed43df8e997 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net26.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net26.C
@@ -4,8 +4,8 @@ extern "C" int printf(const char *, ...);
class A {
public:
- int foo() { printf("ok nv\n"); }
- virtual int vfoo() { printf("ok v\n"); }
+ int foo() { printf("ok nv\n"); return 0; }
+ virtual int vfoo() { printf("ok v\n"); return 0; }
};
struct S {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/virt3.C b/gcc/testsuite/g++.old-deja/g++.mike/virt3.C
index de3ea3d07e2..3795b89cca6 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/virt3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/virt3.C
@@ -3,7 +3,7 @@
class B {
public:
int Bi;
- virtual int g() { };
+ virtual int g() { return 0; };
};
class D : private B {
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/virt6.C b/gcc/testsuite/g++.old-deja/g++.mike/virt6.C
index 61491cede48..26e26dd4bad 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/virt6.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/virt6.C
@@ -3,7 +3,7 @@
class C_A {
public:
- virtual int foo(void *) { }
+ virtual int foo(void *) { return 0; }
} a;
class C_B : public C_A {
@@ -17,22 +17,22 @@ class C_D : public C_A {
class C_E : public C_C, public C_B {
public:
- virtual int foo(void *) { }
+ virtual int foo(void *) { return 0; }
} e;
class C_F : public C_D, public C_B {
public:
- virtual int foo(void *) { }
+ virtual int foo(void *) { return 0; }
} f;
class C_G : public C_A {
public:
- virtual int foo(void *) { }
+ virtual int foo(void *) { return 0; }
} g;
class C_H : public C_G, public C_E, public C_F {
public:
- virtual int foo(void *) { }
+ virtual int foo(void *) { return 0; }
} h;
int main() {
diff --git a/gcc/testsuite/g++.old-deja/g++.other/badopt1.C b/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
index 096770e77ad..fbc4b126cd5 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/badopt1.C
@@ -1,6 +1,8 @@
// Based on a testcase by Bryan Weston <bryanw@bluemoon.sps.mot.com>
// egcs 1.1 fails to increment count
+// Special g++ Options: -O2
+
#include <cstdlib>
struct Base { Base() {} }; // removing the constructor fixes the problem
diff --git a/gcc/testsuite/gcc.c-torture/ChangeLog b/gcc/testsuite/gcc.c-torture/ChangeLog
index 3ac1a5a59d6..a09f7a93989 100644
--- a/gcc/testsuite/gcc.c-torture/ChangeLog
+++ b/gcc/testsuite/gcc.c-torture/ChangeLog
@@ -1,3 +1,38 @@
+Wed Apr 5 22:51:36 2000 Hans-Peter Nilsson <hp@axis.com>
+
+ * execute/960327-1.c (f): Add a letter to s[] to avoid stack-frame
+ overwrite.
+
+2000-04-05 Jakub Jelinek <jakub@redhat.com>
+
+ * compile/20000405-2.c: New test.
+ * compile/20000405-3.c: New test.
+
+2000-04-05 Alexandre Oliva <oliva@lsd.ic.unicamp.br>
+
+ * compile/20000405-1.c: New test.
+
+Mon Apr 3 16:53:52 2000 Hans-Peter Nilsson <hp@axis.com>
+
+ * execute/20000403-1.c: New test.
+
+2000-04-03 Geoff Keating <geoffk@cygnus.com>
+
+ * execute/20000402-1.c: New test.
+
+Mon Apr 3 14:10:34 2000 Donald Lindsay <dlindsay@cygnus.com>
+
+ * execute/va-arg-15.c: New test.
+ * execute/va-arg-16.c: New test.
+ * execute/va-arg-17.c: New test.
+ * execute/va-arg-18.c: New test.
+ * execute/va-arg-19.c: New test.
+
+2000-03-26 Bernd Schmidt <bernds@cygnus.co.uk>
+
+ * compile/20000326-1.c: New test.
+ * compile/20000326-2.c: New test.
+
2000-03-24 Geoff Keating <geoffk@cygnus.com>
* execute/va-arg-14.c: New test for va_start where the first
diff --git a/gcc/testsuite/gcc.c-torture/compile/981211-1.c b/gcc/testsuite/gcc.c-torture/compile/981211-1.c
deleted file mode 100644
index 92c9cfb7013..00000000000
--- a/gcc/testsuite/gcc.c-torture/compile/981211-1.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Basic tests of the #assert preprocessor extension. */
-
-#define fail int fail
-
-#assert abc (def)
-#assert abc (ghi)
-#assert abc (jkl)
-#assert space ( s p a c e )
-
-/* Basic: */
-#if !#abc (def) || !#abc (ghi) || !#abc (jkl)
-fail
-#endif
-
-/* any answer for #abc */
-#if !#abc
-fail
-#endif
-
-/* internal whitespace is collapsed,
- external whitespace is deleted */
-#if !#space (s p a c e) || !#space ( s p a c e ) || #space (space)
-fail
-#endif
-
-/* removing assertions */
-#unassert abc (jkl)
-#if !#abc || !#abc (def) || !#abc (ghi) || #abc (jkl)
-fail
-#endif
-
-#unassert abc
-#if #abc || #abc (def) || #abc (ghi) || #abc (jkl)
-fail
-#endif
-
-int gobble
-
-/* make sure it can succeed too.
- also check space before open paren isn't significant */
-#if #space(s p a c e)
-;
-#endif
diff --git a/gcc/testsuite/gcc.c-torture/execute/960327-1.c b/gcc/testsuite/gcc.c-torture/execute/960327-1.c
index d630a7b572c..bc82cb5dacf 100644
--- a/gcc/testsuite/gcc.c-torture/execute/960327-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/960327-1.c
@@ -6,7 +6,7 @@ g ()
f ()
{
- char s[] = "abcedfg01234";
+ char s[] = "abcedfg012345";
char *sp = s + 12;
switch (g ())
diff --git a/gcc/testsuite/gcc.dg/cpp-if1.c b/gcc/testsuite/gcc.dg/cpp-if1.c
index d3b078fc3c6..9b7c8d3b997 100644
--- a/gcc/testsuite/gcc.dg/cpp-if1.c
+++ b/gcc/testsuite/gcc.dg/cpp-if1.c
@@ -21,10 +21,10 @@
#if 1.2 /* { dg-error "loating point numbers" "floating point in #if" } */
#endif
-#if 4uu /* { dg-error "(too many|two) `u'" "too many suffixes" } */
+#if 4uu /* { dg-error "too many 'u'" "too many suffixes" } */
#endif
-#if 124123231lll /* { dg-error "too many `l'" "too many suffixes" } */
+#if 124123231lll /* { dg-error "too many 'l'" "too many suffixes" } */
#endif
#if 099 /* { dg-error "digits beyond the radix" "decimal in octal constant" } */
diff --git a/gcc/testsuite/gcc.dg/cpp-redef-2.c b/gcc/testsuite/gcc.dg/cpp-redef-2.c
index 99af954e8ae..0dacf07f651 100644
--- a/gcc/testsuite/gcc.dg/cpp-redef-2.c
+++ b/gcc/testsuite/gcc.dg/cpp-redef-2.c
@@ -1,7 +1,7 @@
/* Test for redefining macros with significant differences. */
/* { dg-do preprocess }
- { dg-options "-ansi -pedantic -Wall" } */
+ { dg-options "-ansi -pedantic -Wall -fno-show-column" } */
#define mac(a, b) (a) + (b)
#define mac(a, b) (a) * (b)
diff --git a/gcc/testsuite/gcc.dg/cpp-unc.c b/gcc/testsuite/gcc.dg/cpp-unc.c
index 4daddf65e64..110a8a7021b 100644
--- a/gcc/testsuite/gcc.dg/cpp-unc.c
+++ b/gcc/testsuite/gcc.dg/cpp-unc.c
@@ -1,4 +1,5 @@
/* { dg-do preprocess } */
+/* { dg-options "-fno-show-column" } */
/* Tests for un-terminated conditional diagnostics.
Copyright (c) 1999 Free Software Foundation.
diff --git a/gcc/tlink.c b/gcc/tlink.c
index a6130a14c29..32685b19404 100644
--- a/gcc/tlink.c
+++ b/gcc/tlink.c
@@ -550,9 +550,15 @@ read_repo_files (object_lst)
for (; *object; object++)
{
- const char *p = frob_extension (*object, ".rpo");
+ const char *p;
file *f;
+ /* Don't bother trying for ld flags. */
+ if (*object[0] == '-')
+ continue;
+
+ p = frob_extension (*object, ".rpo");
+
if (! file_exists (p))
continue;
diff --git a/gcc/tm.texi b/gcc/tm.texi
index 1a1396f91a8..7d9610c6245 100644
--- a/gcc/tm.texi
+++ b/gcc/tm.texi
@@ -2316,9 +2316,11 @@ during virtual register instantiation.
The default value for this macro is @code{FIRST_PARM_OFFSET (fundecl)},
which is correct for most machines; in general, the arguments are found
-immediately before the stack frame. See @file{function.c} for details.
+immediately before the stack frame. Note that this is not the case on
+some targets that save registers into the caller's frame, such as SPARC
+and rs6000, and so such targets need to define this macro.
-You only need to define this macro if this default is incorrect, and you
+You only need to define this macro if the default is incorrect, and you
want to support call frame debugging information like that provided by
DWARF 2.
@@ -2628,15 +2630,24 @@ errors in certain cases of mismatch, it also makes for better
code on certain machines. If the macro is not defined in target
header files, it defaults to 0.
+@findex PUSH_ARGS
+@item PUSH_ARGS
+A C expression. If nonzero, push insns will be used to pass
+outgoing arguments.
+If the target machine does not have a push instruction, set it to zero.
+That directs GCC to use an alternate strategy: to
+allocate the entire argument block and then store the arguments into
+it. When PUSH_ARGS is nonzero, PUSH_ROUNDING must be defined too.
+On some machines, the definition
+
+@findex PUSH_ROUNDING
+@item PUSH_ROUNDING (@var{npushed})
+A C expression that is the number of bytes actually pushed onto the
+stack when an instruction attempts to push @var{npushed} bytes.
@findex PUSH_ROUNDING
@item PUSH_ROUNDING (@var{npushed})
A C expression that is the number of bytes actually pushed onto the
stack when an instruction attempts to push @var{npushed} bytes.
-
-If the target machine does not have a push instruction, do not define
-this macro. That directs GCC to use an alternate strategy: to
-allocate the entire argument block and then store the arguments into
-it.
On some machines, the definition
@@ -2656,13 +2667,13 @@ alignment. Then the definition should be
@findex ACCUMULATE_OUTGOING_ARGS
@findex current_function_outgoing_args_size
@item ACCUMULATE_OUTGOING_ARGS
-If defined, the maximum amount of space required for outgoing arguments
+A C expression. If nonzero, the maximum amount of space required for outgoing arguments
will be computed and placed into the variable
@code{current_function_outgoing_args_size}. No space will be pushed
onto the stack for each call; instead, the function prologue should
increase the stack frame size by this amount.
-Defining both @code{PUSH_ROUNDING} and @code{ACCUMULATE_OUTGOING_ARGS}
+Setting both @code{PUSH_ARGS} and @code{ACCUMULATE_OUTGOING_ARGS}
is not proper.
@findex REG_PARM_STACK_SPACE
@@ -7931,4 +7942,12 @@ Note that this functionality is part of POSIX.
Defining @code{TARGET_HAS_F_SETLKW} will enable the test coverage code
to use file locking when exiting a program, which avoids race conditions
if the program has forked.
+
+@findex MAX_CONDITIONAL_EXECUTE
+@item MAX_CONDITIONAL_EXECUTE
+
+A C expression for the maximum number of instructions to execute via
+conditional execution instructions instead of a branch. A value of
+@code{BRANCH_COST}+1 is the default if the machine does not use cc0, and
+1 if it does use cc0.
@end table
diff --git a/gcc/toplev.c b/gcc/toplev.c
index bf6dce21277..00721b31248 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -61,6 +61,10 @@ Boston, MA 02111-1307, USA. */
#include "loop.h"
#include "regs.h"
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
+
#ifdef DWARF_DEBUGGING_INFO
#include "dwarfout.h"
#endif
@@ -158,19 +162,16 @@ static void pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
static void output_lang_identify PARAMS ((FILE *)) ATTRIBUTE_UNUSED;
#endif
-static void open_dump_file PARAMS ((const char *, const char *));
-static void close_dump_file PARAMS ((void (*) (FILE *, rtx), rtx));
-static void dump_rtl PARAMS ((const char *, tree, void (*) (FILE *, rtx), rtx));
-static void clean_dump_file PARAMS ((const char *));
static void compile_file PARAMS ((char *));
static void display_help PARAMS ((void));
static void mark_file_stack PARAMS ((void *));
static void decode_d_option PARAMS ((const char *));
-static int decode_f_option PARAMS ((const char *));
-static int decode_W_option PARAMS ((const char *));
-static int decode_g_option PARAMS ((const char *));
-static unsigned independent_decode_option PARAMS ((int, char **, unsigned));
+static int decode_f_option PARAMS ((const char *));
+static int decode_W_option PARAMS ((const char *));
+static int decode_g_option PARAMS ((const char *));
+static unsigned int independent_decode_option PARAMS ((int, char **,
+ unsigned int));
static void print_version PARAMS ((FILE *, const char *));
static int print_single_switch PARAMS ((FILE *, int, int, const char *,
@@ -225,42 +226,101 @@ const char *dump_base_name;
extern int target_flags;
-/* Flags saying which kinds of debugging dump have been requested. */
-
-int rtl_dump = 0;
-int rtl_dump_and_exit = 0;
-int jump_opt_dump = 0;
-int addressof_dump = 0;
-int cse_dump = 0;
-int gcse_dump = 0;
-int loop_dump = 0;
-int cse2_dump = 0;
-int branch_prob_dump = 0;
-int flow_dump = 0;
-int combine_dump = 0;
-int regmove_dump = 0;
-int sched_dump = 0;
-int local_reg_dump = 0;
-int global_reg_dump = 0;
-int flow2_dump = 0;
-int peephole2_dump = 0;
-int sched2_dump = 0;
-int jump2_opt_dump = 0;
-#ifdef DELAY_SLOTS
-int dbr_sched_dump = 0;
-#endif
-int reorder_blocks_dump = 0;
-int flag_print_asm_name = 0;
-#ifdef STACK_REGS
-int stack_reg_dump = 0;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-int mach_dep_reorg_dump = 0;
-#endif
-int ssa_dump = 0;
-static int flag_print_mem = 0;
-static int version_flag = 0;
-static char * filename = 0;
+/* Describes a dump file. */
+
+struct dump_file_info
+{
+ /* The unique extension to apply, e.g. ".jump". */
+ const char * const extension;
+
+ /* The -d<c> character that enables this dump file. */
+ char const debug_switch;
+
+ /* True if there is a corresponding graph dump file. */
+ char const graph_dump_p;
+
+ /* True if the user selected this dump. */
+ char enabled;
+
+ /* True if the files have been initialized (ie truncated). */
+ char initialized;
+};
+
+/* Enumerate the extant dump files. */
+
+enum dump_file_index
+{
+ DFI_rtl,
+ DFI_jump,
+ DFI_cse,
+ DFI_addressof,
+ DFI_ssa,
+ DFI_ussa,
+ DFI_gcse,
+ DFI_loop,
+ DFI_cse2,
+ DFI_bp,
+ DFI_flow,
+ DFI_combine,
+ DFI_regmove,
+ DFI_sched,
+ DFI_lreg,
+ DFI_greg,
+ DFI_flow2,
+ DFI_peephole2,
+ DFI_sched2,
+ DFI_bbro,
+ DFI_rnreg,
+ DFI_jump2,
+ DFI_mach,
+ DFI_dbr,
+ DFI_stack,
+ DFI_MAX
+};
+
+/* Describes all the dump files. Should be kept in order of the
+ pass and in sync with dump_file_index above. */
+
+struct dump_file_info dump_file[DFI_MAX] =
+{
+ { "rtl", 'r', 0, 0, 0 },
+ { "jump", 'j', 0, 0, 0 },
+ { "cse", 's', 0, 0, 0 },
+ { "addressof", 'F', 0, 0, 0 },
+ { "ssa", 'e', 1, 0, 0 },
+ { "ussa", 'e', 1, 0, 0 }, /* Yes, duplicate enable switch. */
+ { "gcse", 'G', 1, 0, 0 },
+ { "loop", 'L', 1, 0, 0 },
+ { "cse2", 't', 1, 0, 0 },
+ { "bp", 'b', 1, 0, 0 },
+ { "flow", 'f', 1, 0, 0 },
+ { "combine", 'c', 1, 0, 0 },
+ { "regmove", 'N', 1, 0, 0 },
+ { "sched", 'S', 1, 0, 0 },
+ { "lreg", 'l', 1, 0, 0 },
+ { "greg", 'g', 1, 0, 0 },
+ { "flow2", 'w', 1, 0, 0 },
+ { "peephole2", 'z', 1, 0, 0 },
+ { "sched2", 'R', 1, 0, 0 },
+ { "bbro", 'B', 1, 0, 0 },
+ { "rnreg", 'n', 1, 0, 0 },
+ { "jump2", 'J', 1, 0, 0 },
+ { "mach", 'M', 1, 0, 0 },
+ { "dbr", 'd', 0, 0, 0 },
+ { "stack", 'k', 1, 0, 0 },
+};
+
+static int open_dump_file PARAMS ((enum dump_file_index, tree));
+static void close_dump_file PARAMS ((enum dump_file_index,
+ void (*) (FILE *, rtx), rtx));
+
+/* Other flags saying which kinds of debugging dump have been requested. */
+
+int rtl_dump_and_exit;
+int flag_print_asm_name;
+static int flag_print_mem;
+static int version_flag;
+static char * filename;
enum graph_dump_types graph_dump_format;
/* Name for output file of assembly code, specified with -o. */
@@ -365,6 +425,10 @@ int flag_branch_probabilities = 0;
int flag_reorder_blocks = 0;
+/* Nonzero if registers should be renamed */
+
+int flag_rename_registers = 0;
+
/* Nonzero for -pedantic switch: warn about anything
that standard spec forbids. */
@@ -518,6 +582,10 @@ int flag_no_peephole = 0;
int flag_fast_math = 0;
+/* Nonzero allows GCC to optimize sibling and tail recursive calls. */
+
+int flag_optimize_sibling_calls = 0;
+
/* Nonzero means the front end generally wants `errno' maintained by math
operations, like built-in SQRT, unless overridden by flag_fast_math. */
@@ -862,6 +930,8 @@ lang_independent_options f_options[] =
"Defer popping functions args from stack until later" },
{"omit-frame-pointer", &flag_omit_frame_pointer, 1,
"When possible do not generate stack frames"},
+ {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
+ "Optimize sibling and tail recursive calls" },
{"cse-follow-jumps", &flag_cse_follow_jumps, 1,
"When running CSE, follow jumps to their targets" },
{"cse-skip-blocks", &flag_cse_skip_blocks, 1,
@@ -955,6 +1025,8 @@ lang_independent_options f_options[] =
"Use profiling information for branch probabilities" },
{"reorder-blocks", &flag_reorder_blocks, 1,
"Reorder basic blocks to improve code placement" },
+ {"rename-registers", &flag_rename_registers, 1,
+ "Do the register renaming optimization pass"},
{"fast-math", &flag_fast_math, 1,
"Improve FP speed by violating ANSI & IEEE rules" },
{"common", &flag_no_common, 0,
@@ -1351,8 +1423,11 @@ int peephole2_time;
int sched2_time;
int dbr_sched_time;
int reorder_blocks_time;
+int rename_registers_time;
int shorten_branch_time;
int stack_reg_time;
+int to_ssa_time;
+int from_ssa_time;
int final_time;
int symout_time;
int dump_time;
@@ -1437,9 +1512,9 @@ print_time (str, total)
int total;
{
fprintf (stderr,
- "time in %s: %d.%06d (%.0f%%)\n",
+ "time in %s: %d.%06d (%d%%)\n",
str, total / 1000000, total % 1000000,
- all_time == 0 ? 0.00 : (double) total / (double) all_time * 100.0);
+ all_time == 0 ? 0 : (100 * total) / all_time);
}
/* This is the default decl_printable_name function. */
@@ -1725,46 +1800,89 @@ output_lang_identify (asm_out_file)
}
#endif
-/* Routine to open a dump file. */
-static void
-open_dump_file (suffix, function_name)
- const char *suffix;
- const char *function_name;
+/* Routine to open a dump file. Return true if the dump file is enabled. */
+
+static int
+open_dump_file (index, decl)
+ enum dump_file_index index;
+ tree decl;
{
- char *dumpname;
+ char *dump_name;
+ const char *open_arg;
+ char seq[16];
+
+ if (! dump_file[index].enabled)
+ return 0;
TIMEVAR
(dump_time,
- {
- dumpname = concat (dump_base_name, suffix, NULL);
-
- if (rtl_dump_file != NULL)
- fclose (rtl_dump_file);
+ {
+ if (rtl_dump_file != NULL)
+ fclose (rtl_dump_file);
- rtl_dump_file = fopen (dumpname, "a");
-
- if (rtl_dump_file == NULL)
- pfatal_with_name (dumpname);
+ sprintf (seq, ".%02d.", index);
+
+ if (! dump_file[index].initialized)
+ {
+ /* If we've not initialized the files, do so now. */
+ if (graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ dump_name = concat (seq, dump_file[index].extension, NULL);
+ clean_graph_dump_file (dump_base_name, dump_name);
+ free (dump_name);
+ }
+ dump_file[index].initialized = 1;
+ open_arg = "w";
+ }
+ else
+ open_arg = "a";
+
+ dump_name = concat (dump_base_name, seq,
+ dump_file[index].extension, NULL);
+
+ rtl_dump_file = fopen (dump_name, open_arg);
+ if (rtl_dump_file == NULL)
+ pfatal_with_name (dump_name);
- free (dumpname);
+ free (dump_name);
- if (function_name)
- fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
- });
+ if (decl)
+ fprintf (rtl_dump_file, "\n;; Function %s\n\n",
+ decl_printable_name (decl, 2));
+ });
- return;
+ return 1;
}
/* Routine to close a dump file. */
+
static void
-close_dump_file (func, insns)
+close_dump_file (index, func, insns)
+ enum dump_file_index index;
void (*func) PARAMS ((FILE *, rtx));
rtx insns;
{
+ if (! rtl_dump_file)
+ return;
+
TIMEVAR
(dump_time,
- {
- if (func)
+ {
+ if (insns
+ && graph_dump_format != no_graph
+ && dump_file[index].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
+
+ sprintf (seq, ".%02d.", index);
+ suffix = concat (seq, dump_file[index].extension, NULL);
+ print_rtl_graph_with_bb (dump_base_name, suffix, insns);
+ free (suffix);
+ }
+
+ if (func && insns)
func (rtl_dump_file, insns);
fflush (rtl_dump_file);
@@ -1772,40 +1890,6 @@ close_dump_file (func, insns)
rtl_dump_file = NULL;
});
-
- return;
-}
-
-/* Routine to dump rtl into a file. */
-static void
-dump_rtl (suffix, decl, func, insns)
- const char *suffix;
- tree decl;
- void (*func) PARAMS ((FILE *, rtx));
- rtx insns;
-{
- open_dump_file (suffix, decl_printable_name (decl, 2));
- close_dump_file (func, insns);
-}
-
-/* Routine to empty a dump file. */
-static void
-clean_dump_file (suffix)
- const char *suffix;
-{
- char * const dumpname = concat (dump_base_name, suffix, NULL);
-
- rtl_dump_file = fopen (dumpname, "w");
-
- if (rtl_dump_file == NULL)
- pfatal_with_name (dumpname);
-
- free (dumpname);
-
- fclose (rtl_dump_file);
- rtl_dump_file = NULL;
-
- return;
}
/* Do any final processing required for the declarations in VEC, of
@@ -2091,8 +2175,11 @@ compile_file (name)
sched2_time = 0;
dbr_sched_time = 0;
reorder_blocks_time = 0;
+ rename_registers_time = 0;
shorten_branch_time = 0;
stack_reg_time = 0;
+ to_ssa_time = 0;
+ from_ssa_time = 0;
final_time = 0;
symout_time = 0;
dump_time = 0;
@@ -2137,153 +2224,6 @@ compile_file (name)
pfatal_with_name (aux_info_file_name);
}
- /* Clear the dump files. */
- if (rtl_dump)
- clean_dump_file (".00.rtl");
- if (jump_opt_dump)
- {
- clean_dump_file (".01.jump");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".01.jump");
- }
- if (cse_dump)
- {
- clean_dump_file (".02.cse");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".02.cse");
- }
- if (addressof_dump)
- {
- clean_dump_file (".03.addressof");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".03.addressof");
- }
- if (ssa_dump)
- {
- clean_dump_file (".033.ssa");
- clean_dump_file (".037.ussa");
- }
- if (gcse_dump)
- {
- clean_dump_file (".04.gcse");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".04.gcse");
- }
- if (loop_dump)
- {
- clean_dump_file (".05.loop");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".05.loop");
- }
- if (cse2_dump)
- {
- clean_dump_file (".06.cse2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".06.cse2");
- }
- if (branch_prob_dump)
- {
- clean_dump_file (".07.bp");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".07.bp");
- }
- if (flow_dump)
- {
- clean_dump_file (".08.flow");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".08.flow");
- }
- if (combine_dump)
- {
- clean_dump_file (".09.combine");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".09.combine");
- }
- if (regmove_dump)
- {
- clean_dump_file (".10.regmove");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".10.regmove");
- }
-#ifdef INSN_SCHEDULING
- if (sched_dump)
- {
- clean_dump_file (".11.sched");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".11.sched");
- }
-#endif
- if (local_reg_dump)
- {
- clean_dump_file (".12.lreg");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".12.lreg");
- }
- if (global_reg_dump)
- {
- clean_dump_file (".13.greg");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".13.greg");
- }
- if (flow2_dump)
- {
- clean_dump_file (".14.flow2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".14.flow2");
- }
-#ifdef HAVE_peephole2
- if (peephole2_dump)
- {
- clean_dump_file (".15.peephole2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".15.peephole2");
- }
-#endif
-#ifdef INSN_SCHEDULING
- if (sched2_dump)
- {
- clean_dump_file (".16.sched2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".16.sched2");
- }
-#endif
- if (reorder_blocks_dump)
- {
- clean_dump_file (".bbro");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".bbro");
- }
- if (jump2_opt_dump)
- {
- clean_dump_file (".17.jump2");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".17.jump2");
- }
-#ifdef MACHINE_DEPENDENT_REORG
- if (mach_dep_reorg_dump)
- {
- clean_dump_file (".18.mach");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".18.mach");
- }
-#endif
-#ifdef DELAY_SLOTS
- if (dbr_sched_dump)
- {
- clean_dump_file (".19.dbr");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".19.dbr");
- }
-#endif
-#ifdef STACK_REGS
- if (stack_reg_dump)
- {
- clean_dump_file (".20.stack");
- if (graph_dump_format != no_graph)
- clean_graph_dump_file (dump_base_name, ".20.stack");
- }
-#endif
-
/* Open assembler code output file. */
if (flag_syntax_only)
@@ -2548,19 +2488,19 @@ compile_file (name)
end_final (dump_base_name);
- if (branch_prob_dump)
- open_dump_file (".07.bp", NULL);
+ if (flag_test_coverage || flag_branch_probabilities)
+ {
+ open_dump_file (DFI_bp, NULL);
- TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
+ TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
- if (branch_prob_dump)
- close_dump_file (NULL, NULL_RTX);
+ close_dump_file (DFI_bp, NULL, NULL_RTX);
+ }
#ifdef ASM_FILE_END
ASM_FILE_END (asm_out_file);
#endif
-
/* Language-specific end of compilation actions. */
finish_syntax:
lang_finish ();
@@ -2574,11 +2514,10 @@ compile_file (name)
unlink (aux_info_file_name);
}
- if (combine_dump)
+ if (optimize > 0 && open_dump_file (DFI_combine, NULL))
{
- open_dump_file (".09.combine", NULL);
TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
- close_dump_file (NULL, NULL_RTX);
+ close_dump_file (DFI_combine, NULL, NULL_RTX);
}
/* Close non-debugging input and output files. Take special care to note
@@ -2594,60 +2533,19 @@ compile_file (name)
/* Do whatever is necessary to finish printing the graphs. */
if (graph_dump_format != no_graph)
{
- if (jump_opt_dump)
- finish_graph_dump_file (dump_base_name, ".01.jump");
- if (cse_dump)
- finish_graph_dump_file (dump_base_name, ".02.cse");
- if (addressof_dump)
- finish_graph_dump_file (dump_base_name, ".03.addressof");
- if (gcse_dump)
- finish_graph_dump_file (dump_base_name, ".04.gcse");
- if (loop_dump)
- finish_graph_dump_file (dump_base_name, ".05.loop");
- if (cse2_dump)
- finish_graph_dump_file (dump_base_name, ".06.cse2");
- if (branch_prob_dump)
- finish_graph_dump_file (dump_base_name, ".07.bp");
- if (flow_dump)
- finish_graph_dump_file (dump_base_name, ".08.flow");
- if (combine_dump)
- finish_graph_dump_file (dump_base_name, ".09.combine");
- if (regmove_dump)
- finish_graph_dump_file (dump_base_name, ".10.regmove");
-#ifdef INSN_SCHEDULING
- if (sched_dump)
- finish_graph_dump_file (dump_base_name, ".11.sched");
-#endif
- if (local_reg_dump)
- finish_graph_dump_file (dump_base_name, ".12.lreg");
- if (global_reg_dump)
- finish_graph_dump_file (dump_base_name, ".13.greg");
- if (flow2_dump)
- finish_graph_dump_file (dump_base_name, ".14.flow2");
-#ifdef HAVE_peephole2
- if (flow2_dump)
- finish_graph_dump_file (dump_base_name, ".15.peephole2");
-#endif
-#ifdef INSN_SCHEDULING
- if (sched2_dump)
- finish_graph_dump_file (dump_base_name, ".16.sched2");
-#endif
- if (reorder_blocks_dump)
- finish_graph_dump_file (dump_base_name, ".bbro");
- if (jump2_opt_dump)
- finish_graph_dump_file (dump_base_name, ".17.jump2");
-#ifdef MACHINE_DEPENDENT_REORG
- if (mach_dep_reorg_dump)
- finish_graph_dump_file (dump_base_name, ".18.mach");
-#endif
-#ifdef DELAY_SLOTS
- if (dbr_sched_dump)
- finish_graph_dump_file (dump_base_name, ".19.dbr");
-#endif
-#ifdef STACK_REGS
- if (stack_reg_dump)
- finish_graph_dump_file (dump_base_name, ".20.stack");
-#endif
+ int i;
+
+ for (i = 0; i < DFI_MAX; ++i)
+ if (dump_file[i].initialized && dump_file[i].graph_dump_p)
+ {
+ char seq[16];
+ char *suffix;
+
+ sprintf (seq, ".%02d.", i);
+ suffix = concat (seq, dump_file[i].extension, NULL);
+ finish_graph_dump_file (dump_base_name, suffix);
+ free (suffix);
+ }
}
/* Free up memory for the benefit of leak detectors. */
@@ -2665,6 +2563,8 @@ compile_file (name)
print_time ("integration", integration_time);
print_time ("jump", jump_time);
print_time ("cse", cse_time);
+ print_time ("to ssa", to_ssa_time);
+ print_time ("from ssa", from_ssa_time);
print_time ("gcse", gcse_time);
print_time ("loop", loop_time);
print_time ("cse2", cse2_time);
@@ -2688,6 +2588,7 @@ compile_file (name)
print_time ("dbranch", dbr_sched_time);
#endif
print_time ("bbro", reorder_blocks_time);
+ print_time ("rnreg", rename_registers_time);
print_time ("shorten-branch", shorten_branch_time);
#ifdef STACK_REGS
print_time ("stack-reg", stack_reg_time);
@@ -2925,14 +2826,11 @@ rest_of_compilation (decl)
/* Dump the rtl code if we are dumping rtl. */
- if (rtl_dump)
+ if (open_dump_file (DFI_rtl, decl))
{
- open_dump_file (".00.rtl", decl_printable_name (decl, 2));
-
if (DECL_SAVED_INSNS (decl))
fprintf (rtl_dump_file, ";; (integrable)\n\n");
-
- close_dump_file (print_rtl, insns);
+ close_dump_file (DFI_rtl, print_rtl, insns);
}
/* If function is inline, and we don't yet know whether to
@@ -2963,7 +2861,7 @@ rest_of_compilation (decl)
int saved_optimize = optimize;
optimize = 0;
find_exception_handler_labels ();
- jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN);
optimize = saved_optimize;
}
@@ -2990,7 +2888,7 @@ rest_of_compilation (decl)
/* We may have potential sibling or tail recursion sites. Select one
(of possibly multiple) methods of performing the call. */
init_EXPR_INSN_LIST_cache ();
- if (optimize)
+ if (flag_optimize_sibling_calls)
optimize_sibling_and_tail_recursive_calls ();
if (ggc_p)
@@ -3009,9 +2907,7 @@ rest_of_compilation (decl)
/* Don't return yet if -Wreturn-type; we need to do jump_optimize. */
if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
- {
- goto exit_rest_of_compilation;
- }
+ goto exit_rest_of_compilation;
/* Emit code to get eh context, if needed. */
emit_eh_context ();
@@ -3037,7 +2933,6 @@ rest_of_compilation (decl)
insns = get_insns ();
/* Copy any shared structure that should not be shared. */
-
unshare_all_rtl (current_function_decl, insns);
#ifdef SETJMP_VIA_SAVE_AREA
@@ -3047,45 +2942,49 @@ rest_of_compilation (decl)
#endif
/* Instantiate all virtual registers. */
-
- instantiate_virtual_regs (current_function_decl, get_insns ());
-
- /* See if we have allocated stack slots that are not directly addressable.
- If so, scan all the insns and create explicit address computation
- for all references to such slots. */
- /* fixup_stack_slots (); */
+ instantiate_virtual_regs (current_function_decl, insns);
/* Find all the EH handlers. */
find_exception_handler_labels ();
- if (jump_opt_dump)
- open_dump_file (".01.jump", decl_printable_name (decl, 2));
+ open_dump_file (DFI_jump, decl);
/* Always do one jump optimization pass to ensure that JUMP_LABEL fields
are initialized and to compute whether control can drop off the end
of the function. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
-
- /* Jump optimization, and the removal of NULL pointer checks, may
- have reduced the number of instructions substantially. CSE, and
- future passes, allocate arrays whose dimensions involve the maximum
- instruction UID, so if we can reduce the maximum UID we'll save big on
- memory. */
- renumber_insns (rtl_dump_file);
-
- /* Dump rtl code after jump, if we are doing that. */
- if (jump_opt_dump)
- close_dump_file (print_rtl, insns);
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+ JUMP_AFTER_REGSCAN);
+ });
/* Now is when we stop if -fsyntax-only and -Wreturn-type. */
if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
- goto exit_rest_of_compilation;
+ {
+ close_dump_file (DFI_jump, print_rtl, insns);
+ goto exit_rest_of_compilation;
+ }
+
+ TIMEVAR (jump_time,
+ {
+ /* Try to identify useless null pointer tests and delete them. */
+ if (flag_delete_null_pointer_checks)
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ delete_null_pointer_checks (insns);
+ }
- /* Try to identify useless null pointer tests and delete them. */
- if (flag_delete_null_pointer_checks)
- TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+ /* Jump optimization, and the removal of NULL pointer checks,
+ may have reduced the number of instructions substantially.
+ CSE, and future passes, allocate arrays whose dimensions
+ involve the maximum instruction UID, so if we can reduce
+ the maximum UID we'll save big on memory. */
+ renumber_insns (rtl_dump_file);
+ });
+
+ close_dump_file (DFI_jump, print_rtl, insns);
if (ggc_p)
ggc_collect ();
@@ -3097,8 +2996,7 @@ rest_of_compilation (decl)
if (optimize > 0)
{
- if (cse_dump)
- open_dump_file (".02.cse", decl_printable_name (decl, 2));
+ open_dump_file (DFI_cse, decl);
TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
@@ -3107,6 +3005,7 @@ rest_of_compilation (decl)
TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
0, rtl_dump_file));
+
/* If we are not running the second CSE pass, then we are no longer
expecting CSE to be run. */
cse_not_expected = !flag_rerun_cse_after_loop;
@@ -3122,53 +3021,59 @@ rest_of_compilation (decl)
/* Try to identify useless null pointer tests and delete them. */
if (flag_delete_null_pointer_checks)
- TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+ TIMEVAR (jump_time,
+ {
+ find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+ cleanup_cfg (insns);
+ delete_null_pointer_checks (insns);
+ });
/* The second pass of jump optimization is likely to have
removed a bunch more instructions. */
renumber_insns (rtl_dump_file);
- /* Dump rtl code after cse, if we are doing that. */
- if (cse_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".02.cse", insns);
- }
+ close_dump_file (DFI_cse, print_rtl, insns);
}
+ open_dump_file (DFI_addressof, decl);
+
purge_addressof (insns);
reg_scan (insns, max_reg_num (), 1);
- if (addressof_dump)
- {
- dump_rtl (".03.addressof", decl, print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".03.addressof", insns);
- }
+ close_dump_file (DFI_addressof, print_rtl, insns);
if (ggc_p)
ggc_collect ();
- if (flag_ssa)
+ if (optimize > 0 && flag_ssa)
{
- if (ssa_dump)
- open_dump_file (".033.ssa", decl_printable_name (decl, 2));
- convert_to_ssa ();
- if (ssa_dump)
- close_dump_file (print_rtl_with_bb, insns);
-
- if (ssa_dump)
- open_dump_file (".037.ussa", decl_printable_name (decl, 2));
- convert_from_ssa ();
- /* New registers have been created. Rescan their usage. */
- reg_scan (insns, max_reg_num (), 1);
- if (ssa_dump)
- close_dump_file (print_rtl_with_bb, insns);
-
- /* Life analysis used in SSA adds log_links but these shouldn't
- be there until the flow stage, so clear them away. */
- clear_log_links (insns);
+ open_dump_file (DFI_ssa, decl);
+
+ TIMEVAR (to_ssa_time,
+ {
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ convert_to_ssa ();
+ });
+
+ close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
+
+ open_dump_file (DFI_ussa, decl);
+
+ TIMEVAR (from_ssa_time,
+ {
+ convert_from_ssa ();
+
+ /* New registers have been created. Rescan their usage. */
+ reg_scan (insns, max_reg_num (), 1);
+
+ /* Life analysis used in SSA adds log_links but these
+ shouldn't be there until the flow stage, so clear
+ them away. */
+ clear_log_links (insns);
+ });
+
+ close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3178,10 +3083,14 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_gcse)
{
- if (gcse_dump)
- open_dump_file (".04.gcse", decl_printable_name (decl, 2));
+ open_dump_file (DFI_gcse, decl);
- TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
+ TIMEVAR (gcse_time,
+ {
+ find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+ cleanup_cfg (insns);
+ tem = gcse_main (insns, rtl_dump_file);
+ });
/* If gcse altered any jumps, rerun jump optimizations to clean
things up. */
@@ -3192,23 +3101,18 @@ rest_of_compilation (decl)
!JUMP_AFTER_REGSCAN));
}
- if (gcse_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".04.gcse", insns);
- }
+ close_dump_file (DFI_gcse, print_rtl, insns);
if (ggc_p)
ggc_collect ();
}
+
/* Move constant computations out of loops. */
if (optimize > 0)
{
- if (loop_dump)
- open_dump_file (".05.loop", decl_printable_name (decl, 2));
-
+ open_dump_file (DFI_loop, decl);
+
TIMEVAR
(loop_time,
{
@@ -3217,8 +3121,7 @@ rest_of_compilation (decl)
/* We only want to perform unrolling once. */
loop_optimize (insns, rtl_dump_file, 0, 0);
-
-
+
/* The first call to loop_optimize makes some instructions
trivially dead. We delete those instructions now in the
hope that doing so will make the heuristics in loop work
@@ -3232,14 +3135,7 @@ rest_of_compilation (decl)
loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
});
- /* Dump rtl code after loop opt, if we are doing that. */
-
- if (loop_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".05.loop", insns);
- }
+ close_dump_file (DFI_loop, print_rtl, insns);
if (ggc_p)
ggc_collect ();
@@ -3252,8 +3148,7 @@ rest_of_compilation (decl)
if (optimize > 0)
{
- if (cse2_dump)
- open_dump_file (".06.cse2", decl_printable_name (decl, 2));
+ open_dump_file (DFI_cse2, decl);
if (flag_rerun_cse_after_loop)
{
@@ -3262,14 +3157,20 @@ rest_of_compilation (decl)
the second CSE pass to do a better job. Jump_optimize can change
max_reg_num so we must rerun reg_scan afterwards.
??? Rework to not call reg_scan so often. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES,
- JUMP_AFTER_REGSCAN));
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ jump_optimize (insns, !JUMP_CROSS_JUMP,
+ !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
+ });
- TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
- 1, rtl_dump_file));
+ TIMEVAR (cse2_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ tem = cse_main (insns, max_reg_num (),
+ 1, rtl_dump_file);
+ });
+
if (tem)
TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
!JUMP_NOOP_MOVES,
@@ -3280,17 +3181,14 @@ rest_of_compilation (decl)
{
/* This pass of jump threading straightens out code
that was kinked by loop optimization. */
- TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
- TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
+ TIMEVAR (jump_time,
+ {
+ reg_scan (insns, max_reg_num (), 0);
+ thread_jumps (insns, max_reg_num (), 0);
+ });
}
- /* Dump rtl code after cse, if we are doing that. */
- if (cse2_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".06.cse2", insns);
- }
+ close_dump_file (DFI_cse2, print_rtl, insns);
if (ggc_p)
ggc_collect ();
@@ -3298,21 +3196,14 @@ rest_of_compilation (decl)
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- if (branch_prob_dump)
- open_dump_file (".07.bp", decl_printable_name (decl, 2));
+ open_dump_file (DFI_bp, decl);
- TIMEVAR
- (branch_prob_time,
- {
- branch_prob (insns, rtl_dump_file);
- });
+ TIMEVAR (branch_prob_time,
+ {
+ branch_prob (insns, rtl_dump_file);
+ });
- if (branch_prob_dump)
- {
- close_dump_file (print_rtl, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".07.bp", insns);
- }
+ close_dump_file (DFI_bp, print_rtl, insns);
if (ggc_p)
ggc_collect ();
@@ -3323,8 +3214,7 @@ rest_of_compilation (decl)
/* Print function header into flow dump now
because doing the flow analysis makes some of the dump. */
- if (flow_dump)
- open_dump_file (".08.flow", decl_printable_name (decl, 2));
+ open_dump_file (DFI_flow, decl);
/* Do control and data flow analysis; wrote some of the results to
the dump file. */
@@ -3347,14 +3237,7 @@ rest_of_compilation (decl)
setjmp_args_warning ();
}
- /* Dump rtl after flow analysis. */
-
- if (flow_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".08.flow", insns);
- }
+ close_dump_file (DFI_flow, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3369,6 +3252,8 @@ rest_of_compilation (decl)
{
int rebuild_jump_labels_after_combine = 0;
+ open_dump_file (DFI_combine, decl);
+
TIMEVAR (combine_time,
{
rebuild_jump_labels_after_combine
@@ -3383,14 +3268,7 @@ rest_of_compilation (decl)
TIMEVAR (jump_time, rebuild_jump_labels (insns));
}
- /* Dump rtl code after insn combination. */
-
- if (combine_dump)
- {
- dump_rtl (".09.combine", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".09.combine", insns);
- }
+ close_dump_file (DFI_combine, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3400,18 +3278,12 @@ rest_of_compilation (decl)
necessary for two-address machines. */
if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
{
- if (regmove_dump)
- open_dump_file (".10.regmove", decl_printable_name (decl, 2));
+ open_dump_file (DFI_regmove, decl);
TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
rtl_dump_file));
- if (regmove_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".10.regmove", insns);
- }
+ close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3428,22 +3300,14 @@ rest_of_compilation (decl)
because doing the sched analysis makes some of the dump. */
if (optimize > 0 && flag_schedule_insns)
{
- if (sched_dump)
- open_dump_file (".11.sched", decl_printable_name (decl, 2));
+ open_dump_file (DFI_sched, decl);
/* Do control and data sched analysis,
and write some of the results to dump file. */
TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
- /* Dump rtl after instruction scheduling. */
-
- if (sched_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".11.sched", insns);
- }
+ close_dump_file (DFI_sched, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3455,8 +3319,7 @@ rest_of_compilation (decl)
epilogue thus changing register elimination offsets. */
current_function_is_leaf = leaf_function_p ();
- if (local_reg_dump)
- open_dump_file (".12.lreg", decl_printable_name (decl, 2));
+ open_dump_file (DFI_lreg, decl);
/* Allocate pseudo-regs that are used only within 1 basic block.
@@ -3473,23 +3336,21 @@ rest_of_compilation (decl)
rebuild_label_notes_after_reload = local_alloc ();
});
- /* Dump rtl code after allocating regs within basic blocks. */
-
- if (local_reg_dump)
+ if (dump_file[DFI_lreg].enabled)
{
- TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
- TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+ TIMEVAR (dump_time,
+ {
+ dump_flow_info (rtl_dump_file);
+ dump_local_alloc (rtl_dump_file);
+ });
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".12.lreg", insns);
+ close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
}
if (ggc_p)
ggc_collect ();
- if (global_reg_dump)
- open_dump_file (".13.greg", decl_printable_name (decl, 2));
+ open_dump_file (DFI_greg, decl);
/* If optimizing, allocate remaining pseudo-regs. Do the reload
pass fixing up any insns that are invalid. */
@@ -3515,13 +3376,9 @@ rest_of_compilation (decl)
if (optimize > 0)
reload_cse_regs (insns);
- /* If optimizing and we are performing instruction scheduling after
- reload, then go ahead and split insns now since we are about to
- recompute flow information anyway.
-
- reload_cse_regs may expose more splitting opportunities, expecially
- for double-word operations. */
- if (optimize > 0 && flag_schedule_insns_after_reload)
+ /* If optimizing, then go ahead and split insns now since we are about
+ to recompute flow information anyway. */
+ if (optimize > 0)
split_all_insns (0);
/* Register allocation and reloading may have turned an indirect jump into
@@ -3530,20 +3387,18 @@ rest_of_compilation (decl)
if (rebuild_label_notes_after_reload)
TIMEVAR (jump_time, rebuild_jump_labels (insns));
- if (global_reg_dump)
+ if (dump_file[DFI_greg].enabled)
{
TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".13.greg", insns);
+ close_dump_file (DFI_greg, print_rtl_with_bb, insns);
}
/* Re-create the death notes which were deleted during reload. */
- if (flow2_dump)
- open_dump_file (".14.flow2", decl_printable_name (decl, 2));
+ open_dump_file (DFI_flow2, decl);
TIMEVAR (flow2_time,
{
+ jump_optimize_minimal (insns);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
});
@@ -3561,9 +3416,14 @@ rest_of_compilation (decl)
life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
});
-#ifndef ACCUMULATE_OUTGOING_ARGS
- TIMEVAR (flow2_time, { combine_stack_adjustments (); });
+ /* This is kind of heruistics. We need to run combine_stack_adjustments
+ even for machines with possibly nonzero RETURN_POPS_ARGS
+ and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
+ push instructions will have popping returns. */
+#ifndef PUSH_ROUNDING
+ if (!ACCUMULATE_OUTGOING_ARGS)
#endif
+ TIMEVAR (flow2_time, { combine_stack_adjustments (); });
if (ggc_p)
ggc_collect ();
@@ -3571,49 +3431,30 @@ rest_of_compilation (decl)
flow2_completed = 1;
- if (flow2_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".14.flow2", insns);
- }
+ close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
#ifdef HAVE_peephole2
if (optimize > 0 && flag_peephole2)
{
- if (peephole2_dump)
- open_dump_file (".15.peephole2", decl_printable_name (decl, 2));
+ open_dump_file (DFI_peephole2, decl);
TIMEVAR (peephole2_time, peephole2_optimize (rtl_dump_file));
- if (peephole2_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".15.peephole2", insns);
- }
+ close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
}
#endif
#ifdef INSN_SCHEDULING
if (optimize > 0 && flag_schedule_insns_after_reload)
{
- if (sched2_dump)
- open_dump_file (".16.sched2", decl_printable_name (decl, 2));
+ open_dump_file (DFI_sched2, decl);
/* Do control and data sched analysis again,
and write some more of the results to dump file. */
TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
- /* Dump rtl after post-reorder instruction scheduling. */
-
- if (sched2_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".16.sched2", insns);
- }
+ close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -3627,17 +3468,20 @@ rest_of_compilation (decl)
if (optimize > 0 && flag_reorder_blocks)
{
- if (reorder_blocks_dump)
- open_dump_file (".bbro", decl_printable_name (decl, 2));
+ open_dump_file (DFI_bbro, decl);
TIMEVAR (reorder_blocks_time, reorder_basic_blocks ());
- if (reorder_blocks_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".bbro", insns);
- }
+ close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+ }
+
+ if (optimize > 0 && flag_rename_registers)
+ {
+ open_dump_file (DFI_rnreg, decl);
+
+ TIMEVAR (rename_registers_time, regrename_optimize ());
+
+ close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
}
/* One more attempt to remove jumps to .+1 left by dead-store elimination.
@@ -3645,36 +3489,25 @@ rest_of_compilation (decl)
if (optimize > 0)
{
+ open_dump_file (DFI_jump2, decl);
+
TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
JUMP_NOOP_MOVES,
!JUMP_AFTER_REGSCAN));
- /* Dump rtl code after jump, if we are doing that. */
-
- if (jump2_opt_dump)
- {
- dump_rtl (".17.jump2", decl, print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".17.jump2", insns);
- }
+ close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
}
/* If a machine dependent reorganization is needed, call it. */
#ifdef MACHINE_DEPENDENT_REORG
- if (mach_dep_reorg_dump)
- open_dump_file (".18.mach", decl_printable_name (decl, 2));
+ open_dump_file (DFI_mach, decl);
- MACHINE_DEPENDENT_REORG (insns);
+ MACHINE_DEPENDENT_REORG (insns);
- if (mach_dep_reorg_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".18.mach", insns);
- }
+ close_dump_file (DFI_mach, print_rtl_with_bb, insns);
- if (ggc_p)
- ggc_collect ();
+ if (ggc_p)
+ ggc_collect ();
#endif
/* If a scheduling pass for delayed branches is to be done,
@@ -3683,8 +3516,7 @@ rest_of_compilation (decl)
#ifdef DELAY_SLOTS
if (optimize > 0 && flag_delayed_branch)
{
- if (dbr_sched_dump)
- open_dump_file (".19.dbr", decl_printable_name (decl, 2));
+ open_dump_file (DFI_dbr, decl);
TIMEVAR
(dbr_sched_time,
@@ -3692,39 +3524,25 @@ rest_of_compilation (decl)
dbr_schedule (insns, rtl_dump_file);
});
- if (dbr_sched_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".19.dbr", insns);
- }
- }
+ close_dump_file (DFI_dbr, print_rtl_with_bb, insns);
- if (ggc_p)
- ggc_collect ();
+ if (ggc_p)
+ ggc_collect ();
+ }
#endif
/* Shorten branches.
Note this must run before reg-stack because of death note (ab)use
in the ia32 backend. */
- TIMEVAR (shorten_branch_time,
- {
- shorten_branches (get_insns ());
- });
+ TIMEVAR (shorten_branch_time, shorten_branches (get_insns ()));
#ifdef STACK_REGS
- if (stack_reg_dump)
- open_dump_file (".20.stack", decl_printable_name (decl, 2));
+ open_dump_file (DFI_stack, decl);
TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
- if (stack_reg_dump)
- {
- close_dump_file (print_rtl_with_bb, insns);
- if (graph_dump_format != no_graph)
- print_rtl_graph_with_bb (dump_base_name, ".20.stack", insns);
- }
+ close_dump_file (DFI_stack, print_rtl_with_bb, insns);
if (ggc_p)
ggc_collect ();
@@ -4041,138 +3859,48 @@ static void
decode_d_option (arg)
const char * arg;
{
- while (* arg)
- switch (* arg ++)
+ int i, c, matched;
+
+ while (*arg)
+ switch (c = *arg++)
{
case 'a':
- branch_prob_dump = 1;
- combine_dump = 1;
-#ifdef DELAY_SLOTS
- dbr_sched_dump = 1;
-#endif
- reorder_blocks_dump = 1;
- flow_dump = 1;
- flow2_dump = 1;
- global_reg_dump = 1;
- jump_opt_dump = 1;
- addressof_dump = 1;
- jump2_opt_dump = 1;
- local_reg_dump = 1;
- loop_dump = 1;
- regmove_dump = 1;
- rtl_dump = 1;
- cse_dump = 1;
- cse2_dump = 1;
- gcse_dump = 1;
- sched_dump = 1;
- sched2_dump = 1;
-#ifdef STACK_REGS
- stack_reg_dump = 1;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
- mach_dep_reorg_dump = 1;
-#endif
- peephole2_dump = 1;
- ssa_dump = 1;
+ for (i = 0; i < DFI_MAX; ++i)
+ dump_file[i].enabled = 1;
break;
case 'A':
flag_debug_asm = 1;
break;
- case 'b':
- branch_prob_dump = 1;
- break;
- case 'B':
- reorder_blocks_dump = 1;
- break;
- case 'c':
- combine_dump = 1;
- break;
-#ifdef DELAY_SLOTS
- case 'd':
- dbr_sched_dump = 1;
- break;
-#endif
- case 'e':
- ssa_dump = 1;
- break;
- case 'f':
- flow_dump = 1;
- break;
- case 'F':
- addressof_dump = 1;
- break;
- case 'g':
- global_reg_dump = 1;
- break;
- case 'G':
- gcse_dump = 1;
- break;
- case 'j':
- jump_opt_dump = 1;
- break;
- case 'J':
- jump2_opt_dump = 1;
- break;
-#ifdef STACK_REGS
- case 'k':
- stack_reg_dump = 1;
- break;
-#endif
- case 'l':
- local_reg_dump = 1;
- break;
- case 'L':
- loop_dump = 1;
- break;
case 'm':
flag_print_mem = 1;
break;
-#ifdef MACHINE_DEPENDENT_REORG
- case 'M':
- mach_dep_reorg_dump = 1;
- break;
-#endif
case 'p':
flag_print_asm_name = 1;
break;
- case 'r':
- rtl_dump = 1;
- break;
- case 'R':
- sched2_dump = 1;
- break;
- case 's':
- cse_dump = 1;
- break;
- case 'S':
- sched_dump = 1;
- break;
- case 't':
- cse2_dump = 1;
- break;
- case 'N':
- regmove_dump = 1;
- break;
case 'v':
graph_dump_format = vcg;
break;
- case 'w':
- flow2_dump = 1;
- break;
case 'x':
rtl_dump_and_exit = 1;
break;
case 'y':
set_yydebug (1);
break;
- case 'z':
- peephole2_dump = 1;
- break;
case 'D': /* These are handled by the preprocessor. */
case 'I':
break;
+
default:
- warning ("unrecognized gcc debugging option: %c", arg[-1]);
+ matched = 0;
+ for (i = 0; i < DFI_MAX; ++i)
+ if (c == dump_file[i].debug_switch)
+ {
+ dump_file[i].enabled = 1;
+ matched = 1;
+ }
+
+ if (! matched)
+ warning ("unrecognized gcc debugging option: %c", c);
break;
}
}
@@ -4434,13 +4162,13 @@ ignoring option `%s' due to invalid debug level specification",
number of strings that have already been decoded in a language
specific fashion before this function was invoked. */
-static unsigned
+static unsigned int
independent_decode_option (argc, argv, strings_processed)
int argc;
- char ** argv;
- unsigned strings_processed ATTRIBUTE_UNUSED;
+ char **argv;
+ unsigned int strings_processed;
{
- char * arg = argv[0];
+ char *arg = argv[0];
if (arg[0] != '-' || arg[1] == 0)
{
@@ -4463,7 +4191,7 @@ independent_decode_option (argc, argv, strings_processed)
if (* arg == 'Y')
arg ++;
- switch (* arg)
+ switch (*arg)
{
default:
return 0;
@@ -4480,7 +4208,10 @@ independent_decode_option (argc, argv, strings_processed)
return decode_f_option (arg + 1);
case 'g':
- return decode_g_option (arg + 1);
+ if (strings_processed == 0)
+ return decode_g_option (arg + 1);
+ else
+ return strings_processed;
case 'd':
if (!strcmp (arg, "dumpbase"))
@@ -4729,6 +4460,7 @@ main (argc, argv)
if (optimize >= 2)
{
+ flag_optimize_sibling_calls = 1;
flag_cse_follow_jumps = 1;
flag_cse_skip_blocks = 1;
flag_gcse = 1;
@@ -4777,8 +4509,8 @@ main (argc, argv)
/* Perform normal command line switch decoding. */
for (i = 1; i < argc;)
{
- unsigned lang_processed;
- unsigned indep_processed;
+ unsigned int lang_processed;
+ unsigned int indep_processed;
/* Give the language a chance to decode the option for itself. */
lang_processed = lang_decode_option (argc - i, argv + i);
@@ -4786,7 +4518,7 @@ main (argc, argv)
/* Now see if the option also has a language independent meaning.
Some options are both language specific and language independent,
eg --help. It is possible that there might be options that should
- only be decoded in a language independent way if the were not
+ only be decoded in a language independent way if they were not
decoded in a langauge specific way, which is why 'lang_processed'
is passed in. */
indep_processed = independent_decode_option (argc - i, argv + i,
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 49990a8597b..5779ff994e3 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -136,5 +136,5 @@ extern int sorrycount;
extern const char *progname;
-extern void set_fatal_function PARAMS ((void (*)(const char *, va_list)));
+extern void set_fatal_function PARAMS ((void (*) (const char *, va_list)));
#endif /* __GCC_TOPLEV_H */
diff --git a/gcc/tree.c b/gcc/tree.c
index 51c8c3872e3..66078e5646a 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -281,6 +281,7 @@ static void mark_type_hash PARAMS ((void *));
static int type_hash_eq PARAMS ((const void*, const void*));
static unsigned int type_hash_hash PARAMS ((const void*));
static void print_type_hash_statistics PARAMS((void));
+static int mark_hash_entry PARAMS((void **, void *));
/* If non-null, these are language-specific helper functions for
unsave_expr_now. If present, LANG_UNSAVE is called before its
@@ -2171,8 +2172,8 @@ tree_cons (purpose, value, chain)
}
#ifdef GATHER_STATISTICS
- tree_node_counts[(int)x_kind]++;
- tree_node_sizes[(int)x_kind] += sizeof (struct tree_list);
+ tree_node_counts[(int) x_kind]++;
+ tree_node_sizes[(int) x_kind] += sizeof (struct tree_list);
#endif
TREE_SET_CODE (node, TREE_LIST);
@@ -2321,7 +2322,9 @@ tree
bit_position (field)
tree field;
{
- return DECL_FIELD_BITPOS (field);
+
+ return bit_from_pos (DECL_FIELD_OFFSET (field),
+ DECL_FIELD_BIT_OFFSET (field));
}
/* Likewise, but return as an integer. Abort if it cannot be represented
@@ -2335,6 +2338,28 @@ int_bit_position (field)
return tree_low_cst (bit_position (field), 0);
}
+/* Return the byte position of FIELD, in bytes from the start of the record.
+ This is a tree of type sizetype. */
+
+tree
+byte_position (field)
+ tree field;
+{
+ return byte_from_pos (DECL_FIELD_OFFSET (field),
+ DECL_FIELD_BIT_OFFSET (field));
+}
+
+/* Likewise, but return as an integer. Abort if it cannot be represented
+ in that way (since it could be a signed value, we don't have the option
+ of returning -1 like int_size_in_byte can. */
+
+HOST_WIDE_INT
+int_byte_position (field)
+ tree field;
+{
+ return tree_low_cst (byte_position (field), 0);
+}
+
/* Return the strictest alignment, in bits, that T is known to have. */
unsigned int
@@ -2581,6 +2606,13 @@ unsave_expr_1 (expr)
break;
case TARGET_EXPR:
+ /* Don't mess with a TARGET_EXPR that hasn't been expanded.
+ It's OK for this to happen if it was part of a subtree that
+ isn't immediately expanded, such as operand 2 of another
+ TARGET_EXPR. */
+ if (TREE_OPERAND (expr, 1))
+ break;
+
TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3);
TREE_OPERAND (expr, 3) = NULL_TREE;
break;
@@ -4091,8 +4123,8 @@ type_hash_canon (hashcode, type)
obstack_free (TYPE_OBSTACK (type), type);
#ifdef GATHER_STATISTICS
- tree_node_counts[(int)t_kind]--;
- tree_node_sizes[(int)t_kind] -= sizeof (struct tree_type);
+ tree_node_counts[(int) t_kind]--;
+ tree_node_sizes[(int) t_kind] -= sizeof (struct tree_type);
#endif
return t1;
}
@@ -4112,7 +4144,9 @@ mark_hash_entry (entry, param)
void *param ATTRIBUTE_UNUSED;
{
struct type_hash *p = *(struct type_hash **)entry;
+
ggc_mark_tree (p->type);
+
/* Continue scan. */
return 1;
}
@@ -4124,14 +4158,16 @@ mark_type_hash (arg)
void *arg;
{
htab_t t = *(htab_t *) arg;
+
htab_traverse (t, mark_hash_entry, 0);
}
static void
print_type_hash_statistics ()
{
- fprintf (stderr, "Type hash: size %d, %d elements, %f collisions\n",
- htab_size (type_hash_table), htab_elements (type_hash_table),
+ fprintf (stderr, "Type hash: size %ld, %ld elements, %f collisions\n",
+ (long) htab_size (type_hash_table),
+ (long) htab_elements (type_hash_table),
htab_collisions (type_hash_table));
}
@@ -4334,6 +4370,25 @@ tree_int_cst_sgn (t)
return 1;
}
+/* Return true if `t' is known to be non-negative. */
+
+int
+tree_expr_nonnegative_p (t)
+ tree t;
+{
+ switch (TREE_CODE (t))
+ {
+ case INTEGER_CST:
+ return tree_int_cst_sgn (t) >= 0;
+ case COND_EXPR:
+ return tree_expr_nonnegative_p (TREE_OPERAND (t, 1))
+ && tree_expr_nonnegative_p (TREE_OPERAND (t, 2));
+ default:
+ /* We don't know sign of `t', so be safe and return false. */
+ return 0;
+ }
+}
+
/* Compare two constructor-element-type constants. Return 1 if the lists
are known to be equal; otherwise return 0. */
@@ -4594,6 +4649,7 @@ build_index_type (maxval)
{
register tree itype = make_node (INTEGER_TYPE);
+ TREE_TYPE (itype) = sizetype;
TYPE_PRECISION (itype) = TYPE_PRECISION (sizetype);
TYPE_MIN_VALUE (itype) = size_zero_node;
@@ -4605,20 +4661,9 @@ build_index_type (maxval)
TYPE_SIZE (itype) = TYPE_SIZE (sizetype);
TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (sizetype);
TYPE_ALIGN (itype) = TYPE_ALIGN (sizetype);
- if (TREE_CODE (maxval) == INTEGER_CST)
- {
- int maxint = TREE_INT_CST_LOW (maxval);
-
- /* If the domain should be empty, make sure the maxval
- remains -1 and is not spoiled by truncation. */
- if (tree_int_cst_sgn (maxval) < 0)
- {
- TYPE_MAX_VALUE (itype) = build_int_2 (-1, -1);
- TREE_TYPE (TYPE_MAX_VALUE (itype)) = sizetype;
- }
- return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
- }
+ if (host_integerp (maxval, 1))
+ return type_hash_canon (tree_low_cst (maxval, 1), itype);
else
return itype;
}
@@ -4648,21 +4693,11 @@ build_range_type (type, lowval, highval)
TYPE_SIZE (itype) = TYPE_SIZE (type);
TYPE_SIZE_UNIT (itype) = TYPE_SIZE_UNIT (type);
TYPE_ALIGN (itype) = TYPE_ALIGN (type);
- if (TREE_CODE (lowval) == INTEGER_CST)
- {
- HOST_WIDE_INT lowint, highint;
- int maxint;
-
- lowint = TREE_INT_CST_LOW (lowval);
- if (highval && TREE_CODE (highval) == INTEGER_CST)
- highint = TREE_INT_CST_LOW (highval);
- else
- highint = (~(unsigned HOST_WIDE_INT) 0) >> 1;
- maxint = (int) (highint - lowint);
-
- return type_hash_canon (maxint < 0 ? ~maxint : maxint, itype);
- }
+ if (host_integerp (lowval, 0) && highval != 0 && host_integerp (highval, 0))
+ return type_hash_canon (tree_low_cst (highval, 0)
+ - tree_low_cst (lowval, 0),
+ itype);
else
return itype;
}
@@ -4674,7 +4709,7 @@ tree
build_index_2_type (lowval,highval)
tree lowval, highval;
{
- return build_range_type (NULL_TREE, lowval, highval);
+ return build_range_type (sizetype, lowval, highval);
}
/* Return nonzero iff ITYPE1 and ITYPE2 are equal (in the LISP sense).
@@ -5696,14 +5731,13 @@ build_common_tree_nodes_2 (short_double)
{
/* Define these next since types below may used them. */
integer_zero_node = build_int_2 (0, 0);
- TREE_TYPE (integer_zero_node) = integer_type_node;
integer_one_node = build_int_2 (1, 0);
- TREE_TYPE (integer_one_node) = integer_type_node;
- size_zero_node = build_int_2 (0, 0);
- TREE_TYPE (size_zero_node) = sizetype;
- size_one_node = build_int_2 (1, 0);
- TREE_TYPE (size_one_node) = sizetype;
+ size_zero_node = size_int (0);
+ size_one_node = size_int (1);
+ bitsize_zero_node = bitsize_int (0);
+ bitsize_one_node = bitsize_int (1);
+ bitsize_unit_node = bitsize_int (BITS_PER_UNIT);
void_type_node = make_node (VOID_TYPE);
layout_type (void_type_node);
diff --git a/gcc/tree.h b/gcc/tree.h
index bc5225c30ef..03321025181 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1063,27 +1063,33 @@ struct tree_type
containing function, the RECORD_TYPE or UNION_TYPE for the containing
type, or NULL_TREE if the given decl has "file scope". */
#define DECL_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context)
-#define DECL_FIELD_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context)
+#define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.context)
/* In a DECL this is the field where configuration dependent machine
attributes are store */
#define DECL_MACHINE_ATTRIBUTES(NODE) (DECL_CHECK (NODE)->decl.machine_attributes)
-/* In a FIELD_DECL, this is the field position, counting in bits,
- of the bit closest to the beginning of the structure. */
-#define DECL_FIELD_BITPOS(NODE) (DECL_CHECK (NODE)->decl.arguments)
+/* In a FIELD_DECL, this is the field position, counting in bytes, of the
+ byte containing the bit closest to the beginning of the structure. */
+#define DECL_FIELD_OFFSET(NODE) (FIELD_DECL_CHECK (NODE)->decl.arguments)
+/* In a FIELD_DECL, this is the offset, in bits, of the first bit of the
+ field from DECL_FIELD_OFFSET. */
+#define DECL_FIELD_BIT_OFFSET(NODE) (FIELD_DECL_CHECK (NODE)->decl.u2.t)
/* In a FIELD_DECL, this indicates whether the field was a bit-field and
if so, the type that was originally specified for it.
TREE_TYPE may have been modified (in finish_struct). */
-#define DECL_BIT_FIELD_TYPE(NODE) (DECL_CHECK (NODE)->decl.result)
+#define DECL_BIT_FIELD_TYPE(NODE) (FIELD_DECL_CHECK (NODE)->decl.result)
/* In FUNCTION_DECL, a chain of ..._DECL nodes. */
/* VAR_DECL and PARM_DECL reserve the arguments slot
for language-specific uses. */
#define DECL_ARGUMENTS(NODE) (DECL_CHECK (NODE)->decl.arguments)
+/* This field is used to reference anything in decl.result and is meant only
+ for use by the garbage collector. */
+#define DECL_RESULT_FLD(NODE) (DECL_CHECK (NODE)->decl.result)
/* In FUNCTION_DECL, holds the decl for the return value. */
-#define DECL_RESULT(NODE) (DECL_CHECK (NODE)->decl.result)
+#define DECL_RESULT(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.result)
/* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */
-#define DECL_ORIGINAL_TYPE(NODE) (DECL_CHECK (NODE)->decl.result)
+#define DECL_ORIGINAL_TYPE(NODE) (TYPE_DECL_CHECK (NODE)->decl.result)
/* In PARM_DECL, holds the type as written (perhaps a function or array). */
-#define DECL_ARG_TYPE_AS_WRITTEN(NODE) (DECL_CHECK (NODE)->decl.result)
+#define DECL_ARG_TYPE_AS_WRITTEN(NODE) (PARM_DECL_CHECK (NODE)->decl.result)
/* For a FUNCTION_DECL, holds the tree of BINDINGs.
For a VAR_DECL, holds the initial value.
For a PARM_DECL, not used--default
@@ -1092,10 +1098,10 @@ struct tree_type
#define DECL_INITIAL(NODE) (DECL_CHECK (NODE)->decl.initial)
/* For a PARM_DECL, records the data type used to pass the argument,
which may be different from the type seen in the program. */
-#define DECL_ARG_TYPE(NODE) (DECL_CHECK (NODE)->decl.initial)
+#define DECL_ARG_TYPE(NODE) (PARM_DECL_CHECK (NODE)->decl.initial)
/* For a FIELD_DECL in a QUAL_UNION_TYPE, records the expression, which
if nonzero, indicates that the field occupies the type. */
-#define DECL_QUALIFIER(NODE) (DECL_CHECK (NODE)->decl.initial)
+#define DECL_QUALIFIER(NODE) (FIELD_DECL_CHECK (NODE)->decl.initial)
/* These two fields describe where in the source code the declaration was. */
#define DECL_SOURCE_FILE(NODE) (DECL_CHECK (NODE)->decl.filename)
#define DECL_SOURCE_LINE(NODE) (DECL_CHECK (NODE)->decl.linenum)
@@ -1105,7 +1111,9 @@ struct tree_type
/* Likewise for the size in bytes. */
#define DECL_SIZE_UNIT(NODE) (DECL_CHECK (NODE)->decl.size_unit)
/* Holds the alignment required for the datum. */
-#define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.u)
+#define DECL_ALIGN(NODE) (DECL_CHECK (NODE)->decl.u1.a.align)
+/* For FIELD_DECLs, holds the alignment that DECL_FEILD_OFFSET has. */
+#define DECL_OFFSET_ALIGN(NODE) (FIELD_DECL_CHECK (NODE)->decl.u1.a.off_align)
/* Holds the machine mode corresponding to the declaration of a variable or
field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
FIELD_DECL. */
@@ -1121,15 +1129,15 @@ struct tree_type
#define DECL_LIVE_RANGE_RTL(NODE) (DECL_CHECK (NODE)->decl.live_range_rtl)
/* For PARM_DECL, holds an RTL for the stack slot or register
where the data was actually passed. */
-#define DECL_INCOMING_RTL(NODE) (DECL_CHECK (NODE)->decl.u2.r)
+#define DECL_INCOMING_RTL(NODE) (PARM_DECL_CHECK (NODE)->decl.u2.r)
/* For FUNCTION_DECL, if it is inline, holds the saved insn chain. */
-#define DECL_SAVED_INSNS(NODE) (DECL_CHECK (NODE)->decl.u2.f)
+#define DECL_SAVED_INSNS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u2.f)
/* For FUNCTION_DECL, if it is inline,
holds the size of the stack frame, as an integer. */
-#define DECL_FRAME_SIZE(NODE) (DECL_CHECK (NODE)->decl.u1.i)
+#define DECL_FRAME_SIZE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u1.i)
/* For FUNCTION_DECL, if it is built-in,
this identifies which built-in operation it is. */
-#define DECL_FUNCTION_CODE(NODE) (DECL_CHECK (NODE)->decl.u1.f)
+#define DECL_FUNCTION_CODE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.u1.f)
/* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways.
Before the struct containing the FUNCTION_DECL is laid out,
@@ -1142,7 +1150,7 @@ struct tree_type
/* For FIELD_DECLS, DECL_FCONTEXT is the *first* baseclass in
which this FIELD_DECL is defined. This information is needed when
writing debugging information about vfield and vbase decls for C++. */
-#define DECL_FCONTEXT(NODE) (DECL_CHECK (NODE)->decl.vindex)
+#define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.vindex)
/* Every ..._DECL node gets a unique number. */
#define DECL_UID(NODE) (DECL_CHECK (NODE)->decl.uid)
@@ -1206,19 +1214,20 @@ struct tree_type
nonzero means the detail info about this type is not dumped into stabs.
Instead it will generate cross reference ('x') of names.
This uses the same flag as DECL_EXTERNAL. */
-#define TYPE_DECL_SUPPRESS_DEBUG(NODE) (DECL_CHECK (NODE)->decl.external_flag)
-
+#define TYPE_DECL_SUPPRESS_DEBUG(NODE) \
+(TYPE_DECL_CHECK (NODE)->decl.external_flag)
/* In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'. */
#define DECL_REGISTER(NODE) (DECL_CHECK (NODE)->decl.regdecl_flag)
/* In LABEL_DECL nodes, nonzero means that an error message about
jumping into such a binding contour has been printed for this label. */
-#define DECL_ERROR_ISSUED(NODE) (DECL_CHECK (NODE)->decl.regdecl_flag)
+#define DECL_ERROR_ISSUED(NODE) (LABEL_DECL_CHECK (NODE)->decl.regdecl_flag)
/* In a FIELD_DECL, indicates this field should be bit-packed. */
-#define DECL_PACKED(NODE) (DECL_CHECK (NODE)->decl.regdecl_flag)
+#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->decl.regdecl_flag)
/* In a FUNCTION_DECL with a non-zero DECL_CONTEXT, indicates that a
static chain is not needed. */
-#define DECL_NO_STATIC_CHAIN(NODE) (DECL_CHECK (NODE)->decl.regdecl_flag)
+#define DECL_NO_STATIC_CHAIN(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.regdecl_flag)
/* Nonzero in a ..._DECL means this variable is ref'd from a nested function.
For VAR_DECL nodes, PARM_DECL nodes, and FUNCTION_DECL nodes.
@@ -1231,35 +1240,37 @@ struct tree_type
/* Nonzero in a FUNCTION_DECL means this function can be substituted
where it is called. */
-#define DECL_INLINE(NODE) (DECL_CHECK (NODE)->decl.inline_flag)
+#define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag)
/* Nonzero in a FUNCTION_DECL means this is a built-in function
that is not specified by ansi C and that users are supposed to be allowed
to redefine for any purpose whatever. */
-#define DECL_BUILT_IN_NONANSI(NODE) ((NODE)->common.unsigned_flag)
+#define DECL_BUILT_IN_NONANSI(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->common.unsigned_flag)
/* Nonzero in a FUNCTION_DECL means this function should be treated
as if it were a malloc, meaning it returns a pointer that is
not an alias. */
-#define DECL_IS_MALLOC(NODE) (DECL_CHECK (NODE)->decl.malloc_flag)
+#define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag)
/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */
-#define DECL_BIT_FIELD(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
+#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag)
/* In a LABEL_DECL, nonzero means label was defined inside a binding
contour that restored a stack level and which is now exited. */
-#define DECL_TOO_LATE(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
+#define DECL_TOO_LATE(NODE) (LABEL_DECL_CHECK (NODE)->decl.bit_field_flag)
/* Unused in FUNCTION_DECL. */
/* In a VAR_DECL that's static,
nonzero if the space is in the text section. */
-#define DECL_IN_TEXT_SECTION(NODE) (DECL_CHECK (NODE)->decl.bit_field_flag)
+#define DECL_IN_TEXT_SECTION(NODE) (VAR_DECL_CHECK (NODE)->decl.bit_field_flag)
/* In a FUNCTION_DECL, nonzero means a built in function. */
#define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
/* For a builtin function, identify which part of the compiler defined it. */
-#define DECL_BUILT_IN_CLASS(NODE) (DECL_CHECK (NODE)->decl.built_in_class)
+#define DECL_BUILT_IN_CLASS(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.built_in_class)
/* Used in VAR_DECLs to indicate that the variable is a vtable.
Used in FIELD_DECLs for vtable pointers.
@@ -1273,12 +1284,16 @@ struct tree_type
/* Used in PARM_DECLs whose type are unions to indicate that the
argument should be passed in the same way that the first union
alternative would be passed. */
-#define DECL_TRANSPARENT_UNION(NODE) (DECL_CHECK (NODE)->decl.transparent_union)
+#define DECL_TRANSPARENT_UNION(NODE) \
+(PARM_DECL_CHECK (NODE)->decl.transparent_union)
/* Used in FUNCTION_DECLs to indicate that they should be run automatically
at the beginning or end of execution. */
-#define DECL_STATIC_CONSTRUCTOR(NODE) (DECL_CHECK (NODE)->decl.static_ctor_flag)
-#define DECL_STATIC_DESTRUCTOR(NODE) (DECL_CHECK (NODE)->decl.static_dtor_flag)
+#define DECL_STATIC_CONSTRUCTOR(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.static_ctor_flag)
+
+#define DECL_STATIC_DESTRUCTOR(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.static_dtor_flag)
/* Used to indicate that this DECL represents a compiler-generated entity. */
#define DECL_ARTIFICIAL(NODE) (DECL_CHECK (NODE)->decl.artificial_flag)
@@ -1303,15 +1318,18 @@ struct tree_type
/* Used in FUNCTION_DECLs to indicate that function entry and exit should
be instrumented with calls to support routines. */
-#define DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(NODE) ((NODE)->decl.no_instrument_function_entry_exit)
+#define DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.no_instrument_function_entry_exit)
/* Used in FUNCTION_DECLs to indicate that check-memory-usage should be
disabled in this function. */
-#define DECL_NO_CHECK_MEMORY_USAGE(NODE) ((NODE)->decl.no_check_memory_usage)
+#define DECL_NO_CHECK_MEMORY_USAGE(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.no_check_memory_usage)
/* Used in FUNCTION_DECLs to indicate that limit-stack-* should be
disabled in this function. */
-#define DECL_NO_LIMIT_STACK(NODE) ((NODE)->decl.no_limit_stack)
+#define DECL_NO_LIMIT_STACK(NODE) \
+(FUNCTION_DECL_CHECK (NODE)->decl.no_limit_stack)
/* Additional flags for language-specific uses. */
#define DECL_LANG_FLAG_0(NODE) (DECL_CHECK (NODE)->decl.lang_flag_0)
@@ -1391,17 +1409,17 @@ struct tree_decl
/* For a FUNCTION_DECL, if inline, this is the size of frame needed.
If built-in, this is the code for which built-in function.
- For other kinds of decls, this is DECL_ALIGN. */
+ For other kinds of decls, this is DECL_ALIGN and DECL_OFFSET_ALIGN. */
union {
HOST_WIDE_INT i;
- unsigned int u;
enum built_in_function f;
+ struct {unsigned int align : 24; unsigned int off_align : 8;} a;
} u1;
union tree_node *size_unit;
union tree_node *name;
union tree_node *context;
- union tree_node *arguments; /* Also used for DECL_FIELD_BITPOS */
+ union tree_node *arguments; /* Also used for DECL_FIELD_OFFSET */
union tree_node *result; /* Also used for DECL_BIT_FIELD_TYPE */
union tree_node *initial; /* Also used for DECL_QUALIFIER */
union tree_node *abstract_origin;
@@ -1412,6 +1430,7 @@ struct tree_decl
struct rtx_def *live_range_rtl;
/* In FUNCTION_DECL, if it is inline, holds the saved insn chain.
+ In FIELD_DECL, is DECL_FIELD_BIT_OFFSET.
In PARM_DECL, holds an RTL for the stack slot
of register where the data was actually passed.
Used by Chill and Java in LABEL_DECL and by C++ and Java in VAR_DECL. */
@@ -1471,7 +1490,11 @@ enum tree_index
TI_SIZE_ZERO,
TI_SIZE_ONE,
-
+
+ TI_BITSIZE_ZERO,
+ TI_BITSIZE_ONE,
+ TI_BITSIZE_UNIT,
+
TI_COMPLEX_INTEGER_TYPE,
TI_COMPLEX_FLOAT_TYPE,
TI_COMPLEX_DOUBLE_TYPE,
@@ -1510,6 +1533,10 @@ extern tree global_trees[TI_MAX];
#define integer_one_node global_trees[TI_INTEGER_ONE]
#define size_zero_node global_trees[TI_SIZE_ZERO]
#define size_one_node global_trees[TI_SIZE_ONE]
+#define bitsize_zero_node global_trees[TI_BITSIZE_ZERO]
+#define bitsize_one_node global_trees[TI_BITSIZE_ONE]
+#define bitsize_unit_node global_trees[TI_BITSIZE_UNIT]
+
#define null_pointer_node global_trees[TI_NULL_POINTER]
#define float_type_node global_trees[TI_FLOAT_TYPE]
@@ -1670,6 +1697,7 @@ extern int host_integerp PARAMS ((tree, int));
extern HOST_WIDE_INT tree_low_cst PARAMS ((tree, int));
extern int tree_int_cst_msb PARAMS ((tree));
extern int tree_int_cst_sgn PARAMS ((tree));
+extern int tree_expr_nonnegative_p PARAMS ((tree));
extern int index_type_equal PARAMS ((tree, tree));
extern tree get_inner_array_type PARAMS ((tree));
@@ -1749,37 +1777,45 @@ extern void layout_type PARAMS ((tree));
/* These functions allow a front-end to perform a manual layout of a
RECORD_TYPE. (For instance, if the placement of subsequent fields
depends on the placement of fields so far.) Begin by calling
- new_record_layout_info. Then, call layout_field for each of the
+ start_record_layout. Then, call place_field for each of the
fields. Then, call finish_record_layout. See layout_type for the
default way in which these functions are used. */
-struct record_layout_info_s
+typedef struct record_layout_info
{
/* The RECORD_TYPE that we are laying out. */
tree t;
- /* The size of the record so far, in bits. */
- unsigned HOST_WIDE_INT const_size;
+ /* The offset into the record so far, in bytes, not including bits in
+ BITPOS. */
+ tree offset;
+ /* The last known alignment of SIZE. */
+ unsigned int offset_align;
+ /* The bit position within the last OFFSET_ALIGN bits, in bits. */
+ tree bitpos;
/* The alignment of the record so far, in bits. */
unsigned int record_align;
- /* If the record can have a variable size, then this will be
- non-NULL, and the total size will be CONST_SIZE + VAR_SIZE. */
- tree var_size;
- /* If the record can have a variable size, then this will be the
- maximum alignment that we know VAR_SIZE has. */
- unsigned int var_align;
+ /* The alignment of the record so far, not including padding, in bits. */
+ unsigned int unpacked_align;
/* The static variables (i.e., class variables, as opposed to
instance variables) encountered in T. */
tree pending_statics;
- unsigned int unpacked_align;
int packed_maybe_necessary;
-};
-
-typedef struct record_layout_info_s *record_layout_info;
-
-extern record_layout_info new_record_layout_info
- PARAMS ((tree));
-extern void layout_field PARAMS ((record_layout_info, tree));
-extern void finish_record_layout PARAMS ((record_layout_info));
+} *record_layout_info;
+
+extern record_layout_info start_record_layout PARAMS ((tree));
+extern tree bit_from_pos PARAMS ((tree, tree));
+extern tree byte_from_pos PARAMS ((tree, tree));
+extern void pos_from_byte PARAMS ((tree *, tree *, unsigned int,
+ tree));
+extern void pos_from_bit PARAMS ((tree *, tree *, unsigned int,
+ tree));
+extern void normalize_offset PARAMS ((tree *, tree *,
+ unsigned int));
+extern tree rli_size_unit_so_far PARAMS ((record_layout_info));
+extern tree rli_size_so_far PARAMS ((record_layout_info));
+extern void normalize_rli PARAMS ((record_layout_info));
+extern void place_field PARAMS ((record_layout_info, tree));
+extern void finish_record_layout PARAMS ((record_layout_info));
/* Given a hashcode and a ..._TYPE node (for which the hashcode was made),
return a canonicalized ..._TYPE node, so that duplicates are not made.
@@ -1817,6 +1853,8 @@ extern tree size_in_bytes PARAMS ((tree));
extern HOST_WIDE_INT int_size_in_bytes PARAMS ((tree));
extern tree bit_position PARAMS ((tree));
extern HOST_WIDE_INT int_bit_position PARAMS ((tree));
+extern tree byte_position PARAMS ((tree));
+extern HOST_WIDE_INT int_byte_position PARAMS ((tree));
/* Define data structures, macros, and functions for handling sizes
and the various types used to represent sizes. */
@@ -2060,9 +2098,10 @@ extern tree maybe_build_cleanup PARAMS ((tree));
look for nested component-refs or array-refs at constant positions
and find the ultimate containing object, which is returned. */
-extern tree get_inner_reference PARAMS ((tree, int *, int *, tree *,
- enum machine_mode *, int *,
- int *, unsigned int *));
+extern tree get_inner_reference PARAMS ((tree, HOST_WIDE_INT *,
+ HOST_WIDE_INT *, tree *,
+ enum machine_mode *, int *,
+ int *, unsigned int *));
/* Given a DECL or TYPE, return the scope in which it was declared, or
NUL_TREE if there is no containing scope. */
@@ -2460,6 +2499,7 @@ extern void init_function_for_compilation PARAMS ((void));
extern void init_function_start PARAMS ((tree, char *, int));
extern void assign_parms PARAMS ((tree));
extern void put_var_into_stack PARAMS ((tree));
+extern void flush_addressof PARAMS ((tree));
extern void uninitialized_vars_warning PARAMS ((tree));
extern void setjmp_args_warning PARAMS ((void));
extern void mark_all_temps_used PARAMS ((void));
@@ -2512,8 +2552,9 @@ extern struct rtx_def *emit_line_note PARAMS ((const char *, int));
extern struct rtx_def *emit_line_note_force PARAMS ((const char *, int));
/* In calls.c */
-extern void special_function_p PARAMS ((tree, int *, int *,
- int *, int *, int *));
+
+/* Flags used by special_function_p. */
+extern int setjmp_call_p PARAMS ((tree));
/* In c-typeck.c */
extern int mark_addressable PARAMS ((tree));
diff --git a/gcc/unroll.c b/gcc/unroll.c
index ba18c7b183f..aa8f3eeeaf0 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -196,7 +196,7 @@ static int *splittable_regs_updates;
/* Forward declarations. */
static void init_reg_map PARAMS ((struct inline_remap *, int));
-static rtx calculate_giv_inc PARAMS ((rtx, rtx, int));
+static rtx calculate_giv_inc PARAMS ((rtx, rtx, unsigned int));
static rtx initial_reg_note_copy PARAMS ((rtx, struct inline_remap *));
static void final_reg_note_copy PARAMS ((rtx, struct inline_remap *));
static void copy_loop_body PARAMS ((rtx, rtx, struct inline_remap *, rtx, int,
@@ -234,6 +234,7 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
int strength_reduce_p;
{
int i, j;
+ unsigned int r;
unsigned HOST_WIDE_INT temp;
int unroll_number = 1;
rtx copy_start, copy_end;
@@ -243,8 +244,8 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
struct inline_remap *map;
char *local_label = NULL;
char *local_regno;
- int max_local_regnum;
- int maxregnum;
+ unsigned int max_local_regnum;
+ unsigned int maxregnum;
rtx exit_label = 0;
rtx start_label;
struct iv_class *bl;
@@ -829,11 +830,11 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
results in better code. */
/* We must limit the generic test to max_reg_before_loop, because only
these pseudo registers have valid regno_first_uid info. */
- for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; ++j)
- if (REGNO_FIRST_UID (j) > 0 && REGNO_FIRST_UID (j) <= max_uid_for_loop
- && uid_luid[REGNO_FIRST_UID (j)] >= copy_start_luid
- && REGNO_LAST_UID (j) > 0 && REGNO_LAST_UID (j) <= max_uid_for_loop
- && uid_luid[REGNO_LAST_UID (j)] <= copy_end_luid)
+ for (r = FIRST_PSEUDO_REGISTER; r < max_reg_before_loop; ++r)
+ if (REGNO_FIRST_UID (r) > 0 && REGNO_FIRST_UID (r) <= max_uid_for_loop
+ && uid_luid[REGNO_FIRST_UID (r)] >= copy_start_luid
+ && REGNO_LAST_UID (r) > 0 && REGNO_LAST_UID (r) <= max_uid_for_loop
+ && uid_luid[REGNO_LAST_UID (r)] <= copy_end_luid)
{
/* However, we must also check for loop-carried dependencies.
If the value the pseudo has at the end of iteration X is
@@ -844,26 +845,26 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
regno_last_uid. */
/* ??? This check is simplistic. We would get better code if
this check was more sophisticated. */
- if (set_dominates_use (j, REGNO_FIRST_UID (j), REGNO_LAST_UID (j),
+ if (set_dominates_use (r, REGNO_FIRST_UID (r), REGNO_LAST_UID (r),
copy_start, copy_end))
- local_regno[j] = 1;
+ local_regno[r] = 1;
if (loop_dump_stream)
{
- if (local_regno[j])
- fprintf (loop_dump_stream, "Marked reg %d as local\n", j);
+ if (local_regno[r])
+ fprintf (loop_dump_stream, "Marked reg %d as local\n", r);
else
fprintf (loop_dump_stream, "Did not mark reg %d as local\n",
- j);
+ r);
}
}
/* Givs that have been created from multiple biv increments always have
local registers. */
- for (j = first_increment_giv; j <= last_increment_giv; j++)
+ for (r = first_increment_giv; r <= last_increment_giv; r++)
{
- local_regno[j] = 1;
+ local_regno[r] = 1;
if (loop_dump_stream)
- fprintf (loop_dump_stream, "Marked reg %d as local\n", j);
+ fprintf (loop_dump_stream, "Marked reg %d as local\n", r);
}
}
@@ -1080,12 +1081,13 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ());
- for (j = FIRST_PSEUDO_REGISTER; j < max_local_regnum; j++)
- if (local_regno[j])
+ for (r = FIRST_PSEUDO_REGISTER; r < max_local_regnum; r++)
+ if (local_regno[r])
{
- map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
- record_base_value (REGNO (map->reg_map[j]),
- regno_reg_rtx[j], 0);
+ map->reg_map[r]
+ = gen_reg_rtx (GET_MODE (regno_reg_rtx[r]));
+ record_base_value (REGNO (map->reg_map[r]),
+ regno_reg_rtx[r], 0);
}
/* The last copy needs the compare/branch insns at the end,
so reset copy_end here if the loop ends with a conditional
@@ -1223,12 +1225,12 @@ unroll_loop (loop, insn_count, end_insert_before, strength_reduce_p)
if (local_label[j])
set_label_in_map (map, j, gen_label_rtx ());
- for (j = FIRST_PSEUDO_REGISTER; j < max_local_regnum; j++)
- if (local_regno[j])
+ for (r = FIRST_PSEUDO_REGISTER; r < max_local_regnum; r++)
+ if (local_regno[r])
{
- map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
- record_base_value (REGNO (map->reg_map[j]),
- regno_reg_rtx[j], 0);
+ map->reg_map[r] = gen_reg_rtx (GET_MODE (regno_reg_rtx[r]));
+ record_base_value (REGNO (map->reg_map[r]),
+ regno_reg_rtx[r], 0);
}
/* If loop starts with a branch to the test, then fix it so that
@@ -1532,7 +1534,7 @@ init_reg_map (map, maxregnum)
static rtx
calculate_giv_inc (pattern, src_insn, regno)
rtx pattern, src_insn;
- int regno;
+ unsigned int regno;
{
rtx increment;
rtx increment_total = 0;
@@ -1763,7 +1765,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
{
struct iv_class *bl;
struct induction *v, *tv;
- int regno = REGNO (SET_DEST (set));
+ unsigned int regno = REGNO (SET_DEST (set));
v = addr_combined_regs[REGNO (SET_DEST (set))];
bl = reg_biv_class[REGNO (v->src_reg)];
@@ -1856,8 +1858,8 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
&& GET_CODE (SET_DEST (set)) == REG
&& splittable_regs[REGNO (SET_DEST (set))])
{
- int regno = REGNO (SET_DEST (set));
- int src_regno;
+ unsigned int regno = REGNO (SET_DEST (set));
+ unsigned int src_regno;
dest_reg_was_split = 1;
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 3aaca2aa6d4..442fca25892 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1331,7 +1331,6 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
{
register const char *name;
unsigned int align;
- tree size_tree = NULL_TREE;
int reloc = 0;
enum in_section saved_in_section;
@@ -1423,21 +1422,11 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
app_disable ();
- if (! dont_output_data)
+ if (! dont_output_data
+ && ! host_integerp (DECL_SIZE_UNIT (decl), 1))
{
- unsigned int size;
-
- if (TREE_CODE (DECL_SIZE_UNIT (decl)) != INTEGER_CST)
- goto finish;
-
- size_tree = DECL_SIZE_UNIT (decl);
- size = TREE_INT_CST_LOW (size_tree);
-
- if (compare_tree_int (size_tree, size) != 0)
- {
- error_with_decl (decl, "size of variable `%s' is too large");
- goto finish;
- }
+ error_with_decl (decl, "size of variable `%s' is too large");
+ goto finish;
}
name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
@@ -1503,12 +1492,14 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
&& DECL_SECTION_NAME (decl) == NULL_TREE
&& ! dont_output_data)
{
- int size = TREE_INT_CST_LOW (size_tree);
- int rounded = size;
+ unsigned HOST_WIDE_INT size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
+ unsigned HOST_WIDE_INT rounded = size;
/* Don't allocate zero bytes of common,
since that means "undefined external" in the linker. */
- if (size == 0) rounded = 1;
+ if (size == 0)
+ rounded = 1;
+
/* Round size up to multiple of BIGGEST_ALIGNMENT bits
so that each uninitialized object starts on such a boundary. */
rounded += (BIGGEST_ALIGNMENT / BITS_PER_UNIT) - 1;
@@ -1516,7 +1507,7 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
* (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
#if !defined(ASM_OUTPUT_ALIGNED_COMMON) && !defined(ASM_OUTPUT_ALIGNED_BSS)
- if ((DECL_ALIGN (decl) / BITS_PER_UNIT) > (unsigned int) rounded)
+ if (DECL_ALIGN (decl) / BITS_PER_UNIT > rounded)
warning_with_decl
(decl, "requested alignment for %s is greater than implemented alignment of %d.",rounded);
#endif
@@ -1650,10 +1641,11 @@ assemble_variable (decl, top_level, at_end, dont_output_data)
{
if (DECL_INITIAL (decl))
/* Output the actual data. */
- output_constant (DECL_INITIAL (decl), TREE_INT_CST_LOW (size_tree));
+ output_constant (DECL_INITIAL (decl),
+ tree_low_cst (DECL_SIZE_UNIT (decl), 1));
else
/* Leave space for it. */
- assemble_zeros (TREE_INT_CST_LOW (size_tree));
+ assemble_zeros (tree_low_cst (DECL_SIZE_UNIT (decl), 1));
}
finish:
@@ -2279,22 +2271,16 @@ decode_addr_const (exp, value)
while (1)
{
if (TREE_CODE (target) == COMPONENT_REF
- && host_integerp (bit_position (TREE_OPERAND (target, 1)), 0))
+ && host_integerp (byte_position (TREE_OPERAND (target, 1)), 0))
{
- offset
- += int_bit_position (TREE_OPERAND (target, 1)) / BITS_PER_UNIT;
-
+ offset += int_byte_position (TREE_OPERAND (target, 1));
target = TREE_OPERAND (target, 0);
}
else if (TREE_CODE (target) == ARRAY_REF)
{
- if (TREE_CODE (TREE_OPERAND (target, 1)) != INTEGER_CST
- || TREE_CODE (TYPE_SIZE (TREE_TYPE (target))) != INTEGER_CST)
- abort ();
- offset += ((TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (target)))
- * TREE_INT_CST_LOW (TREE_OPERAND (target, 1)))
- / BITS_PER_UNIT);
+ offset += (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (target)), 1)
+ * tree_low_cst (TREE_OPERAND (target, 1), 0));
target = TREE_OPERAND (target, 0);
}
else
@@ -4420,13 +4406,12 @@ output_constructor (exp, size)
register int fieldsize;
/* Since this structure is static,
we know the positions are constant. */
- int bitpos = (field ? (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
- / BITS_PER_UNIT)
- : 0);
+ HOST_WIDE_INT bitpos = field ? int_byte_position (field) : 0;
+
if (index != 0)
- bitpos = (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (val)))
- / BITS_PER_UNIT
- * (TREE_INT_CST_LOW (index) - min_index));
+ bitpos
+ = (tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (val)), 1)
+ * (tree_low_cst (index, 0) - min_index));
/* Output any buffered-up bit-fields preceding this element. */
if (byte_buffer_in_use)
@@ -4472,9 +4457,9 @@ output_constructor (exp, size)
{
/* Element that is a bit-field. */
- int next_offset = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field));
- int end_offset
- = (next_offset + TREE_INT_CST_LOW (DECL_SIZE (field)));
+ HOST_WIDE_INT next_offset = int_bit_position (field);
+ HOST_WIDE_INT end_offset
+ = (next_offset + tree_low_cst (DECL_SIZE (field), 1));
if (val == 0)
val = integer_zero_node;
@@ -4572,17 +4557,15 @@ output_constructor (exp, size)
take first the least significant bits of the value
and pack them starting at the least significant
bits of the bytes. */
- shift = (next_offset
- - TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)));
+ shift = next_offset - int_bit_position (field);
+
/* Don't try to take a bunch of bits that cross
the word boundary in the INTEGER_CST. We can
only select bits from the LOW or HIGH part
not from both. */
if (shift < HOST_BITS_PER_WIDE_INT
&& shift + this_time > HOST_BITS_PER_WIDE_INT)
- {
- this_time = (HOST_BITS_PER_WIDE_INT - shift);
- }
+ this_time = (HOST_BITS_PER_WIDE_INT - shift);
/* Now get the bits from the appropriate constant word. */
if (shift < HOST_BITS_PER_WIDE_INT)
@@ -4594,6 +4577,7 @@ output_constructor (exp, size)
}
else
abort ();
+
/* Get the result. This works only when:
1 <= this_time <= HOST_BITS_PER_WIDE_INT. */
byte |= (((value >> shift)
diff --git a/gcc/varray.h b/gcc/varray.h
index 69482a9a315..4e9b62f8421 100644
--- a/gcc/varray.h
+++ b/gcc/varray.h
@@ -168,6 +168,9 @@ extern varray_type varray_grow PARAMS ((varray_type, size_t));
#define VARRAY_SIZE(VA) ((VA)->num_elements)
+#define VARRAY_ACTIVE_SIZE(VA) ((VA)->elements_used)
+#define VARRAY_POP_ALL(VA) ((VA)->elements_used = 0)
+
/* Check for VARRAY_xxx macros being in bound. */
#if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
extern void varray_check_failed PARAMS ((varray_type, size_t,
diff --git a/gcc/version.c b/gcc/version.c
index fe14670443f..dab87187cd6 100644
--- a/gcc/version.c
+++ b/gcc/version.c
@@ -1,4 +1,4 @@
#include "gansidecl.h"
#include "version.h"
-const char *const version_string = "2.96 20000325 (experimental)";
+const char *const version_string = "2.96 20000408 (experimental)";
diff --git a/include/ChangeLog b/include/ChangeLog
index e36ba7070a3..e2bf4c15cbe 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,13 @@
+2000-04-05 Richard Henderson <rth@cygnus.com>
+
+ * splay-tree.h (splay_tree_remove): Declare.
+
+2000-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * hashtab.h (hashval_t): New type.
+ (htab_find_with_hash): Use it as an argument.
+ (htab_find_slot_with_hash): Likewise.
+
2000-03-14 Bernd Schmidt <bernds@cygnus.co.uk>
* hashtab.h (htab_trav): Modify type so that first arg is of type
diff --git a/include/hashtab.h b/include/hashtab.h
index 5fe239391ff..2426708e378 100644
--- a/include/hashtab.h
+++ b/include/hashtab.h
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This program is free software; you can redistribute it and/or modify
@@ -38,10 +38,13 @@ extern "C" {
#include <ansidecl.h>
+/* The type for a hash code. */
+typedef unsigned int hashval_t;
+
/* Callback function pointer types. */
/* Calculate hash of a table entry. */
-typedef unsigned int (*htab_hash) PARAMS ((const void *));
+typedef hashval_t (*htab_hash) PARAMS ((const void *));
/* Compare a table entry with a possible entry. The entry already in
the table always comes first, so the second element can be of a
@@ -109,9 +112,9 @@ extern void htab_empty PARAMS ((htab_t));
extern void *htab_find PARAMS ((htab_t, const void *));
extern void **htab_find_slot PARAMS ((htab_t, const void *, int));
extern void *htab_find_with_hash PARAMS ((htab_t, const void *,
- unsigned int));
+ hashval_t));
extern void **htab_find_slot_with_hash PARAMS ((htab_t, const void *,
- unsigned int, int));
+ hashval_t, int));
extern void htab_clear_slot PARAMS ((htab_t, void **));
extern void htab_remove_elt PARAMS ((htab_t, void *));
diff --git a/include/splay-tree.h b/include/splay-tree.h
index 6d70c8d9075..39882a4beac 100644
--- a/include/splay-tree.h
+++ b/include/splay-tree.h
@@ -99,6 +99,8 @@ extern splay_tree_node splay_tree_insert
PARAMS((splay_tree,
splay_tree_key,
splay_tree_value));
+extern void splay_tree_remove PARAMS((splay_tree,
+ splay_tree_key));
extern splay_tree_node splay_tree_lookup
PARAMS((splay_tree,
splay_tree_key));
diff --git a/libchill/ChangeLog b/libchill/ChangeLog
index cf6c965e7a7..7fefa5b663f 100644
--- a/libchill/ChangeLog
+++ b/libchill/ChangeLog
@@ -1,3 +1,7 @@
+Mon Apr 3 01:20:50 2000 George France <france@crl.dec.com>
+
+ * basicio.c (PATH_MAX): Always provide a definition.
+
Wed Oct 27 01:13:12 1999 Alan Modra <alan@SPRI.Levels.UniSA.Edu.Au>
* Makefile.in (config.status): Fix leading whitespace.
diff --git a/libchill/basicio.c b/libchill/basicio.c
index 7ff71d9f524..79fd9cbfa93 100644
--- a/libchill/basicio.c
+++ b/libchill/basicio.c
@@ -39,13 +39,15 @@ Boston, MA 02111-1307, USA. */
#include "fileio.h"
#ifndef PATH_MAX
-#ifdef _POSIX_PATH_MAX
-#define PATH_MAX _POSIX_PATH_MAX
-#else
-#ifdef MAXPATHLEN
-#define PATH_MAX MAXPATHLEN
-#endif
-#endif
+# ifdef _POSIX_PATH_MAX
+# define PATH_MAX _POSIX_PATH_MAX
+# else
+# ifdef MAXPATHLEN
+# define PATH_MAX MAXPATHLEN
+# else
+# define PATH_MAX 1024
+# endif
+# endif
#endif
static
diff --git a/libf2c/libF77/Version.c b/libf2c/libF77/Version.c
index 1c7ec6d37b3..e993f67650b 100644
--- a/libf2c/libF77/Version.c
+++ b/libf2c/libF77/Version.c
@@ -3,7 +3,7 @@ static char junk[] = "\n@(#)LIBF77 VERSION 19991115\n";
/*
*/
-char __G77_LIBF77_VERSION__[] = "0.5.25 20000325 (prerelease)";
+char __G77_LIBF77_VERSION__[] = "0.5.25 20000408 (prerelease)";
/*
2.00 11 June 1980. File version.c added to library.
diff --git a/libf2c/libI77/Version.c b/libf2c/libI77/Version.c
index 36bfd68ed8a..f00eae8897f 100644
--- a/libf2c/libI77/Version.c
+++ b/libf2c/libI77/Version.c
@@ -3,7 +3,7 @@ static char junk[] = "\n@(#) LIBI77 VERSION pjw,dmg-mods 19991115\n";
/*
*/
-char __G77_LIBI77_VERSION__[] = "0.5.25 20000325 (prerelease)";
+char __G77_LIBI77_VERSION__[] = "0.5.25 20000408 (prerelease)";
/*
2.01 $ format added
diff --git a/libf2c/libU77/Version.c b/libf2c/libU77/Version.c
index 99c8cf6e412..d1157b8d8cd 100644
--- a/libf2c/libU77/Version.c
+++ b/libf2c/libU77/Version.c
@@ -1,6 +1,6 @@
static char junk[] = "\n@(#) LIBU77 VERSION 19980709\n";
-char __G77_LIBU77_VERSION__[] = "0.5.25 20000325 (prerelease)";
+char __G77_LIBU77_VERSION__[] = "0.5.25 20000408 (prerelease)";
#include <stdio.h>
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index c858409d301..d78a86a3585 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,21 @@
+2000-04-05 Richard Henderson <rth@cygnus.com>
+
+ * splay-tree.c (splay_tree_remove): New.
+
+2000-03-30 Mark Mitchell <mark@codesourcery.com>
+
+ * hashtab.c (find_empty_slot_for_expand): Use hashval_t for hash
+ codes.
+ (htab_find_with_hash): Likewise.
+ (htab_find_slot_with_hash): Likewise.
+
+2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * hashtab.c (htab_find_with_hash): Avoid calculating hash2
+ unless it will be used. Rearrange loop for better
+ optimization.
+ (higher_prime_number): Add static prototype.
+
Thu Mar 16 01:33:58 2000 Jeffrey A Law (law@cygnus.com)
* Makefile.in (partition.o): Depend on config.h
diff --git a/libiberty/configure.bat b/libiberty/configure.bat
deleted file mode 100644
index 18881ac2f75..00000000000
--- a/libiberty/configure.bat
+++ /dev/null
@@ -1,14 +0,0 @@
-@echo off
-if "%1" == "h8/300" goto h8300
-
-echo Configuring libiberty for go32
-copy Makefile.dos Makefile
-echo #define NEED_sys_siglist 1 >> config.h
-echo #define NEED_psignal 1 >> config.h
-goto exit
-
-:h8300
-echo Configuring libiberty for H8/300
-copy Makefile.dos Makefile
-
-:exit
diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c
index 16c5d3e4b12..ba897b2b03d 100644
--- a/libiberty/hashtab.c
+++ b/libiberty/hashtab.c
@@ -1,5 +1,5 @@
/* An expandable hash tables datatype.
- Copyright (C) 1999 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
Contributed by Vladimir Makarov (vmakarov@cygnus.com).
This file is part of the libiberty library.
@@ -55,8 +55,10 @@ Boston, MA 02111-1307, USA. */
#define DELETED_ENTRY ((void *) 1)
+static unsigned long higher_prime_number PARAMS ((unsigned long));
+
/* The following function returns the nearest prime number which is
- greater than given source number. */
+ greater than a given source number. */
static unsigned long
higher_prime_number (n)
@@ -153,10 +155,10 @@ htab_empty (htab)
static void **
find_empty_slot_for_expand (htab, hash)
htab_t htab;
- unsigned int hash;
+ hashval_t hash;
{
size_t size = htab->size;
- unsigned int hash2 = 1 + hash % (size - 2);
+ hashval_t hash2 = 1 + hash % (size - 2);
unsigned int index = hash % size;
for (;;)
@@ -219,28 +221,35 @@ void *
htab_find_with_hash (htab, element, hash)
htab_t htab;
const void *element;
- unsigned int hash;
+ hashval_t hash;
{
- unsigned int index, hash2;
+ unsigned int index;
+ hashval_t hash2;
size_t size;
+ void *entry;
htab->searches++;
size = htab->size;
- hash2 = 1 + hash % (size - 2);
index = hash % size;
+ entry = htab->entries[index];
+ if (entry == EMPTY_ENTRY
+ || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
+ return entry;
+
+ hash2 = 1 + hash % (size - 2);
+
for (;;)
{
- void *entry = htab->entries[index];
- if (entry == EMPTY_ENTRY)
- return NULL;
- else if (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))
- return entry;
-
htab->collisions++;
index += hash2;
if (index >= size)
index -= size;
+
+ entry = htab->entries[index];
+ if (entry == EMPTY_ENTRY
+ || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element)))
+ return entry;
}
}
@@ -264,11 +273,12 @@ void **
htab_find_slot_with_hash (htab, element, hash, insert)
htab_t htab;
const void *element;
- unsigned int hash;
+ hashval_t hash;
int insert;
{
void **first_deleted_slot;
- unsigned int index, hash2;
+ unsigned int index;
+ hashval_t hash2;
size_t size;
if (insert && htab->size * 3 <= htab->n_elements * 4)
diff --git a/libiberty/makefile.dos b/libiberty/makefile.dos
deleted file mode 100644
index 7eba62c3395..00000000000
--- a/libiberty/makefile.dos
+++ /dev/null
@@ -1,29 +0,0 @@
-CFLAGS=-O2
-
-OBJS = \
- argv.o \
- basename.o \
- concat.o \
- cplus-dem.o \
- fdmatch.o \
- floatformat.o \
- getopt.o \
- getopt1.o \
- getruntime.o \
- hex.o \
- msdos.o \
- obstack.o \
- spaces.o \
- strerror.o \
- strsignal.o \
- xatexit.o \
- xexit.o \
- xmalloc.o \
- $E
-
-.c.o:
- gcc -I../include $(CFLAGS) -c $<
-
-libiberty.a : $(OBJS)
- -rm libiberty.a
- ar rvs libiberty.a $(OBJS)
diff --git a/libiberty/splay-tree.c b/libiberty/splay-tree.c
index 22ea07d84ad..de66d11bf56 100644
--- a/libiberty/splay-tree.c
+++ b/libiberty/splay-tree.c
@@ -309,6 +309,47 @@ splay_tree_insert (sp, key, value)
return sp->root;
}
+/* Remove KEY from SP. It is not an error if it did not exist. */
+
+void
+splay_tree_remove (sp, key)
+ splay_tree sp;
+ splay_tree_key key;
+{
+ splay_tree_splay (sp, key);
+
+ if (sp->root && (*sp->comp) (sp->root->key, key) == 0)
+ {
+ splay_tree_node left, right;
+
+ left = sp->root->left;
+ right = sp->root->right;
+
+ /* Delete the root node itself. */
+ if (sp->delete_value)
+ (*sp->delete_value) (sp->root->value);
+ free (sp->root);
+
+ /* One of the children is now the root. Doesn't matter much
+ which, so long as we preserve the properties of the tree. */
+ if (left)
+ {
+ sp->root = left;
+
+ /* If there was a right child as well, hang it off the
+ right-most leaf of the left child. */
+ if (right)
+ {
+ while (left->right)
+ left = left->right;
+ left->right = right;
+ }
+ }
+ else
+ sp->root = right;
+ }
+}
+
/* Lookup KEY in SP, returning VALUE if present, and NULL
otherwise. */
diff --git a/libio/ChangeLog b/libio/ChangeLog
index b15bc38955d..e1df607ebbe 100644
--- a/libio/ChangeLog
+++ b/libio/ChangeLog
@@ -1,3 +1,11 @@
+2000-04-02 Zack Weinberg <zack@wolery.cumb.org>
+
+ * configure.in: Indent the # of #include_next one space.
+
+2000-03-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * configure.in: -linux-gnu*, not -linux-gnu.
+
2000-01-28 Martin v. Löwis <loewis@informatik.hu-berlin.de>
* fstream.h (ifstream::ifstream): Add ios::in to mode.
diff --git a/libio/configure.in b/libio/configure.in
index ea59a131456..307316858b2 100644
--- a/libio/configure.in
+++ b/libio/configure.in
@@ -57,7 +57,7 @@ case "${target}" in
frags="linux.mt linuxaxp1.mt mtsafe.mt" ;;
*-linux-gnulibc1)
frags=linuxlibc1.mt ;;
- *-linux-gnu) frags="linux.mt mtsafe.mt" ;;
+ *-linux-gnu*) frags="linux.mt mtsafe.mt" ;;
*-sco3.2v[45]*) frags=sco4.mt ;;
*-isc*) frags=isc.mt ;;
*-netware*) frags=netware.mt ;;
@@ -104,12 +104,12 @@ case "${target}" in
cp ${srcdir}/config/linuxaxp1-libc-lock.h libc-lock.h
cp ${srcdir}/config/linuxaxp1-stdio-lock.h stdio-lock.h
;;
- *-linux-gnu)
+ *-linux-gnu*)
# We have a correct libc-lock.h in glibc 2.1 but not all glibc 2.0.
# Create a wrapper if necessary.
(echo "#include <bits/libc-lock.h>" | ${CC-cc} -E -) >/dev/null 2>&1 ||
{
- echo "#include_next <libc-lock.h>" > libc-lock.h
+ echo " #include_next <libc-lock.h>" > libc-lock.h
echo 'asm (".weak _pthread_cleanup_pop_restore");' >> libc-lock.h
echo 'asm (".weak _pthread_cleanup_push_defer");' >> libc-lock.h
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index 415102f5ab0..d09f4108ad5 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -1,3 +1,8 @@
+2000-03-29 Zack Weinberg <zack@wolery.cumb.org>
+
+ * objc/Protocol.h, objc/objc-list.h: Change #endif labels to
+ comments.
+
2000-02-23 Zack Weinberg <zack@wolery.cumb.org>
* Makefile.in: Add -DIN_TARGET_LIBS to ALL_CFLAGS.
diff --git a/libobjc/objc/Protocol.h b/libobjc/objc/Protocol.h
index c7464cf17a9..f54b7cd2393 100644
--- a/libobjc/objc/Protocol.h
+++ b/libobjc/objc/Protocol.h
@@ -55,4 +55,4 @@ Boston, MA 02111-1307, USA. */
-#endif __Protocol_INCLUDE_GNU
+#endif /* not __Protocol_INCLUDE_GNU */
diff --git a/libobjc/objc/objc-list.h b/libobjc/objc/objc-list.h
index 19760906238..de083a5861e 100644
--- a/libobjc/objc/objc-list.h
+++ b/libobjc/objc/objc-list.h
@@ -144,4 +144,4 @@ list_free(struct objc_list* list)
objc_free(list);
}
}
-#endif __GNU_OBJC_LIST_H
+#endif /* not __GNU_OBJC_LIST_H */
diff --git a/libstdc++/ChangeLog b/libstdc++/ChangeLog
index f4fa0434882..e5b6fc38e39 100644
--- a/libstdc++/ChangeLog
+++ b/libstdc++/ChangeLog
@@ -1,3 +1,7 @@
+2000-03-29 Jason Merrill <jason@casey.cygnus.com>
+
+ * configure.in: -linux-gnu*, not -linux-gnu.
+
2000-03-10 Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
* std/bastring.h (basic_string<>::push_back): Was missing.
diff --git a/libstdc++/configure.in b/libstdc++/configure.in
index 546fdb843c7..e87e049a17c 100644
--- a/libstdc++/configure.in
+++ b/libstdc++/configure.in
@@ -90,7 +90,7 @@ fi
case "${target}" in
alpha*-*-linux-gnulibc1) frags="${frags} linux.mt" ;;
powerpc*-*-linux-gnulibc1) frags="${frags} linux.mt" ;;
- *-*-linux-gnu) frags="${frags} linux.mt" ;;
+ *-*-linux-gnu*) frags="${frags} linux.mt" ;;
*-*-openbsd*)
case "x${enable_threads}" in
xyes|xposix) frags="${frags} openbsd.mt" ;;